* `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>
<refnamediv>
<refname>nix-collect-garbage</refname>
<refpurpose>determine the set of unreachable store paths</refpurpose>
<refpurpose>remove unreachable store paths</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-collect-garbage</command>
<arg><option>--invert</option></arg>
<arg><option>--no-successors</option></arg>
<group choice='opt'>
<arg choice='plain'><option>--print-live</option></arg>
<arg choice='plain'><option>--print-dead</option></arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
@ -16,10 +18,22 @@
<title>Description</title>
<para>
The command <command>nix-collect-garbage</command> determines
the paths in the Nix store that are garbage, that is, not
reachable from outside of the store. These paths can be safely
deleted without affecting the integrity of the system.
The command <command>nix-collect-garbage</command> performs a
garbage collection on the Nix store: any paths in the Nix store
that are garbage (not reachable from a set of root store
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>
</refsection>
@ -30,27 +44,14 @@
<variablelist>
<varlistentry>
<term><option>--invert</option></term>
<term><option>--print-live</option> / <option>--print-dead</option></term>
<listitem>
<para>
Causes the set of <emphasis>reachable</emphasis> paths to
be printed, rather than the unreachable paths. These are
the paths that may <emphasis>not</emphasis> be deleted.
</para>
</listitem>
</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.
These options cause the set of live or dead paths to be
printed, respectively, rather than performing an actual
garbage collector. They correspond exactly with the
sub-operations in <command>nix-store
<option>--gc</option></command>.
</para>
</listitem>
</varlistentry>
@ -63,10 +64,10 @@
<title>Examples</title>
<para>
To delete all unreachable paths, do the following:
To delete all unreachable paths, just do:
<screen>
$ nix-collect-garbage | xargs nix-store --delete</screen>
$ nix-collect-garbage</screen>
</para>

View file

@ -135,17 +135,18 @@
<!--######################################################################-->
<refsection>
<title>Operation <option>--delete</option></title>
<title>Operation <option>--gc</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--gc</option></arg>
<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>-d</option></arg>
</group>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
@ -153,19 +154,64 @@
<title>Description</title>
<para>
The operation <option>--delete</option> unconditionally deletes the
paths <replaceable>paths</replaceable> from the Nix store. It is an
error to attempt to delete paths outside of the store.
The operation <option>--gc</option> performs a garbage
collection on the Nix store. What it does specifically is
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>
<warning>
<para>
This operation should almost never be called directly, since no
attempt is made to verify that no references exist to the paths to
be deleted. Therefore, careless deletion can result in an
inconsistent system. Deletion of paths in the store is done by the
garbage collector (which uses <option>--delete</option> to delete
unreferenced paths).
You generally will want to use the command
<command>nix-collect-garbage</command>, which figures out
the roots and then calls this command automatically.
</para>
</warning>

View file

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

View file

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

View file

@ -222,7 +222,7 @@ static void opGC(Strings opFlags, Strings opArgs)
if (flag == "--print-live") subOp = soPrintLive;
else if (flag == "--print-dead") subOp = soPrintDead;
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;
while (1) {