Add operation ‘nix-store --repair-path’

This operation allows fixing corrupted or accidentally deleted store
paths by redownloading them using substituters, if available.

Since the corrupted path cannot be replaced atomically, there is a
very small time window (one system call) during which neither the old
(corrupted) nor the new (repaired) contents are available.  So
repairing should be used with some care on critical packages like
Glibc.
This commit is contained in:
Eelco Dolstra 2012-10-02 14:08:59 -04:00
parent e666e1156f
commit 9958bd6992
8 changed files with 151 additions and 36 deletions

View file

@ -486,7 +486,7 @@ sub printSubstitutablePaths {
sub downloadBinary {
my ($storePath) = @_;
my ($storePath, $destPath) = @_;
foreach my $cache (@caches) {
my $info = getCachedInfoFrom($storePath, $cache);
@ -510,7 +510,7 @@ sub downloadBinary {
my $url = "$cache->{url}/$info->{url}"; # FIXME: handle non-relative URLs
print STDERR "\n*** Downloading $url to $storePath...\n";
Nix::Utils::checkURL $url;
if (system("$Nix::Config::curl --fail --location --insecure '$url' | $decompressor | $Nix::Config::binDir/nix-store --restore $storePath") != 0) {
if (system("$Nix::Config::curl --fail --location --insecure '$url' | $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) {
die "download of `$info->{url}' failed" . ($! ? ": $!" : "") . "\n" unless $? == 0;
next;
}
@ -557,8 +557,9 @@ if ($ARGV[0] eq "--query") {
elsif ($ARGV[0] eq "--substitute") {
my $storePath = $ARGV[1] or die;
my $destPath = $ARGV[2] or die;
getAvailableCaches;
downloadBinary($storePath);
downloadBinary($storePath, $destPath);
}
else {