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