mirror of
https://github.com/NixOS/nix.git
synced 2024-11-22 14:52:55 +00:00
* Down to 1 test failure...
This commit is contained in:
parent
07da660396
commit
95fa444587
@ -206,7 +206,9 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
Worker();
|
||||
LocalStore & store;
|
||||
|
||||
Worker(LocalStore & store);
|
||||
~Worker();
|
||||
|
||||
/* Make a goal (with caching). */
|
||||
@ -896,14 +898,14 @@ void DerivationGoal::haveDerivation()
|
||||
return;
|
||||
}
|
||||
|
||||
assert(store->isValidPath(drvPath));
|
||||
assert(worker.store.isValidPath(drvPath));
|
||||
|
||||
/* Get the derivation. */
|
||||
drv = derivationFromPath(drvPath);
|
||||
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
i != drv.outputs.end(); ++i)
|
||||
store->addTempRoot(i->second.path);
|
||||
worker.store.addTempRoot(i->second.path);
|
||||
|
||||
/* Check what outputs paths are not already valid. */
|
||||
PathSet invalidOutputs = checkPathValidity(false);
|
||||
@ -937,7 +939,7 @@ void DerivationGoal::haveDerivation()
|
||||
i != invalidOutputs.end(); ++i)
|
||||
/* Don't bother creating a substitution goal if there are no
|
||||
substitutes. */
|
||||
if (store->hasSubstitutes(*i))
|
||||
if (worker.store.hasSubstitutes(*i))
|
||||
addWaitee(worker.makeSubstitutionGoal(*i));
|
||||
|
||||
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
||||
@ -992,7 +994,7 @@ void DerivationGoal::outputsSubstituted()
|
||||
throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
|
||||
% storePath);
|
||||
storePath = toStorePath(storePath);
|
||||
if (!store->isValidPath(storePath))
|
||||
if (!worker.store.isValidPath(storePath))
|
||||
throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
|
||||
% storePath);
|
||||
|
||||
@ -1249,19 +1251,6 @@ PathSet outputPaths(const DerivationOutputs & outputs)
|
||||
}
|
||||
|
||||
|
||||
string showPaths(const PathSet & paths)
|
||||
{
|
||||
string s;
|
||||
for (PathSet::const_iterator i = paths.begin();
|
||||
i != paths.end(); ++i)
|
||||
{
|
||||
if (s.size() != 0) s += ", ";
|
||||
s += "`" + *i + "'";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
DerivationGoal::HookReply DerivationGoal::tryBuildHook()
|
||||
{
|
||||
if (!useBuildHook) return rpDecline;
|
||||
@ -1473,7 +1462,7 @@ DerivationGoal::PrepareBuildReply DerivationGoal::prepareBuild()
|
||||
i != drv.outputs.end(); ++i)
|
||||
{
|
||||
Path path = i->second.path;
|
||||
if (store->isValidPath(path))
|
||||
if (worker.store.isValidPath(path))
|
||||
throw BuildError(format("obstructed build: path `%1%' exists") % path);
|
||||
if (pathExists(path)) {
|
||||
debug(format("removing unregistered path `%1%'") % path);
|
||||
@ -1501,7 +1490,7 @@ DerivationGoal::PrepareBuildReply DerivationGoal::prepareBuild()
|
||||
/* Add the relevant output closures of the input derivation
|
||||
`*i' as input paths. Only add the closures of output paths
|
||||
that are specified as inputs. */
|
||||
assert(store->isValidPath(i->first));
|
||||
assert(worker.store.isValidPath(i->first));
|
||||
Derivation inDrv = derivationFromPath(i->first);
|
||||
for (StringSet::iterator j = i->second.begin();
|
||||
j != i->second.end(); ++j)
|
||||
@ -1623,7 +1612,7 @@ void DerivationGoal::startBuilder()
|
||||
throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'")
|
||||
% storePath);
|
||||
storePath = toStorePath(storePath);
|
||||
if (!store->isValidPath(storePath))
|
||||
if (!worker.store.isValidPath(storePath))
|
||||
throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
|
||||
% storePath);
|
||||
|
||||
@ -1651,7 +1640,7 @@ void DerivationGoal::startBuilder()
|
||||
throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
|
||||
% storePath);
|
||||
storePath = toStorePath(storePath);
|
||||
if (!store->isValidPath(storePath))
|
||||
if (!worker.store.isValidPath(storePath))
|
||||
throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
|
||||
% storePath);
|
||||
|
||||
@ -1999,7 +1988,7 @@ void DerivationGoal::computeClosure()
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
i != drv.outputs.end(); ++i)
|
||||
{
|
||||
registerValidPath(i->second.path,
|
||||
worker.store.registerValidPath(i->second.path,
|
||||
contentHashes[i->second.path],
|
||||
allReferences[i->second.path],
|
||||
drvPath);
|
||||
@ -2102,7 +2091,7 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid)
|
||||
PathSet result;
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
i != drv.outputs.end(); ++i)
|
||||
if (store->isValidPath(i->second.path)) {
|
||||
if (worker.store.isValidPath(i->second.path)) {
|
||||
if (returnValid) result.insert(i->second.path);
|
||||
} else {
|
||||
if (!returnValid) result.insert(i->second.path);
|
||||
@ -2208,10 +2197,10 @@ void SubstitutionGoal::init()
|
||||
{
|
||||
trace("init");
|
||||
|
||||
store->addTempRoot(storePath);
|
||||
worker.store.addTempRoot(storePath);
|
||||
|
||||
/* If the path already exists we're done. */
|
||||
if (store->isValidPath(storePath)) {
|
||||
if (worker.store.isValidPath(storePath)) {
|
||||
amDone(ecSuccess);
|
||||
return;
|
||||
}
|
||||
@ -2282,7 +2271,7 @@ void SubstitutionGoal::referencesValid()
|
||||
for (PathSet::iterator i = references.begin();
|
||||
i != references.end(); ++i)
|
||||
if (*i != storePath) /* ignore self-references */
|
||||
assert(store->isValidPath(*i));
|
||||
assert(worker.store.isValidPath(*i));
|
||||
|
||||
state = &SubstitutionGoal::tryToRun;
|
||||
worker.waitForBuildSlot(shared_from_this());
|
||||
@ -2316,7 +2305,7 @@ void SubstitutionGoal::tryToRun()
|
||||
(format("waiting for lock on `%1%'") % storePath).str());
|
||||
|
||||
/* Check again whether the path is invalid. */
|
||||
if (store->isValidPath(storePath)) {
|
||||
if (worker.store.isValidPath(storePath)) {
|
||||
debug(format("store path `%1%' has become valid") % storePath);
|
||||
outputLock->setDeletion(true);
|
||||
amDone(ecSuccess);
|
||||
@ -2423,7 +2412,7 @@ void SubstitutionGoal::finished()
|
||||
|
||||
Hash contentHash = hashPath(htSHA256, storePath);
|
||||
|
||||
registerValidPath(storePath, contentHash,
|
||||
worker.store.registerValidPath(storePath, contentHash,
|
||||
references, deriver);
|
||||
|
||||
outputLock->setDeletion(true);
|
||||
@ -2458,7 +2447,8 @@ void SubstitutionGoal::handleEOF(int fd)
|
||||
static bool working = false;
|
||||
|
||||
|
||||
Worker::Worker()
|
||||
Worker::Worker(LocalStore & store)
|
||||
: store(store)
|
||||
{
|
||||
/* Debugging: prevent recursive workers. */
|
||||
if (working) abort();
|
||||
@ -2856,7 +2846,7 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
|
||||
startNest(nest, lvlDebug,
|
||||
format("building %1%") % showPaths(drvPaths));
|
||||
|
||||
Worker worker;
|
||||
Worker worker(*this);
|
||||
|
||||
Goals goals;
|
||||
for (PathSet::const_iterator i = drvPaths.begin();
|
||||
@ -2881,9 +2871,9 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
|
||||
void LocalStore::ensurePath(const Path & path)
|
||||
{
|
||||
/* If the path is already valid, we're done. */
|
||||
if (store->isValidPath(path)) return;
|
||||
if (isValidPath(path)) return;
|
||||
|
||||
Worker worker;
|
||||
Worker worker(*this);
|
||||
GoalPtr goal = worker.makeSubstitutionGoal(path);
|
||||
Goals goals = singleton<Goals>(goal);
|
||||
|
||||
|
@ -21,9 +21,6 @@
|
||||
namespace nix {
|
||||
|
||||
|
||||
void upgradeStore12();
|
||||
|
||||
|
||||
void checkStoreNotSymlink()
|
||||
{
|
||||
if (getEnv("NIX_IGNORE_SYMLINK_STORE") == "1") return;
|
||||
@ -211,17 +208,41 @@ static void appendReferrer(const Path & from, const Path & to)
|
||||
}
|
||||
|
||||
|
||||
void registerValidPath(const Path & path,
|
||||
/* Atomically update the referrers file. */
|
||||
static void rewriteReferrers(const Path & path, const PathSet & referrers)
|
||||
{
|
||||
string s;
|
||||
for (PathSet::const_iterator i = referrers.begin(); i != referrers.end(); ++i) {
|
||||
s += " "; s += *i;
|
||||
}
|
||||
writeFile(referrersFileFor(path), s); /* !!! atomicity, locking */
|
||||
}
|
||||
|
||||
|
||||
void LocalStore::registerValidPath(const Path & path,
|
||||
const Hash & hash, const PathSet & references,
|
||||
const Path & deriver)
|
||||
{
|
||||
Path infoFile = infoFileFor(path);
|
||||
ValidPathInfo info;
|
||||
info.path = path;
|
||||
info.hash = hash;
|
||||
info.references = references;
|
||||
info.deriver = deriver;
|
||||
registerValidPath(info);
|
||||
}
|
||||
|
||||
|
||||
void LocalStore::registerValidPath(const ValidPathInfo & info)
|
||||
{
|
||||
Path infoFile = infoFileFor(info.path);
|
||||
if (pathExists(infoFile)) return;
|
||||
|
||||
// !!! acquire PathLock on infoFile here
|
||||
// !!! acquire PathLock on infoFile here?
|
||||
|
||||
string refs;
|
||||
for (PathSet::const_iterator i = references.begin(); i != references.end(); ++i) {
|
||||
for (PathSet::const_iterator i = info.references.begin();
|
||||
i != info.references.end(); ++i)
|
||||
{
|
||||
if (!refs.empty()) refs += " ";
|
||||
refs += *i;
|
||||
|
||||
@ -231,21 +252,20 @@ void registerValidPath(const Path & path,
|
||||
have referrer mappings back to `path'. A " " is prefixed
|
||||
to separate it from the previous entry. It's not suffixed
|
||||
to deal with interrupted partial writes to this file. */
|
||||
appendReferrer(*i, path);
|
||||
appendReferrer(*i, info.path);
|
||||
}
|
||||
|
||||
string info = (format(
|
||||
string s = (format(
|
||||
"Hash: sha256:%1%\n"
|
||||
"References: %2%\n"
|
||||
"Deriver: %3%\n"
|
||||
"Registered-At: %4%\n")
|
||||
% printHash(hash) % refs % deriver % time(0)).str();
|
||||
% printHash(info.hash) % refs % info.deriver % time(0)).str();
|
||||
|
||||
// !!! atomicity
|
||||
writeFile(infoFile, info);
|
||||
writeFile(infoFile, s);
|
||||
}
|
||||
|
||||
|
||||
Hash parseHashField(const Path & path, const string & s)
|
||||
{
|
||||
string::size_type colon = s.find(':');
|
||||
@ -260,12 +280,16 @@ Hash parseHashField(const Path & path, const string & s)
|
||||
}
|
||||
|
||||
|
||||
ValidPathInfo queryPathInfo(const Path & path)
|
||||
ValidPathInfo LocalStore::queryPathInfo(const Path & path)
|
||||
{
|
||||
ValidPathInfo res;
|
||||
|
||||
assertStorePath(path);
|
||||
// !!! printMsg(lvlError, "queryPathInfo: " + path);
|
||||
|
||||
std::map<Path, ValidPathInfo>::iterator lookup = pathInfoCache.find(path);
|
||||
if (lookup != pathInfoCache.end()) return lookup->second;
|
||||
|
||||
//printMsg(lvlError, "queryPathInfo: " + path);
|
||||
|
||||
/* Read the info file. */
|
||||
Path infoFile = infoFileFor(path);
|
||||
@ -291,7 +315,7 @@ ValidPathInfo queryPathInfo(const Path & path)
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return pathInfoCache[path] = res;
|
||||
}
|
||||
|
||||
|
||||
@ -311,54 +335,6 @@ PathSet LocalStore::queryValidPaths()
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static PathSet getReferrers(const Transaction & txn, const Path & storePath)
|
||||
{
|
||||
throw Error("!!! getReferrers");
|
||||
PathSet referrers;
|
||||
Strings keys;
|
||||
nixDB.enumTable(txn, dbReferrers, keys, storePath + string(1, (char) 0));
|
||||
for (Strings::iterator i = keys.begin(); i != keys.end(); ++i)
|
||||
referrers.insert(stripPrefix(storePath, *i));
|
||||
return referrers;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
void setReferences(const Transaction & txn, const Path & storePath,
|
||||
const PathSet & references)
|
||||
{
|
||||
/* For invalid paths, we can only clear the references. */
|
||||
if (references.size() > 0 && !isValidPathTxn(txn, storePath))
|
||||
throw Error(
|
||||
format("cannot set references for invalid path `%1%'") % storePath);
|
||||
|
||||
Paths oldReferences;
|
||||
nixDB.queryStrings(txn, dbReferences, storePath, oldReferences);
|
||||
|
||||
PathSet oldReferences2(oldReferences.begin(), oldReferences.end());
|
||||
if (oldReferences2 == references) return;
|
||||
|
||||
nixDB.setStrings(txn, dbReferences, storePath,
|
||||
Paths(references.begin(), references.end()));
|
||||
|
||||
/* Update the referrers mappings of all new referenced paths. */
|
||||
for (PathSet::const_iterator i = references.begin();
|
||||
i != references.end(); ++i)
|
||||
if (oldReferences2.find(*i) == oldReferences2.end())
|
||||
nixDB.setString(txn, dbReferrers, addPrefix(*i, storePath), "");
|
||||
|
||||
/* Remove referrer mappings from paths that are no longer
|
||||
references. */
|
||||
for (Paths::iterator i = oldReferences.begin();
|
||||
i != oldReferences.end(); ++i)
|
||||
if (references.find(*i) == references.end())
|
||||
nixDB.delPair(txn, dbReferrers, addPrefix(*i, storePath));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void LocalStore::queryReferences(const Path & path,
|
||||
PathSet & references)
|
||||
{
|
||||
@ -393,20 +369,6 @@ void LocalStore::queryReferrers(const Path & path, PathSet & referrers)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void setDeriver(const Transaction & txn, const Path & storePath,
|
||||
const Path & deriver)
|
||||
{
|
||||
assertStorePath(storePath);
|
||||
if (deriver == "") return;
|
||||
assertStorePath(deriver);
|
||||
if (!isValidPathTxn(txn, storePath))
|
||||
throw Error(format("path `%1%' is not valid") % storePath);
|
||||
nixDB.setString(txn, dbDerivers, storePath, deriver);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Path LocalStore::queryDeriver(const Path & path)
|
||||
{
|
||||
return queryPathInfo(path).deriver;
|
||||
@ -449,24 +411,7 @@ Hash LocalStore::queryPathHash(const Path & path)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void registerValidPath(const Transaction & txn,
|
||||
const Path & path, const Hash & hash, const PathSet & references,
|
||||
const Path & deriver)
|
||||
{
|
||||
ValidPathInfo info;
|
||||
info.path = path;
|
||||
info.hash = hash;
|
||||
info.references = references;
|
||||
info.deriver = deriver;
|
||||
ValidPathInfos infos;
|
||||
infos.push_back(info);
|
||||
registerValidPaths(txn, infos);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void registerValidPaths(const ValidPathInfos & infos)
|
||||
void LocalStore::registerValidPaths(const ValidPathInfos & infos)
|
||||
{
|
||||
throw Error("!!! registerValidPaths");
|
||||
#if 0
|
||||
@ -505,14 +450,16 @@ static void invalidatePath(const Path & path)
|
||||
{
|
||||
debug(format("invalidating path `%1%'") % path);
|
||||
|
||||
throw Error("!!! invalidatePath");
|
||||
#if 0
|
||||
/* Clear the `references' entry for this path, as well as the
|
||||
inverse `referrers' entries, and the `derivers' entry. */
|
||||
setReferences(txn, path, PathSet());
|
||||
nixDB.delPair(txn, dbDerivers, path);
|
||||
nixDB.delPair(txn, dbValidPaths, path);
|
||||
#endif
|
||||
/* Remove the info file. */
|
||||
Path p = infoFileFor(path);
|
||||
if (unlink(p.c_str()) == -1)
|
||||
throw SysError(format("unlinking `%1%'") % p);
|
||||
|
||||
/* Remove the corresponding referrer entries for each path
|
||||
referenced by this one. This has to happen after removing the
|
||||
info file to preserve the invariant (see
|
||||
registerValidPath()). */
|
||||
/* !!! */
|
||||
}
|
||||
|
||||
|
||||
@ -785,28 +732,24 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||
}
|
||||
|
||||
|
||||
void deleteFromStore(const Path & _path, unsigned long long & bytesFreed)
|
||||
void LocalStore::deleteFromStore(const Path & _path, unsigned long long & bytesFreed)
|
||||
{
|
||||
throw Error("!!! deleteFromStore");
|
||||
#if 0
|
||||
bytesFreed = 0;
|
||||
Path path(canonPath(_path));
|
||||
|
||||
assertStorePath(path);
|
||||
|
||||
Transaction txn(nixDB);
|
||||
if (isValidPathTxn(txn, path)) {
|
||||
PathSet referrers = getReferrers(txn, path);
|
||||
for (PathSet::iterator i = referrers.begin();
|
||||
i != referrers.end(); ++i)
|
||||
if (*i != path && isValidPathTxn(txn, *i))
|
||||
throw PathInUse(format("cannot delete path `%1%' because it is in use by path `%2%'") % path % *i);
|
||||
invalidatePath(txn, path);
|
||||
if (isValidPath(path)) {
|
||||
PathSet referrers; queryReferrers(path, referrers);
|
||||
referrers.erase(path); /* ignore self-references */
|
||||
/* !!! check: can a new referrer appear now? */
|
||||
if (!referrers.empty())
|
||||
throw PathInUse(format("cannot delete path `%1%' because it is in use by `%2%'")
|
||||
% path % showPaths(referrers));
|
||||
invalidatePath(path);
|
||||
}
|
||||
txn.commit();
|
||||
|
||||
deletePathWrapped(path, bytesFreed);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -889,6 +832,8 @@ void LocalStore::verifyStore(bool checkContents)
|
||||
/* Check the referrers. */
|
||||
printMsg(lvlInfo, "checking referrers");
|
||||
|
||||
std::map<Path, PathSet> referencesCache;
|
||||
|
||||
Strings entries = readDirectory(nixDBPath + "/referrer");
|
||||
for (Strings::iterator i = entries.begin(); i != entries.end(); ++i) {
|
||||
Path from = nixStore + "/" + *i;
|
||||
@ -906,54 +851,24 @@ void LocalStore::verifyStore(bool checkContents)
|
||||
bool update = false;
|
||||
|
||||
if (!allValid) {
|
||||
printMsg(lvlError, format("removing some stale paths from referrers of `%1%'") % from);
|
||||
printMsg(lvlError, format("removing some stale referrers for `%1%'") % from);
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update)
|
||||
/* !!! */;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Strings referrers;
|
||||
nixDB.enumTable(txn, dbReferrers, referrers);
|
||||
for (Strings::iterator i = referrers.begin(); i != referrers.end(); ++i) {
|
||||
|
||||
/* Decode the entry (it's a tuple of paths). */
|
||||
string::size_type nul = i->find((char) 0);
|
||||
if (nul == string::npos) {
|
||||
printMsg(lvlError, format("removing bad referrer table entry `%1%'") % *i);
|
||||
nixDB.delPair(txn, dbReferrers, *i);
|
||||
continue;
|
||||
}
|
||||
Path to(*i, 0, nul);
|
||||
Path from(*i, nul + 1);
|
||||
|
||||
if (validPaths.find(to) == validPaths.end()) {
|
||||
printMsg(lvlError, format("removing referrer entry from `%1%' to invalid `%2%'")
|
||||
% from % to);
|
||||
nixDB.delPair(txn, dbReferrers, *i);
|
||||
/* Each referrer should have a matching reference. */
|
||||
PathSet referrersNew;
|
||||
for (PathSet::iterator j = referrers.begin(); j != referrers.end(); ++j) {
|
||||
if (referencesCache.find(*j) == referencesCache.end())
|
||||
queryReferences(*j, referencesCache[*j]);
|
||||
if (referencesCache[*j].find(from) == referencesCache[*j].end()) {
|
||||
printMsg(lvlError, format("removing unexpected referrer mapping from `%1%' to `%2%'")
|
||||
% from % *j);
|
||||
update = true;
|
||||
} else referrersNew.insert(*j);
|
||||
}
|
||||
|
||||
else if (validPaths.find(from) == validPaths.end()) {
|
||||
printMsg(lvlError, format("removing referrer entry from invalid `%1%' to `%2%'")
|
||||
% from % to);
|
||||
nixDB.delPair(txn, dbReferrers, *i);
|
||||
}
|
||||
|
||||
else {
|
||||
PathSet references;
|
||||
oldQueryReferences(txn, from, references);
|
||||
if (find(references.begin(), references.end(), to) == references.end()) {
|
||||
printMsg(lvlError, format("adding missing referrer mapping from `%1%' to `%2%'")
|
||||
% from % to);
|
||||
references.insert(to);
|
||||
setReferences(txn, from, references);
|
||||
}
|
||||
}
|
||||
|
||||
if (update) rewriteReferrers(from, referrersNew);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,6 +91,9 @@ public:
|
||||
void collectGarbage(GCAction action, const PathSet & pathsToDelete,
|
||||
bool ignoreLiveness, PathSet & result, unsigned long long & bytesFreed);
|
||||
|
||||
/* Delete a path from the Nix store. */
|
||||
void deleteFromStore(const Path & path, unsigned long long & bytesFreed);
|
||||
|
||||
/* Optimise the disk space usage of the Nix store by hard-linking
|
||||
files with the same contents. */
|
||||
void optimiseStore(bool dryRun, OptimiseStats & stats);
|
||||
@ -98,28 +101,37 @@ public:
|
||||
/* Check the integrity of the Nix store. */
|
||||
void verifyStore(bool checkContents);
|
||||
|
||||
/* 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. */
|
||||
void registerValidPath(const Path & path,
|
||||
const Hash & hash, const PathSet & references, const Path & deriver);
|
||||
|
||||
void registerValidPaths(const ValidPathInfos & infos);
|
||||
|
||||
private:
|
||||
|
||||
/* !!! The cache can grow very big. Maybe it should be pruned
|
||||
every once in a while. */
|
||||
std::map<Path, ValidPathInfo> pathInfoCache;
|
||||
|
||||
void registerValidPath(const ValidPathInfo & info);
|
||||
|
||||
ValidPathInfo queryPathInfo(const Path & path);
|
||||
|
||||
bool queryReferrersInternal(const Path & path, PathSet & referrers);
|
||||
|
||||
void upgradeStore12();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* Copy a path recursively. */
|
||||
void copyPath(const Path & src, const Path & dst);
|
||||
|
||||
/* 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. */
|
||||
void registerValidPath(const Path & path,
|
||||
const Hash & hash, const PathSet & references, const Path & deriver);
|
||||
|
||||
typedef list<ValidPathInfo> ValidPathInfos;
|
||||
|
||||
void registerValidPaths(const ValidPathInfos & infos);
|
||||
|
||||
/* "Fix", or canonicalise, the meta-data of the files in a store path
|
||||
after it has been built. In particular:
|
||||
- the last modification date on each file is set to 0 (i.e.,
|
||||
@ -130,9 +142,6 @@ void registerValidPaths(const ValidPathInfos & infos);
|
||||
in a setuid Nix installation. */
|
||||
void canonicalisePathMetaData(const Path & path);
|
||||
|
||||
/* Delete a value from the nixStore directory. */
|
||||
void deleteFromStore(const Path & path, unsigned long long & bytesFreed);
|
||||
|
||||
MakeError(PathInUse, Error);
|
||||
|
||||
/* Whether we are in build users mode. */
|
||||
|
@ -205,6 +205,19 @@ ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
|
||||
}
|
||||
|
||||
|
||||
string showPaths(const PathSet & paths)
|
||||
{
|
||||
string s;
|
||||
for (PathSet::const_iterator i = paths.begin();
|
||||
i != paths.end(); ++i)
|
||||
{
|
||||
if (s.size() != 0) s += ", ";
|
||||
s += "`" + *i + "'";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -252,6 +252,11 @@ extern boost::shared_ptr<StoreAPI> store;
|
||||
boost::shared_ptr<StoreAPI> openStore();
|
||||
|
||||
|
||||
/* Display a set of paths in human-readable form (i.e., between quotes
|
||||
and separated by commas). */
|
||||
string showPaths(const PathSet & paths);
|
||||
|
||||
|
||||
string makeValidityRegistration(const PathSet & paths,
|
||||
bool showDerivers, bool showHash);
|
||||
|
||||
@ -263,6 +268,8 @@ struct ValidPathInfo
|
||||
PathSet references;
|
||||
};
|
||||
|
||||
typedef list<ValidPathInfo> ValidPathInfos;
|
||||
|
||||
ValidPathInfo decodeValidPathInfo(std::istream & str,
|
||||
bool hashGiven = false);
|
||||
|
||||
|
@ -16,7 +16,7 @@ Hash parseHashField(const Path & path, const string & s);
|
||||
/* Upgrade from schema 4 (Nix 0.11) to schema 5 (Nix >= 0.12). The
|
||||
old schema uses Berkeley DB, the new one stores store path
|
||||
meta-information in files. */
|
||||
void upgradeStore12()
|
||||
void LocalStore::upgradeStore12()
|
||||
{
|
||||
printMsg(lvlError, "upgrading Nix store to new schema (this may take a while)...");
|
||||
|
||||
|
@ -31,6 +31,14 @@ static int rootNr = 0;
|
||||
static bool indirectRoot = false;
|
||||
|
||||
|
||||
LocalStore & ensureLocalStore()
|
||||
{
|
||||
LocalStore * store2(dynamic_cast<LocalStore *>(store.get()));
|
||||
if (!store2) throw Error("you don't have sufficient rights to use --verify");
|
||||
return *store2;
|
||||
}
|
||||
|
||||
|
||||
static Path useDeriver(Path path)
|
||||
{
|
||||
if (!isDerivation(path)) {
|
||||
@ -430,7 +438,7 @@ static void registerValidity(bool reregister, bool hashGiven, bool canonicalise)
|
||||
}
|
||||
}
|
||||
|
||||
registerValidPaths(infos);
|
||||
ensureLocalStore().registerValidPaths(infos);
|
||||
}
|
||||
|
||||
|
||||
@ -638,10 +646,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
|
||||
if (*i == "--check-contents") checkContents = true;
|
||||
else throw UsageError(format("unknown flag `%1%'") % *i);
|
||||
|
||||
LocalStore * store2(dynamic_cast<LocalStore *>(store.get()));
|
||||
if (!store2) throw Error("you don't have sufficient rights to use --verify");
|
||||
|
||||
store2->verifyStore(checkContents);
|
||||
ensureLocalStore().verifyStore(checkContents);
|
||||
}
|
||||
|
||||
|
||||
@ -670,12 +675,9 @@ static void opOptimise(Strings opFlags, Strings opArgs)
|
||||
if (*i == "--dry-run") dryRun = true;
|
||||
else throw UsageError(format("unknown flag `%1%'") % *i);
|
||||
|
||||
LocalStore * store2(dynamic_cast<LocalStore *>(store.get()));
|
||||
if (!store2) throw Error("you don't have sufficient rights to use --optimise");
|
||||
|
||||
OptimiseStats stats;
|
||||
try {
|
||||
store2->optimiseStore(dryRun, stats);
|
||||
ensureLocalStore().optimiseStore(dryRun, stats);
|
||||
} catch (...) {
|
||||
showOptimiseStats(stats);
|
||||
throw;
|
||||
|
@ -472,7 +472,7 @@ static void processConnection()
|
||||
throw Error("if you run `nix-worker' as root, then you MUST set `build-users-group'!");
|
||||
|
||||
/* Open the store. */
|
||||
store = boost::shared_ptr<StoreAPI>(new LocalStore(true));
|
||||
store = boost::shared_ptr<StoreAPI>(new LocalStore());
|
||||
|
||||
stopWork();
|
||||
|
||||
|
@ -95,4 +95,5 @@ chmod +x $NIX_BIN_DIR/nix/download-using-manifests.pl
|
||||
$nixstore --init
|
||||
|
||||
# Did anything happen?
|
||||
test -e "$NIX_DB_DIR"/validpaths
|
||||
test -e "$NIX_DB_DIR"/info
|
||||
test -e "$NIX_DB_DIR"/referrer
|
||||
|
Loading…
Reference in New Issue
Block a user