local-store.hh 8.5 KB

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