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 362dbf8167SIngo Weinhold // are encapsulated in a VolumeState, which is protected by Volume::fLock. The 372dbf8167SIngo Weinhold // lock must be held by the app thread when accessing the data (it reads only) 382dbf8167SIngo Weinhold // and 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; 472dbf8167SIngo Weinhold class PackageFileManager; 4826296b0aSIngo Weinhold class Root; 49273763d0SIngo Weinhold class VolumeState; 5026296b0aSIngo Weinhold 5192b6d585SIngo Weinhold namespace BPackageKit { 5292b6d585SIngo Weinhold class BSolver; 5392b6d585SIngo Weinhold class BSolverRepository; 5492b6d585SIngo Weinhold } 5592b6d585SIngo Weinhold 5638c62dfbSIngo Weinhold using BPackageKit::BPackageInstallationLocation; 5738c62dfbSIngo Weinhold using BPackageKit::BSolver; 5838c62dfbSIngo Weinhold using BPackageKit::BSolverRepository; 5938c62dfbSIngo Weinhold 6026296b0aSIngo Weinhold 613d53bd47SIngo Weinhold class Volume : public BHandler { 6226296b0aSIngo Weinhold public: 639e409614SIngo Weinhold class Listener; 649e409614SIngo Weinhold 659e409614SIngo Weinhold public: 668fb3930aSIngo Weinhold Volume(BLooper* looper); 673d53bd47SIngo Weinhold virtual ~Volume(); 6826296b0aSIngo Weinhold 693d53bd47SIngo Weinhold status_t Init(const node_ref& rootDirectoryRef, 703d53bd47SIngo Weinhold node_ref& _packageRootRef); 719e409614SIngo Weinhold status_t InitPackages(Listener* listener); 728fb3930aSIngo Weinhold 7392b6d585SIngo Weinhold status_t AddPackagesToRepository( 7492b6d585SIngo Weinhold BSolverRepository& repository, 7592b6d585SIngo Weinhold bool activeOnly); 7692b6d585SIngo Weinhold void InitialVerify(Volume* nextVolume, 7792b6d585SIngo Weinhold Volume* nextNextVolume); 78e6216e37SIngo Weinhold void HandleGetLocationInfoRequest(BMessage* message); 7985d2badfSIngo Weinhold void HandleCommitTransactionRequest( 8085d2badfSIngo Weinhold BMessage* message); 8192b6d585SIngo Weinhold 8232cae724SIngo Weinhold void PackageJobPending(); 8332cae724SIngo Weinhold void PackageJobFinished(); 8432cae724SIngo Weinhold bool IsPackageJobPending() const; 8532cae724SIngo Weinhold 868fb3930aSIngo Weinhold void Unmounted(); 873d53bd47SIngo Weinhold 883d53bd47SIngo Weinhold virtual void MessageReceived(BMessage* message); 8926296b0aSIngo Weinhold 9026296b0aSIngo Weinhold const BString& Path() const 9126296b0aSIngo Weinhold { return fPath; } 9226296b0aSIngo Weinhold PackageFSMountType MountType() const 9326296b0aSIngo Weinhold { return fMountType; } 9438c62dfbSIngo Weinhold BPackageInstallationLocation Location() const; 953d53bd47SIngo Weinhold 963d53bd47SIngo Weinhold const node_ref& RootDirectoryRef() const 973d53bd47SIngo Weinhold { return fRootDirectoryRef; } 9826296b0aSIngo Weinhold dev_t DeviceID() const 993d53bd47SIngo Weinhold { return fRootDirectoryRef.device; } 10026296b0aSIngo Weinhold ino_t RootDirectoryID() const 1013d53bd47SIngo Weinhold { return fRootDirectoryRef.node; } 1023d53bd47SIngo Weinhold 103c8dd5bbdSIngo Weinhold const node_ref& PackagesDirectoryRef() const; 1043d53bd47SIngo Weinhold dev_t PackagesDeviceID() const 105c8dd5bbdSIngo Weinhold { return PackagesDirectoryRef().device; } 1063d53bd47SIngo Weinhold ino_t PackagesDirectoryID() const 107c8dd5bbdSIngo Weinhold { return PackagesDirectoryRef().node; } 10826296b0aSIngo Weinhold 10926296b0aSIngo Weinhold Root* GetRoot() const 11026296b0aSIngo Weinhold { return fRoot; } 11126296b0aSIngo Weinhold void SetRoot(Root* root) 11226296b0aSIngo Weinhold { fRoot = root; } 11326296b0aSIngo Weinhold 114870e93acSIngo Weinhold int64 ChangeCount() const 115870e93acSIngo Weinhold { return fChangeCount; } 116870e93acSIngo 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, 1400de3219eSIngo Weinhold BCommitTransactionResult& _result); 141a6c7f5e3SIngo Weinhold 1428fb3930aSIngo Weinhold private: 1438fb3930aSIngo Weinhold struct NodeMonitorEvent; 144c8dd5bbdSIngo Weinhold struct PackagesDirectory; 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(); 1602dbf8167SIngo Weinhold status_t _InitLatestState(); 1612dbf8167SIngo Weinhold status_t _InitLatestStateFromActivatedPackages(); 1623d53bd47SIngo Weinhold status_t _GetActivePackages(int fd); 163*a22fa0c9SAlexander G. M. Smith void _RunQueuedScripts(); // TODO: Never called, fix? 1642dbf8167SIngo Weinhold bool _CheckActivePackagesMatchLatestState( 1652dbf8167SIngo Weinhold PackageFSGetPackageInfosRequest* request); 1662dbf8167SIngo Weinhold void _SetLatestState(VolumeState* state, 1672dbf8167SIngo Weinhold bool isActive); 1682dbf8167SIngo Weinhold void _DumpState(VolumeState* state); 1693d53bd47SIngo Weinhold 17092b6d585SIngo Weinhold status_t _AddRepository(BSolver* solver, 17192b6d585SIngo Weinhold BSolverRepository& repository, 17292b6d585SIngo Weinhold bool activeOnly, bool installed); 17392b6d585SIngo Weinhold 17485d2badfSIngo Weinhold status_t _OpenPackagesSubDirectory( 17585d2badfSIngo Weinhold const RelativePath& path, bool create, 17685d2badfSIngo Weinhold BDirectory& _directory); 17785d2badfSIngo Weinhold 1780de3219eSIngo Weinhold void _CommitTransaction(BMessage* message, 1790de3219eSIngo Weinhold const BActivationTransaction* transaction, 1800de3219eSIngo Weinhold const PackageSet& packagesAlreadyAdded, 1810de3219eSIngo Weinhold const PackageSet& packagesAlreadyRemoved, 1820de3219eSIngo Weinhold BCommitTransactionResult& _result); 1830de3219eSIngo Weinhold 18426296b0aSIngo Weinhold private: 18526296b0aSIngo Weinhold BString fPath; 18626296b0aSIngo Weinhold PackageFSMountType fMountType; 1873d53bd47SIngo Weinhold node_ref fRootDirectoryRef; 188c8dd5bbdSIngo Weinhold PackagesDirectory* fPackagesDirectories; 189c8dd5bbdSIngo Weinhold uint32 fPackagesDirectoryCount; 19026296b0aSIngo Weinhold Root* fRoot; 1919e409614SIngo Weinhold Listener* fListener; 1922dbf8167SIngo Weinhold PackageFileManager* fPackageFileManager; 1932dbf8167SIngo Weinhold VolumeState* fLatestState; 1942dbf8167SIngo Weinhold VolumeState* fActiveState; 195870e93acSIngo Weinhold int64 fChangeCount; 1962dbf8167SIngo Weinhold BLocker fLock; 1978fb3930aSIngo Weinhold BLocker fPendingNodeMonitorEventsLock; 1988fb3930aSIngo Weinhold NodeMonitorEventList fPendingNodeMonitorEvents; 19938c62dfbSIngo Weinhold bigtime_t fNodeMonitorEventHandleTime; 200a6c7f5e3SIngo Weinhold PackageSet fPackagesToBeActivated; 201a6c7f5e3SIngo Weinhold PackageSet fPackagesToBeDeactivated; 202e6216e37SIngo Weinhold BMessage fLocationInfoReply; 20332cae724SIngo Weinhold // only accessed in the application thread 2047a35d803SIngo Weinhold int32 fPendingPackageJobCount; 20526296b0aSIngo Weinhold }; 20626296b0aSIngo Weinhold 20726296b0aSIngo Weinhold 2089e409614SIngo Weinhold class Volume::Listener { 2099e409614SIngo Weinhold public: 2109e409614SIngo Weinhold virtual ~Listener(); 2119e409614SIngo Weinhold 2129e409614SIngo Weinhold virtual void VolumeNodeMonitorEventOccurred(Volume* volume) 2139e409614SIngo Weinhold = 0; 2149e409614SIngo Weinhold }; 2159e409614SIngo Weinhold 2169e409614SIngo Weinhold 21726296b0aSIngo Weinhold #endif // VOLUME_H 218