xref: /haiku/src/servers/package/Volume.h (revision 7a35d803d00c1e363c41dca1802be1dd24a404ea)
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