added 2 changesets to branch 'refs/remotes/HaikuPM-github/package-management' old head: 3d53bd473b49aa91a9611dfe6500492500e1e8c6 new head: 6978941aac85ea329a8552253f384924dcccd1b3 overview: https://github.com/haiku/HaikuPM/compare/3d53bd4...6978941 ---------------------------------------------------------------------------- af5c10a: packagefs: Remove the packages directory node monitoring 6978941: packagefs: Remove support for multiple package domains per volume That also get rid of the job stuff and the package loader thread. [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] ---------------------------------------------------------------------------- 10 files changed, 196 insertions(+), 691 deletions(-) .../kernel/file_systems/packagefs/Jamfile | 1 - .../kernel/file_systems/packagefs/Package.cpp | 8 +- .../kernel/file_systems/packagefs/Package.h | 8 +- .../file_systems/packagefs/PackageDomain.cpp | 166 ------ .../file_systems/packagefs/PackageDomain.h | 57 -- .../packagefs/PackageLinkDirectory.cpp | 4 +- .../packagefs/PackageLinkSymlink.cpp | 2 +- .../file_systems/packagefs/ResolvableFamily.cpp | 4 +- .../kernel/file_systems/packagefs/Volume.cpp | 570 ++++++------------- .../kernel/file_systems/packagefs/Volume.h | 67 +-- ############################################################################ Commit: af5c10ab19555126fc60d7766330ba1cc789cf52 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Apr 7 10:21:54 2013 UTC packagefs: Remove the packages directory node monitoring ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp index d3e48d0..69e5248 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp @@ -16,8 +16,6 @@ #include <AutoDeleter.h> #include <fs/KPath.h> -#include <fs/node_monitor.h> -#include <Notifications.h> #include <team.h> #include <vfs.h> @@ -29,8 +27,7 @@ PackageDomain::PackageDomain(::Volume* volume) : fVolume(volume), fPath(NULL), - fDirFD(-1), - fListener(NULL) + fDirFD(-1) { } @@ -39,11 +36,6 @@ PackageDomain::~PackageDomain() { PRINT("PackageDomain::~PackageDomain()\n"); - if (fListener != NULL) { - remove_node_listener(fDeviceID, fNodeID, *fListener); - delete fListener; - } - Package* package = fPackages.Clear(true); while (package != NULL) { Package* next = package->FileNameHashTableNext(); @@ -128,21 +120,6 @@ PackageDomain::Init(const char* path, struct stat* _st) } -status_t -PackageDomain::Prepare(NotificationListener* listener) -{ - ObjectDeleter<NotificationListener> listenerDeleter(listener); - - status_t error = add_node_listener(fDeviceID, fNodeID, B_WATCH_DIRECTORY, - *listener); - if (error != B_OK) - RETURN_ERROR(error); - fListener = listenerDeleter.Detach(); - - return B_OK; -} - - void PackageDomain::AddPackage(Package* package) { diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h b/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h index 0442547..2c8dd56 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h @@ -15,7 +15,6 @@ struct stat; -class NotificationListener; class Volume; @@ -32,8 +31,6 @@ public: ino_t NodeID() { return fNodeID; } status_t Init(const char* path, struct stat* _st); - status_t Prepare(NotificationListener* listener); - // takes over ownership of the listener void AddPackage(Package* package); void RemovePackage(Package* package); @@ -49,7 +46,6 @@ private: int fDirFD; dev_t fDeviceID; ino_t fNodeID; - NotificationListener* fListener; PackageFileNameHashTable fPackages; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp index 934f7f7..4c4f9c9 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp @@ -23,7 +23,6 @@ #include <AutoDeleter.h> -#include <Notifications.h> #include <vfs.h> #include "AttributeIndex.h" @@ -112,72 +111,6 @@ private: }; -// #pragma mark - DomainDirectoryEventJob - - -struct Volume::DomainDirectoryEventJob : Job { - DomainDirectoryEventJob(Volume* volume, PackageDomain* domain) - : - Job(volume), - fDomain(domain), - fEvent() - { - fDomain->AcquireReference(); - } - - virtual ~DomainDirectoryEventJob() - { - fDomain->ReleaseReference(); - } - - status_t Init(const KMessage* event) - { - RETURN_ERROR(fEvent.SetTo(event->Buffer(), -1, - KMessage::KMESSAGE_CLONE_BUFFER)); - } - - virtual void Do() - { - fVolume->_DomainListenerEventOccurred(fDomain, &fEvent); - } - -private: - PackageDomain* fDomain; - KMessage fEvent; -}; - - -// #pragma mark - DomainDirectoryListener - - -struct Volume::DomainDirectoryListener : NotificationListener { - DomainDirectoryListener(Volume* volume, PackageDomain* domain) - : - fVolume(volume), - fDomain(domain) - { - } - - virtual void EventOccurred(NotificationService& service, - const KMessage* event) - { -// TODO: Remove! -// DomainDirectoryEventJob* job = new(std::nothrow) -// DomainDirectoryEventJob(fVolume, fDomain); -// if (job == NULL || job->Init(event)) { -// delete job; -// return; -// } -// -// fVolume->_PushJob(job); - } - -private: - Volume* fVolume; - PackageDomain* fDomain; -}; - - // #pragma mark - ShineThroughDirectory @@ -870,20 +803,6 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify) { dprintf("packagefs: Adding package domain \"%s\"\n", domain->Path()); - // create a directory listener - DomainDirectoryListener* listener = new(std::nothrow) - DomainDirectoryListener(this, domain); - if (listener == NULL) - RETURN_ERROR(B_NO_MEMORY); - - // prepare the package domain - status_t error = domain->Prepare(listener); - if (error != B_OK) { - ERROR("Failed to prepare package domain \"%s\": %s\n", - domain->Path(), strerror(errno)); - RETURN_ERROR(errno); - } - // iterate through the dir and create packages int fd = dup(domain->DirectoryFD()); if (fd < 0) { @@ -904,9 +823,15 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify) if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - _DomainEntryCreated(domain, domain->DeviceID(), domain->NodeID(), - -1, entry->d_name, false, notify); -// TODO: -1 node ID? + Package* package; + if (_LoadPackage(domain, entry->d_name, package) != B_OK) + continue; + BReference<Package> packageReference(package, true); + + VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf()); + VolumeWriteLocker volumeLocker(this); + domain->AddPackage(package); + } // add the packages to the node tree @@ -914,7 +839,7 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify) VolumeWriteLocker volumeLocker(this); for (PackageFileNameHashTable::Iterator it = domain->Packages().GetIterator(); Package* package = it.Next();) { - error = _AddPackageContent(package, notify); + status_t error = _AddPackageContent(package, notify); if (error != B_OK) { for (it.Rewind(); Package* activePackage = it.Next();) { if (activePackage == package) @@ -1411,141 +1336,6 @@ Volume::_RemoveNodeAndVNode(Node* node) } -void -Volume::_DomainListenerEventOccurred(PackageDomain* domain, - const KMessage* event) -{ - int32 opcode; - if (event->What() != B_NODE_MONITOR - || event->FindInt32("opcode", &opcode) != B_OK) { - return; - } - - switch (opcode) { - case B_ENTRY_CREATED: - { - int32 device; - int64 directory; - int64 node; - const char* name; - if (event->FindInt32("device", &device) == B_OK - && event->FindInt64("directory", &directory) == B_OK - && event->FindInt64("node", &node) == B_OK - && event->FindString("name", &name) == B_OK) { - _DomainEntryCreated(domain, device, directory, node, name, - true, true); - } - break; - } - - case B_ENTRY_REMOVED: - { - int32 device; - int64 directory; - int64 node; - const char* name; - if (event->FindInt32("device", &device) == B_OK - && event->FindInt64("directory", &directory) == B_OK - && event->FindInt64("node", &node) == B_OK - && event->FindString("name", &name) == B_OK) { - _DomainEntryRemoved(domain, device, directory, node, name, - true); - } - break; - } - - case B_ENTRY_MOVED: - { - int32 device; - int64 fromDirectory; - int64 toDirectory; - int32 nodeDevice; - int64 node; - const char* fromName; - const char* name; - if (event->FindInt32("device", &device) == B_OK - && event->FindInt64("from directory", &fromDirectory) == B_OK - && event->FindInt64("to directory", &toDirectory) == B_OK - && event->FindInt32("node device", &nodeDevice) == B_OK - && event->FindInt64("node", &node) == B_OK - && event->FindString("from name", &fromName) == B_OK - && event->FindString("name", &name) == B_OK) { - _DomainEntryMoved(domain, device, fromDirectory, toDirectory, - nodeDevice, node, fromName, name, true); - } - break; - } - - default: - break; - } -} - - -void -Volume::_DomainEntryCreated(PackageDomain* domain, dev_t deviceID, - ino_t directoryID, ino_t nodeID, const char* name, bool addContent, - bool notify) -{ - // let's see, if things look plausible - if (deviceID != domain->DeviceID() || directoryID != domain->NodeID() - || domain->FindPackage(name) != NULL) { - return; - } - - Package* package; - if (_LoadPackage(domain, name, package) != B_OK) - return; - BReference<Package> packageReference(package, true); - - VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf()); - VolumeWriteLocker volumeLocker(this); - domain->AddPackage(package); - - // add the package to the node tree - if (addContent) { - status_t error = _AddPackageContent(package, notify); - if (error != B_OK) { - domain->RemovePackage(package); - return; - } - } -} - - -void -Volume::_DomainEntryRemoved(PackageDomain* domain, dev_t deviceID, - ino_t directoryID, ino_t nodeID, const char* name, bool notify) -{ - // let's see, if things look plausible - if (deviceID != domain->DeviceID() || directoryID != domain->NodeID()) - return; - - Package* package = domain->FindPackage(name); - if (package == NULL) - return; - BReference<Package> packageReference(package); - - // remove the package - VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf()); - VolumeWriteLocker volumeLocker(this); - _RemovePackageContent(package, NULL, true); - domain->RemovePackage(package); -} - - -void -Volume::_DomainEntryMoved(PackageDomain* domain, dev_t deviceID, - ino_t fromDirectoryID, ino_t toDirectoryID, dev_t nodeDeviceID, - ino_t nodeID, const char* fromName, const char* name, bool notify) -{ - _DomainEntryRemoved(domain, deviceID, fromDirectoryID, nodeID, fromName, - notify); - _DomainEntryCreated(domain, deviceID, toDirectoryID, nodeID, name, true, - notify); -} - - /*static*/ status_t Volume::_LoadPackage(PackageDomain* domain, const char* name, Package*& _package) diff --git a/src/add-ons/kernel/file_systems/packagefs/Volume.h b/src/add-ons/kernel/file_systems/packagefs/Volume.h index 66c12d9..2064063 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Volume.h +++ b/src/add-ons/kernel/file_systems/packagefs/Volume.h @@ -108,15 +108,10 @@ private: struct Job; struct AddPackageDomainJob; struct DomainDirectoryEventJob; - struct PackageLoaderErrorOutput; - struct PackageLoaderContentHandler; - struct DomainDirectoryListener; struct ShineThroughDirectory; struct ActivationChangeRequest; friend struct AddPackageDomainJob; - friend struct DomainDirectoryEventJob; - friend struct DomainDirectoryListener; typedef DoublyLinkedList<Job> JobList; typedef DoublyLinkedList<PackageDomain> PackageDomainList; @@ -160,23 +155,6 @@ private: void _RemoveNodeAndVNode(Node* node); // caller must hold a reference - void _DomainListenerEventOccurred( - PackageDomain* domain, - const KMessage* event); - void _DomainEntryCreated(PackageDomain* domain, - dev_t deviceID, ino_t directoryID, - ino_t nodeID, const char* name, - bool addContent, bool notify); - void _DomainEntryRemoved(PackageDomain* domain, - dev_t deviceID, ino_t directoryID, - ino_t nodeID, const char* name, - bool notify); - void _DomainEntryMoved(PackageDomain* domain, - dev_t deviceID, ino_t fromDirectoryID, - ino_t toDirectoryID, dev_t nodeDeviceID, - ino_t nodeID, const char* fromName, - const char* name, bool notify); - static status_t _LoadPackage(PackageDomain* domain, const char* name, Package*& _package); ############################################################################ Commit: 6978941aac85ea329a8552253f384924dcccd1b3 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Apr 7 10:57:15 2013 UTC packagefs: Remove support for multiple package domains per volume That also get rid of the job stuff and the package loader thread. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index 9396497..63763c6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -28,7 +28,6 @@ HAIKU_PACKAGE_FS_SOURCES = Query.cpp Package.cpp PackageDirectory.cpp - PackageDomain.cpp PackageFile.cpp PackageFSRoot.cpp PackageLeafNode.cpp diff --git a/src/add-ons/kernel/file_systems/packagefs/Package.cpp b/src/add-ons/kernel/file_systems/packagefs/Package.cpp index 28fc000..721d321 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Package.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Package.cpp @@ -21,10 +21,10 @@ #include "DebugSupport.h" #include "PackageDirectory.h" -#include "PackageDomain.h" #include "PackageFile.h" #include "PackageSymlink.h" #include "Version.h" +#include "Volume.h" using namespace BPackageKit; @@ -300,9 +300,9 @@ private: // #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), fName(NULL), fInstallPath(NULL), @@ -461,7 +461,7 @@ Package::Open() } // open the file - fFD = openat(fDomain->DirectoryFD(), fFileName, O_RDONLY); + fFD = openat(fVolume->PackagesDirectoryFD(), fFileName, O_RDONLY); if (fFD < 0) { ERROR("Failed to open package file \"%s\"\n", fFileName); return errno; diff --git a/src/add-ons/kernel/file_systems/packagefs/Package.h b/src/add-ons/kernel/file_systems/packagefs/Package.h index d9b0b56..b8495b5 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Package.h +++ b/src/add-ons/kernel/file_systems/packagefs/Package.h @@ -24,22 +24,22 @@ using BPackageKit::BPackageArchitecture; -class PackageDomain; class PackageLinkDirectory; +class Volume; class Version; class Package : public BReferenceable, public DoublyLinkedListLinkImpl<Package> { public: - Package(PackageDomain* domain, dev_t deviceID, + Package(::Volume* volume, dev_t deviceID, ino_t nodeID); ~Package(); status_t Init(const char* fileName); status_t Load(); - PackageDomain* Domain() const { return fDomain; } + ::Volume* Volume() const { return fVolume; } const char* FileName() const { return fFileName; } status_t SetName(const char* name); @@ -93,7 +93,7 @@ private: private: mutex fLock; - PackageDomain* fDomain; + ::Volume* fVolume; char* fFileName; char* fName; char* fInstallPath; diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp deleted file mode 100644 index 69e5248..0000000 --- a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx. - * 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); -} diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h b/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h deleted file mode 100644 index 2c8dd56..0000000 --- a/src/add-ons/kernel/file_systems/packagefs/PackageDomain.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@xxxxxx. - * 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 diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp index 48a11f5..b0dc5a4 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp @@ -99,11 +99,11 @@ PackageLinkDirectory::AddPackage(Package* package, // Find the insertion point in the list. We sort by mount type -- the more // specific the higher the priority. - MountType mountType = package->Domain()->Volume()->MountType(); + MountType mountType = package->Volume()->MountType(); Package* otherPackage = NULL; for (PackageList::Iterator it = fPackages.GetIterator(); (otherPackage = it.Next()) != NULL;) { - if (otherPackage->Domain()->Volume()->MountType() <= mountType) + if (otherPackage->Volume()->MountType() <= mountType) break; } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinkSymlink.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLinkSymlink.cpp index ed674e2..4fbf81f 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinkSymlink.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinkSymlink.cpp @@ -94,7 +94,7 @@ PackageLinkSymlink::Update(Package* package, PackageLinksListener* listener) fLinkPath = package->InstallPath(); if (fLinkPath == NULL) { fLinkPath = link_path_for_mount_type( - package->Domain()->Volume()->MountType()); + package->Volume()->MountType()); } } else fLinkPath = kUnknownLinkTarget; diff --git a/src/add-ons/kernel/file_systems/packagefs/ResolvableFamily.cpp b/src/add-ons/kernel/file_systems/packagefs/ResolvableFamily.cpp index f396eb6..9e61317 100644 --- a/src/add-ons/kernel/file_systems/packagefs/ResolvableFamily.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/ResolvableFamily.cpp @@ -17,11 +17,11 @@ ResolvableFamily::AddResolvable(Resolvable* resolvable, // Find the insertion point in the list. We sort by mount type -- the more // specific the higher the priority. MountType mountType - = resolvable->Package()->Domain()->Volume()->MountType(); + = resolvable->Package()->Volume()->MountType(); Resolvable* otherResolvable = NULL; for (FamilyResolvableList::Iterator it = fResolvables.GetIterator(); (otherResolvable = it.Next()) != NULL;) { - if (otherResolvable->Package()->Domain()->Volume()->MountType() + if (otherResolvable->Package()->Volume()->MountType() <= mountType) { break; } diff --git a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp index 4c4f9c9..523189d 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx. * Distributed under the terms of the MIT License. */ @@ -23,6 +23,8 @@ #include <AutoDeleter.h> +#include <fs/KPath.h> +#include <team.h> #include <vfs.h> #include "AttributeIndex.h" @@ -63,51 +65,112 @@ const char* const* kHomeShineThroughDirectories const size_t kMaxActivationRequestSize = 10 * 1024 * 1024; -// #pragma mark - Job +// #pragma mark - ShineThroughDirectory -struct Volume::Job : DoublyLinkedListLinkImpl<Job> { - Job(Volume* volume) +struct Volume::PackagesDirectory { + PackagesDirectory() : - fVolume(volume) - { - } - - virtual ~Job() + fPath(NULL), + fDirFD(-1) { } - virtual void Do() = 0; -protected: - Volume* fVolume; -}; + ~PackagesDirectory() + { + if (fDirFD >= 0) + close(fDirFD); + free(fPath); + } -// #pragma mark - AddPackageDomainJob + const char* Path() const + { + return fPath; + } + int DirectoryFD() const + { + return fDirFD; + } -struct Volume::AddPackageDomainJob : Job { - AddPackageDomainJob(Volume* volume, PackageDomain* domain) - : - Job(volume), - fDomain(domain) + dev_t DeviceID() const { - fDomain->AcquireReference(); + return fDeviceID; } - virtual ~AddPackageDomainJob() + ino_t NodeID() const { - fDomain->ReleaseReference(); + return fNodeID; } - virtual void Do() + status_t Init(const char* path, dev_t mountPointDeviceID, + ino_t mountPointNodeID, struct stat& _st) { - fVolume->_AddPackageDomain(fDomain, true); + // 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: - PackageDomain* fDomain; + char* fPath; + int fDirFD; + dev_t fDeviceID; + ino_t fNodeID; }; @@ -264,22 +327,32 @@ Volume::Volume(fs_volume* fsVolume) fFSVolume(fsVolume), fRootDirectory(NULL), fPackageFSRoot(NULL), - fPackageLoader(-1), - fNextNodeID(kRootDirectoryID + 1), - fTerminating(false) + fPackagesDirectory(NULL), + fNextNodeID(kRootDirectoryID + 1) { rw_lock_init(&fLock, "packagefs volume"); - mutex_init(&fJobQueueLock, "packagefs volume job queue"); - fJobQueueCondition.Init(this, "packagefs volume job queue"); } 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()) - _RemovePackageDomain(packageDomain); + // delete the packages + Package* package = fPackages.Clear(true); + while (package != NULL) { + Package* next = package->FileNameHashTableNext(); + package->ReleaseReference(); + package = next; + } // delete all indices Index* index = fIndices.Clear(true); @@ -307,11 +380,17 @@ Volume::~Volume() if (fRootDirectory != NULL) fRootDirectory->ReleaseReference(); - mutex_destroy(&fJobQueueLock); rw_lock_destroy(&fLock); } +int +Volume::PackagesDirectoryFD() const +{ + return fPackagesDirectory->DirectoryFD(); +} + + status_t Volume::Mount(const char* parameterString) { @@ -324,6 +403,10 @@ Volume::Mount(const char* parameterString) if (error != B_OK) RETURN_ERROR(error); + error = fPackages.Init(); + if (error != B_OK) + RETURN_ERROR(error); + error = fIndices.Init(); if (error != B_OK) RETURN_ERROR(error); @@ -425,14 +508,14 @@ Volume::Mount(const char* parameterString) if (error != B_OK) RETURN_ERROR(error); - // create initial package domain - PackageDomain* packageDomain = new(std::nothrow) PackageDomain(this); - if (packageDomain == NULL) + // create package domain + fPackagesDirectory = new(std::nothrow) PackagesDirectory; + if (fPackagesDirectory == NULL) RETURN_ERROR(B_NO_MEMORY); - BReference<PackageDomain> packageDomainReference(packageDomain, true); struct stat st; - error = packageDomain->Init(packages, &st); + error = fPackagesDirectory->Init(packages, fMountPoint.deviceID, + fMountPoint.nodeID, st); if (error != B_OK) RETURN_ERROR(error); @@ -481,17 +564,11 @@ Volume::Mount(const char* parameterString) if (error != B_OK) RETURN_ERROR(error); - // add initial package domain - error = _AddPackageDomain(packageDomain, false); + // add initial packages + error = _AddInitialPackages(); if (error != B_OK) 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 fRootDirectory->AcquireReference(); error = PublishVNode(fRootDirectory); @@ -505,9 +582,6 @@ Volume::Mount(const char* parameterString) if (error != B_OK) RETURN_ERROR(error); - // run the package loader - resume_thread(fPackageLoader); - return B_OK; } @@ -515,7 +589,6 @@ Volume::Mount(const char* parameterString) void Volume::Unmount() { - _TerminatePackageLoader(); } @@ -534,10 +607,8 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size) info.mountType = fMountType; info.rootDeviceID = fPackageFSRoot->DeviceID(); info.rootDirectoryID = fPackageFSRoot->NodeID(); - - PackageDomain* domain = fPackageDomains.Head(); - info.packagesDeviceID = domain != NULL ? domain->DeviceID() : -1; - info.packagesDirectoryID = domain != NULL ? domain->NodeID() : -1; + info.packagesDeviceID = fPackagesDirectory->DeviceID(); + info.packagesDirectoryID = fPackagesDirectory->NodeID(); 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); - PackageDomain* domain = fPackageDomains.Head(); - if (domain == NULL) - RETURN_ERROR(B_BAD_VALUE); - uint32 packageIndex = 0; for (PackageFileNameHashTable::Iterator it - = domain->Packages().GetIterator(); it.HasNext(); + = fPackages.GetIterator(); it.HasNext(); packageIndex++) { Package* package = it.Next(); PackageFSPackageInfo info; @@ -572,7 +639,7 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size) return B_BAD_ADDRESS; } - uint32 packageCount = domain->Packages().CountElements(); + uint32 packageCount = fPackages.CountElements(); RETURN_ERROR(user_memcpy(&request->packageCount, &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 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 -Volume::_PackageLoader() -{ - while (!fTerminating) { - MutexLocker jobQueueLocker(fJobQueueLock); - - 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) +Volume::_AddInitialPackages() { - dprintf("packagefs: Adding package domain \"%s\"\n", domain->Path()); + dprintf("packagefs: Adding packages from \"%s\"\n", + fPackagesDirectory->Path()); // iterate through the dir and create packages - int fd = dup(domain->DirectoryFD()); + int fd = dup(fPackagesDirectory->DirectoryFD()); 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); } DIR* dir = fdopendir(fd); if (dir == NULL) { - ERROR("Failed to open package domain directory \"%s\": %s\n", - domain->Path(), strerror(errno)); + ERROR("Failed to open packages directory \"%s\": %s\n", + fPackagesDirectory->Path(), strerror(errno)); RETURN_ERROR(errno); } CObjectDeleter<DIR, int> dirCloser(dir, closedir); @@ -824,53 +808,56 @@ Volume::_AddPackageDomain(PackageDomain* domain, bool notify) continue; Package* package; - if (_LoadPackage(domain, entry->d_name, package) != B_OK) + if (_LoadPackage(entry->d_name, package) != B_OK) continue; BReference<Package> packageReference(package, true); VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf()); VolumeWriteLocker volumeLocker(this); - domain->AddPackage(package); + _AddPackage(package); } // add the packages to the node tree VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf()); VolumeWriteLocker volumeLocker(this); - for (PackageFileNameHashTable::Iterator it - = domain->Packages().GetIterator(); Package* package = it.Next();) { - status_t error = _AddPackageContent(package, notify); + for (PackageFileNameHashTable::Iterator it = fPackages.GetIterator(); + Package* package = it.Next();) { + status_t error = _AddPackageContent(package, false); if (error != B_OK) { for (it.Rewind(); Package* activePackage = it.Next();) { if (activePackage == package) break; - _RemovePackageContent(activePackage, NULL, notify); + _RemovePackageContent(activePackage, NULL, false); } RETURN_ERROR(error); } } - fPackageDomains.Add(domain); - domain->AcquireReference(); - return B_OK; } -void -Volume::_RemovePackageDomain(PackageDomain* domain) +inline void +Volume::_AddPackage(Package* package) { - // remove the domain's packages from the node tree - VolumeWriteLocker systemVolumeLocker(_SystemVolumeIfNotSelf()); - VolumeWriteLocker volumeLocker(this); - for (PackageFileNameHashTable::Iterator it - = domain->Packages().GetIterator(); Package* package = it.Next();) { - _RemovePackageContent(package, NULL, false); - } + fPackages.Insert(package); + package->AcquireReference(); +} - // remove the domain - fPackageDomains.Remove(domain); - domain->ReleaseReference(); + +inline void +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 -Volume::_LoadPackage(PackageDomain* domain, const char* name, - Package*& _package) +status_t +Volume::_LoadPackage(const char* name, Package*& _package) { // check whether the entry is a file struct stat st; - if (fstatat(domain->DirectoryFD(), name, &st, 0) < 0 + if (fstatat(fPackagesDirectory->DirectoryFD(), name, &st, 0) < 0 || !S_ISREG(st.st_mode)) { return B_BAD_VALUE; } // 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) RETURN_ERROR(B_NO_MEMORY); BReference<Package> packageReference(package, true); @@ -1369,12 +1355,6 @@ Volume::_LoadPackage(PackageDomain* domain, const char* name, status_t 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 int32 newPackageCount = 0; int32 oldPackageCount = 0; @@ -1384,14 +1364,14 @@ Volume::_ChangeActivation(ActivationChangeRequest& request) for (ActivationChangeRequest::Iterator it = request.GetIterator(); it.HasNext();) { PackageFSActivationChangeItem* item = it.Next(); - if (item->parentDeviceID != domain->DeviceID() - || item->parentDirectoryID != domain->NodeID()) { + if (item->parentDeviceID != fPackagesDirectory->DeviceID() + || item->parentDirectoryID != fPackagesDirectory->NodeID()) { ERROR("Volume::_ChangeActivation(): mismatching packages " - "domain\n"); + "directory\n"); 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! if (item->type == PACKAGE_FS_ACTIVATE_PACKAGE) { if (package != NULL) { @@ -1449,7 +1429,7 @@ INFORM("Volume::_ChangeActivation(): %" B_PRId32 " new packages, %" B_PRId32 " o } Package* package; - status_t error = _LoadPackage(domain, item->name, package); + status_t error = _LoadPackage(item->name, package); if (error != B_OK) { ERROR("Volume::_ChangeActivation(): failed to load package " "\"%s\"\n", item->name); @@ -1476,11 +1456,11 @@ INFORM("Volume::_ChangeActivation(): %" B_PRId32 " new packages, %" B_PRId32 " o continue; } - Package* package = domain->FindPackage(item->name); + Package* package = _FindPackage(item->name); // TODO: We should better look up the package by node_ref! oldPackageReferences[oldPackageIndex++].SetTo(package); _RemovePackageContent(package, NULL, true); - domain->RemovePackage(package); + _RemovePackage(package); INFORM("package \"%s\" deactivated\n", package->FileName()); } // 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; newPackageIndex++) { Package* package = newPackageReferences[newPackageIndex]; - domain->AddPackage(package); + _AddPackage(package); // add the package to the node tree error = _AddPackageContent(package, true); if (error != B_OK) { - domain->RemovePackage(package); + _RemovePackage(package); break; } 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--) { Package* package = newPackageReferences[i]; _RemovePackageContent(package, NULL, true); - domain->RemovePackage(package); + _RemovePackage(package); } for (int32 i = oldPackageCount - 1; i >= 0; i--) { Package* package = oldPackageReferences[i]; - domain->AddPackage(package); + _AddPackage(package); if (_AddPackageContent(package, true) != B_OK) { // nothing we can do here ERROR("Volume::_ChangeActivation(): failed to roll back " "deactivation of package \"%s\" after error\n", package->FileName()); - domain->RemovePackage(package); + _RemovePackage(package); } } } diff --git a/src/add-ons/kernel/file_systems/packagefs/Volume.h b/src/add-ons/kernel/file_systems/packagefs/Volume.h index 2064063..23caf19 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Volume.h +++ b/src/add-ons/kernel/file_systems/packagefs/Volume.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx. * Distributed under the terms of the MIT License. */ #ifndef VOLUME_H @@ -19,7 +19,7 @@ #include "Index.h" #include "Node.h" #include "NodeListener.h" -#include "PackageDomain.h" +#include "Package.h" #include "PackageLinksListener.h" #include "Query.h" @@ -51,6 +51,8 @@ public: ::MountType MountType() const { return fMountType; } + int PackagesDirectoryFD() const; + void SetPackageFSRoot(::PackageFSRoot* root) { fPackageFSRoot = root; } ::PackageFSRoot* PackageFSRoot() const @@ -94,8 +96,6 @@ public: status_t RemoveVNode(ino_t nodeID); status_t PublishVNode(Node* node); - status_t AddPackageDomain(const char* path); - private: // PackageLinksListener virtual void PackageLinkNodeAdded(Node* node); @@ -105,29 +105,16 @@ private: const OldNodeAttributes& oldAttributes); private: - struct Job; - struct AddPackageDomainJob; - struct DomainDirectoryEventJob; + struct PackagesDirectory; struct ShineThroughDirectory; struct ActivationChangeRequest; - friend struct AddPackageDomainJob; - - typedef DoublyLinkedList<Job> JobList; - typedef DoublyLinkedList<PackageDomain> PackageDomainList; - private: - static status_t _PackageLoaderEntry(void* data); - status_t _PackageLoader(); - - void _TerminatePackageLoader(); + status_t _AddInitialPackages(); - void _PushJob(Job* job); - - status_t _AddInitialPackageDomain(const char* path); - status_t _AddPackageDomain(PackageDomain* domain, - bool notify); - void _RemovePackageDomain(PackageDomain* domain); + inline void _AddPackage(Package* package); + inline void _RemovePackage(Package* package); + inline Package* _FindPackage(const char* fileName) const; status_t _AddPackageContent(Package* package, bool notify); @@ -155,8 +142,8 @@ private: void _RemoveNodeAndVNode(Node* node); // caller must hold a reference - static status_t _LoadPackage(PackageDomain* domain, - const char* name, Package*& _package); + status_t _LoadPackage(const char* name, + Package*& _package); status_t _ChangeActivation( ActivationChangeRequest& request); @@ -187,8 +174,7 @@ private: Directory* fRootDirectory; ::PackageFSRoot* fPackageFSRoot; ::MountType fMountType; - thread_id fPackageLoader; - PackageDomainList fPackageDomains; + PackagesDirectory* fPackagesDirectory; struct { dev_t deviceID; @@ -197,16 +183,11 @@ private: NodeIDHashTable fNodes; NodeListenerHashTable fNodeListeners; + PackageFileNameHashTable fPackages; QueryList fQueries; IndexHashTable fIndices; - JobList fJobQueue; - mutex fJobQueueLock; - ConditionVariable fJobQueueCondition; - ino_t fNextNodeID; - - volatile bool fTerminating; };