From 66602def168a3080bfb1fcb978764db5b981ec9a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 6 Feb 2009 21:01:20 +0000 Subject: [PATCH] * Register builds as GC roots so they don't get deleted. --- src/Hydra/lib/Hydra/Helper/Nix.pm | 24 +++++++++++++++++++++++ src/Hydra/script/hydra_build.pl | 2 ++ src/Hydra/script/hydra_scheduler.pl | 3 +++ src/Hydra/script/hydra_update_gc_roots.pl | 24 +++++++++-------------- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/Hydra/lib/Hydra/Helper/Nix.pm b/src/Hydra/lib/Hydra/Helper/Nix.pm index 5a18710c..c642c89e 100644 --- a/src/Hydra/lib/Hydra/Helper/Nix.pm +++ b/src/Hydra/lib/Hydra/Helper/Nix.pm @@ -2,11 +2,13 @@ package Hydra::Helper::Nix; use strict; use Exporter; +use File::Path; use File::Basename; our @ISA = qw(Exporter); our @EXPORT = qw( isValidPath getHydraPath getHydraDBPath openHydraDB + registerRoot getGCRootsDir getPrimaryBuildsForReleaseSet getRelease getLatestSuccessfulRelease ); @@ -42,6 +44,28 @@ sub openHydraDB { } +sub getGCRootsDir { + die unless defined $ENV{LOGNAME}; + return "/nix/var/nix/gcroots/per-user/$ENV{LOGNAME}/hydra-roots"; +} + + +sub registerRoot { + my ($path) = @_; + + my $gcRootsDir = getGCRootsDir; + + mkpath($gcRootsDir) if !-e $gcRootsDir; + + my $link = "$gcRootsDir/" . basename $path; + + if (!-l $link) { + symlink($path, $link) + or die "cannot create symlink in $gcRootsDir to $path"; + } +} + + sub attrsToSQL { my ($attrs, $id) = @_; my @attrs = split / /, $attrs; diff --git a/src/Hydra/script/hydra_build.pl b/src/Hydra/script/hydra_build.pl index 880ef363..9b9cbb3b 100755 --- a/src/Hydra/script/hydra_build.pl +++ b/src/Hydra/script/hydra_build.pl @@ -25,6 +25,8 @@ sub doBuild { my $errormsg = undef; + registerRoot $outPath; + if (!isValidPath($outPath)) { $isCachedBuild = 0; diff --git a/src/Hydra/script/hydra_scheduler.pl b/src/Hydra/script/hydra_scheduler.pl index 4197bfd1..7d10e96e 100755 --- a/src/Hydra/script/hydra_scheduler.pl +++ b/src/Hydra/script/hydra_scheduler.pl @@ -248,6 +248,9 @@ sub checkJob { , sha256hash => $input->{sha256hash} }); } + + # !!! this should really by done by nix-instantiate to prevent a GC race. + registerRoot $drvPath; }); }; diff --git a/src/Hydra/script/hydra_update_gc_roots.pl b/src/Hydra/script/hydra_update_gc_roots.pl index 6796ad33..5e91572d 100755 --- a/src/Hydra/script/hydra_update_gc_roots.pl +++ b/src/Hydra/script/hydra_update_gc_roots.pl @@ -9,25 +9,12 @@ use POSIX qw(strftime); my $db = openHydraDB; -die unless defined $ENV{LOGNAME}; -my $gcRootsDir = "/nix/var/nix/gcroots/per-user/$ENV{LOGNAME}/hydra-roots"; - my %roots; sub registerRoot { my ($path) = @_; - #print "$path\n"; - - mkpath($gcRootsDir) if !-e $gcRootsDir; - - my $link = "$gcRootsDir/" . basename $path; - - if (!-l $link) { - symlink($path, $link) - or die "cannot create symlink in $gcRootsDir to $path"; - } - + Hydra::Helper::Nix::registerRoot($path); $roots{$path} = 1; } @@ -97,11 +84,14 @@ my @buildsToKeep = $db->resultset('Builds')->search({finished => 1, keep => 1}, keepBuild $_ foreach @buildsToKeep; -# For scheduled builds, we register the derivation as a GC root. +# For scheduled builds, we register the derivation and the output as a GC root. print "*** looking for scheduled builds\n"; foreach my $build ($db->resultset('Builds')->search({finished => 0}, {join => 'schedulingInfo'})) { if (isValidPath($build->drvpath)) { + print "keeping scheduled build ", $build->id, " (", + strftime("%Y-%m-%d %H:%M:%S", localtime($build->timestamp)), ")\n"; registerRoot $build->drvpath; + registerRoot $build->outpath; } else { print STDERR "warning: derivation ", $build->drvpath, " has disappeared\n"; } @@ -109,6 +99,10 @@ foreach my $build ($db->resultset('Builds')->search({finished => 0}, {join => 's # Remove existing roots that are no longer wanted. !!! racy +print "*** removing unneeded GC roots\n"; + +my $gcRootsDir = getGCRootsDir; + opendir DIR, $gcRootsDir or die; foreach my $link (readdir DIR) {