* Eliminate all uses of the global variable ‘store’ from libstore.
This should also fix: nix-instantiate: ./../boost/shared_ptr.hpp:254: T* boost::shared_ptr<T>::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.
This commit is contained in:
parent
5bcdc7e351
commit
93227ff65c
15 changed files with 95 additions and 89 deletions
|
@ -357,7 +357,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
runs. */
|
runs. */
|
||||||
if (path.at(0) == '=') {
|
if (path.at(0) == '=') {
|
||||||
path = string(path, 1);
|
path = string(path, 1);
|
||||||
PathSet refs; computeFSClosure(path, refs);
|
PathSet refs; computeFSClosure(*store, path, refs);
|
||||||
foreach (PathSet::iterator, j, refs) {
|
foreach (PathSet::iterator, j, refs) {
|
||||||
drv.inputSrcs.insert(*j);
|
drv.inputSrcs.insert(*j);
|
||||||
if (isDerivation(*j))
|
if (isDerivation(*j))
|
||||||
|
@ -433,7 +433,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
|
|
||||||
/* Use the masked derivation expression to compute the output
|
/* Use the masked derivation expression to compute the output
|
||||||
path. */
|
path. */
|
||||||
Hash h = hashDerivationModulo(drv);
|
Hash h = hashDerivationModulo(*store, drv);
|
||||||
|
|
||||||
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||||
if (i->second.path == "") {
|
if (i->second.path == "") {
|
||||||
|
@ -444,7 +444,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the resulting term into the Nix store directory. */
|
/* Write the resulting term into the Nix store directory. */
|
||||||
Path drvPath = writeDerivation(drv, drvName);
|
Path drvPath = writeDerivation(*store, drv, drvName);
|
||||||
|
|
||||||
printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
|
printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
|
||||||
% drvName % drvPath);
|
% drvName % drvPath);
|
||||||
|
@ -452,7 +452,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
/* Optimisation, but required in read-only mode! because in that
|
/* Optimisation, but required in read-only mode! because in that
|
||||||
case we don't actually write store derivations, so we can't
|
case we don't actually write store derivations, so we can't
|
||||||
read them later. */
|
read them later. */
|
||||||
drvHashes[drvPath] = hashDerivationModulo(drv);
|
drvHashes[drvPath] = hashDerivationModulo(*store, drv);
|
||||||
|
|
||||||
state.mkAttrs(v, 1 + drv.outputs.size());
|
state.mkAttrs(v, 1 + drv.outputs.size());
|
||||||
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
|
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
|
||||||
|
|
|
@ -52,11 +52,11 @@ void printGCWarning()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void printMissing(const PathSet & paths)
|
void printMissing(StoreAPI & store, const PathSet & paths)
|
||||||
{
|
{
|
||||||
unsigned long long downloadSize, narSize;
|
unsigned long long downloadSize, narSize;
|
||||||
PathSet willBuild, willSubstitute, unknown;
|
PathSet willBuild, willSubstitute, unknown;
|
||||||
queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
queryMissing(store, paths, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||||
|
|
||||||
if (!willBuild.empty()) {
|
if (!willBuild.empty()) {
|
||||||
printMsg(lvlInfo, format("these derivations will be built:"));
|
printMsg(lvlInfo, format("these derivations will be built:"));
|
||||||
|
|
|
@ -24,11 +24,13 @@ namespace nix {
|
||||||
|
|
||||||
MakeError(UsageError, nix::Error);
|
MakeError(UsageError, nix::Error);
|
||||||
|
|
||||||
|
class StoreAPI;
|
||||||
|
|
||||||
/* Ugh. No better place to put this. */
|
/* Ugh. No better place to put this. */
|
||||||
Path makeRootName(const Path & gcRoot, int & counter);
|
Path makeRootName(const Path & gcRoot, int & counter);
|
||||||
void printGCWarning();
|
void printGCWarning();
|
||||||
|
|
||||||
void printMissing(const PathSet & paths);
|
void printMissing(StoreAPI & store, const PathSet & paths);
|
||||||
|
|
||||||
template<class N> N getIntArg(const string & opt,
|
template<class N> N getIntArg(const string & opt,
|
||||||
Strings::iterator & i, const Strings::iterator & end)
|
Strings::iterator & i, const Strings::iterator & end)
|
||||||
|
|
|
@ -934,7 +934,7 @@ void DerivationGoal::haveDerivation()
|
||||||
assert(worker.store.isValidPath(drvPath));
|
assert(worker.store.isValidPath(drvPath));
|
||||||
|
|
||||||
/* Get the derivation. */
|
/* Get the derivation. */
|
||||||
drv = derivationFromPath(drvPath);
|
drv = derivationFromPath(worker.store, drvPath);
|
||||||
|
|
||||||
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||||
worker.store.addTempRoot(i->second.path);
|
worker.store.addTempRoot(i->second.path);
|
||||||
|
@ -1030,10 +1030,10 @@ void DerivationGoal::inputsRealised()
|
||||||
`*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(worker.store.isValidPath(i->first));
|
assert(worker.store.isValidPath(i->first));
|
||||||
Derivation inDrv = derivationFromPath(i->first);
|
Derivation inDrv = derivationFromPath(worker.store, i->first);
|
||||||
foreach (StringSet::iterator, j, i->second)
|
foreach (StringSet::iterator, j, i->second)
|
||||||
if (inDrv.outputs.find(*j) != inDrv.outputs.end())
|
if (inDrv.outputs.find(*j) != inDrv.outputs.end())
|
||||||
computeFSClosure(inDrv.outputs[*j].path, inputPaths);
|
computeFSClosure(worker.store, inDrv.outputs[*j].path, inputPaths);
|
||||||
else
|
else
|
||||||
throw Error(
|
throw Error(
|
||||||
format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
|
format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
|
||||||
|
@ -1042,7 +1042,7 @@ void DerivationGoal::inputsRealised()
|
||||||
|
|
||||||
/* Second, the input sources. */
|
/* Second, the input sources. */
|
||||||
foreach (PathSet::iterator, i, drv.inputSrcs)
|
foreach (PathSet::iterator, i, drv.inputSrcs)
|
||||||
computeFSClosure(*i, inputPaths);
|
computeFSClosure(worker.store, *i, inputPaths);
|
||||||
|
|
||||||
debug(format("added input paths %1%") % showPaths(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.) */
|
list it since the remote system *probably* already has it.) */
|
||||||
PathSet allInputs;
|
PathSet allInputs;
|
||||||
allInputs.insert(inputPaths.begin(), inputPaths.end());
|
allInputs.insert(inputPaths.begin(), inputPaths.end());
|
||||||
computeFSClosure(drvPath, allInputs);
|
computeFSClosure(worker.store, drvPath, allInputs);
|
||||||
|
|
||||||
string s;
|
string s;
|
||||||
foreach (PathSet::iterator, i, allInputs) s += *i + " ";
|
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
|
like passing all build-time dependencies of some path to a
|
||||||
derivation that builds a NixOS DVD image. */
|
derivation that builds a NixOS DVD image. */
|
||||||
PathSet paths, paths2;
|
PathSet paths, paths2;
|
||||||
computeFSClosure(storePath, paths);
|
computeFSClosure(worker.store, storePath, paths);
|
||||||
paths2 = paths;
|
paths2 = paths;
|
||||||
|
|
||||||
foreach (PathSet::iterator, j, paths2) {
|
foreach (PathSet::iterator, j, paths2) {
|
||||||
if (isDerivation(*j)) {
|
if (isDerivation(*j)) {
|
||||||
Derivation drv = derivationFromPath(*j);
|
Derivation drv = derivationFromPath(worker.store, *j);
|
||||||
foreach (DerivationOutputs::iterator, k, drv.outputs)
|
foreach (DerivationOutputs::iterator, k, drv.outputs)
|
||||||
computeFSClosure(k->second.path, paths);
|
computeFSClosure(worker.store, k->second.path, paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
PathSet references;
|
||||||
references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
|
references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
|
||||||
|
@ -39,7 +40,7 @@ Path writeDerivation(const Derivation & drv, const string & name)
|
||||||
string contents = unparseDerivation(drv);
|
string contents = unparseDerivation(drv);
|
||||||
return readOnlyMode
|
return readOnlyMode
|
||||||
? computeStorePathForText(suffix, contents, references)
|
? 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
|
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
|
function, and that for fixed-output derivations we return a hash of
|
||||||
its output path. */
|
its output path. */
|
||||||
Hash hashDerivationModulo(Derivation drv)
|
Hash hashDerivationModulo(StoreAPI & store, Derivation drv)
|
||||||
{
|
{
|
||||||
/* Return a fixed hash for fixed-output derivations. */
|
/* Return a fixed hash for fixed-output derivations. */
|
||||||
if (isFixedOutputDrv(drv)) {
|
if (isFixedOutputDrv(drv)) {
|
||||||
|
@ -238,8 +239,8 @@ Hash hashDerivationModulo(Derivation drv)
|
||||||
foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
|
foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
|
||||||
Hash h = drvHashes[i->first];
|
Hash h = drvHashes[i->first];
|
||||||
if (h.type == htUnknown) {
|
if (h.type == htUnknown) {
|
||||||
Derivation drv2 = derivationFromPath(i->first);
|
Derivation drv2 = derivationFromPath(store, i->first);
|
||||||
h = hashDerivationModulo(drv2);
|
h = hashDerivationModulo(store, drv2);
|
||||||
drvHashes[i->first] = h;
|
drvHashes[i->first] = h;
|
||||||
}
|
}
|
||||||
inputs2[printHash(h)] = i->second;
|
inputs2[printHash(h)] = i->second;
|
||||||
|
|
|
@ -53,8 +53,12 @@ struct Derivation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class StoreAPI;
|
||||||
|
|
||||||
|
|
||||||
/* Write a derivation to the Nix store, and return its path. */
|
/* 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. */
|
/* Parse a derivation. */
|
||||||
Derivation parseDerivation(const string & s);
|
Derivation parseDerivation(const string & s);
|
||||||
|
@ -69,7 +73,7 @@ bool isDerivation(const string & fileName);
|
||||||
/* Return true iff this is a fixed-output derivation. */
|
/* Return true iff this is a fixed-output derivation. */
|
||||||
bool isFixedOutputDrv(const Derivation & drv);
|
bool isFixedOutputDrv(const Derivation & drv);
|
||||||
|
|
||||||
Hash hashDerivationModulo(Derivation drv);
|
Hash hashDerivationModulo(StoreAPI & store, Derivation drv);
|
||||||
|
|
||||||
/* Memoisation of hashDerivationModulo(). */
|
/* Memoisation of hashDerivationModulo(). */
|
||||||
typedef std::map<Path, Hash> DrvHashes;
|
typedef std::map<Path, Hash> DrvHashes;
|
||||||
|
|
|
@ -90,8 +90,8 @@ void LocalStore::addIndirectRoot(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
|
Path addPermRoot(StoreAPI & store, const Path & _storePath,
|
||||||
bool indirect, bool allowOutsideRootsDir)
|
const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir)
|
||||||
{
|
{
|
||||||
Path storePath(canonPath(_storePath));
|
Path storePath(canonPath(_storePath));
|
||||||
Path gcRoot(canonPath(_gcRoot));
|
Path gcRoot(canonPath(_gcRoot));
|
||||||
|
@ -104,7 +104,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
|
||||||
|
|
||||||
if (indirect) {
|
if (indirect) {
|
||||||
createSymlink(gcRoot, storePath, true);
|
createSymlink(gcRoot, storePath, true);
|
||||||
store->addIndirectRoot(gcRoot);
|
store.addIndirectRoot(gcRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
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
|
check if the root is in a directory in or linked from the
|
||||||
gcroots directory. */
|
gcroots directory. */
|
||||||
if (queryBoolSetting("gc-check-reachability", false)) {
|
if (queryBoolSetting("gc-check-reachability", false)) {
|
||||||
Roots roots = store->findRoots();
|
Roots roots = store.findRoots();
|
||||||
if (roots.find(gcRoot) == roots.end())
|
if (roots.find(gcRoot) == roots.end())
|
||||||
printMsg(lvlError,
|
printMsg(lvlError,
|
||||||
format(
|
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
|
/* Grab the global GC root, causing us to block while a GC is in
|
||||||
progress. This prevents the set of permanent roots from
|
progress. This prevents the set of permanent roots from
|
||||||
increasing while a GC is in progress. */
|
increasing while a GC is in progress. */
|
||||||
store->syncWithGC();
|
store.syncWithGC();
|
||||||
|
|
||||||
return gcRoot;
|
return gcRoot;
|
||||||
}
|
}
|
||||||
|
@ -275,8 +275,8 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void findRoots(const Path & path, bool recurseSymlinks,
|
static void findRoots(StoreAPI & store, const Path & path,
|
||||||
bool deleteStale, Roots & roots)
|
bool recurseSymlinks, bool deleteStale, Roots & roots)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ static void findRoots(const Path & path, bool recurseSymlinks,
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
Strings names = readDirectory(path);
|
Strings names = readDirectory(path);
|
||||||
foreach (Strings::iterator, i, names)
|
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)) {
|
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%'")
|
debug(format("found root `%1%' in `%2%'")
|
||||||
% target % path);
|
% target % path);
|
||||||
Path storePath = toStorePath(target);
|
Path storePath = toStorePath(target);
|
||||||
if (store->isValidPath(storePath))
|
if (store.isValidPath(storePath))
|
||||||
roots[path] = storePath;
|
roots[path] = storePath;
|
||||||
else
|
else
|
||||||
printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'")
|
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) {
|
else if (recurseSymlinks) {
|
||||||
if (pathExists(target))
|
if (pathExists(target))
|
||||||
findRoots(target, false, deleteStale, roots);
|
findRoots(store, target, false, deleteStale, roots);
|
||||||
else if (deleteStale) {
|
else if (deleteStale) {
|
||||||
printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target);
|
printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target);
|
||||||
/* Note that we only delete when recursing, i.e.,
|
/* 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;
|
Roots roots;
|
||||||
Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
|
Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
|
||||||
findRoots(rootsDir, true, deleteStale, roots);
|
findRoots(store, rootsDir, true, deleteStale, roots);
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Roots LocalStore::findRoots()
|
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",
|
Path rootFinder = getEnv("NIX_ROOT_FINDER",
|
||||||
nixLibexecDir + "/nix/find-runtime-roots.pl");
|
nixLibexecDir + "/nix/find-runtime-roots.pl");
|
||||||
|
@ -362,7 +362,7 @@ static void addAdditionalRoots(PathSet & roots)
|
||||||
foreach (Strings::iterator, i, paths) {
|
foreach (Strings::iterator, i, paths) {
|
||||||
if (isInStore(*i)) {
|
if (isInStore(*i)) {
|
||||||
Path path = toStorePath(*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);
|
debug(format("got additional root `%1%'") % path);
|
||||||
roots.insert(path);
|
roots.insert(path);
|
||||||
}
|
}
|
||||||
|
@ -371,32 +371,32 @@ static void addAdditionalRoots(PathSet & roots)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dfsVisit(const PathSet & paths, const Path & path,
|
static void dfsVisit(StoreAPI & store, const PathSet & paths,
|
||||||
PathSet & visited, Paths & sorted)
|
const Path & path, PathSet & visited, Paths & sorted)
|
||||||
{
|
{
|
||||||
if (visited.find(path) != visited.end()) return;
|
if (visited.find(path) != visited.end()) return;
|
||||||
visited.insert(path);
|
visited.insert(path);
|
||||||
|
|
||||||
PathSet references;
|
PathSet references;
|
||||||
if (store->isValidPath(path))
|
if (store.isValidPath(path))
|
||||||
store->queryReferences(path, references);
|
store.queryReferences(path, references);
|
||||||
|
|
||||||
foreach (PathSet::iterator, i, references)
|
foreach (PathSet::iterator, i, references)
|
||||||
/* Don't traverse into paths that don't exist. That can
|
/* Don't traverse into paths that don't exist. That can
|
||||||
happen due to substitutes for non-existent paths. */
|
happen due to substitutes for non-existent paths. */
|
||||||
if (*i != path && paths.find(*i) != paths.end())
|
if (*i != path && paths.find(*i) != paths.end())
|
||||||
dfsVisit(paths, *i, visited, sorted);
|
dfsVisit(store, paths, *i, visited, sorted);
|
||||||
|
|
||||||
sorted.push_front(path);
|
sorted.push_front(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Paths topoSortPaths(const PathSet & paths)
|
Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
|
||||||
{
|
{
|
||||||
Paths sorted;
|
Paths sorted;
|
||||||
PathSet visited;
|
PathSet visited;
|
||||||
foreach (PathSet::const_iterator, i, paths)
|
foreach (PathSet::const_iterator, i, paths)
|
||||||
dfsVisit(paths, *i, visited, sorted);
|
dfsVisit(store, paths, *i, visited, sorted);
|
||||||
return 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
|
/* Find the roots. Since we've grabbed the GC lock, the set of
|
||||||
permanent roots cannot increase now. */
|
permanent roots cannot increase now. */
|
||||||
printMsg(lvlError, format("finding garbage collector roots..."));
|
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);
|
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
|
to add running programs to the set of roots (to prevent them
|
||||||
from being garbage collected). */
|
from being garbage collected). */
|
||||||
if (!options.ignoreLiveness)
|
if (!options.ignoreLiveness)
|
||||||
addAdditionalRoots(state.roots);
|
addAdditionalRoots(*this, state.roots);
|
||||||
|
|
||||||
/* Read the temporary roots. This acquires read locks on all
|
/* Read the temporary roots. This acquires read locks on all
|
||||||
per-process temporary root files. So after this point no paths
|
per-process temporary root files. So after this point no paths
|
||||||
|
|
|
@ -497,7 +497,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||||
drvCopy.env[i->first] = "";
|
drvCopy.env[i->first] = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash h = hashDerivationModulo(drvCopy);
|
Hash h = hashDerivationModulo(*this, drvCopy);
|
||||||
|
|
||||||
foreach (DerivationOutputs::const_iterator, i, drv.outputs) {
|
foreach (DerivationOutputs::const_iterator, i, drv.outputs) {
|
||||||
Path outPath = makeOutputPath(i->first, h, drvName);
|
Path outPath = makeOutputPath(i->first, h, drvName);
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
Derivation derivationFromPath(const Path & drvPath)
|
Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
|
||||||
{
|
{
|
||||||
assertStorePath(drvPath);
|
assertStorePath(drvPath);
|
||||||
store->ensurePath(drvPath);
|
store.ensurePath(drvPath);
|
||||||
return parseDerivation(readFile(drvPath));
|
return parseDerivation(readFile(drvPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void computeFSClosure(const Path & storePath,
|
void computeFSClosure(StoreAPI & store, const Path & storePath,
|
||||||
PathSet & paths, bool flipDirection, bool includeOutputs)
|
PathSet & paths, bool flipDirection, bool includeOutputs)
|
||||||
{
|
{
|
||||||
if (paths.find(storePath) != paths.end()) return;
|
if (paths.find(storePath) != paths.end()) return;
|
||||||
|
@ -22,19 +22,19 @@ void computeFSClosure(const Path & storePath,
|
||||||
|
|
||||||
PathSet references;
|
PathSet references;
|
||||||
if (flipDirection)
|
if (flipDirection)
|
||||||
store->queryReferrers(storePath, references);
|
store.queryReferrers(storePath, references);
|
||||||
else
|
else
|
||||||
store->queryReferences(storePath, references);
|
store.queryReferences(storePath, references);
|
||||||
|
|
||||||
if (includeOutputs && isDerivation(storePath)) {
|
if (includeOutputs && isDerivation(storePath)) {
|
||||||
PathSet outputs = store->queryDerivationOutputs(storePath);
|
PathSet outputs = store.queryDerivationOutputs(storePath);
|
||||||
foreach (PathSet::iterator, i, outputs)
|
foreach (PathSet::iterator, i, outputs)
|
||||||
if (store->isValidPath(*i))
|
if (store.isValidPath(*i))
|
||||||
computeFSClosure(*i, paths, flipDirection, true);
|
computeFSClosure(store, *i, paths, flipDirection, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (PathSet::iterator, i, references)
|
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,
|
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
||||||
unsigned long long & downloadSize, unsigned long long & narSize)
|
unsigned long long & downloadSize, unsigned long long & narSize)
|
||||||
{
|
{
|
||||||
|
@ -61,15 +61,15 @@ void queryMissing(const PathSet & targets,
|
||||||
done.insert(p);
|
done.insert(p);
|
||||||
|
|
||||||
if (isDerivation(p)) {
|
if (isDerivation(p)) {
|
||||||
if (!store->isValidPath(p)) {
|
if (!store.isValidPath(p)) {
|
||||||
unknown.insert(p);
|
unknown.insert(p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Derivation drv = derivationFromPath(p);
|
Derivation drv = derivationFromPath(store, p);
|
||||||
|
|
||||||
bool mustBuild = false;
|
bool mustBuild = false;
|
||||||
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
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;
|
mustBuild = true;
|
||||||
|
|
||||||
if (mustBuild) {
|
if (mustBuild) {
|
||||||
|
@ -83,9 +83,9 @@ void queryMissing(const PathSet & targets,
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (store->isValidPath(p)) continue;
|
if (store.isValidPath(p)) continue;
|
||||||
SubstitutablePathInfo info;
|
SubstitutablePathInfo info;
|
||||||
if (store->querySubstitutablePathInfo(p, info)) {
|
if (store.querySubstitutablePathInfo(p, info)) {
|
||||||
willSubstitute.insert(p);
|
willSubstitute.insert(p);
|
||||||
downloadSize += info.downloadSize;
|
downloadSize += info.downloadSize;
|
||||||
narSize += info.narSize;
|
narSize += info.narSize;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace nix {
|
||||||
|
|
||||||
/* Read a derivation, after ensuring its existence through
|
/* Read a derivation, after ensuring its existence through
|
||||||
ensurePath(). */
|
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
|
/* 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
|
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
|
`storePath' is returned; that is, the closures under the
|
||||||
`referrers' relation instead of the `references' relation is
|
`referrers' relation instead of the `references' relation is
|
||||||
returned. */
|
returned. */
|
||||||
void computeFSClosure(const Path & storePath,
|
void computeFSClosure(StoreAPI & store, const Path & storePath,
|
||||||
PathSet & paths, bool flipDirection = false,
|
PathSet & paths, bool flipDirection = false,
|
||||||
bool includeOutputs = 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
|
/* 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
|
derivations that will be built, and the set of output paths that
|
||||||
will be substituted. */
|
will be substituted. */
|
||||||
void queryMissing(const PathSet & targets,
|
void queryMissing(StoreAPI & store, const PathSet & targets,
|
||||||
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
||||||
unsigned long long & downloadSize, unsigned long long & narSize);
|
unsigned long long & downloadSize, unsigned long long & narSize);
|
||||||
|
|
||||||
|
|
|
@ -314,13 +314,13 @@ void removeTempRoots();
|
||||||
|
|
||||||
|
|
||||||
/* Register a permanent GC root. */
|
/* Register a permanent GC root. */
|
||||||
Path addPermRoot(const Path & storePath, const Path & gcRoot,
|
Path addPermRoot(StoreAPI & store, const Path & storePath,
|
||||||
bool indirect, bool allowOutsideRootsDir = false);
|
const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false);
|
||||||
|
|
||||||
|
|
||||||
/* Sort a set of paths topologically under the references relation.
|
/* Sort a set of paths topologically under the references relation.
|
||||||
If p refers to q, then p follows q in this list. */
|
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
|
/* For now, there is a single global store API object, but we'll
|
||||||
|
|
|
@ -381,7 +381,7 @@ static void queryInstSources(EvalState & state,
|
||||||
|
|
||||||
if (isDerivation(path)) {
|
if (isDerivation(path)) {
|
||||||
elem.setDrvPath(path);
|
elem.setDrvPath(path);
|
||||||
elem.setOutPath(findOutput(derivationFromPath(path), "out"));
|
elem.setOutPath(findOutput(derivationFromPath(*store, path), "out"));
|
||||||
if (name.size() >= drvExtension.size() &&
|
if (name.size() >= drvExtension.size() &&
|
||||||
string(name, name.size() - drvExtension.size()) == drvExtension)
|
string(name, name.size() - drvExtension.size()) == drvExtension)
|
||||||
name = string(name, 0, name.size() - drvExtension.size());
|
name = string(name, 0, name.size() - drvExtension.size());
|
||||||
|
@ -430,7 +430,7 @@ static void printMissing(EvalState & state, const DrvInfos & elems)
|
||||||
targets.insert(i->queryOutPath(state));
|
targets.insert(i->queryOutPath(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
printMissing(targets);
|
printMissing(*store, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -693,12 +693,12 @@ static void opSet(Globals & globals,
|
||||||
|
|
||||||
if (drv.queryDrvPath(globals.state) != "") {
|
if (drv.queryDrvPath(globals.state) != "") {
|
||||||
PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state));
|
PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state));
|
||||||
printMissing(paths);
|
printMissing(*store, paths);
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
store->buildDerivations(paths);
|
store->buildDerivations(paths);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printMissing(singleton<PathSet>(drv.queryOutPath(globals.state)));
|
printMissing(*store, singleton<PathSet>(drv.queryOutPath(globals.state)));
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
store->ensurePath(drv.queryOutPath(globals.state));
|
store->ensurePath(drv.queryOutPath(globals.state));
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ Path createGeneration(Path profile, Path outPath)
|
||||||
user environment etc. we've just built. */
|
user environment etc. we've just built. */
|
||||||
Path generation;
|
Path generation;
|
||||||
makeName(profile, num + 1, generation);
|
makeName(profile, num + 1, generation);
|
||||||
addPermRoot(outPath, generation, false, true);
|
addPermRoot(*store, outPath, generation, false, true);
|
||||||
|
|
||||||
return generation;
|
return generation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,8 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
printGCWarning();
|
printGCWarning();
|
||||||
else
|
else
|
||||||
drvPath = addPermRoot(drvPath,
|
drvPath = addPermRoot(*store, drvPath,
|
||||||
makeRootName(gcRoot, rootNr),
|
makeRootName(gcRoot, rootNr), indirectRoot);
|
||||||
indirectRoot);
|
|
||||||
std::cout << format("%1%\n") % drvPath;
|
std::cout << format("%1%\n") % drvPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,14 +58,13 @@ static Path realisePath(const Path & path)
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
paths.insert(path);
|
paths.insert(path);
|
||||||
store->buildDerivations(paths);
|
store->buildDerivations(paths);
|
||||||
Path outPath = findOutput(derivationFromPath(path), "out");
|
Path outPath = findOutput(derivationFromPath(*store, path), "out");
|
||||||
|
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
printGCWarning();
|
printGCWarning();
|
||||||
else
|
else
|
||||||
outPath = addPermRoot(outPath,
|
outPath = addPermRoot(*store, outPath,
|
||||||
makeRootName(gcRoot, rootNr),
|
makeRootName(gcRoot, rootNr), indirectRoot);
|
||||||
indirectRoot);
|
|
||||||
|
|
||||||
return outPath;
|
return outPath;
|
||||||
} else {
|
} else {
|
||||||
|
@ -87,7 +86,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
||||||
foreach (Strings::iterator, i, opArgs)
|
foreach (Strings::iterator, i, opArgs)
|
||||||
*i = followLinksToStorePath(*i);
|
*i = followLinksToStorePath(*i);
|
||||||
|
|
||||||
printMissing(PathSet(opArgs.begin(), opArgs.end()));
|
printMissing(*store, PathSet(opArgs.begin(), opArgs.end()));
|
||||||
|
|
||||||
if (dryRun) return;
|
if (dryRun) return;
|
||||||
|
|
||||||
|
@ -170,7 +169,7 @@ static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRea
|
||||||
{
|
{
|
||||||
if (forceRealise) realisePath(storePath);
|
if (forceRealise) realisePath(storePath);
|
||||||
if (useOutput && isDerivation(storePath)) {
|
if (useOutput && isDerivation(storePath)) {
|
||||||
Derivation drv = derivationFromPath(storePath);
|
Derivation drv = derivationFromPath(*store, storePath);
|
||||||
return findOutput(drv, "out");
|
return findOutput(drv, "out");
|
||||||
}
|
}
|
||||||
else return storePath;
|
else return storePath;
|
||||||
|
@ -210,7 +209,7 @@ static void printTree(const Path & path,
|
||||||
closure(B). That is, if derivation A is an (possibly indirect)
|
closure(B). That is, if derivation A is an (possibly indirect)
|
||||||
input of B, then A is printed first. This has the effect of
|
input of B, then A is printed first. This has the effect of
|
||||||
flattening the tree, preventing deeply nested structures. */
|
flattening the tree, preventing deeply nested structures. */
|
||||||
Paths sorted = topoSortPaths(references);
|
Paths sorted = topoSortPaths(*store, references);
|
||||||
reverse(sorted.begin(), sorted.end());
|
reverse(sorted.begin(), sorted.end());
|
||||||
|
|
||||||
for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i) {
|
for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i) {
|
||||||
|
@ -265,7 +264,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
*i = followLinksToStorePath(*i);
|
*i = followLinksToStorePath(*i);
|
||||||
if (forceRealise) realisePath(*i);
|
if (forceRealise) realisePath(*i);
|
||||||
Derivation drv = derivationFromPath(*i);
|
Derivation drv = derivationFromPath(*store, *i);
|
||||||
cout << format("%1%\n") % findOutput(drv, "out");
|
cout << format("%1%\n") % findOutput(drv, "out");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -278,12 +277,12 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
|
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
if (query == qRequisites) computeFSClosure(path, paths, false, includeOutputs);
|
if (query == qRequisites) computeFSClosure(*store, path, paths, false, includeOutputs);
|
||||||
else if (query == qReferences) store->queryReferences(path, paths);
|
else if (query == qReferences) store->queryReferences(path, paths);
|
||||||
else if (query == qReferrers) store->queryReferrers(path, paths);
|
else if (query == qReferrers) store->queryReferrers(path, paths);
|
||||||
else if (query == qReferrersClosure) computeFSClosure(path, paths, true);
|
else if (query == qReferrersClosure) computeFSClosure(*store, path, paths, true);
|
||||||
}
|
}
|
||||||
Paths sorted = topoSortPaths(paths);
|
Paths sorted = topoSortPaths(*store, paths);
|
||||||
for (Paths::reverse_iterator i = sorted.rbegin();
|
for (Paths::reverse_iterator i = sorted.rbegin();
|
||||||
i != sorted.rend(); ++i)
|
i != sorted.rend(); ++i)
|
||||||
cout << format("%s\n") % *i;
|
cout << format("%s\n") % *i;
|
||||||
|
@ -301,7 +300,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qBinding:
|
case qBinding:
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
Path path = useDeriver(followLinksToStorePath(*i));
|
Path path = useDeriver(followLinksToStorePath(*i));
|
||||||
Derivation drv = derivationFromPath(path);
|
Derivation drv = derivationFromPath(*store, path);
|
||||||
StringPairs::iterator j = drv.env.find(bindingName);
|
StringPairs::iterator j = drv.env.find(bindingName);
|
||||||
if (j == drv.env.end())
|
if (j == drv.env.end())
|
||||||
throw Error(format("derivation `%1%' has no environment binding named `%2%'")
|
throw Error(format("derivation `%1%' has no environment binding named `%2%'")
|
||||||
|
@ -355,7 +354,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qRoots: {
|
case qRoots: {
|
||||||
PathSet referrers;
|
PathSet referrers;
|
||||||
foreach (Strings::iterator, i, opArgs)
|
foreach (Strings::iterator, i, opArgs)
|
||||||
computeFSClosure(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise),
|
computeFSClosure(*store,
|
||||||
|
maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise),
|
||||||
referrers, true);
|
referrers, true);
|
||||||
Roots roots = store->findRoots();
|
Roots roots = store->findRoots();
|
||||||
foreach (Roots::iterator, i, roots)
|
foreach (Roots::iterator, i, roots)
|
||||||
|
|
Loading…
Reference in a new issue