From 93227ff65c73e726c4ceef0cdd9439e7a4301417 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 31 Aug 2011 21:11:50 +0000 Subject: * Eliminate all uses of the global variable ‘store’ from libstore. This should also fix: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nix-instantiate: ./../boost/shared_ptr.hpp:254: T* boost::shared_ptr::operator->() const [with T = nix::StoreAPI]: Assertion `px != 0' failed. which was caused by hashDerivationModulo() calling the ‘store’ object (during store upgrades) before openStore() assigned it. --- src/libstore/build.cc | 16 +++++++-------- src/libstore/derivations.cc | 11 ++++++----- src/libstore/derivations.hh | 8 ++++++-- src/libstore/gc.cc | 48 ++++++++++++++++++++++----------------------- src/libstore/local-store.cc | 2 +- src/libstore/misc.cc | 30 ++++++++++++++-------------- src/libstore/misc.hh | 6 +++--- src/libstore/store-api.hh | 6 +++--- 8 files changed, 66 insertions(+), 61 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 26f9fcc59820..d12f41d66941 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -934,7 +934,7 @@ void DerivationGoal::haveDerivation() assert(worker.store.isValidPath(drvPath)); /* Get the derivation. */ - drv = derivationFromPath(drvPath); + drv = derivationFromPath(worker.store, drvPath); foreach (DerivationOutputs::iterator, i, drv.outputs) worker.store.addTempRoot(i->second.path); @@ -1030,10 +1030,10 @@ void DerivationGoal::inputsRealised() `*i' as input paths. Only add the closures of output paths that are specified as inputs. */ assert(worker.store.isValidPath(i->first)); - Derivation inDrv = derivationFromPath(i->first); + Derivation inDrv = derivationFromPath(worker.store, i->first); foreach (StringSet::iterator, j, i->second) if (inDrv.outputs.find(*j) != inDrv.outputs.end()) - computeFSClosure(inDrv.outputs[*j].path, inputPaths); + computeFSClosure(worker.store, inDrv.outputs[*j].path, inputPaths); else throw Error( format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'") @@ -1042,7 +1042,7 @@ void DerivationGoal::inputsRealised() /* Second, the input sources. */ foreach (PathSet::iterator, i, drv.inputSrcs) - computeFSClosure(*i, inputPaths); + computeFSClosure(worker.store, *i, inputPaths); debug(format("added input paths %1%") % showPaths(inputPaths)); @@ -1399,7 +1399,7 @@ HookReply DerivationGoal::tryBuildHook() list it since the remote system *probably* already has it.) */ PathSet allInputs; allInputs.insert(inputPaths.begin(), inputPaths.end()); - computeFSClosure(drvPath, allInputs); + computeFSClosure(worker.store, drvPath, allInputs); string s; foreach (PathSet::iterator, i, allInputs) s += *i + " "; @@ -1545,14 +1545,14 @@ void DerivationGoal::startBuilder() like passing all build-time dependencies of some path to a derivation that builds a NixOS DVD image. */ PathSet paths, paths2; - computeFSClosure(storePath, paths); + computeFSClosure(worker.store, storePath, paths); paths2 = paths; foreach (PathSet::iterator, j, paths2) { if (isDerivation(*j)) { - Derivation drv = derivationFromPath(*j); + Derivation drv = derivationFromPath(worker.store, *j); foreach (DerivationOutputs::iterator, k, drv.outputs) - computeFSClosure(k->second.path, paths); + computeFSClosure(worker.store, k->second.path, paths); } } diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index db9fc6b8a561..5a0f4ecc69e0 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -26,7 +26,8 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash } -Path writeDerivation(const Derivation & drv, const string & name) +Path writeDerivation(StoreAPI & store, + const Derivation & drv, const string & name) { PathSet references; references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); @@ -39,7 +40,7 @@ Path writeDerivation(const Derivation & drv, const string & name) string contents = unparseDerivation(drv); return readOnlyMode ? computeStorePathForText(suffix, contents, references) - : store->addTextToStore(suffix, contents, references); + : store.addTextToStore(suffix, contents, references); } @@ -221,7 +222,7 @@ DrvHashes drvHashes; paths have been replaced by the result of a recursive call to this function, and that for fixed-output derivations we return a hash of its output path. */ -Hash hashDerivationModulo(Derivation drv) +Hash hashDerivationModulo(StoreAPI & store, Derivation drv) { /* Return a fixed hash for fixed-output derivations. */ if (isFixedOutputDrv(drv)) { @@ -238,8 +239,8 @@ Hash hashDerivationModulo(Derivation drv) foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) { Hash h = drvHashes[i->first]; if (h.type == htUnknown) { - Derivation drv2 = derivationFromPath(i->first); - h = hashDerivationModulo(drv2); + Derivation drv2 = derivationFromPath(store, i->first); + h = hashDerivationModulo(store, drv2); drvHashes[i->first] = h; } inputs2[printHash(h)] = i->second; diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 4860f708c56f..27e471d885cc 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -53,8 +53,12 @@ struct Derivation }; +class StoreAPI; + + /* Write a derivation to the Nix store, and return its path. */ -Path writeDerivation(const Derivation & drv, const string & name); +Path writeDerivation(StoreAPI & store, + const Derivation & drv, const string & name); /* Parse a derivation. */ Derivation parseDerivation(const string & s); @@ -69,7 +73,7 @@ bool isDerivation(const string & fileName); /* Return true iff this is a fixed-output derivation. */ bool isFixedOutputDrv(const Derivation & drv); -Hash hashDerivationModulo(Derivation drv); +Hash hashDerivationModulo(StoreAPI & store, Derivation drv); /* Memoisation of hashDerivationModulo(). */ typedef std::map DrvHashes; diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index b8395bfc4352..e79d93723b83 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -90,8 +90,8 @@ void LocalStore::addIndirectRoot(const Path & path) } -Path addPermRoot(const Path & _storePath, const Path & _gcRoot, - bool indirect, bool allowOutsideRootsDir) +Path addPermRoot(StoreAPI & store, const Path & _storePath, + const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir) { Path storePath(canonPath(_storePath)); Path gcRoot(canonPath(_gcRoot)); @@ -104,7 +104,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot, if (indirect) { createSymlink(gcRoot, storePath, true); - store->addIndirectRoot(gcRoot); + store.addIndirectRoot(gcRoot); } else { @@ -127,7 +127,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot, check if the root is in a directory in or linked from the gcroots directory. */ if (queryBoolSetting("gc-check-reachability", false)) { - Roots roots = store->findRoots(); + Roots roots = store.findRoots(); if (roots.find(gcRoot) == roots.end()) printMsg(lvlError, format( @@ -139,7 +139,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot, /* Grab the global GC root, causing us to block while a GC is in progress. This prevents the set of permanent roots from increasing while a GC is in progress. */ - store->syncWithGC(); + store.syncWithGC(); return gcRoot; } @@ -275,8 +275,8 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) } -static void findRoots(const Path & path, bool recurseSymlinks, - bool deleteStale, Roots & roots) +static void findRoots(StoreAPI & store, const Path & path, + bool recurseSymlinks, bool deleteStale, Roots & roots) { try { @@ -289,7 +289,7 @@ static void findRoots(const Path & path, bool recurseSymlinks, if (S_ISDIR(st.st_mode)) { Strings names = readDirectory(path); foreach (Strings::iterator, i, names) - findRoots(path + "/" + *i, recurseSymlinks, deleteStale, roots); + findRoots(store, path + "/" + *i, recurseSymlinks, deleteStale, roots); } else if (S_ISLNK(st.st_mode)) { @@ -299,7 +299,7 @@ static void findRoots(const Path & path, bool recurseSymlinks, debug(format("found root `%1%' in `%2%'") % target % path); Path storePath = toStorePath(target); - if (store->isValidPath(storePath)) + if (store.isValidPath(storePath)) roots[path] = storePath; else printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'") @@ -308,7 +308,7 @@ static void findRoots(const Path & path, bool recurseSymlinks, else if (recurseSymlinks) { if (pathExists(target)) - findRoots(target, false, deleteStale, roots); + findRoots(store, target, false, deleteStale, roots); else if (deleteStale) { printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target); /* Note that we only delete when recursing, i.e., @@ -331,22 +331,22 @@ static void findRoots(const Path & path, bool recurseSymlinks, } -static Roots findRoots(bool deleteStale) +static Roots findRoots(StoreAPI & store, bool deleteStale) { Roots roots; Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str()); - findRoots(rootsDir, true, deleteStale, roots); + findRoots(store, rootsDir, true, deleteStale, roots); return roots; } Roots LocalStore::findRoots() { - return nix::findRoots(false); + return nix::findRoots(*this, false); } -static void addAdditionalRoots(PathSet & roots) +static void addAdditionalRoots(StoreAPI & store, PathSet & roots) { Path rootFinder = getEnv("NIX_ROOT_FINDER", nixLibexecDir + "/nix/find-runtime-roots.pl"); @@ -362,7 +362,7 @@ static void addAdditionalRoots(PathSet & roots) foreach (Strings::iterator, i, paths) { if (isInStore(*i)) { Path path = toStorePath(*i); - if (roots.find(path) == roots.end() && store->isValidPath(path)) { + if (roots.find(path) == roots.end() && store.isValidPath(path)) { debug(format("got additional root `%1%'") % path); roots.insert(path); } @@ -371,32 +371,32 @@ static void addAdditionalRoots(PathSet & roots) } -static void dfsVisit(const PathSet & paths, const Path & path, - PathSet & visited, Paths & sorted) +static void dfsVisit(StoreAPI & store, const PathSet & paths, + const Path & path, PathSet & visited, Paths & sorted) { if (visited.find(path) != visited.end()) return; visited.insert(path); PathSet references; - if (store->isValidPath(path)) - store->queryReferences(path, references); + if (store.isValidPath(path)) + store.queryReferences(path, references); foreach (PathSet::iterator, i, references) /* Don't traverse into paths that don't exist. That can happen due to substitutes for non-existent paths. */ if (*i != path && paths.find(*i) != paths.end()) - dfsVisit(paths, *i, visited, sorted); + dfsVisit(store, paths, *i, visited, sorted); sorted.push_front(path); } -Paths topoSortPaths(const PathSet & paths) +Paths topoSortPaths(StoreAPI & store, const PathSet & paths) { Paths sorted; PathSet visited; foreach (PathSet::const_iterator, i, paths) - dfsVisit(paths, *i, visited, sorted); + dfsVisit(store, paths, *i, visited, sorted); return sorted; } @@ -582,7 +582,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) /* Find the roots. Since we've grabbed the GC lock, the set of permanent roots cannot increase now. */ printMsg(lvlError, format("finding garbage collector roots...")); - Roots rootMap = options.ignoreLiveness ? Roots() : nix::findRoots(true); + Roots rootMap = options.ignoreLiveness ? Roots() : nix::findRoots(*this, true); foreach (Roots::iterator, i, rootMap) state.roots.insert(i->second); @@ -591,7 +591,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) to add running programs to the set of roots (to prevent them from being garbage collected). */ if (!options.ignoreLiveness) - addAdditionalRoots(state.roots); + addAdditionalRoots(*this, state.roots); /* Read the temporary roots. This acquires read locks on all per-process temporary root files. So after this point no paths diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 691069e2b8a0..6ad4c84c69ff 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -497,7 +497,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation & drvCopy.env[i->first] = ""; } - Hash h = hashDerivationModulo(drvCopy); + Hash h = hashDerivationModulo(*this, drvCopy); foreach (DerivationOutputs::const_iterator, i, drv.outputs) { Path outPath = makeOutputPath(i->first, h, drvName); diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 01d6a97ae6fb..d4bbccd111ba 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -6,15 +6,15 @@ namespace nix { -Derivation derivationFromPath(const Path & drvPath) +Derivation derivationFromPath(StoreAPI & store, const Path & drvPath) { assertStorePath(drvPath); - store->ensurePath(drvPath); + store.ensurePath(drvPath); return parseDerivation(readFile(drvPath)); } -void computeFSClosure(const Path & storePath, +void computeFSClosure(StoreAPI & store, const Path & storePath, PathSet & paths, bool flipDirection, bool includeOutputs) { if (paths.find(storePath) != paths.end()) return; @@ -22,19 +22,19 @@ void computeFSClosure(const Path & storePath, PathSet references; if (flipDirection) - store->queryReferrers(storePath, references); + store.queryReferrers(storePath, references); else - store->queryReferences(storePath, references); + store.queryReferences(storePath, references); if (includeOutputs && isDerivation(storePath)) { - PathSet outputs = store->queryDerivationOutputs(storePath); + PathSet outputs = store.queryDerivationOutputs(storePath); foreach (PathSet::iterator, i, outputs) - if (store->isValidPath(*i)) - computeFSClosure(*i, paths, flipDirection, true); + if (store.isValidPath(*i)) + computeFSClosure(store, *i, paths, flipDirection, true); } foreach (PathSet::iterator, i, references) - computeFSClosure(*i, paths, flipDirection, includeOutputs); + computeFSClosure(store, *i, paths, flipDirection, includeOutputs); } @@ -46,7 +46,7 @@ Path findOutput(const Derivation & drv, string id) } -void queryMissing(const PathSet & targets, +void queryMissing(StoreAPI & store, const PathSet & targets, PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown, unsigned long long & downloadSize, unsigned long long & narSize) { @@ -61,15 +61,15 @@ void queryMissing(const PathSet & targets, done.insert(p); if (isDerivation(p)) { - if (!store->isValidPath(p)) { + if (!store.isValidPath(p)) { unknown.insert(p); continue; } - Derivation drv = derivationFromPath(p); + Derivation drv = derivationFromPath(store, p); bool mustBuild = false; foreach (DerivationOutputs::iterator, i, drv.outputs) - if (!store->isValidPath(i->second.path) && !store->hasSubstitutes(i->second.path)) + if (!store.isValidPath(i->second.path) && !store.hasSubstitutes(i->second.path)) mustBuild = true; if (mustBuild) { @@ -83,9 +83,9 @@ void queryMissing(const PathSet & targets, } else { - if (store->isValidPath(p)) continue; + if (store.isValidPath(p)) continue; SubstitutablePathInfo info; - if (store->querySubstitutablePathInfo(p, info)) { + if (store.querySubstitutablePathInfo(p, info)) { willSubstitute.insert(p); downloadSize += info.downloadSize; narSize += info.narSize; diff --git a/src/libstore/misc.hh b/src/libstore/misc.hh index abef6237e7f6..850c12af4ebc 100644 --- a/src/libstore/misc.hh +++ b/src/libstore/misc.hh @@ -9,7 +9,7 @@ namespace nix { /* Read a derivation, after ensuring its existence through ensurePath(). */ -Derivation derivationFromPath(const Path & drvPath); +Derivation derivationFromPath(StoreAPI & store, const Path & drvPath); /* Place in `paths' the set of all store paths in the file system closure of `storePath'; that is, all paths than can be directly or @@ -18,7 +18,7 @@ Derivation derivationFromPath(const Path & drvPath); `storePath' is returned; that is, the closures under the `referrers' relation instead of the `references' relation is returned. */ -void computeFSClosure(const Path & storePath, +void computeFSClosure(StoreAPI & store, const Path & storePath, PathSet & paths, bool flipDirection = false, bool includeOutputs = false); @@ -29,7 +29,7 @@ Path findOutput(const Derivation & drv, string id); /* Given a set of paths that are to be built, return the set of derivations that will be built, and the set of output paths that will be substituted. */ -void queryMissing(const PathSet & targets, +void queryMissing(StoreAPI & store, const PathSet & targets, PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown, unsigned long long & downloadSize, unsigned long long & narSize); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 243a6324ccaa..b3e67436c6c3 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -314,13 +314,13 @@ void removeTempRoots(); /* Register a permanent GC root. */ -Path addPermRoot(const Path & storePath, const Path & gcRoot, - bool indirect, bool allowOutsideRootsDir = false); +Path addPermRoot(StoreAPI & store, const Path & storePath, + const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false); /* Sort a set of paths topologically under the references relation. If p refers to q, then p follows q in this list. */ -Paths topoSortPaths(const PathSet & paths); +Paths topoSortPaths(StoreAPI & store, const PathSet & paths); /* For now, there is a single global store API object, but we'll -- cgit 1.4.1