5 #include <unordered_set>
7 #include "pathlocks.hh"
8 #include "store-api.hh"
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;
22 extern string drvsLogDir
;
30 unsigned long filesLinked
;
31 unsigned long long bytesFreed
;
32 unsigned long long blocksFreed
;
36 bytesFreed
= blocksFreed
= 0;
41 struct RunningSubstituter
44 AutoCloseFD to
, from
, error
;
47 RunningSubstituter() : disabled(false) { };
51 class LocalStore
: public StoreAPI
54 /* The currently running substituter or empty. */
55 std::unique_ptr
<RunningSubstituter
> runningSubstituter
;
61 /* Initialise the local store, upgrading the schema if
63 LocalStore(bool reserveSpace
= true);
67 /* Implementations of abstract store API methods. */
69 bool isValidPath(const Path
& path
);
71 PathSet
queryValidPaths(const PathSet
& paths
);
73 PathSet
queryAllValidPaths();
75 ValidPathInfo
queryPathInfo(const Path
& path
);
77 Hash
queryPathHash(const Path
& path
);
79 void queryReferences(const Path
& path
, PathSet
& references
);
81 void queryReferrers(const Path
& path
, PathSet
& referrers
);
83 Path
queryDeriver(const Path
& path
);
85 PathSet
queryValidDerivers(const Path
& path
);
87 PathSet
queryDerivationOutputs(const Path
& path
);
89 StringSet
queryDerivationOutputNames(const Path
& path
);
91 Path
queryPathFromHashPart(const string
& hashPart
);
93 PathSet
querySubstitutablePaths(const PathSet
& paths
);
95 void querySubstitutablePathInfos(PathSet
& paths
,
96 SubstitutablePathInfos
& infos
);
98 void querySubstitutablePathInfos(const PathSet
& paths
,
99 SubstitutablePathInfos
& infos
);
101 Path
addToStore(const string
& name
, const Path
& srcPath
,
102 bool recursive
= true, HashType hashAlgo
= htSHA256
,
103 PathFilter
& filter
= defaultPathFilter
, bool repair
= false);
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 ==
109 Path
addToStoreFromDump(const string
& dump
, const string
& name
,
110 bool recursive
= true, HashType hashAlgo
= htSHA256
, bool repair
= false);
112 Path
addTextToStore(const string
& name
, const string
& s
,
113 const PathSet
& references
, bool repair
= false);
115 void exportPath(const Path
& path
, bool sign
,
118 Paths
importPaths(bool requireSignature
, Source
& source
);
120 void buildPaths(const PathSet
& paths
, BuildMode buildMode
);
122 void ensurePath(const Path
& path
);
124 void addTempRoot(const Path
& path
);
126 void addIndirectRoot(const Path
& path
);
132 void collectGarbage(const GCOptions
& options
, GCResults
& results
);
134 /* Optimise the disk space usage of the Nix store by hard-linking
135 files with the same contents. */
136 void optimiseStore(OptimiseStats
& stats
);
138 /* Generic variant of the above method. */
139 void optimiseStore();
141 /* Optimise a single store path. */
142 void optimisePath(const Path
& path
);
144 /* Check the integrity of the Nix store. Returns true if errors
146 bool verifyStore(bool checkContents
, bool repair
);
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
);
156 void registerValidPaths(const ValidPathInfos
& infos
);
158 /* Register that the build of a derivation with output `path' has
160 void registerFailedPath(const Path
& path
);
162 /* Query whether `path' previously failed to build. */
163 bool hasPathFailed(const Path
& path
);
165 PathSet
queryFailedPaths();
167 void clearFailedPaths(const PathSet
& paths
);
171 /* Repair the contents of the given path by redownloading it using
172 a substituter (if available). */
173 void repairPath(const Path
& path
);
175 /* Check whether the given valid path exists and has the right
177 bool pathContentsGood(const Path
& path
);
179 void markContentsGood(const Path
& path
);
181 void setSubstituterEnv();
183 void createUser(const std::string
& userName
, uid_t userId
);
189 /* Lock file used for upgrading. */
190 AutoCloseFD globalLock
;
192 /* The SQLite database object. */
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
;
213 /* Cache for pathContentsGood(). */
214 std::map
<Path
, bool> pathContentsGoodCache
;
216 bool didSetSubstituterEnv
;
218 /* The file to which we write our temporary roots. */
220 AutoCloseFD fdTempRoots
;
224 void openDB(bool create
);
226 void makeStoreWritable();
228 uint64_t queryValidPathId(const Path
& path
);
230 uint64_t addValidPath(const ValidPathInfo
& info
, bool checkOutputs
= true);
232 void addReference(uint64_t referrer
, uint64_t reference
);
234 void appendReferrer(const Path
& from
, const Path
& to
, bool lock
);
236 void rewriteReferrers(const Path
& path
, bool purge
, PathSet referrers
);
238 void invalidatePath(const Path
& path
);
240 /* Delete a path from the Nix store. */
241 void invalidatePathChecked(const Path
& path
);
243 void verifyPath(const Path
& path
, const PathSet
& store
,
244 PathSet
& done
, PathSet
& validPaths
, bool repair
, bool & errors
);
246 void updatePathInfo(const ValidPathInfo
& info
);
250 void deleteGarbage(GCState
& state
, const Path
& path
);
252 void tryToDelete(GCState
& state
, const Path
& path
);
254 bool canReachRoot(GCState
& state
, PathSet
& visited
, const Path
& path
);
256 void deletePathRecursive(GCState
& state
, const Path
& path
);
258 bool isActiveTempFile(const GCState
& state
,
259 const Path
& path
, const string
& suffix
);
261 int openGCLock(LockType lockType
);
263 void removeUnusedLinks(const GCState
& state
);
265 void startSubstituter(RunningSubstituter
& runningSubstituter
);
267 string
getLineFromSubstituter(RunningSubstituter
& run
);
269 template<class T
> T
getIntLineFromSubstituter(RunningSubstituter
& run
);
271 Path
createTempDirInStore();
273 Path
importPath(bool requireSignature
, Source
& source
);
275 void checkDerivationOutputs(const Path
& drvPath
, const Derivation
& drv
);
277 typedef std::unordered_set
<ino_t
> InodeHash
;
279 InodeHash
loadInodeHash();
280 Strings
readDirectoryIgnoringInodes(const Path
& path
, const InodeHash
& inodeHash
);
281 void optimisePath_(OptimiseStats
& stats
, const Path
& path
, InodeHash
& inodeHash
);
283 // Internal versions that are not wrapped in retry_sqlite.
284 bool isValidPath_(const Path
& path
);
285 void queryReferrers_(const Path
& path
, PathSet
& referrers
);
289 typedef std::pair
<dev_t
, ino_t
> Inode
;
290 typedef set
<Inode
> InodesSeen
;
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
301 void canonicalisePathMetaData(const Path
& path
, uid_t fromUid
, InodesSeen
& inodesSeen
);
302 void canonicalisePathMetaData(const Path
& path
, uid_t fromUid
);
304 void canonicaliseTimestampAndPermissions(const Path
& path
);
306 MakeError(PathInUse
, Error
);