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