about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-08-25T11·54+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-08-25T11·54+0000
commit95deba581dc3a93874b13406fb5c4dfb6747bbc3 (patch)
treea95e95749e7ad06c2267bebae49d8ff7695971de
parent1e5f5ea2e9f522397c05e710ae32ff7c0b0f1611 (diff)
* In the build hook, temporarily register the derivation and its
  output as GC roots.  This prevents a race if the garbage collector
  is running during the build.

-rwxr-xr-xscripts/build-remote.pl.in28
1 files changed, 23 insertions, 5 deletions
diff --git a/scripts/build-remote.pl.in b/scripts/build-remote.pl.in
index c440b6a0f142..2fb29dcfc894 100755
--- a/scripts/build-remote.pl.in
+++ b/scripts/build-remote.pl.in
@@ -192,7 +192,6 @@ if ($x ne "okay") {
 }
 
 
-# Do the actual build.
 print STDERR "building `$drvPath' on `$hostName'\n";
 
 my $inputs = `cat inputs`; die if ($? != 0);
@@ -201,17 +200,29 @@ $inputs =~ s/\n/ /g;
 my $outputs = `cat outputs`; die if ($? != 0);
 $outputs =~ s/\n/ /g;
 
-print "copying inputs...\n";
-
 my $maybeSign = "";
 $maybeSign = "--sign" if -e "/nix/etc/nix/signing-key.sec";
 
+
+# Register the derivation as a temporary GC root.  Note that $PPID is
+# the PID of the remote SSH process, which, due to the use of a
+# persistant SSH connection, should be the same across all remote
+# command invocations for this session.
+my $rootsDir = "@localstatedir@/nix/gcroots/tmp";
+system("ssh $hostName @sshOpts 'mkdir -m 1777 -p $rootsDir; ln -sfn $drvPath $rootsDir/\$PPID.drv'");
+
+sub removeRoots {
+    system("ssh $hostName @sshOpts 'rm -f $rootsDir/\$PPID.drv $rootsDir/\$PPID.out'");
+}
+
+
+# Copy the derivation and its dependencies to the build machine.
 system("NIX_SSHOPTS=\"@sshOpts\" @bindir@/nix-copy-closure $hostName $maybeSign $drvPath $inputs") == 0
     or die "cannot copy inputs to $hostName: $?";
 
-print "building...\n";
 
-my $buildFlags = "--max-silent-time $maxSilentTime --fallback";
+# Perform the build.
+my $buildFlags = "--max-silent-time $maxSilentTime --fallback --add-root $rootsDir/\$PPID.out";
 
 # `-tt' forces allocation of a pseudo-terminal.  This is required to
 # make the remote nix-store process receive a signal when the
@@ -226,11 +237,14 @@ if (system("ssh $hostName @sshOpts -tt 'nix-store -r $drvPath $buildFlags > /dev
     # the first is a transient failure and the latter is permanent.
     my $res = $? == -1 || ($? >> 8) == 255 ? 1 : 100;
     print STDERR "build of `$drvPath' on `$hostName' failed with exit code $?\n";
+    removeRoots;
     exit $res;
 }
 
 print "build of `$drvPath' on `$hostName' succeeded\n";
 
+
+# Copy the output from the build machine.
 foreach my $output (split '\n', $outputs) {
     my $maybeSignRemote = "";
     $maybeSignRemote = "--sign" if $UID != 0;
@@ -238,3 +252,7 @@ foreach my $output (split '\n', $outputs) {
     system("ssh $hostName @sshOpts 'nix-store --export $maybeSignRemote $output' | @bindir@/nix-store --import > /dev/null") == 0
 	or die "cannot copy $output from $hostName: $?";
 }
+
+
+# Get rid of the temporary GC roots.
+removeRoots;