xref: /haiku/src/servers/package/Volume.h (revision 1149fa6ece3567c466008a04ae8a830a63bafdaa)
1 /*
2  * Copyright 2013, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ingo Weinhold <ingo_weinhold@gmx.de>
7  */
8 #ifndef VOLUME_H
9 #define VOLUME_H
10 
11 
12 #include <Handler.h>
13 #include <Locker.h>
14 #include <Message.h>
15 #include <String.h>
16 
17 #include <package/ActivationTransaction.h>
18 #include <package/DaemonClient.h>
19 #include <package/packagefs.h>
20 #include <util/DoublyLinkedList.h>
21 
22 #include "FSUtils.h"
23 #include "Package.h"
24 
25 
26 using BPackageKit::BPrivate::BActivationTransaction;
27 using BPackageKit::BPrivate::BDaemonClient;
28 
29 class BDirectory;
30 
31 class Root;
32 
33 namespace BPackageKit {
34 	class BSolver;
35 	class BSolverRepository;
36 }
37 
38 using BPackageKit::BPackageInstallationLocation;
39 using BPackageKit::BSolver;
40 using BPackageKit::BSolverRepository;
41 
42 
43 class Volume : public BHandler {
44 public:
45 			class Listener;
46 
47 public:
48 								Volume(BLooper* looper);
49 	virtual						~Volume();
50 
51 			status_t			Init(const node_ref& rootDirectoryRef,
52 									node_ref& _packageRootRef);
53 			status_t			InitPackages(Listener* listener);
54 
55 			status_t			AddPackagesToRepository(
56 									BSolverRepository& repository,
57 									bool activeOnly);
58 			void				InitialVerify(Volume* nextVolume,
59 									Volume* nextNextVolume);
60 			void				HandleGetLocationInfoRequest(BMessage* message);
61 			void				HandleCommitTransactionRequest(
62 									BMessage* message);
63 
64 			void				Unmounted();
65 
66 	virtual	void				MessageReceived(BMessage* message);
67 
68 			const BString&		Path() const
69 									{ return fPath; }
70 			PackageFSMountType	MountType() const
71 									{ return fMountType; }
72 			BPackageInstallationLocation Location() const;
73 
74 			const node_ref&		RootDirectoryRef() const
75 									{ return fRootDirectoryRef; }
76 			dev_t				DeviceID() const
77 									{ return fRootDirectoryRef.device; }
78 			ino_t				RootDirectoryID() const
79 									{ return fRootDirectoryRef.node; }
80 
81 			const node_ref&		PackagesDirectoryRef() const
82 									{ return fPackagesDirectoryRef; }
83 			dev_t				PackagesDeviceID() const
84 									{ return fPackagesDirectoryRef.device; }
85 			ino_t				PackagesDirectoryID() const
86 									{ return fPackagesDirectoryRef.node; }
87 
88 			Root*				GetRoot() const
89 									{ return fRoot; }
90 			void				SetRoot(Root* root)
91 									{ fRoot = root; }
92 
93 			const PackageFileNameHashTable& PackagesByFileName() const
94 									{ return fPackagesByFileName; }
95 			const PackageNodeRefHashTable& PackagesByNodeRef() const
96 									{ return fPackagesByNodeRef; }
97 
98 			int					OpenRootDirectory() const;
99 
100 			void				ProcessPendingNodeMonitorEvents();
101 
102 			bool				HasPendingPackageActivationChanges() const;
103 			void				ProcessPendingPackageActivationChanges();
104 			void				ClearPackageActivationChanges();
105 			const PackageSet&	PackagesToBeActivated() const
106 									{ return fPackagesToBeActivated; }
107 			const PackageSet&	PackagesToBeDeactivated() const
108 									{ return fPackagesToBeDeactivated; }
109 
110 			status_t			CreateTransaction(
111 									BPackageInstallationLocation location,
112 									BActivationTransaction& _transaction,
113 									BDirectory& _transactionDirectory);
114 			void				CommitTransaction(
115 									const BActivationTransaction& transaction,
116 									const PackageSet& packagesAlreadyAdded,
117 									const PackageSet& packagesAlreadyRemoved,
118 									BDaemonClient::BCommitTransactionResult&
119 										_result);
120 
121 private:
122 			struct NodeMonitorEvent;
123 			struct CommitTransactionHandler;
124 
125 			friend struct CommitTransactionHandler;
126 
127 			typedef FSUtils::RelativePath RelativePath;
128 			typedef DoublyLinkedList<NodeMonitorEvent> NodeMonitorEventList;
129 
130 private:
131 			void				_HandleEntryCreatedOrRemoved(
132 									const BMessage* message, bool created);
133 			void				_HandleEntryMoved(const BMessage* message);
134 			void				_QueueNodeMonitorEvent(const BString& name,
135 									bool wasCreated);
136 
137 			void				_PackagesEntryCreated(const char* name);
138 			void				_PackagesEntryRemoved(const char* name);
139 
140 			void				_FillInActivationChangeItem(
141 									PackageFSActivationChangeItem* item,
142 									PackageFSActivationChangeType type,
143 									Package* package, char*& nameBuffer);
144 
145 			void				_AddPackage(Package* package);
146 			void				_RemovePackage(Package* package);
147 
148 			status_t			_ReadPackagesDirectory();
149 			status_t			_GetActivePackages(int fd);
150 
151 			status_t			_AddRepository(BSolver* solver,
152 									BSolverRepository& repository,
153 							 		bool activeOnly, bool installed);
154 
155 			status_t			_OpenPackagesFile(
156 									const RelativePath& subDirectoryPath,
157 									const char* fileName, uint32 openMode,
158 									BFile& _file, BEntry* _entry = NULL);
159 			status_t			_OpenPackagesSubDirectory(
160 									const RelativePath& path, bool create,
161 									BDirectory& _directory);
162 
163 			status_t			_OpenSettingsRootDirectory(
164 									BDirectory& _directory);
165 
166 			status_t			_CreateActivationFileContent(
167 									const PackageSet& toActivate,
168 									const PackageSet& toDeactivate,
169 									BString& _content);
170 			status_t			_WriteActivationFile(
171 									const RelativePath& directoryPath,
172 									const char* fileName,
173 									const PackageSet& toActivate,
174 									const PackageSet& toDeactivate,
175 									BEntry& _entry);
176 
177 			status_t			_WriteTextFile(
178 									const RelativePath& directoryPath,
179 									const char* fileName,
180 									const BString& content, BEntry& _entry);
181 
182 			void				_ChangePackageActivation(
183 									const PackageSet& packagesToActivate,
184 									const PackageSet& packagesToDeactivate);
185 									// throws Exception
186 
187 			status_t			_ExtractPackageContent(Package* package,
188 									const char* contentPath,
189 									BDirectory& targetDirectory,
190 									BDirectory& _extractedFilesDirectory);
191 
192 private:
193 			BString				fPath;
194 			PackageFSMountType	fMountType;
195 			node_ref			fRootDirectoryRef;
196 			node_ref			fPackagesDirectoryRef;
197 			Root*				fRoot;
198 			Listener*			fListener;
199 			PackageFileNameHashTable fPackagesByFileName;
200 			PackageNodeRefHashTable fPackagesByNodeRef;
201 			BLocker				fPendingNodeMonitorEventsLock;
202 			NodeMonitorEventList fPendingNodeMonitorEvents;
203 			bigtime_t			fNodeMonitorEventHandleTime;
204 			PackageSet			fPackagesToBeActivated;
205 			PackageSet			fPackagesToBeDeactivated;
206 			int64				fChangeCount;
207 			BMessage			fLocationInfoReply;
208 };
209 
210 
211 class Volume::Listener {
212 public:
213 	virtual						~Listener();
214 
215 	virtual	void				VolumeNodeMonitorEventOccurred(Volume* volume)
216 									= 0;
217 };
218 
219 
220 #endif	// VOLUME_H
221