2004-03-15 16:23:53 +01:00
|
|
|
#! @perl@ -w
|
2003-07-14 12:45:04 +02:00
|
|
|
|
2003-08-25 16:36:04 +02:00
|
|
|
use strict;
|
|
|
|
use IPC::Open2;
|
|
|
|
|
2004-04-22 16:17:57 +02:00
|
|
|
my $rootsDir = "@localstatedir@/nix/gcroots";
|
|
|
|
my $storeDir = "@storedir@";
|
2003-07-14 12:45:04 +02:00
|
|
|
|
|
|
|
my %alive;
|
|
|
|
|
2004-08-25 17:39:13 +02:00
|
|
|
my $gcOper = "--delete";
|
2004-04-22 16:17:57 +02:00
|
|
|
my $keepSuccessors = 1;
|
2003-07-29 16:28:17 +02:00
|
|
|
|
2004-04-22 16:17:57 +02:00
|
|
|
my @roots = ();
|
|
|
|
|
|
|
|
|
|
|
|
# Parse the command line.
|
2003-07-29 16:28:17 +02:00
|
|
|
foreach my $arg (@ARGV) {
|
2004-08-25 17:39:13 +02:00
|
|
|
if ($arg eq "--delete" || $arg eq "--print-live" || $arg eq "--print-dead") {
|
|
|
|
$gcOper = $arg;
|
|
|
|
} else { die "unknown argument `$arg'" };
|
2003-07-29 16:28:17 +02:00
|
|
|
}
|
|
|
|
|
2003-11-22 16:58:34 +01:00
|
|
|
|
2004-04-22 16:17:57 +02:00
|
|
|
# Read all GC roots from the given file.
|
|
|
|
sub readRoots {
|
|
|
|
my $fileName = shift;
|
|
|
|
open ROOT, "<$fileName" or die "cannot open `$fileName': $!";
|
2004-04-14 10:09:27 +02:00
|
|
|
while (<ROOT>) {
|
|
|
|
chomp;
|
|
|
|
foreach my $root (split ' ') {
|
2004-04-22 16:17:57 +02:00
|
|
|
die "bad root `$root' in file `$fileName'"
|
|
|
|
unless $root =~ /^\S+$/;
|
2004-04-14 10:09:27 +02:00
|
|
|
push @roots, $root;
|
|
|
|
}
|
|
|
|
}
|
2003-11-22 16:58:34 +01:00
|
|
|
close ROOT;
|
|
|
|
}
|
|
|
|
|
2004-04-22 16:17:57 +02:00
|
|
|
|
|
|
|
# Recursively finds all *.gcroot files in the given directory.
|
|
|
|
sub findRoots;
|
|
|
|
sub findRoots {
|
|
|
|
my $followSymlinks = shift;
|
|
|
|
my $dir = shift;
|
|
|
|
|
|
|
|
opendir(DIR, $dir) or die "cannot open directory `$dir': $!";
|
|
|
|
my @names = readdir DIR or die "cannot read directory `$dir': $!";
|
|
|
|
closedir DIR;
|
|
|
|
|
|
|
|
foreach my $name (@names) {
|
|
|
|
next if $name eq "." || $name eq "..";
|
|
|
|
$name = $dir . "/" . $name;
|
|
|
|
if ($name =~ /.gcroot$/ && -f $name) {
|
|
|
|
readRoots $name;
|
|
|
|
}
|
|
|
|
elsif (-d $name) {
|
|
|
|
if ($followSymlinks || !-l $name) {
|
|
|
|
findRoots 0, $name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Find GC roots, starting at $rootsDir.
|
|
|
|
findRoots 1, $rootsDir;
|
|
|
|
|
|
|
|
|
2004-08-25 17:39:13 +02:00
|
|
|
# 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'";
|
2003-08-25 16:36:04 +02:00
|
|
|
|
2004-08-25 17:39:13 +02:00
|
|
|
foreach my $root (@roots) {
|
|
|
|
print WRITE "$root\n";
|
|
|
|
}
|
2003-07-29 16:28:17 +02:00
|
|
|
|
2004-08-25 17:39:13 +02:00
|
|
|
close WRITE;
|
2003-07-14 12:45:04 +02:00
|
|
|
|
2004-08-25 17:39:13 +02:00
|
|
|
waitpid $pid, 0;
|
|
|
|
$? == 0 or die "`nix-store --gc' failed";
|