* A command `nix-store --query --roots <paths>' to find the garbage

collector roots that point (directly or indirectly) to the given
  paths.
This commit is contained in:
Eelco Dolstra 2009-11-23 18:16:25 +00:00
parent ae6bf87273
commit 3d55f1eb57
3 changed files with 53 additions and 32 deletions

View file

@ -404,6 +404,7 @@ error: cannot delete path `/nix/store/zq0h41l75vlb4z45kzgjjmsjxvcv1qk7-mesa-6.4'
<arg choice='plain'><option>--tree</option></arg> <arg choice='plain'><option>--tree</option></arg>
<arg choice='plain'><option>--binding</option> <replaceable>name</replaceable></arg> <arg choice='plain'><option>--binding</option> <replaceable>name</replaceable></arg>
<arg choice='plain'><option>--hash</option></arg> <arg choice='plain'><option>--hash</option></arg>
<arg choice='plain'><option>--roots</option></arg>
</group> </group>
<arg><option>--use-output</option></arg> <arg><option>--use-output</option></arg>
<arg><option>-u</option></arg> <arg><option>-u</option></arg>
@ -586,12 +587,20 @@ query is applied to the target of the symlink.</para>
<varlistentry><term><option>--hash</option></term> <varlistentry><term><option>--hash</option></term>
<listitem><para>Prints the SHA-256 hash of the contents of the <listitem><para>Prints the SHA-256 hash of the contents of the
store path <replaceable>paths</replaceable>. Since the hash is store paths <replaceable>paths</replaceable>. Since the hash is
stored in the Nix database, this is a fast stored in the Nix database, this is a fast
operation.</para></listitem> operation.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry><term><option>--roots</option></term>
<listitem><para>Prints the garbage collector roots that point,
directly or indirectly, at the store paths
<replaceable>paths</replaceable>.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsection> </refsection>
@ -669,6 +678,18 @@ $ gv graph.ps</screen>
</para> </para>
<para>Show every garbage collector root that points to a store path
that depends on <command>svn</command>:
<screen>
$ nix-store -q --roots $(which svn)
/nix/var/nix/profiles/default-81-link
/nix/var/nix/profiles/default-82-link
/nix/var/nix/profiles/per-user/eelco/profile-97-link
</screen>
</para>
</refsection> </refsection>

View file

@ -24,7 +24,6 @@ Operations:
--import: import a path from a Nix archive, and register as --import: import a path from a Nix archive, and register as
valid valid
--init: initialise the Nix database
--verify: verify Nix structures --verify: verify Nix structures
--optimise: optimise the Nix store by hard-linking identical files --optimise: optimise the Nix store by hard-linking identical files
@ -34,12 +33,14 @@ Operations:
Query flags: Query flags:
--outputs: query the output paths of a Nix derivation (default) --outputs: query the output paths of a Nix derivation (default)
--requisites / -R: print all paths necessary to realise a path --requisites / -R: print all paths necessary to realise the path
--references: print all paths referenced by the given path --references: print all paths referenced by the path
--referrers: print all paths directly refering to the given path --referrers: print all paths directly refering to the path
--referrers-closure: print all paths (in)directly refering to the given path --referrers-closure: print all paths (in)directly refering to the path
--tree: print a tree showing the dependency graph of the given paths --tree: print a tree showing the dependency graph of the path
--graph: print a dot graph rooted at given paths --graph: print a dot graph rooted at given path
--hash: print the SHA-256 hash of the contents of the path
--roots: print the garbage collector roots that point to the path
Query switches (not applicable to all queries): Query switches (not applicable to all queries):

View file

