Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
local-store.hh
Go to the documentation of this file.
1#pragma once
3
5
9#include "lix/libutil/sync.hh"
10#include "lix/libutil/types.hh"
11
12#include <chrono>
13#include <future>
14#include <kj/async.h>
15#include <string>
16#include <mutex>
17#include <memory>
18#include <unordered_set>
19
20
21namespace nix {
22
23
35const int nixSchemaVersion = 10;
36
37
39{
40 unsigned long filesLinked = 0;
41 uint64_t bytesFreed = 0;
42 uint64_t blocksFreed = 0;
43};
44
46{
47 using LocalFSStoreConfig::LocalFSStoreConfig;
48
49 Setting<bool> requireSigs{this,
50 settings.requireSigs,
51 "require-sigs",
52 "Whether store paths copied into this store should have a trusted signature."};
53
54 Setting<bool> readOnly{this,
55 false,
56 "read-only",
57 R"(
58 Allow this store to be opened when its [database](@docroot@/glossary.md#gloss-nix-database) is on a read-only filesystem.
59
60 Normally Lix will attempt to open the store database in read-write mode, even for querying (when write access is not needed), causing it to fail if the database is on a read-only filesystem.
61
62 Enable read-only mode to disable locking and open the SQLite database with the [`immutable` parameter](https://www.sqlite.org/c3ref/open.html) set.
63
64 > **Warning**
65 > Do not use this unless the filesystem is read-only.
66 >
67 > Using it when the filesystem is writable can cause incorrect query results or corruption errors if the database is changed by another process.
68 > While the filesystem the database resides on might appear to be read-only, consider whether another user or system might have write access to it.
69 )"};
70
71 const std::string name() override { return "Local Store"; }
72
73 std::string doc() override;
74};
75
76class LocalStore : public virtual IndirectRootStore
77 , public virtual GcStore
78{
79private:
80
81 LocalStoreConfig config_;
82
86 AutoCloseFD globalLock;
87
95 std::unique_ptr<const PublicKeys> publicKeys = nullptr;
96 std::once_flag publicKeysFlag;
97
98 struct DBState
99 {
103 SQLite db;
104
105 struct Stmts;
106 std::unique_ptr<Stmts> stmts;
107 };
108
110
111 struct GCState
112 {
117 std::chrono::time_point<std::chrono::steady_clock> lastGCCheck;
118
123 bool gcRunning = false;
124 std::future<void> gcFuture;
125 std::list<kj::Own<kj::CrossThreadPromiseFulfiller<void>>> gcWaiters;
126
133 uint64_t availAfterGC = std::numeric_limits<uint64_t>::max();
134 };
135
136 Sync<GCState> _gcState;
137
138 std::optional<AssociatedCredentials> association;
139
140public:
141
142 const Path dbDir;
143 const Path linksDir;
146 const Path schemaPath;
147 const Path tempRootsDir;
148 const Path fnTempRoots;
149
150 LocalStoreConfig & config() override { return config_; }
151 const LocalStoreConfig & config() const override { return config_; }
152
153 std::optional<AssociatedCredentials> associatedCredentials() const override
154 {
155 return association;
156 }
157
158 void associateWithCredentials(uid_t user, gid_t group)
159 {
160 association = {user, group};
161 }
162
163private:
164
165 const PublicKeys & getPublicKeys();
166
167protected:
168
175 LocalStore(LocalStoreConfig config);
176 LocalStore(std::string scheme, std::string path, LocalStoreConfig config);
177
178public:
179
183 PathSet locksHeld;
184
185 virtual ~LocalStore();
186
187 static std::set<std::string> uriSchemes()
188 { return {}; }
189
193 static ref<LocalStore> makeLocalStore(const StoreConfig::Params & params);
194
198
199 std::string getUri() override;
200
201 kj::Promise<Result<bool>> isValidPathUncached(const StorePath & path) override;
202
203 kj::Promise<Result<StorePathSet>> queryValidPaths(const StorePathSet & paths,
204 SubstituteFlag maybeSubstitute = NoSubstitute) override;
205
206 kj::Promise<Result<StorePathSet>> queryAllValidPaths() override;
207
208 kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
209 queryPathInfoUncached(const StorePath & path) override;
210
211 kj::Promise<Result<void>>
212 queryReferrers(const StorePath & path, StorePathSet & referrers) override;
213
214 kj::Promise<Result<StorePathSet>> queryValidDerivers(const StorePath & path) override;
215
216 kj::Promise<Result<std::map<std::string, std::optional<StorePath>>>>
217 queryStaticPartialDerivationOutputMap(const StorePath & path) override;
218
219 kj::Promise<Result<std::optional<StorePath>>>
220 queryPathFromHashPart(const std::string & hashPart) override;
221
222 kj::Promise<Result<StorePathSet>> querySubstitutablePaths(const StorePathSet & paths) override;
223
224 bool pathInfoIsUntrusted(const ValidPathInfo &) override;
225 bool realisationIsUntrusted(const Realisation & ) override;
226
227 kj::Promise<Result<void>> addToStore(const ValidPathInfo & info, AsyncInputStream & source,
228 RepairFlag repair, CheckSigsFlag checkSigs) override;
229
230 kj::Promise<Result<StorePath>> addToStoreFromDump(
231 AsyncInputStream & dump,
232 std::string_view name,
233 FileIngestionMethod method,
234 HashType hashAlgo,
235 RepairFlag repair,
236 const StorePathSet & references
237 ) override;
238
239 kj::Promise<Result<StorePath>> addTextToStore(
240 std::string_view name,
241 std::string_view s,
242 const StorePathSet & references,
243 RepairFlag repair) override;
244
245 kj::Promise<Result<void>> addTempRoot(const StorePath & path) override;
246
247private:
248
249 void createTempRootsFile();
250
254 Sync<AutoCloseFD> _fdTempRoots;
255
259 Sync<AutoCloseFD> _fdGCLock;
260
264 Sync<AutoCloseFD> _fdRootsSocket;
265
266public:
267
274 kj::Promise<Result<void>> addIndirectRoot(const Path & path) override;
275
276private:
277
278 void findTempRoots(Roots & roots, bool censor);
279
280 AutoCloseFD openGCLock();
281
282public:
283
284 kj::Promise<Result<Roots>> findRoots(bool censor) override;
285
286 kj::Promise<Result<void>>
287 collectGarbage(const GCOptions & options, GCResults & results) override;
288
293 kj::Promise<Result<void>> optimiseStore(OptimiseStats & stats);
294
295 kj::Promise<Result<void>> optimiseStore() override;
296
301 void optimisePath(const Path & path, RepairFlag repair);
302
303 kj::Promise<Result<bool>> verifyStore(bool checkContents, RepairFlag repair) override;
304
313 kj::Promise<Result<void>> registerValidPath(const ValidPathInfo & info);
314
315 kj::Promise<Result<void>> registerValidPaths(const ValidPathInfos & infos);
316
317 kj::Promise<Result<unsigned int>> getProtocol() override;
318
319 kj::Promise<Result<std::optional<TrustedFlag>>> isTrustedClient() override;
320
321 kj::Promise<Result<void>>
322 addSignatures(const StorePath & storePath, const StringSet & sigs) override;
323
328 kj::Promise<Result<void>> autoGC(bool sync = true);
329
334 kj::Promise<Result<void>> registerDrvOutput(const Realisation & info) override;
335 kj::Promise<Result<void>>
336 registerDrvOutput(const Realisation & info, CheckSigsFlag checkSigs) override;
337 void cacheDrvOutputMapping(
338 DBState & state,
339 const uint64_t deriver,
340 const std::string & outputName,
341 const StorePath & output);
342
343 std::optional<const Realisation> queryRealisation_(DBState & state, const DrvOutput & id);
344 std::optional<std::pair<int64_t, Realisation>> queryRealisationCore_(DBState & state, const DrvOutput & id);
345 kj::Promise<Result<std::shared_ptr<const Realisation>>>
346 queryRealisationUncached(const DrvOutput&) override;
347
348 kj::Promise<Result<std::optional<std::string>>> getVersion() override;
349
350private:
351
356 int getSchema();
357
358 void initDB(DBState & state);
359 void openDB(DBState & state, bool create);
360 void prepareStatements(DBState & state);
361
362 void makeStoreWritable();
363
364 uint64_t queryValidPathId(DBState & state, const StorePath & path);
365
366 kj::Promise<Result<uint64_t>>
367 addValidPath(DBState & state, const ValidPathInfo & info, bool checkOutputs = true);
368
369 kj::Promise<Result<void>> invalidatePath(DBState & state, const StorePath & path);
370
374 kj::Promise<Result<void>> invalidatePathChecked(const StorePath & path);
375
376 kj::Promise<Result<void>> verifyPath(const StorePath & path, const StorePathSet & store,
377 StorePathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors);
378
379 std::shared_ptr<const ValidPathInfo> queryPathInfoInternal(DBState & state, const StorePath & path);
380
381 void updatePathInfo(DBState & state, const ValidPathInfo & info);
382
383 PathSet queryValidPathsOld();
384 ValidPathInfo queryPathInfoOld(const Path & path);
385
386 kj::Promise<Result<void>> findRoots(const Path & path, unsigned char type, Roots & roots);
387
388 kj::Promise<Result<void>> findRootsNoTemp(Roots & roots, bool censor);
389
394 virtual void findPlatformRoots(UncheckedRoots & unchecked);
395
396 kj::Promise<Result<void>> findRuntimeRoots(Roots & roots, bool censor);
397
398 std::pair<Path, AutoCloseFD> createTempDirInStore();
399
400 typedef std::unordered_set<ino_t> InodeHash;
401
402 InodeHash loadInodeHash();
403 Strings readDirectoryIgnoringInodes(const Path & path, const InodeHash & inodeHash);
404 void optimisePath_(Activity * act, OptimiseStats & stats, const Path & path, InodeHash & inodeHash, RepairFlag repair);
405
406 // Internal versions that are not wrapped in retry_sqlite.
407 bool isValidPath_(DBState & state, const StorePath & path);
408 void queryReferrers(DBState & state, const StorePath & path, StorePathSet & referrers);
409
414 void signPathInfo(ValidPathInfo & info);
415 void signRealisation(Realisation &);
416
417 // XXX: Make a generic `Store` method
418 ContentAddress hashCAPath(
419 const ContentAddressMethod & method,
420 const HashType & hashType,
421 const StorePath & path);
422
423 ContentAddress hashCAPath(
424 const ContentAddressMethod & method,
425 const HashType & hashType,
426 const Path & path,
427 const std::string_view pathHash
428 );
429
430 kj::Promise<Result<void>> addBuildLog(const StorePath & drvPath, std::string_view log) override;
431
432 friend struct LocalDerivationGoal;
433 friend struct PathSubstitutionGoal;
434 friend struct SubstitutionGoal;
435 friend struct DerivationGoal;
436};
437
438
439typedef std::pair<dev_t, ino_t> Inode;
440typedef std::set<Inode> InodesSeen;
441
442
460void canonicalisePathMetaData(
461 const Path & path,
462 std::optional<std::pair<uid_t, uid_t>> uidRange,
463 InodesSeen & inodesSeen);
464void canonicalisePathMetaData(
465 const Path & path,
466 std::optional<std::pair<uid_t, uid_t>> uidRange);
467
468void canonicaliseTimestampAndPermissions(const Path & path);
469
470MakeError(PathInUse, Error);
471
472// Implemented by the relevant platform/ module being used.
473void registerLocalStore();
474
475}
Definition file-descriptor.hh:51
kj::Promise< Result< std::optional< StorePath > > > queryPathFromHashPart(const std::string &hashPart) override
Definition local-store.cc:1068
kj::Promise< Result< unsigned int > > getProtocol() override
Definition local-store.cc:1793
kj::Promise< Result< std::shared_ptr< const ValidPathInfo > > > queryPathInfoUncached(const StorePath &path) override
Definition local-store.cc:847
std::string getUri() override
Definition local-store.cc:442
kj::Promise< Result< void > > registerValidPath(const ValidPathInfo &info)
Definition local-store.cc:1129
kj::Promise< Result< void > > addSignatures(const StorePath &storePath, const StringSet &sigs) override
Definition local-store.cc:1805
kj::Promise< Result< void > > collectGarbage(const GCOptions &options, GCResults &results) override
Definition gc.cc:600
kj::Promise< Result< void > > addIndirectRoot(const Path &path) override
Definition gc.cc:52
kj::Promise< Result< StorePathSet > > queryValidDerivers(const StorePath &path) override
Definition local-store.cc:1019
kj::Promise< Result< void > > addToStore(const ValidPathInfo &info, AsyncInputStream &source, RepairFlag repair, CheckSigsFlag checkSigs) override
Definition local-store.cc:1246
kj::Promise< Result< StorePathSet > > queryValidPaths(const StorePathSet &paths, SubstituteFlag maybeSubstitute=NoSubstitute) override
Definition local-store.cc:961
kj::Promise< Result< void > > queryReferrers(const StorePath &path, StorePathSet &referrers) override
Definition local-store.cc:1001
kj::Promise< Result< void > > optimiseStore() override
Definition optimise-store.cc:293
bool pathInfoIsUntrusted(const ValidPathInfo &) override
Definition local-store.cc:1236
kj::Promise< Result< StorePathSet > > querySubstitutablePaths(const StorePathSet &paths) override
Definition local-store.cc:1096
const Path reservedSpacePath
Definition local-store.hh:145
kj::Promise< Result< StorePath > > addTextToStore(std::string_view name, std::string_view s, const StorePathSet &references, RepairFlag repair) override
Definition local-store.cc:1503
kj::Promise< Result< void > > registerDrvOutput(const Realisation &info) override
Definition local-store.cc:716
std::optional< AssociatedCredentials > associatedCredentials() const override
Definition local-store.hh:153
kj::Promise< Result< Roots > > findRoots(bool censor) override
Definition gc.cc:349
kj::Promise< Result< StorePathSet > > queryAllValidPaths() override
Definition local-store.cc:972
kj::Promise< Result< std::map< std::string, std::optional< StorePath > > > > queryStaticPartialDerivationOutputMap(const StorePath &path) override
Definition local-store.cc:1043
kj::Promise< Result< void > > autoGC(bool sync=true)
Definition gc.cc:950
kj::Promise< Result< bool > > verifyStore(bool checkContents, RepairFlag repair) override
Definition local-store.cc:1607
PathSet locksHeld
Definition local-store.hh:183
kj::Promise< Result< std::optional< TrustedFlag > > > isTrustedClient() override
Definition local-store.cc:1798
static ref< LocalStore > makeLocalStore(const StoreConfig::Params &params)
Definition platform.cc:15
LocalStore(LocalStoreConfig config)
Definition local-store.cc:148
kj::Promise< Result< StorePath > > addToStoreFromDump(AsyncInputStream &dump, std::string_view name, FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet &references) override
Definition local-store.cc:1331
kj::Promise< Result< void > > addTempRoot(const StorePath &path) override
Definition gc.cc:127
void optimisePath(const Path &path, RepairFlag repair)
Definition optimise-store.cc:307
Definition sqlite.hh:72
Definition config.hh:310
Definition sync.hh:37
const int nixSchemaVersion
Definition local-store.hh:35
Definition gc-store.hh:121
Definition indirect-root-store.hh:16
Definition local-fs-store.hh:11
Definition local-store.hh:46
const std::string name() override
Definition local-store.hh:71
std::string doc() override
Definition local-store.cc:54
Definition local-store.hh:39
std::string Path
Definition types.hh:28