Nix  2.93.0-dev
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
138public:
139
140 const Path dbDir;
141 const Path linksDir;
144 const Path schemaPath;
145 const Path tempRootsDir;
146 const Path fnTempRoots;
147
148 LocalStoreConfig & config() override { return config_; }
149 const LocalStoreConfig & config() const override { return config_; }
150
151private:
152
153 const PublicKeys & getPublicKeys();
154
155protected:
156
163 LocalStore(LocalStoreConfig config);
164 LocalStore(std::string scheme, std::string path, LocalStoreConfig config);
165
166public:
167
171 PathSet locksHeld;
172
173 virtual ~LocalStore();
174
175 static std::set<std::string> uriSchemes()
176 { return {}; }
177
181 static std::shared_ptr<LocalStore> makeLocalStore(const StoreConfig::Params & params);
182
187 std::string getUri() override;
188
189 kj::Promise<Result<bool>> isValidPathUncached(const StorePath & path) override;
190
191 kj::Promise<Result<StorePathSet>> queryValidPaths(const StorePathSet & paths,
192 SubstituteFlag maybeSubstitute = NoSubstitute) override;
193
194 kj::Promise<Result<StorePathSet>> queryAllValidPaths() override;
195
196 kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
197 queryPathInfoUncached(const StorePath & path) override;
198
199 kj::Promise<Result<void>>
200 queryReferrers(const StorePath & path, StorePathSet & referrers) override;
201
202 kj::Promise<Result<StorePathSet>> queryValidDerivers(const StorePath & path) override;
203
204 kj::Promise<Result<std::map<std::string, std::optional<StorePath>>>>
205 queryStaticPartialDerivationOutputMap(const StorePath & path) override;
206
207 kj::Promise<Result<std::optional<StorePath>>>
208 queryPathFromHashPart(const std::string & hashPart) override;
209
210 kj::Promise<Result<StorePathSet>> querySubstitutablePaths(const StorePathSet & paths) override;
211
212 bool pathInfoIsUntrusted(const ValidPathInfo &) override;
213 bool realisationIsUntrusted(const Realisation & ) override;
214
215 kj::Promise<Result<void>> addToStore(const ValidPathInfo & info, AsyncInputStream & source,
216 RepairFlag repair, CheckSigsFlag checkSigs) override;
217
218 kj::Promise<Result<StorePath>> addToStoreFromDump(
219 AsyncInputStream & dump,
220 std::string_view name,
221 FileIngestionMethod method,
222 HashType hashAlgo,
223 RepairFlag repair,
224 const StorePathSet & references
225 ) override;
226
227 kj::Promise<Result<StorePath>> addTextToStore(
228 std::string_view name,
229 std::string_view s,
230 const StorePathSet & references,
231 RepairFlag repair) override;
232
233 kj::Promise<Result<void>> addTempRoot(const StorePath & path) override;
234
235private:
236
237 void createTempRootsFile();
238
242 Sync<AutoCloseFD> _fdTempRoots;
243
247 Sync<AutoCloseFD> _fdGCLock;
248
252 Sync<AutoCloseFD> _fdRootsSocket;
253
254public:
255
262 kj::Promise<Result<void>> addIndirectRoot(const Path & path) override;
263
264private:
265
266 void findTempRoots(Roots & roots, bool censor);
267
268 AutoCloseFD openGCLock();
269
270public:
271
272 kj::Promise<Result<Roots>> findRoots(bool censor) override;
273
274 kj::Promise<Result<void>>
275 collectGarbage(const GCOptions & options, GCResults & results) override;
276
281 kj::Promise<Result<void>> optimiseStore(OptimiseStats & stats);
282
283 kj::Promise<Result<void>> optimiseStore() override;
284
289 void optimisePath(const Path & path, RepairFlag repair);
290
291 kj::Promise<Result<bool>> verifyStore(bool checkContents, RepairFlag repair) override;
292
301 kj::Promise<Result<void>> registerValidPath(const ValidPathInfo & info);
302
303 kj::Promise<Result<void>> registerValidPaths(const ValidPathInfos & infos);
304
305 kj::Promise<Result<unsigned int>> getProtocol() override;
306
307 kj::Promise<Result<std::optional<TrustedFlag>>> isTrustedClient() override;
308
309 kj::Promise<Result<void>>
310 addSignatures(const StorePath & storePath, const StringSet & sigs) override;
311
316 kj::Promise<Result<void>> autoGC(bool sync = true);
317
322 kj::Promise<Result<void>> registerDrvOutput(const Realisation & info) override;
323 kj::Promise<Result<void>>
324 registerDrvOutput(const Realisation & info, CheckSigsFlag checkSigs) override;
325 void cacheDrvOutputMapping(
326 DBState & state,
327 const uint64_t deriver,
328 const std::string & outputName,
329 const StorePath & output);
330
331 std::optional<const Realisation> queryRealisation_(DBState & state, const DrvOutput & id);
332 std::optional<std::pair<int64_t, Realisation>> queryRealisationCore_(DBState & state, const DrvOutput & id);
333 kj::Promise<Result<std::shared_ptr<const Realisation>>>
334 queryRealisationUncached(const DrvOutput&) override;
335
336 kj::Promise<Result<std::optional<std::string>>> getVersion() override;
337
338private:
339
344 int getSchema();
345
346 void initDB(DBState & state);
347 void openDB(DBState & state, bool create);
348 void prepareStatements(DBState & state);
349
350 void makeStoreWritable();
351
352 uint64_t queryValidPathId(DBState & state, const StorePath & path);
353
354 kj::Promise<Result<uint64_t>>
355 addValidPath(DBState & state, const ValidPathInfo & info, bool checkOutputs = true);
356
357 kj::Promise<Result<void>> invalidatePath(DBState & state, const StorePath & path);
358
362 kj::Promise<Result<void>> invalidatePathChecked(const StorePath & path);
363
364 kj::Promise<Result<void>> verifyPath(const StorePath & path, const StorePathSet & store,
365 StorePathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors);
366
367 std::shared_ptr<const ValidPathInfo> queryPathInfoInternal(DBState & state, const StorePath & path);
368
369 void updatePathInfo(DBState & state, const ValidPathInfo & info);
370
371 PathSet queryValidPathsOld();
372 ValidPathInfo queryPathInfoOld(const Path & path);
373
374 kj::Promise<Result<void>> findRoots(const Path & path, unsigned char type, Roots & roots);
375
376 kj::Promise<Result<void>> findRootsNoTemp(Roots & roots, bool censor);
377
382 virtual void findPlatformRoots(UncheckedRoots & unchecked);
383
384 kj::Promise<Result<void>> findRuntimeRoots(Roots & roots, bool censor);
385
386 std::pair<Path, AutoCloseFD> createTempDirInStore();
387
388 typedef std::unordered_set<ino_t> InodeHash;
389
390 InodeHash loadInodeHash();
391 Strings readDirectoryIgnoringInodes(const Path & path, const InodeHash & inodeHash);
392 void optimisePath_(Activity * act, OptimiseStats & stats, const Path & path, InodeHash & inodeHash, RepairFlag repair);
393
394 // Internal versions that are not wrapped in retry_sqlite.
395 bool isValidPath_(DBState & state, const StorePath & path);
396 void queryReferrers(DBState & state, const StorePath & path, StorePathSet & referrers);
397
402 void signPathInfo(ValidPathInfo & info);
403 void signRealisation(Realisation &);
404
405 // XXX: Make a generic `Store` method
406 ContentAddress hashCAPath(
407 const ContentAddressMethod & method,
408 const HashType & hashType,
409 const StorePath & path);
410
411 ContentAddress hashCAPath(
412 const ContentAddressMethod & method,
413 const HashType & hashType,
414 const Path & path,
415 const std::string_view pathHash
416 );
417
418 kj::Promise<Result<void>> addBuildLog(const StorePath & drvPath, std::string_view log) override;
419
420 friend struct LocalDerivationGoal;
421 friend struct PathSubstitutionGoal;
422 friend struct SubstitutionGoal;
423 friend struct DerivationGoal;
424};
425
426
427typedef std::pair<dev_t, ino_t> Inode;
428typedef std::set<Inode> InodesSeen;
429
430
448void canonicalisePathMetaData(
449 const Path & path,
450 std::optional<std::pair<uid_t, uid_t>> uidRange,
451 InodesSeen & inodesSeen);
452void canonicalisePathMetaData(
453 const Path & path,
454 std::optional<std::pair<uid_t, uid_t>> uidRange);
455
456void canonicaliseTimestampAndPermissions(const Path & path);
457
458MakeError(PathInUse, Error);
459
460// Implemented by the relevant platform/ module being used.
461void registerLocalStore();
462
463}
Definition file-descriptor.hh:42
Definition local-store.hh:78
kj::Promise< Result< std::optional< StorePath > > > queryPathFromHashPart(const std::string &hashPart) override
Definition local-store.cc:1104
kj::Promise< Result< unsigned int > > getProtocol() override
Definition local-store.cc:1829
kj::Promise< Result< std::shared_ptr< const ValidPathInfo > > > queryPathInfoUncached(const StorePath &path) override
Definition local-store.cc:883
std::string getUri() override
Definition local-store.cc:478
kj::Promise< Result< void > > registerValidPath(const ValidPathInfo &info)
Definition local-store.cc:1165
kj::Promise< Result< void > > addSignatures(const StorePath &storePath, const StringSet &sigs) override
Definition local-store.cc:1841
kj::Promise< Result< void > > collectGarbage(const GCOptions &options, GCResults &results) override
Definition gc.cc:598
kj::Promise< Result< void > > addIndirectRoot(const Path &path) override
Definition gc.cc:50
kj::Promise< Result< StorePathSet > > queryValidDerivers(const StorePath &path) override
Definition local-store.cc:1055
kj::Promise< Result< void > > addToStore(const ValidPathInfo &info, AsyncInputStream &source, RepairFlag repair, CheckSigsFlag checkSigs) override
Definition local-store.cc:1282
kj::Promise< Result< StorePathSet > > queryValidPaths(const StorePathSet &paths, SubstituteFlag maybeSubstitute=NoSubstitute) override
Definition local-store.cc:997
kj::Promise< Result< void > > queryReferrers(const StorePath &path, StorePathSet &referrers) override
Definition local-store.cc:1037
kj::Promise< Result< void > > optimiseStore() override
Definition optimise-store.cc:293
bool pathInfoIsUntrusted(const ValidPathInfo &) override
Definition local-store.cc:1272
kj::Promise< Result< StorePathSet > > querySubstitutablePaths(const StorePathSet &paths) override
Definition local-store.cc:1132
static std::shared_ptr< LocalStore > makeLocalStore(const StoreConfig::Params &params)
Definition platform.cc:15
const Path reservedSpacePath
Definition local-store.hh:143
kj::Promise< Result< StorePath > > addTextToStore(std::string_view name, std::string_view s, const StorePathSet &references, RepairFlag repair) override
Definition local-store.cc:1539
kj::Promise< Result< void > > registerDrvOutput(const Realisation &info) override
Definition local-store.cc:752
kj::Promise< Result< Roots > > findRoots(bool censor) override
Definition gc.cc:347
kj::Promise< Result< StorePathSet > > queryAllValidPaths() override
Definition local-store.cc:1008
kj::Promise< Result< std::map< std::string, std::optional< StorePath > > > > queryStaticPartialDerivationOutputMap(const StorePath &path) override
Definition local-store.cc:1079
kj::Promise< Result< void > > autoGC(bool sync=true)
Definition gc.cc:948
kj::Promise< Result< bool > > verifyStore(bool checkContents, RepairFlag repair) override
Definition local-store.cc:1643
PathSet locksHeld
Definition local-store.hh:171
kj::Promise< Result< std::optional< TrustedFlag > > > isTrustedClient() override
Definition local-store.cc:1834
LocalStore(LocalStoreConfig config)
Definition local-store.cc:184
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:1367
kj::Promise< Result< void > > addTempRoot(const StorePath &path) override
Definition gc.cc:125
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