* `nix-collect-garbage' now actually performs a garbage collection, it

doesn't just print the set of paths that should be deleted.  So
  there is no more need to pipe the result into `nix-store --delete'
  (which doesn't even exist anymore).
This commit is contained in:
Eelco Dolstra 2004-08-25 15:39:13 +00:00
parent 818047881e
commit fdec72c6cc
5 changed files with 102 additions and 73 deletions

View file

@ -1,14 +1,16 @@
<refentry> <refentry>
<refnamediv> <refnamediv>
<refname>nix-collect-garbage</refname> <refname>nix-collect-garbage</refname>
<refpurpose>determine the set of unreachable store paths</refpurpose> <refpurpose>remove unreachable store paths</refpurpose>
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<cmdsynopsis> <cmdsynopsis>
<command>nix-collect-garbage</command> <command>nix-collect-garbage</command>
<arg><option>--invert</option></arg> <group choice='opt'>
<arg><option>--no-successors</option></arg> <arg choice='plain'><option>--print-live</option></arg>
<arg choice='plain'><option>--print-dead</option></arg>
</group>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -16,10 +18,22 @@
<title>Description</title> <title>Description</title>
<para> <para>
The command <command>nix-collect-garbage</command> determines The command <command>nix-collect-garbage</command> performs a
the paths in the Nix store that are garbage, that is, not garbage collection on the Nix store: any paths in the Nix store
reachable from outside of the store. These paths can be safely that are garbage (not reachable from a set of root store
deleted without affecting the integrity of the system. expressions) are deleted.
</para>
<para>
The roots of the garbage collector are the store expressions
mentioned in the files in the directory
<filename><replaceable>prefix</replaceable>/var/nix/gcroots</filename>.
By default, the roots are all user environments in
<filename><replaceable>prefix</replaceable>/var/nix/profiles</filename>.
You can register other store expressions as roots by writing the
full path of the store expression to an arbitrary file in the
<filename>gcroots</filename> directory (or a subdirectory
thereof).
</para> </para>
</refsection> </refsection>
@ -30,27 +44,14 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><option>--invert</option></term> <term><option>--print-live</option> / <option>--print-dead</option></term>
<listitem> <listitem>
<para> <para>
Causes the set of <emphasis>reachable</emphasis> paths to These options cause the set of live or dead paths to be
be printed, rather than the unreachable paths. These are printed, respectively, rather than performing an actual
the paths that may <emphasis>not</emphasis> be deleted. garbage collector. They correspond exactly with the
</para> sub-operations in <command>nix-store
</listitem> <option>--gc</option></command>.
</varlistentry>
<varlistentry>
<term><option>--no-successors</option></term>
<listitem>
<para>
Causes <command>nix-collect-garbage</command> not to
follow successor relations. By default, if a derivation
store expression is reachable, its successor (i.e., a
closure store expression) is also considered to be
reachable. This option is always safe, but garbage
collecting successors may cause undesirable rebuilds later
on.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -63,10 +64,10 @@
<title>Examples</title> <title>Examples</title>
<para> <para>
To delete all unreachable paths, do the following: To delete all unreachable paths, just do:
<screen> <screen>
$ nix-collect-garbage | xargs nix-store --delete</screen> $ nix-collect-garbage</screen>
</para> </para>

View file

@ -135,17 +135,18 @@
<!--######################################################################--> <!--######################################################################-->
<refsection> <refsection>
<title>Operation <option>--delete</option></title> <title>Operation <option>--gc</option></title>
<refsection> <refsection>
<title>Synopsis</title> <title>Synopsis</title>
<cmdsynopsis> <cmdsynopsis>
<command>nix-store</command> <command>nix-store</command>
<arg choice='plain'><option>--gc</option></arg>
<group choice='req'> <group choice='req'>
<arg choice='plain'><option>--print-live</option></arg>
<arg choice='plain'><option>--print-dead</option></arg>
<arg choice='plain'><option>--delete</option></arg> <arg choice='plain'><option>--delete</option></arg>
<arg choice='plain'><option>-d</option></arg>
</group> </group>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
</refsection> </refsection>
@ -153,19 +154,64 @@
<title>Description</title> <title>Description</title>
<para> <para>
The operation <option>--delete</option> unconditionally deletes the The operation <option>--gc</option> performs a garbage
paths <replaceable>paths</replaceable> from the Nix store. It is an collection on the Nix store. What it does specifically is
error to attempt to delete paths outside of the store. determined by the sub-operation, which is one of the
following:
</para>
<variablelist>
<varlistentry>
<term><option>--print-live</option></term>
<listitem>
<para>
This operation prints on standard output the set of
<quote>live</quote> store paths, which are all the store
paths reachable from a set of <quote>root</quote> store
expressions read from standard input. Live paths should
never be deleted, since that would break consistency
&mdash; it would become possible that applications are
installed that reference things that are no longer
present in the store.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--print-dead</option></term>
<listitem>
<para>
This operation prints out on standard output the set of
<quote>dead</quote> store paths, which is just the
opposite of the set of live paths: any path in the store
that is not live (with respect to the roots) is dead.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--delete</option></term>
<listitem>
<para>
This operation performs an actual garbage collection.
All dead paths are removed from the store.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The set of root store expressions is read from standard input.
Each line should contain exactly one store path.
</para> </para>
<warning> <warning>
<para> <para>
This operation should almost never be called directly, since no You generally will want to use the command
attempt is made to verify that no references exist to the paths to <command>nix-collect-garbage</command>, which figures out
be deleted. Therefore, careless deletion can result in an the roots and then calls this command automatically.
inconsistent system. Deletion of paths in the store is done by the
garbage collector (which uses <option>--delete</option> to delete
unreferenced paths).
</para> </para>
</warning> </warning>

View file

@ -131,7 +131,7 @@ $ nix-env -uBf nixpkgs-<replaceable>version</replaceable>/ '*'</screen>
actual delete them: actual delete them:
<screen> <screen>
$ nix-collect-garbage | xargs nix-store --delete</screen> $ nix-collect-garbage</screen>
</para> </para>
</listitem> </listitem>

View file

@ -8,17 +8,17 @@ my $storeDir = "@storedir@";
my %alive; my %alive;
my $gcOper = "--delete";
my $keepSuccessors = 1; my $keepSuccessors = 1;
my $invert = 0;
my @roots = (); my @roots = ();
# Parse the command line. # Parse the command line.
foreach my $arg (@ARGV) { foreach my $arg (@ARGV) {
if ($arg eq "--no-successors") { $keepSuccessors = 0; } if ($arg eq "--delete" || $arg eq "--print-live" || $arg eq "--print-dead") {
elsif ($arg eq "--invert") { $invert = 1; } $gcOper = $arg;
else { die "unknown argument `$arg'" }; } else { die "unknown argument `$arg'" };
} }
@ -68,33 +68,15 @@ sub findRoots {
findRoots 1, $rootsDir; findRoots 1, $rootsDir;
# Determine all store paths reachable from the roots. # Run the collector with the roots we found.
my $extraarg = ""; my $pid = open2(">&1", \*WRITE, "@bindir@/nix-store --gc $gcOper")
if ($keepSuccessors) { $extraarg = "--include-successors"; }; or die "cannot run `nix-store --gc'";
my $pid = open2(\*READ, \*WRITE, "@bindir@/nix-store --query --requisites $extraarg @roots")
or die "determining live paths"; foreach my $root (@roots) {
close WRITE; print WRITE "$root\n";
while (<READ>) {
chomp;
$alive{$_} = 1;
if ($invert) { print "$_\n"; };
} }
close READ;
close WRITE;
waitpid $pid, 0; waitpid $pid, 0;
$? == 0 or die "determining live paths"; $? == 0 or die "`nix-store --gc' failed";
exit 0 if ($invert);
# Using that information, find all store paths *not* reachable from
# the roots.
opendir(DIR, $storeDir) or die "cannot open directory $storeDir: $!";
foreach my $name (readdir DIR) {
next if ($name eq "." || $name eq "..");
$name = "$storeDir/$name";
if (!$alive{$name}) {
print "$name\n";
}
}
closedir DIR;

View file

@ -222,7 +222,7 @@ static void opGC(Strings opFlags, Strings opArgs)
if (flag == "--print-live") subOp = soPrintLive; if (flag == "--print-live") subOp = soPrintLive;
else if (flag == "--print-dead") subOp = soPrintDead; else if (flag == "--print-dead") subOp = soPrintDead;
else if (flag == "--delete") subOp = soDelete; else if (flag == "--delete") subOp = soDelete;
else throw UsageError(format("bad sub-operation `%1% in GC") % flag); else throw UsageError(format("bad sub-operation `%1%' in GC") % flag);
Paths roots; Paths roots;
while (1) { while (1) {