@ -261,14 +261,13 @@ static void opQuery(Strings opFlags, Strings opArgs)
{ {
enum { qOutputs, qRequisites, qReferences, qReferrers enum { qOutputs, qRequisites, qReferences, qReferrers
, qReferrersClosure, qDeriver, qBinding, qHash , qReferrersClosure, qDeriver, qBinding, qHash
, qTree, qGraph, qResolve } query = qOutputs; , qTree, qGraph, qResolve, qRoots } query = qOutputs;
bool useOutput = false; bool useOutput = false;
bool includeOutputs = false; bool includeOutputs = false;
bool forceRealise = false; bool forceRealise = false;
string bindingName; string bindingName;
for (Strings::iterator i = opFlags.begin(); foreach (Strings::iterator, i, opFlags)
i != opFlags.end(); ++i)
if (*i == "--outputs") query = qOutputs; if (*i == "--outputs") query = qOutputs;
else if (*i == "--requisites" || *i == "-R") query = qRequisites; else if (*i == "--requisites" || *i == "-R") query = qRequisites;
else if (*i == "--references") query = qReferences; else if (*i == "--references") query = qReferences;
@ -286,6 +285,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
else if (*i == "--tree") query = qTree; else if (*i == "--tree") query = qTree;
else if (*i == "--graph") query = qGraph; else if (*i == "--graph") query = qGraph;
else if (*i == "--resolve") query = qResolve; else if (*i == "--resolve") query = qResolve;
else if (*i == "--roots") query = qRoots;
else if (*i == "--use-output" || *i == "-u") useOutput = true; else if (*i == "--use-output" || *i == "-u") useOutput = true;
else if (*i == "--force-realise" || *i == "-f") forceRealise = true; else if (*i == "--force-realise" || *i == "-f") forceRealise = true;
else if (*i == "--include-outputs") includeOutputs = true; else if (*i == "--include-outputs") includeOutputs = true;
@ -294,9 +294,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
switch (query) { switch (query) {
case qOutputs: { case qOutputs: {
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs) {
i != opArgs.end(); ++i)
{
*i = followLinksToStorePath(*i); *i = followLinksToStorePath(*i);
if (forceRealise) realisePath(*i); if (forceRealise) realisePath(*i);
Derivation drv = derivationFromPath(*i); Derivation drv = derivationFromPath(*i);
@ -310,9 +308,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qReferrers: case qReferrers:
case qReferrersClosure: { case qReferrersClosure: {
PathSet paths; PathSet paths;
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs) {
i != opArgs.end(); ++i)
{
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise); Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
if (query == qRequisites) if (query == qRequisites)
storePathRequisites(path, includeOutputs, paths); storePathRequisites(path, includeOutputs, paths);
@ -328,9 +324,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
} }
case qDeriver: case qDeriver:
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs) {
i != opArgs.end(); ++i)
{
Path deriver = store->queryDeriver(followLinksToStorePath(*i)); Path deriver = store->queryDeriver(followLinksToStorePath(*i));
cout << format("%1%\n") % cout << format("%1%\n") %
(deriver == "" ? "unknown-deriver" : deriver); (deriver == "" ? "unknown-deriver" : deriver);
@ -338,9 +332,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
break; break;
case qBinding: case qBinding:
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs) {
i != opArgs.end(); ++i)
{
Path path = useDeriver(followLinksToStorePath(*i)); Path path = useDeriver(followLinksToStorePath(*i));
Derivation drv = derivationFromPath(path); Derivation drv = derivationFromPath(path);
StringPairs::iterator j = drv.env.find(bindingName); StringPairs::iterator j = drv.env.find(bindingName);
@ -352,9 +344,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
break; break;
case qHash: case qHash:
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs) {
i != opArgs.end(); ++i)
{
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise); Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
Hash hash = store->queryPathHash(path); Hash hash = store->queryPathHash(path);
assert(hash.type == htSHA256); assert(hash.type == htSHA256);
@ -364,28 +354,37 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qTree: { case qTree: {
PathSet done; PathSet done;
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs)
i != opArgs.end(); ++i)
printTree(followLinksToStorePath(*i), "", "", done); printTree(followLinksToStorePath(*i), "", "", done);
break; break;
} }
case qGraph: { case qGraph: {
PathSet roots; PathSet roots;
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs)
i != opArgs.end(); ++i)
roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise)); roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise));
printDotGraph(roots); printDotGraph(roots);
break; break;
} }
case qResolve: { case qResolve: {
for (Strings::iterator i = opArgs.begin(); foreach (Strings::iterator, i, opArgs)
i != opArgs.end(); ++i)
cout << format("%1%\n") % followLinksToStorePath(*i); cout << format("%1%\n") % followLinksToStorePath(*i);
break; break;
} }
case qRoots: {
PathSet referrers;
foreach (Strings::iterator, i, opArgs)
computeFSClosure(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise),
referrers, true);
Roots roots = store->findRoots();
foreach (Roots::iterator, i, roots)
if (referrers.find(i->second) != referrers.end())
cout << format("%1%\n") % i->first;
break;
}
default: default:
abort(); abort();
} }