Skip to content

Commit 2754a07

Browse files
committed
nix-store -q --roots: Respect the gc-keep-outputs/gc-keep-derivations settings
So if a path is not garbage solely because it's reachable from a root due to the gc-keep-outputs or gc-keep-derivations settings, ‘nix-store -q --roots’ now shows that root.
1 parent 06f62de commit 2754a07

File tree

9 files changed

+64
-25
lines changed

9 files changed

+64
-25
lines changed

src/libstore/local-store.hh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,6 @@ public:
111111

112112
Path queryDeriver(const Path & path);
113113

114-
/* Return all currently valid derivations that have `path' as an
115-
output. (Note that the result of `queryDeriver()' is the
116-
derivation that was actually used to produce `path', which may
117-
not exist anymore.) */
118114
PathSet queryValidDerivers(const Path & path);
119115

120116
PathSet queryDerivationOutputs(const Path & path);

src/libstore/misc.cc

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,47 @@ Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
1515
}
1616

1717

18-
void computeFSClosure(StoreAPI & store, const Path & storePath,
19-
PathSet & paths, bool flipDirection, bool includeOutputs)
18+
void computeFSClosure(StoreAPI & store, const Path & path,
19+
PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
2020
{
21-
if (paths.find(storePath) != paths.end()) return;
22-
paths.insert(storePath);
21+
if (paths.find(path) != paths.end()) return;
22+
paths.insert(path);
2323

24-
PathSet references;
25-
if (flipDirection)
26-
store.queryReferrers(storePath, references);
27-
else
28-
store.queryReferences(storePath, references);
29-
30-
if (includeOutputs && isDerivation(storePath)) {
31-
PathSet outputs = store.queryDerivationOutputs(storePath);
32-
foreach (PathSet::iterator, i, outputs)
33-
if (store.isValidPath(*i))
34-
computeFSClosure(store, *i, paths, flipDirection, true);
24+
PathSet edges;
25+
26+
if (flipDirection) {
27+
store.queryReferrers(path, edges);
28+
29+
if (includeOutputs) {
30+
PathSet derivers = store.queryValidDerivers(path);
31+
foreach (PathSet::iterator, i, derivers)
32+
edges.insert(*i);
33+
}
34+
35+
if (includeDerivers && isDerivation(path)) {
36+
PathSet outputs = store.queryDerivationOutputs(path);
37+
foreach (PathSet::iterator, i, outputs)
38+
if (store.isValidPath(*i) && store.queryDeriver(*i) == path)
39+
edges.insert(*i);
40+
}
41+
42+
} else {
43+
store.queryReferences(path, edges);
44+
45+
if (includeOutputs && isDerivation(path)) {
46+
PathSet outputs = store.queryDerivationOutputs(path);
47+
foreach (PathSet::iterator, i, outputs)
48+
if (store.isValidPath(*i)) edges.insert(*i);
49+
}
50+
51+
if (includeDerivers) {
52+
Path deriver = store.queryDeriver(path);
53+
if (store.isValidPath(deriver)) edges.insert(deriver);
54+
}
3555
}
3656

37-
foreach (PathSet::iterator, i, references)
38-
computeFSClosure(store, *i, paths, flipDirection, includeOutputs);
57+
foreach (PathSet::iterator, i, edges)
58+
computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers);
3959
}
4060

4161

src/libstore/misc.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ Derivation derivationFromPath(StoreAPI & store, const Path & drvPath);
1717
`storePath' is returned; that is, the closures under the
1818
`referrers' relation instead of the `references' relation is
1919
returned. */
20-
void computeFSClosure(StoreAPI & store, const Path & storePath,
20+
void computeFSClosure(StoreAPI & store, const Path & path,
2121
PathSet & paths, bool flipDirection = false,
22-
bool includeOutputs = false);
22+
bool includeOutputs = false, bool includeDerivers = false);
2323

2424
/* Return the path corresponding to the output identifier `id' in the
2525
given derivation. */

src/libstore/remote-store.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,16 @@ Path RemoteStore::queryDeriver(const Path & path)
334334
}
335335

336336

337+
PathSet RemoteStore::queryValidDerivers(const Path & path)
338+
{
339+
openConnection();
340+
writeInt(wopQueryValidDerivers, to);
341+
writeString(path, to);
342+
processStderr();
343+
return readStorePaths<PathSet>(from);
344+
}
345+
346+
337347
PathSet RemoteStore::queryDerivationOutputs(const Path & path)
338348
{
339349
openConnection();

src/libstore/remote-store.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public:
4040

4141
Path queryDeriver(const Path & path);
4242

43+
PathSet queryValidDerivers(const Path & path);
44+
4345
PathSet queryDerivationOutputs(const Path & path);
4446

4547
StringSet queryDerivationOutputNames(const Path & path);

src/libstore/store-api.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ public:
133133
no deriver has been set. */
134134
virtual Path queryDeriver(const Path & path) = 0;
135135

136+
/* Return all currently valid derivations that have `path' as an
137+
output. (Note that the result of `queryDeriver()' is the
138+
derivation that was actually used to produce `path', which may
139+
not exist anymore.) */
140+
virtual PathSet queryValidDerivers(const Path & path) = 0;
141+
136142
/* Query the outputs of the derivation denoted by `path'. */
137143
virtual PathSet queryDerivationOutputs(const Path & path) = 0;
138144

src/libstore/worker-protocol.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace nix {
66
#define WORKER_MAGIC_1 0x6e697863
77
#define WORKER_MAGIC_2 0x6478696f
88

9-
#define PROTOCOL_VERSION 0x10c
9+
#define PROTOCOL_VERSION 0x10d
1010
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
1111
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
1212

@@ -42,6 +42,7 @@ typedef enum {
4242
wopQuerySubstitutablePathInfos = 30,
4343
wopQueryValidPaths = 31,
4444
wopQuerySubstitutablePaths = 32,
45+
wopQueryValidDerivers = 33,
4546
} WorkerOp;
4647

4748

src/nix-daemon/nix-daemon.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ static void performOp(unsigned int clientVersion,
334334

335335
case wopQueryReferences:
336336
case wopQueryReferrers:
337+
case wopQueryValidDerivers:
337338
case wopQueryDerivationOutputs: {
338339
Path path = readStorePath(from);
339340
startWork();
@@ -342,6 +343,8 @@ static void performOp(unsigned int clientVersion,
342343
store->queryReferences(path, paths);
343344
else if (op == wopQueryReferrers)
344345
store->queryReferrers(path, paths);
346+
else if (op == wopQueryValidDerivers)
347+
paths = store->queryValidDerivers(path);
345348
else paths = store->queryDerivationOutputs(path);
346349
stopWork();
347350
writeStrings(paths, to);

src/nix-store/nix-store.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
404404
foreach (Strings::iterator, i, opArgs) {
405405
PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
406406
foreach (PathSet::iterator, j, paths)
407-
computeFSClosure(*store, *j, referrers, true);
407+
computeFSClosure(*store, *j, referrers, true,
408+
settings.gcKeepOutputs, settings.gcKeepDerivations);
408409
}
409410
Roots roots = store->findRoots();
410411
foreach (Roots::iterator, i, roots)

0 commit comments

Comments
 (0)