1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-26 04:00:59 +01:00

* Down to 1 test failure...

This commit is contained in:
Eelco Dolstra 2008-03-05 13:48:19 +00:00
parent 07da660396
commit 95fa444587
9 changed files with 156 additions and 219 deletions

View file

@ -206,7 +206,9 @@ private:
public: public:
Worker(); LocalStore & store;
Worker(LocalStore & store);
~Worker(); ~Worker();
/* Make a goal (with caching). */ /* Make a goal (with caching). */
@ -896,14 +898,14 @@ void DerivationGoal::haveDerivation()
return; return;
} }
assert(store->isValidPath(drvPath)); assert(worker.store.isValidPath(drvPath));
/* Get the derivation. */ /* Get the derivation. */
drv = derivationFromPath(drvPath); drv = derivationFromPath(drvPath);
for (DerivationOutputs::iterator i = drv.outputs.begin(); for (DerivationOutputs::iterator i = drv.outputs.begin();
i != drv.outputs.end(); ++i) i != drv.outputs.end(); ++i)
store->addTempRoot(i->second.path); worker.store.addTempRoot(i->second.path);
/* Check what outputs paths are not already valid. */ /* Check what outputs paths are not already valid. */
PathSet invalidOutputs = checkPathValidity(false); PathSet invalidOutputs = checkPathValidity(false);
@ -937,7 +939,7 @@ void DerivationGoal::haveDerivation()
i != invalidOutputs.end(); ++i) i != invalidOutputs.end(); ++i)
/* Don't bother creating a substitution goal if there are no /* Don't bother creating a substitution goal if there are no
substitutes. */ substitutes. */
if (store->hasSubstitutes(*i)) if (worker.store.hasSubstitutes(*i))
addWaitee(worker.makeSubstitutionGoal(*i)); addWaitee(worker.makeSubstitutionGoal(*i));
if (waitees.empty()) /* to prevent hang (no wake-up event) */ 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%'") throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
% storePath); % storePath);
storePath = toStorePath(storePath); storePath = toStorePath(storePath);
if (!store->isValidPath(storePath)) if (!worker.store.isValidPath(storePath))
throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'") throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
% storePath); % 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() DerivationGoal::HookReply DerivationGoal::tryBuildHook()
{ {
if (!useBuildHook) return rpDecline; if (!useBuildHook) return rpDecline;
@ -1473,7 +1462,7 @@ DerivationGoal::PrepareBuildReply DerivationGoal::prepareBuild()
i != drv.outputs.end(); ++i) i != drv.outputs.end(); ++i)
{ {
Path path = i->second.path; Path path = i->second.path;
if (store->isValidPath(path)) if (worker.store.isValidPath(path))
throw BuildError(format("obstructed build: path `%1%' exists") % path); throw BuildError(format("obstructed build: path `%1%' exists") % path);
if (pathExists(path)) { if (pathExists(path)) {
debug(format("removing unregistered path `%1%'") % 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 /* Add the relevant output closures of the input derivation
`*i' as input paths. Only add the closures of output paths `*i' as input paths. Only add the closures of output paths
that are specified as inputs. */ that are specified as inputs. */
assert(store->isValidPath(i->first)); assert(worker.store.isValidPath(i->first));
Derivation inDrv = derivationFromPath(i->first); Derivation inDrv = derivationFromPath(i->first);
for (StringSet::iterator j = i->second.begin(); for (StringSet::iterator j = i->second.begin();
j != i->second.end(); ++j) j != i->second.end(); ++j)
@ -1623,7 +1612,7 @@ void DerivationGoal::startBuilder()
throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'") throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'")
% storePath); % storePath);
storePath = toStorePath(storePath); storePath = toStorePath(storePath);
if (!store->isValidPath(storePath)) if (!worker.store.isValidPath(storePath))
throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'") throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
% storePath); % storePath);
@ -1651,7 +1640,7 @@ void DerivationGoal::startBuilder()
throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'") throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
% storePath); % storePath);
storePath = toStorePath(storePath); storePath = toStorePath(storePath);
if (!store->isValidPath(storePath)) if (!worker.store.isValidPath(storePath))
throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'") throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
% storePath); % storePath);
@ -1999,7 +1988,7 @@ void DerivationGoal::computeClosure()
for (DerivationOutputs::iterator i = drv.outputs.begin(); for (DerivationOutputs::iterator i = drv.outputs.begin();
i != drv.outputs.end(); ++i) i != drv.outputs.end(); ++i)
{ {
registerValidPath(i->second.path, worker.store.registerValidPath(i->second.path,
contentHashes[i->second.path], contentHashes[i->second.path],
allReferences[i->second.path], allReferences[i->second.path],
drvPath); drvPath);
@ -2102,7 +2091,7 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid)
PathSet result; PathSet result;
for (DerivationOutputs::iterator i = drv.outputs.begin(); for (DerivationOutputs::iterator i = drv.outputs.begin();
i != drv.outputs.end(); ++i) 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); if (returnValid) result.insert(i->second.path);
} else { } else {
if (!returnValid) result.insert(i->second.path); if (!returnValid) result.insert(i->second.path);
@ -2208,10 +2197,10 @@ void SubstitutionGoal::init()
{ {
trace("init"); trace("init");
store->addTempRoot(storePath); worker.store.addTempRoot(storePath);
/* If the path already exists we're done. */ /* If the path already exists we're done. */
if (store->isValidPath(storePath)) { if (worker.store.isValidPath(storePath)) {
amDone(ecSuccess); amDone(ecSuccess);
return; return;
} }
@ -2282,7 +2271,7 @@ void SubstitutionGoal::referencesValid()
for (PathSet::iterator i = references.begin(); for (PathSet::iterator i = references.begin();
i != references.end(); ++i) i != references.end(); ++i)
if (*i != storePath) /* ignore self-references */ if (*i != storePath) /* ignore self-references */
assert(store->isValidPath(*i)); assert(worker.store.isValidPath(*i));
state = &SubstitutionGoal::tryToRun; state = &SubstitutionGoal::tryToRun;
worker.waitForBuildSlot(shared_from_this()); worker.waitForBuildSlot(shared_from_this());
@ -2316,7 +2305,7 @@ void SubstitutionGoal::tryToRun()
(format("waiting for lock on `%1%'") % storePath).str()); (format("waiting for lock on `%1%'") % storePath).str());
/* Check again whether the path is invalid. */ /* 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); debug(format("store path `%1%' has become valid") % storePath);
outputLock->setDeletion(true); outputLock->setDeletion(true);
amDone(ecSuccess); amDone(ecSuccess);
@ -2423,7 +2412,7 @@ void SubstitutionGoal::finished()
Hash contentHash = hashPath(htSHA256, storePath); Hash contentHash = hashPath(htSHA256, storePath);
registerValidPath(storePath, contentHash, worker.store.registerValidPath(storePath, contentHash,
references, deriver); references, deriver);
outputLock->setDeletion(true); outputLock->setDeletion(true);
@ -2458,7 +2447,8 @@ void SubstitutionGoal::handleEOF(int fd)
static bool working = false; static bool working = false;
Worker::Worker() Worker::Worker(LocalStore & store)
: store(store)
{ {
/* Debugging: prevent recursive workers. */ /* Debugging: prevent recursive workers. */
if (working) abort(); if (working) abort();
@ -2856,7 +2846,7 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
startNest(nest, lvlDebug, startNest(nest, lvlDebug,
format("building %1%") % showPaths(drvPaths)); format("building %1%") % showPaths(drvPaths));
Worker worker; Worker worker(*this);
Goals goals; Goals goals;
for (PathSet::const_iterator i = drvPaths.begin(); for (PathSet::const_iterator i = drvPaths.begin();
@ -2881,9 +2871,9 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
void LocalStore::ensurePath(const Path & path) void LocalStore::ensurePath(const Path & path)
{ {
/* If the path is already valid, we're done. */ /* 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); GoalPtr goal = worker.makeSubstitutionGoal(path);
Goals goals = singleton<Goals>(goal); Goals goals = singleton<Goals>(goal);

View file

@ -21,9 +21,6 @@
namespace nix { namespace nix {
void upgradeStore12();
void checkStoreNotSymlink() void checkStoreNotSymlink()
{ {
if (getEnv("NIX_IGNORE_SYMLINK_STORE") == "1") return; 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 Hash & hash, const PathSet & references,
const Path & deriver) 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; if (pathExists(infoFile)) return;
// !!! acquire PathLock on infoFile here // !!! acquire PathLock on infoFile here?
string refs; 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 += " "; if (!refs.empty()) refs += " ";
refs += *i; refs += *i;
@ -231,21 +252,20 @@ void registerValidPath(const Path & path,
have referrer mappings back to `path'. A " " is prefixed have referrer mappings back to `path'. A " " is prefixed
to separate it from the previous entry. It's not suffixed to separate it from the previous entry. It's not suffixed
to deal with interrupted partial writes to this file. */ 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" "Hash: sha256:%1%\n"
"References: %2%\n" "References: %2%\n"
"Deriver: %3%\n" "Deriver: %3%\n"
"Registered-At: %4%\n") "Registered-At: %4%\n")
% printHash(hash) % refs % deriver % time(0)).str(); % printHash(info.hash) % refs % info.deriver % time(0)).str();
// !!! atomicity // !!! atomicity
writeFile(infoFile, info); writeFile(infoFile, s);
} }
Hash parseHashField(const Path & path, const string & s) Hash parseHashField(const Path & path, const string & s)
{ {
string::size_type colon = s.find(':'); 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; ValidPathInfo res;
assertStorePath(path); 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. */ /* Read the info file. */
Path infoFile = infoFileFor(path); 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, void LocalStore::queryReferences(const Path & path,
PathSet & references) 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) Path LocalStore::queryDeriver(const Path & path)
{ {
return queryPathInfo(path).deriver; return queryPathInfo(path).deriver;
@ -449,24 +411,7 @@ Hash LocalStore::queryPathHash(const Path & path)
} }
#if 0 void LocalStore::registerValidPaths(const ValidPathInfos & infos)
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)
{ {
throw Error("!!! registerValidPaths"); throw Error("!!! registerValidPaths");
#if 0 #if 0
@ -505,14 +450,16 @@ static void invalidatePath(const Path & path)
{ {
debug(format("invalidating path `%1%'") % path); debug(format("invalidating path `%1%'") % path);
throw Error("!!! invalidatePath"); /* Remove the info file. */
#if 0 Path p = infoFileFor(path);
/* Clear the `references' entry for this path, as well as the if (unlink(p.c_str()) == -1)
inverse `referrers' entries, and the `derivers' entry. */ throw SysError(format("unlinking `%1%'") % p);
setReferences(txn, path, PathSet());
nixDB.delPair(txn, dbDerivers, path); /* Remove the corresponding referrer entries for each path
nixDB.delPair(txn, dbValidPaths, path); referenced by this one. This has to happen after removing the
#endif 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; bytesFreed = 0;
Path path(canonPath(_path)); Path path(canonPath(_path));
assertStorePath(path); assertStorePath(path);
Transaction txn(nixDB); if (isValidPath(path)) {
if (isValidPathTxn(txn, path)) { PathSet referrers; queryReferrers(path, referrers);
PathSet referrers = getReferrers(txn, path); referrers.erase(path); /* ignore self-references */
for (PathSet::iterator i = referrers.begin(); /* !!! check: can a new referrer appear now? */
i != referrers.end(); ++i) if (!referrers.empty())
if (*i != path && isValidPathTxn(txn, *i)) throw PathInUse(format("cannot delete path `%1%' because it is in use by `%2%'")
throw PathInUse(format("cannot delete path `%1%' because it is in use by path `%2%'") % path % *i); % path % showPaths(referrers));
invalidatePath(txn, path); invalidatePath(path);
} }
txn.commit();
deletePathWrapped(path, bytesFreed); deletePathWrapped(path, bytesFreed);
#endif
} }
@ -889,6 +832,8 @@ void LocalStore::verifyStore(bool checkContents)
/* Check the referrers. */ /* Check the referrers. */
printMsg(lvlInfo, "checking referrers"); printMsg(lvlInfo, "checking referrers");
std::map<Path, PathSet> referencesCache;
Strings entries = readDirectory(nixDBPath + "/referrer"); Strings entries = readDirectory(nixDBPath + "/referrer");
for (Strings::iterator i = entries.begin(); i != entries.end(); ++i) { for (Strings::iterator i = entries.begin(); i != entries.end(); ++i) {
Path from = nixStore + "/" + *i; Path from = nixStore + "/" + *i;
@ -906,54 +851,24 @@ void LocalStore::verifyStore(bool checkContents)
bool update = false; bool update = false;
if (!allValid) { 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; update = true;
} }
if (update) /* 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);
} }
#if 0 if (update) rewriteReferrers(from, referrersNew);
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);
}
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);
}
}
}
#endif
} }

View file

@ -91,6 +91,9 @@ public:
void collectGarbage(GCAction action, const PathSet & pathsToDelete, void collectGarbage(GCAction action, const PathSet & pathsToDelete,
bool ignoreLiveness, PathSet & result, unsigned long long & bytesFreed); 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 /* Optimise the disk space usage of the Nix store by hard-linking
files with the same contents. */ files with the same contents. */
void optimiseStore(bool dryRun, OptimiseStats & stats); void optimiseStore(bool dryRun, OptimiseStats & stats);
@ -98,28 +101,37 @@ public:
/* Check the integrity of the Nix store. */ /* Check the integrity of the Nix store. */
void verifyStore(bool checkContents); 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: 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); bool queryReferrersInternal(const Path & path, PathSet & referrers);
void upgradeStore12();
}; };
/* Copy a path recursively. */ /* Copy a path recursively. */
void copyPath(const Path & src, const Path & dst); 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 /* "Fix", or canonicalise, the meta-data of the files in a store path
after it has been built. In particular: after it has been built. In particular:
- the last modification date on each file is set to 0 (i.e., - 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. */ in a setuid Nix installation. */
void canonicalisePathMetaData(const Path & path); void canonicalisePathMetaData(const Path & path);
/* Delete a value from the nixStore directory. */
void deleteFromStore(const Path & path, unsigned long long & bytesFreed);
MakeError(PathInUse, Error); MakeError(PathInUse, Error);
/* Whether we are in build users mode. */ /* Whether we are in build users mode. */

