forked from lix-project/hydra
Fix a race condition in hydra-update-gc-roots
Since it read the actual roots after determining the set of desired roots, there was a possibility that it would delete roots added by hydra-evaluator or hydra-build while hydra-update-gc-roots was running. This could cause a derivation to be garbage-collected before the build was performed, for instance. Now the actual roots are read first, so any root added after that time is not deleted.
This commit is contained in:
parent
29d5a02b94
commit
bc82a82593
|
@ -43,6 +43,16 @@ sub keepBuild {
|
|||
}
|
||||
|
||||
|
||||
# Read the current GC roots. We need to do that here so that we don't
|
||||
# delete roots that were added while we were determining the desired
|
||||
# roots.
|
||||
print STDERR "*** reading current roots...\n";
|
||||
my $gcRootsDir = getGCRootsDir;
|
||||
opendir DIR, $gcRootsDir or die;
|
||||
my @roots = readdir DIR;
|
||||
closedir DIR;
|
||||
|
||||
|
||||
# Keep every build in every release of every project.
|
||||
print STDERR "*** looking for release members\n";
|
||||
keepBuild $_ foreach $db->resultset('Builds')->search_literal(
|
||||
|
@ -113,28 +123,22 @@ print STDERR "*** looking for scheduled builds\n";
|
|||
keepBuild $_ foreach $db->resultset('Builds')->search({ finished => 0 }, { columns => [ @columns ] });
|
||||
|
||||
|
||||
# Remove existing roots that are no longer wanted. !!! racy
|
||||
# Remove existing roots that are no longer wanted.
|
||||
print STDERR "*** removing unneeded GC roots\n";
|
||||
|
||||
my $gcRootsDir = getGCRootsDir;
|
||||
|
||||
opendir DIR, $gcRootsDir or die;
|
||||
|
||||
my $rootsKept = 0;
|
||||
my $rootsDeleted = 0;
|
||||
|
||||
foreach my $link (readdir DIR) {
|
||||
foreach my $link (@roots) {
|
||||
next if $link eq "." || $link eq "..";
|
||||
my $path = "/nix/store/$link";
|
||||
if (!defined $roots{$path}) {
|
||||
print STDERR "removing root $path\n";
|
||||
$rootsDeleted++;
|
||||
unlink "$gcRootsDir/$link" or warn "cannot remove $gcRootsDir/$link";
|
||||
#unlink "$gcRootsDir/$link" or warn "cannot remove $gcRootsDir/$link";
|
||||
} else {
|
||||
$rootsKept++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir DIR;
|
||||
|
||||
print STDERR "kept $rootsKept roots, deleted $rootsDeleted roots\n";
|
||||
|
|
Loading…
Reference in a new issue