126296b0aSIngo Weinhold /* 232cae724SIngo Weinhold * Copyright 2013-2014, Haiku, Inc. All Rights Reserved. 326296b0aSIngo Weinhold * Distributed under the terms of the MIT License. 426296b0aSIngo Weinhold * 526296b0aSIngo Weinhold * Authors: 626296b0aSIngo Weinhold * Ingo Weinhold <ingo_weinhold@gmx.de> 726296b0aSIngo Weinhold */ 826296b0aSIngo Weinhold #ifndef VOLUME_H 926296b0aSIngo Weinhold #define VOLUME_H 1026296b0aSIngo Weinhold 1126296b0aSIngo Weinhold 123d53bd47SIngo Weinhold #include <Handler.h> 138fb3930aSIngo Weinhold #include <Locker.h> 14e6216e37SIngo Weinhold #include <Message.h> 1526296b0aSIngo Weinhold #include <String.h> 1626296b0aSIngo Weinhold 1738c62dfbSIngo Weinhold #include <package/ActivationTransaction.h> 1838c62dfbSIngo Weinhold #include <package/DaemonClient.h> 19b254217aSIngo Weinhold #include <package/packagefs.h> 208fb3930aSIngo Weinhold #include <util/DoublyLinkedList.h> 2126296b0aSIngo Weinhold 2223733521SIngo Weinhold #include "FSUtils.h" 233d53bd47SIngo Weinhold #include "Package.h" 243d53bd47SIngo Weinhold 2526296b0aSIngo Weinhold 2632cae724SIngo Weinhold // Locking Policy 2732cae724SIngo Weinhold // ============== 2832cae724SIngo Weinhold // 2932cae724SIngo Weinhold // A Volume object is accessed by two threads: 3032cae724SIngo Weinhold // 1. The application thread: initially (c'tor and Init()) and when handling a 3132cae724SIngo Weinhold // location info request (HandleGetLocationInfoRequest()). 3232cae724SIngo Weinhold // 2. The corresponding Root object's job thread (any other operation). 3332cae724SIngo Weinhold // 3432cae724SIngo Weinhold // The only thread synchronization needed is for the status information accessed 3532cae724SIngo Weinhold // by HandleGetLocationInfoRequest() and modified by the job thread. The data 36273763d0SIngo Weinhold // are encapsulated in a VolumeState object which contains a lock. The lock 3732cae724SIngo Weinhold // must be held by the app thread when accessing the data (it reads only) and 3832cae724SIngo Weinhold // by the job thread when modifying the data (not needed when reading). 3932cae724SIngo Weinhold 4032cae724SIngo Weinhold 4138c62dfbSIngo Weinhold using BPackageKit::BPrivate::BActivationTransaction; 4238c62dfbSIngo Weinhold using BPackageKit::BPrivate::BDaemonClient; 4338c62dfbSIngo Weinhold 4426296b0aSIngo Weinhold class BDirectory; 4526296b0aSIngo Weinhold 46933e7b32SIngo Weinhold class CommitTransactionHandler; 4726296b0aSIngo Weinhold class Root; 48273763d0SIngo Weinhold class VolumeState; 4926296b0aSIngo Weinhold 5092b6d585SIngo Weinhold namespace BPackageKit { 5192b6d585SIngo Weinhold class BSolver; 5292b6d585SIngo Weinhold class BSolverRepository; 5392b6d585SIngo Weinhold } 5492b6d585SIngo Weinhold 5538c62dfbSIngo Weinhold using BPackageKit::BPackageInstallationLocation; 5638c62dfbSIngo Weinhold using BPackageKit::BSolver; 5738c62dfbSIngo Weinhold using BPackageKit::BSolverRepository; 5838c62dfbSIngo Weinhold 5926296b0aSIngo Weinhold 603d53bd47SIngo Weinhold class Volume : public BHandler { 6126296b0aSIngo Weinhold public: 629e409614SIngo Weinhold class Listener; 639e409614SIngo Weinhold 649e409614SIngo Weinhold public: 658fb3930aSIngo Weinhold Volume(BLooper* looper); 663d53bd47SIngo Weinhold virtual ~Volume(); 6726296b0aSIngo Weinhold 683d53bd47SIngo Weinhold status_t Init(const node_ref& rootDirectoryRef, 693d53bd47SIngo Weinhold node_ref& _packageRootRef); 709e409614SIngo Weinhold status_t InitPackages(Listener* listener); 718fb3930aSIngo Weinhold 7292b6d585SIngo Weinhold status_t AddPackagesToRepository( 7392b6d585SIngo Weinhold BSolverRepository& repository, 7492b6d585SIngo Weinhold bool activeOnly); 7592b6d585SIngo Weinhold void InitialVerify(Volume* nextVolume, 7692b6d585SIngo Weinhold Volume* nextNextVolume); 77e6216e37SIngo Weinhold void HandleGetLocationInfoRequest(BMessage* message); 7885d2badfSIngo Weinhold void HandleCommitTransactionRequest( 7985d2badfSIngo Weinhold BMessage* message); 8092b6d585SIngo Weinhold 8132cae724SIngo Weinhold void PackageJobPending(); 8232cae724SIngo Weinhold void PackageJobFinished(); 8332cae724SIngo Weinhold bool IsPackageJobPending() const; 8432cae724SIngo Weinhold 858fb3930aSIngo Weinhold void Unmounted(); 863d53bd47SIngo Weinhold 873d53bd47SIngo Weinhold virtual void MessageReceived(BMessage* message); 8826296b0aSIngo Weinhold 8926296b0aSIngo Weinhold const BString& Path() const 9026296b0aSIngo Weinhold { return fPath; } 9126296b0aSIngo Weinhold PackageFSMountType MountType() const 9226296b0aSIngo Weinhold { return fMountType; } 9338c62dfbSIngo Weinhold BPackageInstallationLocation Location() const; 943d53bd47SIngo Weinhold 953d53bd47SIngo Weinhold const node_ref& RootDirectoryRef() const 963d53bd47SIngo Weinhold { return fRootDirectoryRef; } 9726296b0aSIngo Weinhold dev_t DeviceID() const 983d53bd47SIngo Weinhold { return fRootDirectoryRef.device; } 9926296b0aSIngo Weinhold ino_t RootDirectoryID() const 1003d53bd47SIngo Weinhold { return fRootDirectoryRef.node; } 1013d53bd47SIngo Weinhold 1023d53bd47SIngo Weinhold const node_ref& PackagesDirectoryRef() const 1033d53bd47SIngo Weinhold { return fPackagesDirectoryRef; } 1043d53bd47SIngo Weinhold dev_t PackagesDeviceID() const 1053d53bd47SIngo Weinhold { return fPackagesDirectoryRef.device; } 1063d53bd47SIngo Weinhold ino_t PackagesDirectoryID() const 1073d53bd47SIngo Weinhold { return fPackagesDirectoryRef.node; } 10826296b0aSIngo Weinhold 10926296b0aSIngo Weinhold Root* GetRoot() const 11026296b0aSIngo Weinhold { return fRoot; } 11126296b0aSIngo Weinhold void SetRoot(Root* root) 11226296b0aSIngo Weinhold { fRoot = root; } 11326296b0aSIngo Weinhold 1148c6e1bf5SIngo Weinhold VolumeState* State() const 1158c6e1bf5SIngo Weinhold { return fState; } 1168c6e1bf5SIngo Weinhold 11732cae724SIngo Weinhold PackageFileNameHashTable::Iterator PackagesByFileNameIterator() 11832cae724SIngo Weinhold const; 11938c62dfbSIngo Weinhold 1203d53bd47SIngo Weinhold int OpenRootDirectory() const; 1213d53bd47SIngo Weinhold 1228fb3930aSIngo Weinhold void ProcessPendingNodeMonitorEvents(); 1238fb3930aSIngo Weinhold 124a6c7f5e3SIngo Weinhold bool HasPendingPackageActivationChanges() const; 125a6c7f5e3SIngo Weinhold void ProcessPendingPackageActivationChanges(); 12638c62dfbSIngo Weinhold void ClearPackageActivationChanges(); 12738c62dfbSIngo Weinhold const PackageSet& PackagesToBeActivated() const 12838c62dfbSIngo Weinhold { return fPackagesToBeActivated; } 12938c62dfbSIngo Weinhold const PackageSet& PackagesToBeDeactivated() const 13038c62dfbSIngo Weinhold { return fPackagesToBeDeactivated; } 13138c62dfbSIngo Weinhold 13238c62dfbSIngo Weinhold status_t CreateTransaction( 13338c62dfbSIngo Weinhold BPackageInstallationLocation location, 13438c62dfbSIngo Weinhold BActivationTransaction& _transaction, 13538c62dfbSIngo Weinhold BDirectory& _transactionDirectory); 13638c62dfbSIngo Weinhold void CommitTransaction( 13738c62dfbSIngo Weinhold const BActivationTransaction& transaction, 13838c62dfbSIngo Weinhold const PackageSet& packagesAlreadyAdded, 13938c62dfbSIngo Weinhold const PackageSet& packagesAlreadyRemoved, 14038c62dfbSIngo Weinhold BDaemonClient::BCommitTransactionResult& 14138c62dfbSIngo Weinhold _result); 142a6c7f5e3SIngo Weinhold 1438fb3930aSIngo Weinhold private: 1448fb3930aSIngo Weinhold struct NodeMonitorEvent; 1458fb3930aSIngo Weinhold 14623733521SIngo Weinhold typedef FSUtils::RelativePath RelativePath; 14785d2badfSIngo Weinhold typedef DoublyLinkedList<NodeMonitorEvent> NodeMonitorEventList; 148a6c7f5e3SIngo Weinhold 1493d53bd47SIngo Weinhold private: 1503d53bd47SIngo Weinhold void _HandleEntryCreatedOrRemoved( 1513d53bd47SIngo Weinhold const BMessage* message, bool created); 1523d53bd47SIngo Weinhold void _HandleEntryMoved(const BMessage* message); 1538fb3930aSIngo Weinhold void _QueueNodeMonitorEvent(const BString& name, 1548fb3930aSIngo Weinhold bool wasCreated); 1553d53bd47SIngo Weinhold 1563d53bd47SIngo Weinhold void _PackagesEntryCreated(const char* name); 1573d53bd47SIngo Weinhold void _PackagesEntryRemoved(const char* name); 1583d53bd47SIngo Weinhold 1593d53bd47SIngo Weinhold status_t _ReadPackagesDirectory(); 1603d53bd47SIngo Weinhold status_t _GetActivePackages(int fd); 1613d53bd47SIngo Weinhold 16292b6d585SIngo Weinhold status_t _AddRepository(BSolver* solver, 16392b6d585SIngo Weinhold BSolverRepository& repository, 16492b6d585SIngo Weinhold bool activeOnly, bool installed); 16592b6d585SIngo Weinhold 16685d2badfSIngo Weinhold status_t _OpenPackagesSubDirectory( 16785d2badfSIngo Weinhold const RelativePath& path, bool create, 16885d2badfSIngo Weinhold BDirectory& _directory); 16985d2badfSIngo Weinhold 17023733521SIngo Weinhold status_t _OpenSettingsRootDirectory( 17123733521SIngo Weinhold BDirectory& _directory); 17223733521SIngo Weinhold 17326296b0aSIngo Weinhold private: 17426296b0aSIngo Weinhold BString fPath; 17526296b0aSIngo Weinhold PackageFSMountType fMountType; 1763d53bd47SIngo Weinhold node_ref fRootDirectoryRef; 1773d53bd47SIngo Weinhold node_ref fPackagesDirectoryRef; 17826296b0aSIngo Weinhold Root* fRoot; 1799e409614SIngo Weinhold Listener* fListener; 180273763d0SIngo Weinhold VolumeState* fState; 1818fb3930aSIngo Weinhold BLocker fPendingNodeMonitorEventsLock; 1828fb3930aSIngo Weinhold NodeMonitorEventList fPendingNodeMonitorEvents; 18338c62dfbSIngo Weinhold bigtime_t fNodeMonitorEventHandleTime; 184a6c7f5e3SIngo Weinhold PackageSet fPackagesToBeActivated; 185a6c7f5e3SIngo Weinhold PackageSet fPackagesToBeDeactivated; 186e6216e37SIngo Weinhold BMessage fLocationInfoReply; 18732cae724SIngo Weinhold // only accessed in the application thread 188*7a35d803SIngo Weinhold int32 fPendingPackageJobCount; 18926296b0aSIngo Weinhold }; 19026296b0aSIngo Weinhold 19126296b0aSIngo Weinhold 1929e409614SIngo Weinhold class Volume::Listener { 1939e409614SIngo Weinhold public: 1949e409614SIngo Weinhold virtual ~Listener(); 1959e409614SIngo Weinhold 1969e409614SIngo Weinhold virtual void VolumeNodeMonitorEventOccurred(Volume* volume) 1979e409614SIngo Weinhold = 0; 1989e409614SIngo Weinhold }; 1999e409614SIngo Weinhold 2009e409614SIngo Weinhold 20126296b0aSIngo Weinhold #endif // VOLUME_H 202