View file

@ -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;
}
} }

View file

@ -252,6 +252,11 @@ extern boost::shared_ptr<StoreAPI> store;
boost::shared_ptr<StoreAPI> openStore(); 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, string makeValidityRegistration(const PathSet & paths,
bool showDerivers, bool showHash); bool showDerivers, bool showHash);
@ -263,6 +268,8 @@ struct ValidPathInfo
PathSet references; PathSet references;
}; };
typedef list<ValidPathInfo> ValidPathInfos;
ValidPathInfo decodeValidPathInfo(std::istream & str, ValidPathInfo decodeValidPathInfo(std::istream & str,
bool hashGiven = false); bool hashGiven = false);

View file

@ -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 /* 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 old schema uses Berkeley DB, the new one stores store path
meta-information in files. */ meta-information in files. */
void upgradeStore12() void LocalStore::upgradeStore12()
{ {
printMsg(lvlError, "upgrading Nix store to new schema (this may take a while)..."); printMsg(lvlError, "upgrading Nix store to new schema (this may take a while)...");

View file

@ -31,6 +31,14 @@ static int rootNr = 0;
static bool indirectRoot = false; 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) static Path useDeriver(Path path)
{ {
if (!isDerivation(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; if (*i == "--check-contents") checkContents = true;
else throw UsageError(format("unknown flag `%1%'") % *i); else throw UsageError(format("unknown flag `%1%'") % *i);
LocalStore * store2(dynamic_cast<LocalStore *>(store.get())); ensureLocalStore().verifyStore(checkContents);
if (!store2) throw Error("you don't have sufficient rights to use --verify");
store2->verifyStore(checkContents);
} }
@ -670,12 +675,9 @@ static void opOptimise(Strings opFlags, Strings opArgs)
if (*i == "--dry-run") dryRun = true; if (*i == "--dry-run") dryRun = true;
else throw UsageError(format("unknown flag `%1%'") % *i); 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; OptimiseStats stats;
try { try {
store2->optimiseStore(dryRun, stats); ensureLocalStore().optimiseStore(dryRun, stats);
} catch (...) { } catch (...) {
showOptimiseStats(stats); showOptimiseStats(stats);
throw; throw;

View file

@ -472,7 +472,7 @@ static void processConnection()
throw Error("if you run `nix-worker' as root, then you MUST set `build-users-group'!"); throw Error("if you run `nix-worker' as root, then you MUST set `build-users-group'!");
/* Open the store. */ /* Open the store. */
store = boost::shared_ptr<StoreAPI>(new LocalStore(true)); store = boost::shared_ptr<StoreAPI>(new LocalStore());
stopWork(); stopWork();

View file

@ -95,4 +95,5 @@ chmod +x $NIX_BIN_DIR/nix/download-using-manifests.pl
$nixstore --init $nixstore --init
# Did anything happen? # Did anything happen?
test -e "$NIX_DB_DIR"/validpaths test -e "$NIX_DB_DIR"/info
test -e "$NIX_DB_DIR"/referrer