2012-07-18 20:59:03 +02:00
|
|
|
#pragma once
|
2006-11-30 18:43:04 +01:00
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include "store-api.hh"
|
2008-06-09 15:52:45 +02:00
|
|
|
#include "util.hh"
|
2010-08-31 13:47:31 +02:00
|
|
|
#include "pathlocks.hh"
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2010-02-18 15:30:42 +01:00
|
|
|
|
|
|
|
class sqlite3;
|
|
|
|
class sqlite3_stmt;
|
2010-02-18 14:16:59 +01:00
|
|
|
|
2006-11-30 18:43:04 +01:00
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
|
|
|
|
/* Nix store and database schema version. Version 1 (or 0) was Nix <=
|
2007-08-13 13:37:39 +02:00
|
|
|
0.7. Version 2 was Nix 0.8 and 0.9. Version 3 is Nix 0.10.
|
2010-08-31 13:47:31 +02:00
|
|
|
Version 4 is Nix 0.11. Version 5 is Nix 0.12-0.16. Version 6 is
|
|
|
|
Nix 1.0. */
|
2010-02-18 15:30:42 +01:00
|
|
|
const int nixSchemaVersion = 6;
|
2006-11-30 18:43:04 +01:00
|
|
|
|
|
|
|
|
2006-11-30 19:02:04 +01:00
|
|
|
extern string drvsLogDir;
|
|
|
|
|
|
|
|
|
2011-07-20 20:10:47 +02:00
|
|
|
struct Derivation;
|
|
|
|
|
|
|
|
|
2007-10-10 00:14:27 +02:00
|
|
|
struct OptimiseStats
|
|
|
|
{
|
|
|
|
unsigned long totalFiles;
|
|
|
|
unsigned long sameContents;
|
|
|
|
unsigned long filesLinked;
|
|
|
|
unsigned long long bytesFreed;
|
2008-06-18 11:34:17 +02:00
|
|
|
unsigned long long blocksFreed;
|
2007-10-10 00:14:27 +02:00
|
|
|
OptimiseStats()
|
|
|
|
{
|
|
|
|
totalFiles = sameContents = filesLinked = 0;
|
2008-06-18 11:34:17 +02:00
|
|
|
bytesFreed = blocksFreed = 0;
|
2007-10-10 00:14:27 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-08-02 14:54:35 +02:00
|
|
|
struct RunningSubstituter
|
|
|
|
{
|
|
|
|
Pid pid;
|
2009-03-28 20:41:53 +01:00
|
|
|
AutoCloseFD to, from;
|
2008-08-02 14:54:35 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-18 15:30:42 +01:00
|
|
|
/* Wrapper object to close the SQLite database automatically. */
|
|
|
|
struct SQLite
|
|
|
|
{
|
|
|
|
sqlite3 * db;
|
|
|
|
SQLite() { db = 0; }
|
|
|
|
~SQLite();
|
|
|
|
operator sqlite3 * () { return db; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Wrapper object to create and destroy SQLite prepared statements. */
|
|
|
|
struct SQLiteStmt
|
|
|
|
{
|
|
|
|
sqlite3 * db;
|
|
|
|
sqlite3_stmt * stmt;
|
2010-02-19 17:43:25 +01:00
|
|
|
unsigned int curArg;
|
2010-02-18 15:30:42 +01:00
|
|
|
SQLiteStmt() { stmt = 0; }
|
|
|
|
void create(sqlite3 * db, const string & s);
|
2010-02-18 16:11:08 +01:00
|
|
|
void reset();
|
2010-02-18 15:30:42 +01:00
|
|
|
~SQLiteStmt();
|
|
|
|
operator sqlite3_stmt * () { return stmt; }
|
2010-02-19 17:43:25 +01:00
|
|
|
void bind(const string & value);
|
|
|
|
void bind(int value);
|
2010-11-17 13:40:52 +01:00
|
|
|
void bind64(long long value);
|
2010-02-19 17:43:25 +01:00
|
|
|
void bind();
|
2010-02-18 15:30:42 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-11-30 18:43:04 +01:00
|
|
|
class LocalStore : public StoreAPI
|
|
|
|
{
|
2007-08-12 02:29:28 +02:00
|
|
|
private:
|
|
|
|
bool substitutablePathsLoaded;
|
|
|
|
PathSet substitutablePaths;
|
2008-08-02 14:54:35 +02:00
|
|
|
|
|
|
|
typedef std::map<Path, RunningSubstituter> RunningSubstituters;
|
|
|
|
RunningSubstituters runningSubstituters;
|
2012-07-23 21:02:52 +02:00
|
|
|
|
|
|
|
Path linksDir;
|
2007-08-12 02:29:28 +02:00
|
|
|
|
2006-11-30 18:43:04 +01:00
|
|
|
public:
|
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
/* Initialise the local store, upgrading the schema if
|
|
|
|
necessary. */
|
2012-05-30 04:59:12 +02:00
|
|
|
LocalStore(bool reserveSpace = true);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
|
|
|
~LocalStore();
|
|
|
|
|
|
|
|
/* Implementations of abstract store API methods. */
|
|
|
|
|
|
|
|
bool isValidPath(const Path & path);
|
|
|
|
|
2008-01-29 19:17:36 +01:00
|
|
|
PathSet queryValidPaths();
|
|
|
|
|
2010-11-16 18:11:46 +01:00
|
|
|
ValidPathInfo queryPathInfo(const Path & path);
|
|
|
|
|
2006-11-30 18:43:04 +01:00
|
|
|
Hash queryPathHash(const Path & path);
|
|
|
|
|
2006-12-01 21:51:18 +01:00
|
|
|
void queryReferences(const Path & path, PathSet & references);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2006-12-01 21:51:18 +01:00
|
|
|
void queryReferrers(const Path & path, PathSet & referrers);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2007-06-12 18:53:44 +02:00
|
|
|
Path queryDeriver(const Path & path);
|
2010-02-22 12:44:17 +01:00
|
|
|
|
|
|
|
/* Return all currently valid derivations that have `path' as an
|
|
|
|
output. (Note that the result of `queryDeriver()' is the
|
|
|
|
derivation that was actually used to produce `path', which may
|
|
|
|
not exist anymore.) */
|
|
|
|
PathSet queryValidDerivers(const Path & path);
|
2010-02-22 13:44:36 +01:00
|
|
|
|
|
|
|
PathSet queryDerivationOutputs(const Path & path);
|
2011-11-06 07:28:20 +01:00
|
|
|
|
|
|
|
StringSet queryDerivationOutputNames(const Path & path);
|
2007-06-12 18:53:44 +02:00
|
|
|
|
2012-07-18 00:55:39 +02:00
|
|
|
Path queryPathFromHashPart(const string & hashPart);
|
|
|
|
|
2007-08-12 02:29:28 +02:00
|
|
|
PathSet querySubstitutablePaths();
|
|
|
|
|
|
|
|
bool hasSubstitutes(const Path & path);
|
2008-08-02 14:54:35 +02:00
|
|
|
|
|
|
|
bool querySubstitutablePathInfo(const Path & path,
|
|
|
|
SubstitutablePathInfo & info);
|
2007-08-12 02:29:28 +02:00
|
|
|
|
2008-08-04 15:15:35 +02:00
|
|
|
bool querySubstitutablePathInfo(const Path & substituter,
|
|
|
|
const Path & path, SubstitutablePathInfo & info);
|
|
|
|
|
2008-12-03 16:06:30 +01:00
|
|
|
Path addToStore(const Path & srcPath,
|
2008-12-03 17:10:17 +01:00
|
|
|
bool recursive = true, HashType hashAlgo = htSHA256,
|
2006-12-13 00:05:01 +01:00
|
|
|
PathFilter & filter = defaultPathFilter);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2008-12-03 19:05:14 +01:00
|
|
|
/* Like addToStore(), but the contents of the path are contained
|
|
|
|
in `dump', which is either a NAR serialisation (if recursive ==
|
|
|
|
true) or simply the contents of a regular file (if recursive ==
|
|
|
|
false). */
|
|
|
|
Path addToStoreFromDump(const string & dump, const string & name,
|
|
|
|
bool recursive = true, HashType hashAlgo = htSHA256);
|
|
|
|
|
2008-12-03 16:06:30 +01:00
|
|
|
Path addTextToStore(const string & name, const string & s,
|
2006-11-30 18:43:04 +01:00
|
|
|
const PathSet & references);
|
|
|
|
|
2007-02-21 00:17:20 +01:00
|
|
|
void exportPath(const Path & path, bool sign,
|
|
|
|
Sink & sink);
|
|
|
|
|
2011-12-16 23:31:25 +01:00
|
|
|
Paths importPaths(bool requireSignature, Source & source);
|
2007-02-21 16:45:32 +01:00
|
|
|
|
2012-06-27 22:58:15 +02:00
|
|
|
void buildPaths(const PathSet & paths);
|
2006-11-30 19:02:04 +01:00
|
|
|
|
2006-12-01 21:51:18 +01:00
|
|
|
void ensurePath(const Path & path);
|
2006-12-02 17:41:36 +01:00
|
|
|
|
|
|
|
void addTempRoot(const Path & path);
|
|
|
|
|
2006-12-05 00:29:16 +01:00
|
|
|
void addIndirectRoot(const Path & path);
|
|
|
|
|
2006-12-02 17:41:36 +01:00
|
|
|
void syncWithGC();
|
2006-12-05 02:31:45 +01:00
|
|
|
|
|
|
|
Roots findRoots();
|
2006-12-05 03:18:46 +01:00
|
|
|
|
2008-06-18 11:34:17 +02:00
|
|
|
void collectGarbage(const GCOptions & options, GCResults & results);
|
2007-10-10 00:14:27 +02:00
|
|
|
|
|
|
|
/* Optimise the disk space usage of the Nix store by hard-linking
|
|
|
|
files with the same contents. */
|
2012-07-23 18:08:34 +02:00
|
|
|
void optimiseStore(OptimiseStats & stats);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2012-07-23 21:02:52 +02:00
|
|
|
/* Optimise a single store path. */
|
|
|
|
void optimisePath(const Path & path);
|
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
/* Check the integrity of the Nix store. */
|
|
|
|
void verifyStore(bool checkContents);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
/* Register the validity of a path, i.e., that `path' exists, that
|
|
|
|
the paths referenced by it exists, and in the case of an output
|
|
|
|
path of a derivation, that it has been produced by a succesful
|
|
|
|
execution of the derivation (or something equivalent). Also
|
|
|
|
register the hash of the file system contents of the path. The
|
|
|
|
hash must be a SHA-256 hash. */
|
2010-11-16 18:11:46 +01:00
|
|
|
void registerValidPath(const ValidPathInfo & info);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
void registerValidPaths(const ValidPathInfos & infos);
|
|
|
|
|
2009-03-25 22:05:42 +01:00
|
|
|
/* Register that the build of a derivation with output `path' has
|
|
|
|
failed. */
|
|
|
|
void registerFailedPath(const Path & path);
|
|
|
|
|
|
|
|
/* Query whether `path' previously failed to build. */
|
|
|
|
bool hasPathFailed(const Path & path);
|
|
|
|
|
2010-04-26 14:43:42 +02:00
|
|
|
PathSet queryFailedPaths();
|
|
|
|
|
2010-04-26 14:56:42 +02:00
|
|
|
void clearFailedPaths(const PathSet & paths);
|
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
private:
|
|
|
|
|
|
|
|
Path schemaPath;
|
|
|
|
|
|
|
|
/* Lock file used for upgrading. */
|
|
|
|
AutoCloseFD globalLock;
|
|
|
|
|
2010-02-18 15:30:42 +01:00
|
|
|
/* The SQLite database object. */
|
|
|
|
SQLite db;
|
|
|
|
|
|
|
|
/* Some precompiled SQLite statements. */
|
|
|
|
SQLiteStmt stmtRegisterValidPath;
|
2010-12-06 16:29:38 +01:00
|
|
|
SQLiteStmt stmtUpdatePathInfo;
|
2010-02-18 15:30:42 +01:00
|
|
|
SQLiteStmt stmtAddReference;
|
2010-02-18 16:52:57 +01:00
|
|
|
SQLiteStmt stmtQueryPathInfo;
|
|
|
|
SQLiteStmt stmtQueryReferences;
|
2010-02-18 17:21:59 +01:00
|
|
|
SQLiteStmt stmtQueryReferrers;
|
2010-02-19 17:43:25 +01:00
|
|
|
SQLiteStmt stmtInvalidatePath;
|
2010-02-19 18:15:22 +01:00
|
|
|
SQLiteStmt stmtRegisterFailedPath;
|
|
|
|
SQLiteStmt stmtHasPathFailed;
|
2010-04-26 14:43:42 +02:00
|
|
|
SQLiteStmt stmtQueryFailedPaths;
|
2010-04-26 14:56:42 +02:00
|
|
|
SQLiteStmt stmtClearFailedPath;
|
2010-02-22 12:15:50 +01:00
|
|
|
SQLiteStmt stmtAddDerivationOutput;
|
2010-02-22 12:44:17 +01:00
|
|
|
SQLiteStmt stmtQueryValidDerivers;
|
2010-02-22 13:44:36 +01:00
|
|
|
SQLiteStmt stmtQueryDerivationOutputs;
|
2012-07-18 00:55:39 +02:00
|
|
|
SQLiteStmt stmtQueryPathFromHashPart;
|
2010-02-18 14:16:59 +01:00
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
int getSchema();
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2010-02-24 17:30:20 +01:00
|
|
|
void openDB(bool create);
|
2010-02-18 15:30:42 +01:00
|
|
|
|
2010-02-24 16:07:23 +01:00
|
|
|
unsigned long long queryValidPathId(const Path & path);
|
|
|
|
|
2011-09-12 11:07:43 +02:00
|
|
|
unsigned long long addValidPath(const ValidPathInfo & info, bool checkOutputs = true);
|
2010-02-19 17:04:51 +01:00
|
|
|
|
|
|
|
void addReference(unsigned long long referrer, unsigned long long reference);
|
|
|
|
|
2010-01-29 13:22:58 +01:00
|
|
|
void appendReferrer(const Path & from, const Path & to, bool lock);
|
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
void rewriteReferrers(const Path & path, bool purge, PathSet referrers);
|
|
|
|
|
|
|
|
void invalidatePath(const Path & path);
|
2010-02-18 16:11:08 +01:00
|
|
|
|
2012-03-26 20:43:33 +02:00
|
|
|
/* Delete a path from the Nix store. */
|
|
|
|
void invalidatePathChecked(const Path & path);
|
|
|
|
|
2010-08-31 13:47:31 +02:00
|
|
|
void verifyPath(const Path & path, const PathSet & store,
|
|
|
|
PathSet & done, PathSet & validPaths);
|
|
|
|
|
2010-12-06 16:29:38 +01:00
|
|
|
void updatePathInfo(const ValidPathInfo & info);
|
|
|
|
|
2010-02-18 14:16:59 +01:00
|
|
|
void upgradeStore6();
|
2010-02-18 16:11:08 +01:00
|
|
|
PathSet queryValidPathsOld();
|
|
|
|
ValidPathInfo queryPathInfoOld(const Path & path);
|
2008-06-09 15:52:45 +02:00
|
|
|
|
2009-11-23 17:34:24 +01:00
|
|
|
struct GCState;
|
2008-08-02 14:54:35 +02:00
|
|
|
|
2012-03-26 20:43:33 +02:00
|
|
|
void deleteGarbage(GCState & state, const Path & path);
|
|
|
|
|
2009-11-23 17:34:24 +01:00
|
|
|
bool tryToDelete(GCState & state, const Path & path);
|
|
|
|
|
|
|
|
bool isActiveTempFile(const GCState & state,
|
|
|
|
const Path & path, const string & suffix);
|
|
|
|
|
2010-08-31 13:47:31 +02:00
|
|
|
int openGCLock(LockType lockType);
|
|
|
|
|
2008-08-02 14:54:35 +02:00
|
|
|
void startSubstituter(const Path & substituter,
|
|
|
|
RunningSubstituter & runningSubstituter);
|
2010-06-21 13:08:09 +02:00
|
|
|
|
|
|
|
Path createTempDirInStore();
|
2011-07-20 20:10:47 +02:00
|
|
|
|
2011-12-16 23:31:25 +01:00
|
|
|
Path importPath(bool requireSignature, Source & source);
|
|
|
|
|
2011-07-20 20:10:47 +02:00
|
|
|
void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
|
2012-07-23 21:02:52 +02:00
|
|
|
|
|
|
|
void optimisePath_(OptimiseStats & stats, const Path & path);
|
2008-06-09 15:52:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-11-30 18:43:04 +01:00
|
|
|
/* "Fix", or canonicalise, the meta-data of the files in a store path
|
|
|
|
after it has been built. In particular:
|
2009-06-13 18:30:58 +02:00
|
|
|
- the last modification date on each file is set to 1 (i.e.,
|
|
|
|
00:00:01 1/1/1970 UTC)
|
2006-11-30 18:43:04 +01:00
|
|
|
- the permissions are set of 444 or 555 (i.e., read-only with or
|
|
|
|
without execute permission; setuid bits etc. are cleared)
|
|
|
|
- the owner and group are set to the Nix user and group, if we're
|
|
|
|
in a setuid Nix installation. */
|
|
|
|
void canonicalisePathMetaData(const Path & path);
|
|
|
|
|
2008-06-09 15:52:45 +02:00
|
|
|
void canonicalisePathMetaData(const Path & path, bool recurse);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
2007-01-14 17:24:49 +01:00
|
|
|
MakeError(PathInUse, Error);
|
|
|
|
|
2006-12-07 16:54:52 +01:00
|
|
|
/* Whether we are in build users mode. */
|
|
|
|
bool haveBuildUsers();
|
|
|
|
|
|
|
|
/* Whether we are root. */
|
|
|
|
bool amPrivileged();
|
|
|
|
|
|
|
|
/* Recursively change the ownership of `path' to the current uid. */
|
|
|
|
void getOwnership(const Path & path);
|
|
|
|
|
2006-12-09 01:26:24 +01:00
|
|
|
/* Like deletePath(), but changes the ownership of `path' using the
|
|
|
|
setuid wrapper if necessary (and possible). */
|
|
|
|
void deletePathWrapped(const Path & path,
|
2008-06-18 11:34:17 +02:00
|
|
|
unsigned long long & bytesFreed, unsigned long long & blocksFreed);
|
2006-12-09 01:26:24 +01:00
|
|
|
|
|
|
|
void deletePathWrapped(const Path & path);
|
2006-11-30 18:43:04 +01:00
|
|
|
|
|
|
|
}
|