* `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:
parent
818047881e
commit
fdec72c6cc
5 changed files with 102 additions and 73 deletions
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
— 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>
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue