about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/nix-collect-garbage.xml57
-rw-r--r--doc/manual/nix-store.xml70
-rw-r--r--doc/manual/quick-start.xml2
-rwxr-xr-xscripts/nix-collect-garbage.in44
-rw-r--r--src/nix-store/main.cc2
5 files changed, 102 insertions, 73 deletions
diff --git a/doc/manual/nix-collect-garbage.xml b/doc/manual/nix-collect-garbage.xml
index 8ff741e2212a..adc6c1e730a7 100644
--- a/doc/manual/nix-collect-garbage.xml
+++ b/doc/manual/nix-collect-garbage.xml
@@ -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>
-        <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>
+        <term><option>--print-live</option> / <option>--print-dead</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>
 
diff --git a/doc/manual/nix-store.xml b/doc/manual/nix-store.xml
index a3fcad0631d0..febe02fd4ada 100644
--- a/doc/manual/nix-store.xml
+++ b/doc/manual/nix-store.xml
@@ -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>
 
diff --git a/doc/manual/quick-start.xml b/doc/manual/quick-start.xml
index 294fbcba29f5..badbfa29461c 100644
--- a/doc/manual/quick-start.xml
+++ b/doc/manual/quick-start.xml
@@ -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>
diff --git a/scripts/nix-collect-garbage.in b/scripts/nix-collect-garbage.in
index 8b571536d87f..539979cbb6c0 100755
--- a/scripts/nix-collect-garbage.in
+++ b/scripts/nix-collect-garbage.in
@@ -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"; };
-}
-close READ;
+# 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'";
 
-waitpid $pid, 0;
-$? == 0 or die "determining live paths";
-
-exit 0 if ($invert);
+foreach my $root (@roots) {
+    print WRITE "$root\n";
+}
 
+close WRITE;
 
-# 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;
+waitpid $pid, 0;
+$? == 0 or die "`nix-store --gc' failed";
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index 78599e30869c..7bc8565d293d 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -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) {