packagefs: Remove support for multiple package domains per volume
That also get rid of the job stuff and the package loader thread.
This commit is contained in:
@@ -28,7 +28,6 @@ HAIKU_PACKAGE_FS_SOURCES =
|
|||||||
Query.cpp
|
Query.cpp
|
||||||
Package.cpp
|
Package.cpp
|
||||||
PackageDirectory.cpp
|
PackageDirectory.cpp
|
||||||
PackageDomain.cpp
|
|
||||||
PackageFile.cpp
|
PackageFile.cpp
|
||||||
PackageFSRoot.cpp
|
PackageFSRoot.cpp
|
||||||
PackageLeafNode.cpp
|
PackageLeafNode.cpp
|
||||||
|
|||||||
@@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "PackageDirectory.h"
|
#include "PackageDirectory.h"
|
||||||
#include "PackageDomain.h"
|
|
||||||
#include "PackageFile.h"
|
#include "PackageFile.h"
|
||||||
#include "PackageSymlink.h"
|
#include "PackageSymlink.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace BPackageKit;
|
using namespace BPackageKit;
|
||||||
@@ -300,9 +300,9 @@ private:
|
|||||||
// #pragma mark - Package
|
// #pragma mark - Package
|
||||||
|
|
||||||
|
|
||||||
Package::Package(PackageDomain* domain, dev_t deviceID, ino_t nodeID)
|
Package::Package(::Volume* volume, dev_t deviceID, ino_t nodeID)
|
||||||
:
|
:
|
||||||
fDomain(domain),
|
fVolume(volume),
|
||||||
fFileName(NULL),
|
fFileName(NULL),
|
||||||
fName(NULL),
|
fName(NULL),
|
||||||
fInstallPath(NULL),
|
fInstallPath(NULL),
|
||||||
@@ -461,7 +461,7 @@ Package::Open()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open the file
|
// open the file
|
||||||
fFD = openat(fDomain->DirectoryFD(), fFileName, O_RDONLY);
|
fFD = openat(fVolume->PackagesDirectoryFD(), fFileName, O_RDONLY);
|
||||||
if (fFD < 0) {
|
if (fFD < 0) {
|
||||||
ERROR("Failed to open package file \"%s\"\n", fFileName);
|
ERROR("Failed to open package file \"%s\"\n", fFileName);
|
||||||
return errno;
|
return errno;
|
||||||
|
|||||||
@@ -24,22 +24,22 @@
|
|||||||
using BPackageKit::BPackageArchitecture;
|
using BPackageKit::BPackageArchitecture;
|
||||||
|
|
||||||
|
|
||||||
class PackageDomain;
|
|
||||||
class PackageLinkDirectory;
|
class PackageLinkDirectory;
|
||||||
|
class Volume;
|
||||||
class Version;
|
class Version;
|
||||||
|
|
||||||
|
|
||||||
class Package : public BReferenceable,
|
class Package : public BReferenceable,
|
||||||
public DoublyLinkedListLinkImpl<Package> {
|
public DoublyLinkedListLinkImpl<Package> {
|
||||||
public:
|
public:
|
||||||
Package(PackageDomain* domain, dev_t deviceID,
|
Package(::Volume* volume, dev_t deviceID,
|
||||||
ino_t nodeID);
|
ino_t nodeID);
|
||||||
~Package();
|
~Package();
|
||||||
|
|
||||||
status_t Init(const char* fileName);
|
status_t Init(const char* fileName);
|
||||||
status_t Load();
|
status_t Load();
|
||||||
|
|
||||||
PackageDomain* Domain() const { return fDomain; }
|
::Volume* Volume() const { return fVolume; }
|
||||||
const char* FileName() const { return fFileName; }
|
const char* FileName() const { return fFileName; }
|
||||||
|
|
||||||
status_t SetName(const char* name);
|
status_t SetName(const char* name);
|
||||||
@@ -93,7 +93,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
PackageDomain* fDomain;
|
::Volume* fVolume;
|
||||||
char* fFileName;
|
char* fFileName;
|
||||||
char* fName;
|
char* fName;
|
||||||
char* fInstallPath;
|
char* fInstallPath;
|
||||||
|
|||||||
@@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "PackageDomain.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <NodeMonitor.h>
|
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
|
||||||
|
|
||||||
#include <fs/KPath.h>
|
|
||||||
#include <team.h>
|
|
||||||
#include <vfs.h>
|
|
||||||
|
|
||||||
#include "DebugSupport.h"
|
|
||||||
#include "Volume.h"
|
|
||||||
|
|
||||||
|
|
||||||
PackageDomain::PackageDomain(::Volume* volume)
|
|
||||||
:
|
|
||||||
fVolume(volume),
|
|
||||||
fPath(NULL),
|
|
||||||
fDirFD(-1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PackageDomain::~PackageDomain()
|
|
||||||
{
|
|
||||||
PRINT("PackageDomain::~PackageDomain()\n");
|
|
||||||
|
|
||||||
Package* package = fPackages.Clear(true);
|
|
||||||
while (package != NULL) {
|
|
||||||
Package* next = package->FileNameHashTableNext();
|
|
||||||
package->ReleaseReference();
|
|
||||||
package = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fDirFD >= 0)
|
|
||||||
close(fDirFD);
|
|
||||||
|
|
||||||
free(fPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
PackageDomain::Init(const char* path, struct stat* _st)
|
|
||||||
{
|
|
||||||
// Open the directory. We want the path be interpreted depending on from
|
|
||||||
// where it came (kernel or userland), but we always want a FD in the kernel
|
|
||||||
// I/O context. There's no VFS service method to do that for us, so we need
|
|
||||||
// to do that ourselves.
|
|
||||||
bool calledFromKernel
|
|
||||||
= team_get_current_team_id() == team_get_kernel_team_id();
|
|
||||||
// Not entirely correct, but good enough for now. The only alternative
|
|
||||||
// is to have that information passed in as well.
|
|
||||||
|
|
||||||
struct vnode* vnode;
|
|
||||||
status_t error;
|
|
||||||
if (path != NULL) {
|
|
||||||
error = vfs_get_vnode_from_path(path, calledFromKernel, &vnode);
|
|
||||||
} else {
|
|
||||||
// No path given -- use the "packages" directory at our mount point.
|
|
||||||
error = vfs_entry_ref_to_vnode(fVolume->MountPointDeviceID(),
|
|
||||||
fVolume->MountPointNodeID(), "packages", &vnode);
|
|
||||||
}
|
|
||||||
if (error != B_OK) {
|
|
||||||
ERROR("Failed to open package domain \"%s\"\n", strerror(error));
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
fDirFD = vfs_open_vnode(vnode, O_RDONLY, true);
|
|
||||||
|
|
||||||
if (fDirFD < 0) {
|
|
||||||
ERROR("Failed to open package domain \"%s\"\n", strerror(fDirFD));
|
|
||||||
vfs_put_vnode(vnode);
|
|
||||||
RETURN_ERROR(fDirFD);
|
|
||||||
}
|
|
||||||
// Our vnode reference has been transferred to the FD.
|
|
||||||
|
|
||||||
// Is it a directory at all?
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(fDirFD, &st) < 0)
|
|
||||||
RETURN_ERROR(errno);
|
|
||||||
|
|
||||||
fDeviceID = st.st_dev;
|
|
||||||
fNodeID = st.st_ino;
|
|
||||||
|
|
||||||
// get a normalized path
|
|
||||||
KPath normalizedPath;
|
|
||||||
if (normalizedPath.InitCheck() != B_OK)
|
|
||||||
RETURN_ERROR(normalizedPath.InitCheck());
|
|
||||||
|
|
||||||
char* normalizedPathBuffer = normalizedPath.LockBuffer();
|
|
||||||
error = vfs_entry_ref_to_path(fDeviceID, fNodeID, NULL,
|
|
||||||
normalizedPathBuffer, normalizedPath.BufferSize());
|
|
||||||
if (error != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
|
|
||||||
fPath = strdup(normalizedPathBuffer);
|
|
||||||
if (fPath == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
|
|
||||||
// init packages hash table
|
|
||||||
error = fPackages.Init();
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
if (_st != NULL)
|
|
||||||
*_st = st;
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PackageDomain::AddPackage(Package* package)
|
|
||||||
{
|
|
||||||
fPackages.Insert(package);
|
|
||||||
package->AcquireReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PackageDomain::RemovePackage(Package* package)
|
|
||||||
{
|
|
||||||
fPackages.Remove(package);
|
|
||||||
package->ReleaseReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Package*
|
|
||||||
PackageDomain::FindPackage(const char* fileName) const
|
|
||||||
{
|
|
||||||
return fPackages.Lookup(fileName);
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef PACKAGE_DOMAIN_H
|
|
||||||
#define PACKAGE_DOMAIN_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <Referenceable.h>
|
|
||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
|
||||||
|
|
||||||
#include "Package.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct stat;
|
|
||||||
|
|
||||||
class Volume;
|
|
||||||
|
|
||||||
|
|
||||||
class PackageDomain : public BReferenceable,
|
|
||||||
public DoublyLinkedListLinkImpl<PackageDomain> {
|
|
||||||
public:
|
|
||||||
PackageDomain(::Volume* volume);
|
|
||||||
~PackageDomain();
|
|
||||||
|
|
||||||
::Volume* Volume() const { return fVolume; }
|
|
||||||
const char* Path() const { return fPath; }
|
|
||||||
int DirectoryFD() { return fDirFD; }
|
|
||||||
dev_t DeviceID() { return fDeviceID; }
|
|
||||||
ino_t NodeID() { return fNodeID; }
|
|
||||||
|
|
||||||
status_t Init(const char* path, struct stat* _st);
|
|
||||||
|
|
||||||
void AddPackage(Package* package);
|
|
||||||
void RemovePackage(Package* package);
|
|
||||||
|
|
||||||
Package* FindPackage(const char* fileName) const;
|
|
||||||
|
|
||||||
const PackageFileNameHashTable& Packages() const
|
|
||||||
{ return fPackages; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
::Volume* fVolume;
|
|
||||||
char* fPath;
|
|
||||||
int fDirFD;
|
|
||||||
dev_t fDeviceID;
|
|
||||||
ino_t fNodeID;
|
|
||||||
PackageFileNameHashTable fPackages;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PACKAGE_DOMAIN_H
|
|
||||||
@@ -99,11 +99,11 @@ PackageLinkDirectory::AddPackage(Package* package,
|
|||||||
|
|
||||||
// Find the insertion point in the list. We sort by mount type -- the more
|
// Find the insertion point in the list. We sort by mount type -- the more
|
||||||
// specific the higher the priority.
|
// specific the higher the priority.
|
||||||
MountType mountType = package->Domain()->Volume()->MountType();
|
MountType mountType = package->Volume()->MountType();
|
||||||
Package* otherPackage = NULL;
|
Package* otherPackage = NULL;
|
||||||
for (PackageList::Iterator it = fPackages.GetIterator();
|
for (PackageList::Iterator it = fPackages.GetIterator();
|
||||||
(otherPackage = it.Next()) != NULL;) {
|
(otherPackage = it.Next()) != NULL;) {
|
||||||
if (otherPackage->Domain()->Volume()->MountType() <= mountType)
|
if (otherPackage->Volume()->MountType() <= mountType)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ PackageLinkSymlink::Update(Package* package, PackageLinksListener* listener)
|
|||||||
fLinkPath = package->InstallPath();
|
fLinkPath = package->InstallPath();
|
||||||
if (fLinkPath == NULL) {
|
if (fLinkPath == NULL) {
|
||||||
fLinkPath = link_path_for_mount_type(
|
fLinkPath = link_path_for_mount_type(
|
||||||
package->Domain()->Volume()->MountType());
|
package->Volume()->MountType());
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
fLinkPath = kUnknownLinkTarget;
|
fLinkPath = kUnknownLinkTarget;
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ ResolvableFamily::AddResolvable(Resolvable* resolvable,
|
|||||||
// Find the insertion point in the list. We sort by mount type -- the more
|
// Find the insertion point in the list. We sort by mount type -- the more
|
||||||
// specific the higher the priority.
|
// specific the higher the priority.
|
||||||
MountType mountType
|
MountType mountType
|
||||||
= resolvable->Package()->Domain()->Volume()->MountType();
|
= resolvable->Package()->Volume()->MountType();
|
||||||
Resolvable* otherResolvable = NULL;
|
Resolvable* otherResolvable = NULL;
|
||||||
for (FamilyResolvableList::Iterator it = fResolvables.GetIterator();
|
for (FamilyResolvableList::Iterator it = fResolvables.GetIterator();
|
||||||
(otherResolvable = it.Next()) != NULL;) {
|
(otherResolvable = it.Next()) != NULL;) {
|
||||||
if (otherResolvable->Package()->Domain()->Volume()->MountType()
|
if (otherResolvable->Package()->Volume()->MountType()
|
||||||
<= mountType) {
|
<= mountType) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
* Copyright 2009-2013, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
#include <fs/KPath.h>
|
||||||
|
#include <team.h>
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
|
|
||||||
#include "AttributeIndex.h"
|
#include "AttributeIndex.h"
|
||||||
@@ -63,51 +65,112 @@ const char* const* kHomeShineThroughDirectories
|
|||||||
const size_t kMaxActivationRequestSize = 10 * 1024 * 1024;
|
const size_t kMaxActivationRequestSize = 10 * 1024 * 1024;
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Job
|
// #pragma mark - ShineThroughDirectory
|
||||||
|
|
||||||
|
|
||||||
struct Volume::Job : DoublyLinkedListLinkImpl<Job> {
|
struct Volume::PackagesDirectory {
|
||||||
Job(Volume* volume)
|
PackagesDirectory()
|
||||||
:
|
:
|
||||||
fVolume(volume)
|
fPath(NULL),
|
||||||
|
fDirFD(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Job()
|
|
||||||
|
~PackagesDirectory()
|
||||||
{
|
{
|
||||||
|
if (fDirFD >= 0)
|
||||||
|
close(fDirFD);
|
||||||
|
|
||||||
|
free(fPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Do() = 0;
|
const char* Path() const
|
||||||
|
|
||||||
protected:
|
|
||||||
Volume* fVolume;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - AddPackageDomainJob
|
|
||||||
|
|
||||||
|
|
||||||
struct Volume::AddPackageDomainJob : Job {
|
|
||||||
AddPackageDomainJob(Volume* volume, PackageDomain* domain)
|
|
||||||
:
|
|
||||||
Job(volume),
|
|
||||||
fDomain(domain)
|
|
||||||
{
|
{
|
||||||
fDomain->AcquireReference();
|
return fPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~AddPackageDomainJob()
|
int DirectoryFD() const
|
||||||
{
|
{
|
||||||
fDomain->ReleaseReference();
|
return fDirFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Do()
|
dev_t DeviceID() const
|
||||||
{
|
{
|
||||||
fVolume->_AddPackageDomain(fDomain, true);
|
return fDeviceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
ino_t NodeID() const
|
||||||
|
{
|
||||||
|
return fNodeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t Init(const char* path, dev_t mountPointDeviceID,
|
||||||
|
ino_t mountPointNodeID, struct stat& _st)
|
||||||
|
{
|
||||||
|
// Open the directory. We want the path be interpreted depending on from
|
||||||
|
// where it came (kernel or userland), but we always want a FD in the
|
||||||
|
// kernel I/O context. There's no VFS service method to do that for us,
|
||||||
|
// so we need to do that ourselves.
|
||||||
|
bool calledFromKernel
|
||||||
|
= team_get_current_team_id() == team_get_kernel_team_id();
|
||||||
|
// Not entirely correct, but good enough for now. The only
|
||||||
|
// alternative is to have that information passed in as well.
|
||||||
|
|
||||||
|
struct vnode* vnode;
|
||||||
|
status_t error;
|
||||||
|
if (path != NULL) {
|
||||||
|
error = vfs_get_vnode_from_path(path, calledFromKernel, &vnode);
|
||||||
|
} else {
|
||||||
|
// No path given -- use the "packages" directory at our mount point.
|
||||||
|
error = vfs_entry_ref_to_vnode(mountPointDeviceID, mountPointNodeID,
|
||||||
|
"packages", &vnode);
|
||||||
|
}
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("Failed to open package domain \"%s\"\n", strerror(error));
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
fDirFD = vfs_open_vnode(vnode, O_RDONLY, true);
|
||||||
|
|
||||||
|
if (fDirFD < 0) {
|
||||||
|
ERROR("Failed to open package domain \"%s\"\n", strerror(fDirFD));
|
||||||
|
vfs_put_vnode(vnode);
|
||||||
|
RETURN_ERROR(fDirFD);
|
||||||
|
}
|
||||||
|
// Our vnode reference has been transferred to the FD.
|
||||||
|
|
||||||
|
// Is it a directory at all?
|
||||||
|
struct stat& st = _st;
|
||||||
|
if (fstat(fDirFD, &st) < 0)
|
||||||
|
RETURN_ERROR(errno);
|
||||||
|
|
||||||
|
fDeviceID = st.st_dev;
|
||||||
|
fNodeID = st.st_ino;
|
||||||
|
|
||||||
|
// get a normalized path
|
||||||
|
KPath normalizedPath;
|
||||||
|
if (normalizedPath.InitCheck() != B_OK)
|
||||||
|
RETURN_ERROR(normalizedPath.InitCheck());
|
||||||
|
|
||||||
|
char* normalizedPathBuffer = normalizedPath.LockBuffer();
|
||||||
|
error = vfs_entry_ref_to_path(fDeviceID, fNodeID, NULL,
|
||||||
|
normalizedPathBuffer, normalizedPath.BufferSize());
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
fPath = strdup(normalizedPathBuffer);
|
||||||
|
if (fPath == NULL)
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PackageDomain* fDomain;
|
char* fPath;
|
||||||
|
int fDirFD;
|
||||||
|
dev_t fDeviceID;
|
||||||
|
ino_t fNodeID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -264,22 +327,32 @@ Volume::Volume(fs_volume* fsVolume)
|
|||||||
fFSVolume(fsVolume),
|
fFSVolume(fsVolume),
|
||||||
fRootDirectory(NULL),
|
fRootDirectory(NULL),
|
||||||
fPackageFSRoot(NULL),
|
fPackageFSRoot(NULL),
|
||||||
fPackageLoader(-1),
|
fPackagesDirectory(NULL),
|
||||||
fNextNodeID(kRootDirectoryID + 1),
|
fNextNodeID(kRootDirectoryID + 1)
|
||||||
fTerminating(false)
|
|
||||||
{
|
{
|
||||||
rw_lock_init(&fLock, "packagefs volume");
|
rw_lock_init(&fLock, "packagefs volume");
|
||||||
mutex_init(&fJobQueueLock, "packagefs volume job queue");
|
|
||||||
fJobQueueCondition.Init(this, "packagefs volume job queue");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Volume::~Volume()
|
Volume::~Volume()
|
||||||
{
|
{
|
||||||
_TerminatePackageLoader();
|
// remove the packages from the node tree
|
||||||
|
{
|
||||||
|
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||||
|
VolumeWriteLocker volumeLocker(this);
|
||||||
|
for (PackageFileNameHashTable::Iterator it = fPackages.GetIterator();
|
||||||
|
Package* package = it.Next();) {
|
||||||
|
_RemovePackageContent(package, NULL, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (PackageDomain* packageDomain = fPackageDomains.Head())
|
// delete the packages
|
||||||
_RemovePackageDomain(packageDomain);
|
Package* package = fPackages.Clear(true);
|
||||||
|
while (package != NULL) {
|
||||||
|
Package* next = package->FileNameHashTableNext();
|
||||||
|
package->ReleaseReference();
|
||||||
|
package = next;
|
||||||
|
}
|
||||||
|
|
||||||
// delete all indices
|
// delete all indices
|
||||||
Index* index = fIndices.Clear(true);
|
Index* index = fIndices.Clear(true);
|
||||||
@@ -307,11 +380,17 @@ Volume::~Volume()
|
|||||||
if (fRootDirectory != NULL)
|
if (fRootDirectory != NULL)
|
||||||
fRootDirectory->ReleaseReference();
|
fRootDirectory->ReleaseReference();
|
||||||
|
|
||||||
mutex_destroy(&fJobQueueLock);
|
|
||||||
rw_lock_destroy(&fLock);
|
rw_lock_destroy(&fLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Volume::PackagesDirectoryFD() const
|
||||||
|
{
|
||||||
|
return fPackagesDirectory->DirectoryFD();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::Mount(const char* parameterString)
|
Volume::Mount(const char* parameterString)
|
||||||
{
|
{
|
||||||
@@ -324,6 +403,10 @@ Volume::Mount(const char* parameterString)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
error = fPackages.Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
error = fIndices.Init();
|
error = fIndices.Init();
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
@@ -425,14 +508,14 @@ Volume::Mount(const char* parameterString)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// create initial package domain
|
// create package domain
|
||||||
PackageDomain* packageDomain = new(std::nothrow) PackageDomain(this);
|
fPackagesDirectory = new(std::nothrow) PackagesDirectory;
|
||||||
if (packageDomain == NULL)
|
if (fPackagesDirectory == NULL)
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
BReference<PackageDomain> packageDomainReference(packageDomain, true);
|
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
error = packageDomain->Init(packages, &st);
|
error = fPackagesDirectory->Init(packages, fMountPoint.deviceID,
|
||||||
|
fMountPoint.nodeID, st);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
@@ -481,17 +564,11 @@ Volume::Mount(const char* parameterString)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// add initial package domain
|
// add initial packages
|
||||||
error = _AddPackageDomain(packageDomain, false);
|
error = _AddInitialPackages();
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// spawn package loader thread
|
|
||||||
fPackageLoader = spawn_kernel_thread(&_PackageLoaderEntry,
|
|
||||||
"package loader", B_NORMAL_PRIORITY, this);
|
|
||||||
if (fPackageLoader < 0)
|
|
||||||
RETURN_ERROR(fPackageLoader);
|
|
||||||
|
|
||||||
// publish the root node
|
// publish the root node
|
||||||
fRootDirectory->AcquireReference();
|
fRootDirectory->AcquireReference();
|
||||||
error = PublishVNode(fRootDirectory);
|
error = PublishVNode(fRootDirectory);
|
||||||
@@ -505,9 +582,6 @@ Volume::Mount(const char* parameterString)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// run the package loader
|
|
||||||
resume_thread(fPackageLoader);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,7 +589,6 @@ Volume::Mount(const char* parameterString)
|
|||||||
void
|
void
|
||||||
Volume::Unmount()
|
Volume::Unmount()
|
||||||
{
|
{
|
||||||
_TerminatePackageLoader();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -534,10 +607,8 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size)
|
|||||||
info.mountType = fMountType;
|
info.mountType = fMountType;
|
||||||
info.rootDeviceID = fPackageFSRoot->DeviceID();
|
info.rootDeviceID = fPackageFSRoot->DeviceID();
|
||||||
info.rootDirectoryID = fPackageFSRoot->NodeID();
|
info.rootDirectoryID = fPackageFSRoot->NodeID();
|
||||||
|
info.packagesDeviceID = fPackagesDirectory->DeviceID();
|
||||||
PackageDomain* domain = fPackageDomains.Head();
|
info.packagesDirectoryID = fPackagesDirectory->NodeID();
|
||||||
info.packagesDeviceID = domain != NULL ? domain->DeviceID() : -1;
|
|
||||||
info.packagesDirectoryID = domain != NULL ? domain->NodeID() : -1;
|
|
||||||
|
|
||||||
RETURN_ERROR(user_memcpy(buffer, &info, sizeof(info)));
|
RETURN_ERROR(user_memcpy(buffer, &info, sizeof(info)));
|
||||||
}
|
}
|
||||||
@@ -552,13 +623,9 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size)
|
|||||||
|
|
||||||
VolumeReadLocker volumeReadLocker(this);
|
VolumeReadLocker volumeReadLocker(this);
|
||||||
|
|
||||||
PackageDomain* domain = fPackageDomains.Head();
|
|
||||||
if (domain == NULL)
|
|
||||||
RETURN_ERROR(B_BAD_VALUE);
|
|
||||||
|
|
||||||
uint32 packageIndex = 0;
|
uint32 packageIndex = 0;
|
||||||
for (PackageFileNameHashTable::Iterator it
|
for (PackageFileNameHashTable::Iterator it
|
||||||
= domain->Packages().GetIterator(); it.HasNext();
|
= fPackages.GetIterator(); it.HasNext();
|
||||||
packageIndex++) {
|
packageIndex++) {
|
||||||
Package* package = it.Next();
|
Package* package = it.Next();
|
||||||
PackageFSPackageInfo info;
|
PackageFSPackageInfo info;
|
||||||
@@ -572,7 +639,7 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size)
|
|||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 packageCount = domain->Packages().CountElements();
|
uint32 packageCount = fPackages.CountElements();
|
||||||
RETURN_ERROR(user_memcpy(&request->packageCount, &packageCount,
|
RETURN_ERROR(user_memcpy(&request->packageCount, &packageCount,
|
||||||
sizeof(packageCount)));
|
sizeof(packageCount)));
|
||||||
}
|
}
|
||||||
@@ -685,28 +752,6 @@ Volume::PublishVNode(Node* node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::AddPackageDomain(const char* path)
|
|
||||||
{
|
|
||||||
PackageDomain* packageDomain = new(std::nothrow) PackageDomain(this);
|
|
||||||
if (packageDomain == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
BReference<PackageDomain> packageDomainReference(packageDomain, true);
|
|
||||||
|
|
||||||
status_t error = packageDomain->Init(path, NULL);
|
|
||||||
if (error != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
|
|
||||||
Job* job = new(std::nothrow) AddPackageDomainJob(this, packageDomain);
|
|
||||||
if (job == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
|
|
||||||
_PushJob(job);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Volume::PackageLinkNodeAdded(Node* node)
|
Volume::PackageLinkNodeAdded(Node* node)
|
||||||
{
|
{
|
||||||
@@ -736,84 +781,23 @@ Volume::PackageLinkNodeChanged(Node* node, uint32 statFields,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
|
||||||
Volume::_PackageLoaderEntry(void* data)
|
|
||||||
{
|
|
||||||
return ((Volume*)data)->_PackageLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::_PackageLoader()
|
Volume::_AddInitialPackages()
|
||||||
{
|
{
|
||||||
while (!fTerminating) {
|
dprintf("packagefs: Adding packages from \"%s\"\n",
|
||||||
MutexLocker jobQueueLocker(fJobQueueLock);
|
fPackagesDirectory->Path());
|
||||||
|
|
||||||
Job* job = fJobQueue.RemoveHead();
|
|
||||||
if (job == NULL) {
|
|
||||||
// no job yet -- wait for someone notifying us
|
|
||||||
ConditionVariableEntry waitEntry;
|
|
||||||
fJobQueueCondition.Add(&waitEntry);
|
|
||||||
jobQueueLocker.Unlock();
|
|
||||||
waitEntry.Wait();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do the job
|
|
||||||
jobQueueLocker.Unlock();
|
|
||||||
job->Do();
|
|
||||||
delete job;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Volume::_TerminatePackageLoader()
|
|
||||||
{
|
|
||||||
fTerminating = true;
|
|
||||||
|
|
||||||
if (fPackageLoader >= 0) {
|
|
||||||
MutexLocker jobQueueLocker(fJobQueueLock);
|
|
||||||
fJobQueueCondition.NotifyOne();
|
|
||||||
jobQueueLocker.Unlock();
|
|
||||||
|
|
||||||
wait_for_thread(fPackageLoader, NULL);
|
|
||||||
fPackageLoader = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty the job queue
|
|
||||||
while (Job* job = fJobQueue.RemoveHead())
|
|
||||||
delete job;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Volume::_PushJob(Job* job)
|
|
||||||
{
|
|
||||||
MutexLocker jobQueueLocker(fJobQueueLock);
|
|
||||||
fJobQueue.Add(job);
|
|
||||||
fJobQueueCondition.NotifyOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::_AddPackageDomain(PackageDomain* domain, bool notify)
|
|
||||||
{
|
|
||||||
dprintf("packagefs: Adding package domain \"%s\"\n", domain->Path());
|
|
||||||
|
|
||||||
// iterate through the dir and create packages
|
// iterate through the dir and create packages
|
||||||
int fd = dup(domain->DirectoryFD());
|
int fd = dup(fPackagesDirectory->DirectoryFD());
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ERROR("Failed to dup() package domain FD: %s\n", strerror(errno));
|
ERROR("Failed to dup() packages directory FD: %s\n", strerror(errno));
|
||||||
RETURN_ERROR(errno);
|
RETURN_ERROR(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
DIR* dir = fdopendir(fd);
|
DIR* dir = fdopendir(fd);
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
ERROR("Failed to open package domain directory \"%s\": %s\n",
|
ERROR("Failed to open packages directory \"%s\": %s\n",
|
||||||
domain->Path(), strerror(errno));
|
fPackagesDirectory->Path(), strerror(errno));
|
||||||
RETURN_ERROR(errno);
|
RETURN_ERROR(errno);
|
||||||
}
|
}
|
||||||
CObjectDeleter<DIR, int> dirCloser(dir, closedir);
|
CObjectDeleter<DIR, int> dirCloser(dir, closedir);
|
||||||
@@ -824,53 +808,56 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Package* package;
|
Package* package;
|
||||||
if (_LoadPackage(domain, entry->d_name, package) != B_OK)
|
if (_LoadPackage(entry->d_name, package) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
BReference<Package> packageReference(package, true);
|
BReference<Package> packageReference(package, true);
|
||||||
|
|
||||||
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||||
VolumeWriteLocker volumeLocker(this);
|
VolumeWriteLocker volumeLocker(this);
|
||||||
domain->AddPackage(package);
|
_AddPackage(package);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the packages to the node tree
|
// add the packages to the node tree
|
||||||
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
||||||
VolumeWriteLocker volumeLocker(this);
|
VolumeWriteLocker volumeLocker(this);
|
||||||
for (PackageFileNameHashTable::Iterator it
|
for (PackageFileNameHashTable::Iterator it = fPackages.GetIterator();
|
||||||
= domain->Packages().GetIterator(); Package* package = it.Next();) {
|
Package* package = it.Next();) {
|
||||||
status_t error = _AddPackageContent(package, notify);
|
status_t error = _AddPackageContent(package, false);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
for (it.Rewind(); Package* activePackage = it.Next();) {
|
for (it.Rewind(); Package* activePackage = it.Next();) {
|
||||||
if (activePackage == package)
|
if (activePackage == package)
|
||||||
break;
|
break;
|
||||||
_RemovePackageContent(activePackage, NULL, notify);
|
_RemovePackageContent(activePackage, NULL, false);
|
||||||
}
|
}
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fPackageDomains.Add(domain);
|
|
||||||
domain->AcquireReference();
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
inline void
|
||||||
Volume::_RemovePackageDomain(PackageDomain* domain)
|
Volume::_AddPackage(Package* package)
|
||||||
{
|
{
|
||||||
// remove the domain's packages from the node tree
|
fPackages.Insert(package);
|
||||||
VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf());
|
package->AcquireReference();
|
||||||
VolumeWriteLocker volumeLocker(this);
|
}
|
||||||
for (PackageFileNameHashTable::Iterator it
|
|
||||||
= domain->Packages().GetIterator(); Package* package = it.Next();) {
|
|
||||||
_RemovePackageContent(package, NULL, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the domain
|
|
||||||
fPackageDomains.Remove(domain);
|
inline void
|
||||||
domain->ReleaseReference();
|
Volume::_RemovePackage(Package* package)
|
||||||
|
{
|
||||||
|
fPackages.Remove(package);
|
||||||
|
package->ReleaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Package*
|
||||||
|
Volume::_FindPackage(const char* fileName) const
|
||||||
|
{
|
||||||
|
return fPackages.Lookup(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1336,19 +1323,18 @@ Volume::_RemoveNodeAndVNode(Node* node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
status_t
|
||||||
Volume::_LoadPackage(PackageDomain* domain, const char* name,
|
Volume::_LoadPackage(const char* name, Package*& _package)
|
||||||
Package*& _package)
|
|
||||||
{
|
{
|
||||||
// check whether the entry is a file
|
// check whether the entry is a file
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstatat(domain->DirectoryFD(), name, &st, 0) < 0
|
if (fstatat(fPackagesDirectory->DirectoryFD(), name, &st, 0) < 0
|
||||||
|| !S_ISREG(st.st_mode)) {
|
|| !S_ISREG(st.st_mode)) {
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a package
|
// create a package
|
||||||
Package* package = new(std::nothrow) Package(domain, st.st_dev, st.st_ino);
|
Package* package = new(std::nothrow) Package(this, st.st_dev, st.st_ino);
|
||||||
if (package == NULL)
|
if (package == NULL)
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
BReference<Package> packageReference(package, true);
|
BReference<Package> packageReference(package, true);
|
||||||
@@ -1369,12 +1355,6 @@ Volume::_LoadPackage(PackageDomain* domain, const char* name,
|
|||||||
status_t
|
status_t
|
||||||
Volume::_ChangeActivation(ActivationChangeRequest& request)
|
Volume::_ChangeActivation(ActivationChangeRequest& request)
|
||||||
{
|
{
|
||||||
// TODO: Would need locking, but will be irrelevant when removing the support
|
|
||||||
// for multiple package domains.
|
|
||||||
PackageDomain* domain = fPackageDomains.Head();
|
|
||||||
if (domain == NULL)
|
|
||||||
RETURN_ERROR(B_BAD_VALUE);
|
|
||||||
|
|
||||||
// first check the request
|
// first check the request
|
||||||
int32 newPackageCount = 0;
|
int32 newPackageCount = 0;
|
||||||
int32 oldPackageCount = 0;
|
int32 oldPackageCount = 0;
|
||||||
@@ -1384,14 +1364,14 @@ Volume::_ChangeActivation(ActivationChangeRequest& request)
|
|||||||
for (ActivationChangeRequest::Iterator it = request.GetIterator();
|
for (ActivationChangeRequest::Iterator it = request.GetIterator();
|
||||||
it.HasNext();) {
|
it.HasNext();) {
|
||||||
PackageFSActivationChangeItem* item = it.Next();
|
PackageFSActivationChangeItem* item = it.Next();
|
||||||
if (item->parentDeviceID != domain->DeviceID()
|
if (item->parentDeviceID != fPackagesDirectory->DeviceID()
|
||||||
|| item->parentDirectoryID != domain->NodeID()) {
|
|| item->parentDirectoryID != fPackagesDirectory->NodeID()) {
|
||||||
ERROR("Volume::_ChangeActivation(): mismatching packages "
|
ERROR("Volume::_ChangeActivation(): mismatching packages "
|
||||||
"domain\n");
|
"directory\n");
|
||||||
RETURN_ERROR(B_BAD_VALUE);
|
RETURN_ERROR(B_BAD_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Package* package = domain->FindPackage(item->name);
|
Package* package = _FindPackage(item->name);
|
||||||
// TODO: We should better look up the package by node_ref!
|
// TODO: We should better look up the package by node_ref!
|
||||||
if (item->type == PACKAGE_FS_ACTIVATE_PACKAGE) {
|
if (item->type == PACKAGE_FS_ACTIVATE_PACKAGE) {
|
||||||
if (package != NULL) {
|
if (package != NULL) {
|
||||||
@@ -1449,7 +1429,7 @@ INFORM("Volume::_ChangeActivation(): %" B_PRId32 " new packages, %" B_PRId32 " o
|
|||||||
}
|
}
|
||||||
|
|
||||||
Package* package;
|
Package* package;
|
||||||
status_t error = _LoadPackage(domain, item->name, package);
|
status_t error = _LoadPackage(item->name, package);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
ERROR("Volume::_ChangeActivation(): failed to load package "
|
ERROR("Volume::_ChangeActivation(): failed to load package "
|
||||||
"\"%s\"\n", item->name);
|
"\"%s\"\n", item->name);
|
||||||
@@ -1476,11 +1456,11 @@ INFORM("Volume::_ChangeActivation(): %" B_PRId32 " new packages, %" B_PRId32 " o
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Package* package = domain->FindPackage(item->name);
|
Package* package = _FindPackage(item->name);
|
||||||
// TODO: We should better look up the package by node_ref!
|
// TODO: We should better look up the package by node_ref!
|
||||||
oldPackageReferences[oldPackageIndex++].SetTo(package);
|
oldPackageReferences[oldPackageIndex++].SetTo(package);
|
||||||
_RemovePackageContent(package, NULL, true);
|
_RemovePackageContent(package, NULL, true);
|
||||||
domain->RemovePackage(package);
|
_RemovePackage(package);
|
||||||
INFORM("package \"%s\" deactivated\n", package->FileName());
|
INFORM("package \"%s\" deactivated\n", package->FileName());
|
||||||
}
|
}
|
||||||
// TODO: Since package removal cannot fail, consider adding the new packages
|
// TODO: Since package removal cannot fail, consider adding the new packages
|
||||||
@@ -1492,12 +1472,12 @@ INFORM("package \"%s\" deactivated\n", package->FileName());
|
|||||||
for (newPackageIndex = 0; newPackageIndex < newPackageCount;
|
for (newPackageIndex = 0; newPackageIndex < newPackageCount;
|
||||||
newPackageIndex++) {
|
newPackageIndex++) {
|
||||||
Package* package = newPackageReferences[newPackageIndex];
|
Package* package = newPackageReferences[newPackageIndex];
|
||||||
domain->AddPackage(package);
|
_AddPackage(package);
|
||||||
|
|
||||||
// add the package to the node tree
|
// add the package to the node tree
|
||||||
error = _AddPackageContent(package, true);
|
error = _AddPackageContent(package, true);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
domain->RemovePackage(package);
|
_RemovePackage(package);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
INFORM("package \"%s\" activated\n", package->FileName());
|
INFORM("package \"%s\" activated\n", package->FileName());
|
||||||
@@ -1508,19 +1488,19 @@ INFORM("package \"%s\" activated\n", package->FileName());
|
|||||||
for (int32 i = newPackageIndex - 1; i >= 0; i--) {
|
for (int32 i = newPackageIndex - 1; i >= 0; i--) {
|
||||||
Package* package = newPackageReferences[i];
|
Package* package = newPackageReferences[i];
|
||||||
_RemovePackageContent(package, NULL, true);
|
_RemovePackageContent(package, NULL, true);
|
||||||
domain->RemovePackage(package);
|
_RemovePackage(package);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 i = oldPackageCount - 1; i >= 0; i--) {
|
for (int32 i = oldPackageCount - 1; i >= 0; i--) {
|
||||||
Package* package = oldPackageReferences[i];
|
Package* package = oldPackageReferences[i];
|
||||||
domain->AddPackage(package);
|
_AddPackage(package);
|
||||||
|
|
||||||
if (_AddPackageContent(package, true) != B_OK) {
|
if (_AddPackageContent(package, true) != B_OK) {
|
||||||
// nothing we can do here
|
// nothing we can do here
|
||||||
ERROR("Volume::_ChangeActivation(): failed to roll back "
|
ERROR("Volume::_ChangeActivation(): failed to roll back "
|
||||||
"deactivation of package \"%s\" after error\n",
|
"deactivation of package \"%s\" after error\n",
|
||||||
package->FileName());
|
package->FileName());
|
||||||
domain->RemovePackage(package);
|
_RemovePackage(package);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef VOLUME_H
|
#ifndef VOLUME_H
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "Index.h"
|
#include "Index.h"
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
#include "NodeListener.h"
|
#include "NodeListener.h"
|
||||||
#include "PackageDomain.h"
|
#include "Package.h"
|
||||||
#include "PackageLinksListener.h"
|
#include "PackageLinksListener.h"
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
|
|
||||||
@@ -51,6 +51,8 @@ public:
|
|||||||
|
|
||||||
::MountType MountType() const { return fMountType; }
|
::MountType MountType() const { return fMountType; }
|
||||||
|
|
||||||
|
int PackagesDirectoryFD() const;
|
||||||
|
|
||||||
void SetPackageFSRoot(::PackageFSRoot* root)
|
void SetPackageFSRoot(::PackageFSRoot* root)
|
||||||
{ fPackageFSRoot = root; }
|
{ fPackageFSRoot = root; }
|
||||||
::PackageFSRoot* PackageFSRoot() const
|
::PackageFSRoot* PackageFSRoot() const
|
||||||
@@ -94,8 +96,6 @@ public:
|
|||||||
status_t RemoveVNode(ino_t nodeID);
|
status_t RemoveVNode(ino_t nodeID);
|
||||||
status_t PublishVNode(Node* node);
|
status_t PublishVNode(Node* node);
|
||||||
|
|
||||||
status_t AddPackageDomain(const char* path);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// PackageLinksListener
|
// PackageLinksListener
|
||||||
virtual void PackageLinkNodeAdded(Node* node);
|
virtual void PackageLinkNodeAdded(Node* node);
|
||||||
@@ -105,29 +105,16 @@ private:
|
|||||||
const OldNodeAttributes& oldAttributes);
|
const OldNodeAttributes& oldAttributes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Job;
|
struct PackagesDirectory;
|
||||||
struct AddPackageDomainJob;
|
|
||||||
struct DomainDirectoryEventJob;
|
|
||||||
struct ShineThroughDirectory;
|
struct ShineThroughDirectory;
|
||||||
struct ActivationChangeRequest;
|
struct ActivationChangeRequest;
|
||||||
|
|
||||||
friend struct AddPackageDomainJob;
|
|
||||||
|
|
||||||
typedef DoublyLinkedList<Job> JobList;
|
|
||||||
typedef DoublyLinkedList<PackageDomain> PackageDomainList;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static status_t _PackageLoaderEntry(void* data);
|
status_t _AddInitialPackages();
|
||||||
status_t _PackageLoader();
|
|
||||||
|
|
||||||
void _TerminatePackageLoader();
|
inline void _AddPackage(Package* package);
|
||||||
|
inline void _RemovePackage(Package* package);
|
||||||
void _PushJob(Job* job);
|
inline Package* _FindPackage(const char* fileName) const;
|
||||||
|
|
||||||
status_t _AddInitialPackageDomain(const char* path);
|
|
||||||
status_t _AddPackageDomain(PackageDomain* domain,
|
|
||||||
bool notify);
|
|
||||||
void _RemovePackageDomain(PackageDomain* domain);
|
|
||||||
|
|
||||||
status_t _AddPackageContent(Package* package,
|
status_t _AddPackageContent(Package* package,
|
||||||
bool notify);
|
bool notify);
|
||||||
@@ -155,8 +142,8 @@ private:
|
|||||||
void _RemoveNodeAndVNode(Node* node);
|
void _RemoveNodeAndVNode(Node* node);
|
||||||
// caller must hold a reference
|
// caller must hold a reference
|
||||||
|
|
||||||
static status_t _LoadPackage(PackageDomain* domain,
|
status_t _LoadPackage(const char* name,
|
||||||
const char* name, Package*& _package);
|
Package*& _package);
|
||||||
|
|
||||||
status_t _ChangeActivation(
|
status_t _ChangeActivation(
|
||||||
ActivationChangeRequest& request);
|
ActivationChangeRequest& request);
|
||||||
@@ -187,8 +174,7 @@ private:
|
|||||||
Directory* fRootDirectory;
|
Directory* fRootDirectory;
|
||||||
::PackageFSRoot* fPackageFSRoot;
|
::PackageFSRoot* fPackageFSRoot;
|
||||||
::MountType fMountType;
|
::MountType fMountType;
|
||||||
thread_id fPackageLoader;
|
PackagesDirectory* fPackagesDirectory;
|
||||||
PackageDomainList fPackageDomains;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
dev_t deviceID;
|
dev_t deviceID;
|
||||||
@@ -197,16 +183,11 @@ private:
|
|||||||
|
|
||||||
NodeIDHashTable fNodes;
|
NodeIDHashTable fNodes;
|
||||||
NodeListenerHashTable fNodeListeners;
|
NodeListenerHashTable fNodeListeners;
|
||||||
|
PackageFileNameHashTable fPackages;
|
||||||
QueryList fQueries;
|
QueryList fQueries;
|
||||||
IndexHashTable fIndices;
|
IndexHashTable fIndices;
|
||||||
|
|
||||||
JobList fJobQueue;
|
|
||||||
mutex fJobQueueLock;
|
|
||||||
ConditionVariable fJobQueueCondition;
|
|
||||||
|
|
||||||
ino_t fNextNodeID;
|
ino_t fNextNodeID;
|
||||||
|
|
||||||
volatile bool fTerminating;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user