* `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…
	
	Add table
		Add a link
		
	
		Reference in a new issue