aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstore/local-store.hh4
-rw-r--r--src/libstore/misc.cc54
-rw-r--r--src/libstore/misc.hh4
-rw-r--r--src/libstore/remote-store.cc10
-rw-r--r--src/libstore/remote-store.hh2
-rw-r--r--src/libstore/store-api.hh6
-rw-r--r--src/libstore/worker-protocol.hh3
-rw-r--r--src/nix-daemon/nix-daemon.cc3
-rw-r--r--src/nix-store/nix-store.cc3
9 files changed, 64 insertions, 25 deletions
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index bb5a9143c..82ca791a3 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -111,10 +111,6 @@ public:
Path queryDeriver(const Path & path);
- /* Return all currently valid derivations that have `path' as an
- output. (Note that the result of `queryDeriver()' is the
- derivation that was actually used to produce `path', which may
- not exist anymore.) */
PathSet queryValidDerivers(const Path & path);
PathSet queryDerivationOutputs(const Path & path);
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 899e4764c..74ff26b9c 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -15,27 +15,47 @@ Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
}
-void computeFSClosure(StoreAPI & store, const Path & storePath,
- PathSet & paths, bool flipDirection, bool includeOutputs)
+void computeFSClosure(StoreAPI & store, const Path & path,
+ PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
{
- if (paths.find(storePath) != paths.end()) return;
- paths.insert(storePath);
+ if (paths.find(path) != paths.end()) return;
+ paths.insert(path);
- PathSet references;
- if (flipDirection)
- store.queryReferrers(storePath, references);
- else
- store.queryReferences(storePath, references);
-
- if (includeOutputs && isDerivation(storePath)) {
- PathSet outputs = store.queryDerivationOutputs(storePath);
- foreach (PathSet::iterator, i, outputs)
- if (store.isValidPath(*i))
- computeFSClosure(store, *i, paths, flipDirection, true);
+ PathSet edges;
+
+ if (flipDirection) {
+ store.queryReferrers(path, edges);
+
+ if (includeOutputs) {
+ PathSet derivers = store.queryValidDerivers(path);
+ foreach (PathSet::iterator, i, derivers)
+ edges.insert(*i);
+ }
+
+ if (includeDerivers && isDerivation(path)) {
+ PathSet outputs = store.queryDerivationOutputs(path);
+ foreach (PathSet::iterator, i, outputs)
+ if (store.isValidPath(*i) && store.queryDeriver(*i) == path)
+ edges.insert(*i);
+ }
+
+ } else {
+ store.queryReferences(path, edges);
+
+ if (includeOutputs && isDerivation(path)) {
+ PathSet outputs = store.queryDerivationOutputs(path);
+ foreach (PathSet::iterator, i, outputs)
+ if (store.isValidPath(*i)) edges.insert(*i);
+ }
+
+ if (includeDerivers) {
+ Path deriver = store.queryDeriver(path);
+ if (store.isValidPath(deriver)) edges.insert(deriver);
+ }
}
- foreach (PathSet::iterator, i, references)
- computeFSClosure(store, *i, paths, flipDirection, includeOutputs);
+ foreach (PathSet::iterator, i, edges)
+ computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers);
}
diff --git a/src/libstore/misc.hh b/src/libstore/misc.hh
index fe0bbdd79..b4bd9ed8a 100644
--- a/src/libstore/misc.hh
+++ b/src/libstore/misc.hh
@@ -17,9 +17,9 @@ Derivation derivationFromPath(StoreAPI & store, const Path & drvPath);
`storePath' is returned; that is, the closures under the
`referrers' relation instead of the `references' relation is
returned. */
-void computeFSClosure(StoreAPI & store, const Path & storePath,
+void computeFSClosure(StoreAPI & store, const Path & path,
PathSet & paths, bool flipDirection = false,
- bool includeOutputs = false);
+ bool includeOutputs = false, bool includeDerivers = false);
/* Return the path corresponding to the output identifier `id' in the
given derivation. */
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index c97c5fbf0..8f33b7e5c 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -334,6 +334,16 @@ Path RemoteStore::queryDeriver(const Path & path)
}
+PathSet RemoteStore::queryValidDerivers(const Path & path)
+{
+ openConnection();
+ writeInt(wopQueryValidDerivers, to);
+ writeString(path, to);
+ processStderr();
+ return readStorePaths<PathSet>(from);
+}
+
+
PathSet RemoteStore::queryDerivationOutputs(const Path & path)
{
openConnection();
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 47c822969..14253b92c 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -40,6 +40,8 @@ public:
Path queryDeriver(const Path & path);
+ PathSet queryValidDerivers(const Path & path);
+
PathSet queryDerivationOutputs(const Path & path);
StringSet queryDerivationOutputNames(const Path & path);
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index cbbacc12c..053bece7a 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -133,6 +133,12 @@ public:
no deriver has been set. */
virtual Path queryDeriver(const Path & path) = 0;
+ /* Return all currently valid derivations that have `path' as an
+ output. (Note that the result of `queryDeriver()' is the
+ derivation that was actually used to produce `path', which may
+ not exist anymore.) */
+ virtual PathSet queryValidDerivers(const Path & path) = 0;
+
/* Query the outputs of the derivation denoted by `path'. */
virtual PathSet queryDerivationOutputs(const Path & path) = 0;
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index 7e4c3ec5f..46035f457 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -6,7 +6,7 @@ namespace nix {
#define WORKER_MAGIC_1 0x6e697863
#define WORKER_MAGIC_2 0x6478696f
-#define PROTOCOL_VERSION 0x10c
+#define PROTOCOL_VERSION 0x10d
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
@@ -42,6 +42,7 @@ typedef enum {
wopQuerySubstitutablePathInfos = 30,
wopQueryValidPaths = 31,
wopQuerySubstitutablePaths = 32,
+ wopQueryValidDerivers = 33,
} WorkerOp;
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 9b3c5bda1..35e5c546e 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -334,6 +334,7 @@ static void performOp(unsigned int clientVersion,
case wopQueryReferences:
case wopQueryReferrers:
+ case wopQueryValidDerivers:
case wopQueryDerivationOutputs: {
Path path = readStorePath(from);
startWork();
@@ -342,6 +343,8 @@ static void performOp(unsigned int clientVersion,
store->queryReferences(path, paths);
else if (op == wopQueryReferrers)
store->queryReferrers(path, paths);
+ else if (op == wopQueryValidDerivers)
+ paths = store->queryValidDerivers(path);
else paths = store->queryDerivationOutputs(path);
stopWork();
writeStrings(paths, to);
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index c0da37d25..af4f264a6 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -404,7 +404,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
foreach (Strings::iterator, i, opArgs) {
PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
foreach (PathSet::iterator, j, paths)
- computeFSClosure(*store, *j, referrers, true);
+ computeFSClosure(*store, *j, referrers, true,
+ settings.gcKeepOutputs, settings.gcKeepDerivations);
}
Roots roots = store->findRoots();
foreach (Roots::iterator, i, roots)