WIP: bees service
[jackhill/guix/guix.git] / nix / libstore / local-store.hh
CommitLineData
36457566
LC
1#pragma once
2
7bed5d91 3#include "sqlite.hh"
36457566 4#include <string>
2bb04905 5#include <unordered_set>
36457566 6
7bed5d91 7#include "pathlocks.hh"
36457566
LC
8#include "store-api.hh"
9#include "util.hh"
36457566
LC
10
11
12namespace nix {
13
14
15/* Nix store and database schema version. Version 1 (or 0) was Nix <=
16 0.7. Version 2 was Nix 0.8 and 0.9. Version 3 is Nix 0.10.
17 Version 4 is Nix 0.11. Version 5 is Nix 0.12-0.16. Version 6 is
602a1486 18 Nix 1.0. Version 7 is Nix 1.3. Guix has always used version 7. */
36457566
LC
19const int nixSchemaVersion = 7;
20
21
22extern string drvsLogDir;
23
24
25struct Derivation;
26
27
28struct OptimiseStats
29{
36457566
LC
30 unsigned long filesLinked;
31 unsigned long long bytesFreed;
32 unsigned long long blocksFreed;
33 OptimiseStats()
34 {
15ddeff5 35 filesLinked = 0;
36457566
LC
36 bytesFreed = blocksFreed = 0;
37 }
38};
39
40
36457566
LC
41class LocalStore : public StoreAPI
42{
43private:
f6919ebd 44 /* The currently running substituter or empty. */
a618a8c6
LC
45 std::shared_ptr<Agent> runningSubstituter;
46
47 /* Ensure the substituter is running and return it. */
48 std::shared_ptr<Agent> substituter();
36457566
LC
49
50 Path linksDir;
51
52public:
53
54 /* Initialise the local store, upgrading the schema if
55 necessary. */
56 LocalStore(bool reserveSpace = true);
57
58 ~LocalStore();
59
60 /* Implementations of abstract store API methods. */
61
62 bool isValidPath(const Path & path);
63
64 PathSet queryValidPaths(const PathSet & paths);
65
66 PathSet queryAllValidPaths();
67
68 ValidPathInfo queryPathInfo(const Path & path);
69
70 Hash queryPathHash(const Path & path);
71
72 void queryReferences(const Path & path, PathSet & references);
73
74 void queryReferrers(const Path & path, PathSet & referrers);
75
76 Path queryDeriver(const Path & path);
77
78 PathSet queryValidDerivers(const Path & path);
79
80 PathSet queryDerivationOutputs(const Path & path);
81
82 StringSet queryDerivationOutputNames(const Path & path);
83
84 Path queryPathFromHashPart(const string & hashPart);
85
86 PathSet querySubstitutablePaths(const PathSet & paths);
87
f6919ebd
LC
88 void querySubstitutablePathInfos(PathSet & paths,
89 SubstitutablePathInfos & infos);
36457566
LC
90
91 void querySubstitutablePathInfos(const PathSet & paths,
92 SubstitutablePathInfos & infos);
93
54c260e6 94 Path addToStore(const string & name, const Path & srcPath,
36457566
LC
95 bool recursive = true, HashType hashAlgo = htSHA256,
96 PathFilter & filter = defaultPathFilter, bool repair = false);
97
98 /* Like addToStore(), but the contents of the path are contained
99 in `dump', which is either a NAR serialisation (if recursive ==
100 true) or simply the contents of a regular file (if recursive ==
101 false). */
102 Path addToStoreFromDump(const string & dump, const string & name,
103 bool recursive = true, HashType hashAlgo = htSHA256, bool repair = false);
104
105 Path addTextToStore(const string & name, const string & s,
106 const PathSet & references, bool repair = false);
107
108 void exportPath(const Path & path, bool sign,
109 Sink & sink);
110
111 Paths importPaths(bool requireSignature, Source & source);
112
113 void buildPaths(const PathSet & paths, BuildMode buildMode);
114
115 void ensurePath(const Path & path);
116
117 void addTempRoot(const Path & path);
118
119 void addIndirectRoot(const Path & path);
120
121 void syncWithGC();
122
123 Roots findRoots();
124
125 void collectGarbage(const GCOptions & options, GCResults & results);
126
127 /* Optimise the disk space usage of the Nix store by hard-linking
128 files with the same contents. */
129 void optimiseStore(OptimiseStats & stats);
130
2bb04905
LC
131 /* Generic variant of the above method. */
132 void optimiseStore();
133
36457566
LC
134 /* Optimise a single store path. */
135 void optimisePath(const Path & path);
136
137 /* Check the integrity of the Nix store. Returns true if errors
138 remain. */
139 bool verifyStore(bool checkContents, bool repair);
140
141 /* Register the validity of a path, i.e., that `path' exists, that
142 the paths referenced by it exists, and in the case of an output
143 path of a derivation, that it has been produced by a successful
144 execution of the derivation (or something equivalent). Also
145 register the hash of the file system contents of the path. The
146 hash must be a SHA-256 hash. */
147 void registerValidPath(const ValidPathInfo & info);
148
149 void registerValidPaths(const ValidPathInfos & infos);
150
151 /* Register that the build of a derivation with output `path' has
152 failed. */
153 void registerFailedPath(const Path & path);
154
155 /* Query whether `path' previously failed to build. */
156 bool hasPathFailed(const Path & path);
157
158 PathSet queryFailedPaths();
159
160 void clearFailedPaths(const PathSet & paths);
161
162 void vacuumDB();
163
164 /* Repair the contents of the given path by redownloading it using
165 a substituter (if available). */
166 void repairPath(const Path & path);
167
168 /* Check whether the given valid path exists and has the right
169 contents. */
170 bool pathContentsGood(const Path & path);
171
172 void markContentsGood(const Path & path);
173
81c580c8
LC
174 void createUser(const std::string & userName, uid_t userId);
175
36457566
LC
176private:
177
178 Path schemaPath;
179
180 /* Lock file used for upgrading. */
181 AutoCloseFD globalLock;
182
183 /* The SQLite database object. */
184 SQLite db;
185
186 /* Some precompiled SQLite statements. */
187 SQLiteStmt stmtRegisterValidPath;
188 SQLiteStmt stmtUpdatePathInfo;
189 SQLiteStmt stmtAddReference;
190 SQLiteStmt stmtQueryPathInfo;
191 SQLiteStmt stmtQueryReferences;
192 SQLiteStmt stmtQueryReferrers;
193 SQLiteStmt stmtInvalidatePath;
194 SQLiteStmt stmtRegisterFailedPath;
195 SQLiteStmt stmtHasPathFailed;
196 SQLiteStmt stmtQueryFailedPaths;
197 SQLiteStmt stmtClearFailedPath;
198 SQLiteStmt stmtAddDerivationOutput;
199 SQLiteStmt stmtQueryValidDerivers;
200 SQLiteStmt stmtQueryDerivationOutputs;
201 SQLiteStmt stmtQueryPathFromHashPart;
b1fd0ab7 202 SQLiteStmt stmtQueryValidPaths;
36457566
LC
203
204 /* Cache for pathContentsGood(). */
205 std::map<Path, bool> pathContentsGoodCache;
206
2bb04905
LC
207 /* The file to which we write our temporary roots. */
208 Path fnTempRoots;
209 AutoCloseFD fdTempRoots;
210
36457566
LC
211 int getSchema();
212
213 void openDB(bool create);
214
215 void makeStoreWritable();
216
b1fd0ab7 217 uint64_t queryValidPathId(const Path & path);
36457566 218
b1fd0ab7 219 uint64_t addValidPath(const ValidPathInfo & info, bool checkOutputs = true);
36457566 220
b1fd0ab7 221 void addReference(uint64_t referrer, uint64_t reference);
36457566
LC
222
223 void appendReferrer(const Path & from, const Path & to, bool lock);
224
225 void rewriteReferrers(const Path & path, bool purge, PathSet referrers);
226
227 void invalidatePath(const Path & path);
228
229 /* Delete a path from the Nix store. */
230 void invalidatePathChecked(const Path & path);
231
232 void verifyPath(const Path & path, const PathSet & store,
233 PathSet & done, PathSet & validPaths, bool repair, bool & errors);
234
235 void updatePathInfo(const ValidPathInfo & info);
236
36457566
LC
237 struct GCState;
238
239 void deleteGarbage(GCState & state, const Path & path);
240
241 void tryToDelete(GCState & state, const Path & path);
242
243 bool canReachRoot(GCState & state, PathSet & visited, const Path & path);
244
245 void deletePathRecursive(GCState & state, const Path & path);
246
247 bool isActiveTempFile(const GCState & state,
248 const Path & path, const string & suffix);
249
250 int openGCLock(LockType lockType);
251
252 void removeUnusedLinks(const GCState & state);
253
79c6614f 254 string getLineFromSubstituter(Agent & run);
36457566 255
79c6614f 256 template<class T> T getIntLineFromSubstituter(Agent & run);
36457566
LC
257
258 Path createTempDirInStore();
259
260 Path importPath(bool requireSignature, Source & source);
261
262 void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
263
2bb04905 264 typedef std::unordered_set<ino_t> InodeHash;
15ddeff5
LC
265
266 InodeHash loadInodeHash();
267 Strings readDirectoryIgnoringInodes(const Path & path, const InodeHash & inodeHash);
268 void optimisePath_(OptimiseStats & stats, const Path & path, InodeHash & inodeHash);
36457566
LC
269
270 // Internal versions that are not wrapped in retry_sqlite.
271 bool isValidPath_(const Path & path);
272 void queryReferrers_(const Path & path, PathSet & referrers);
273};
274
275
276typedef std::pair<dev_t, ino_t> Inode;
277typedef set<Inode> InodesSeen;
278
279
280/* "Fix", or canonicalise, the meta-data of the files in a store path
281 after it has been built. In particular:
282 - the last modification date on each file is set to 1 (i.e.,
283 00:00:01 1/1/1970 UTC)
284 - the permissions are set of 444 or 555 (i.e., read-only with or
285 without execute permission; setuid bits etc. are cleared)
286 - the owner and group are set to the Nix user and group, if we're
287 running as root. */
288void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & inodesSeen);
289void canonicalisePathMetaData(const Path & path, uid_t fromUid);
290
291void canonicaliseTimestampAndPermissions(const Path & path);
292
293MakeError(PathInUse, Error);
294
295}