local-store.hh 8.7 KB

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