![Eelco Dolstra](/assets/img/avatar_default.png)
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.
99 lines
2.7 KiB
Perl
Executable file
99 lines
2.7 KiB
Perl
Executable file
#! @perl@ -w @perlFlags@
|
|
|
|
use strict;
|
|
use File::Basename;
|
|
use IO::Handle;
|
|
|
|
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
|
|
|
|
|
|
STDOUT->autoflush(1);
|
|
|
|
my @remoteStoresAll = split ':', ($ENV{"NIX_OTHER_STORES"} or "");
|
|
|
|
my @remoteStores;
|
|
foreach my $dir (@remoteStoresAll) {
|
|
push @remoteStores, glob($dir);
|
|
}
|
|
|
|
|
|
$ENV{"NIX_REMOTE"} = "";
|
|
|
|
|
|
sub findStorePath {
|
|
my $storePath = shift;
|
|
foreach my $store (@remoteStores) {
|
|
my $sourcePath = "$store/store/" . basename $storePath;
|
|
next unless -e $sourcePath || -l $sourcePath;
|
|
$ENV{"NIX_DB_DIR"} = "$store/var/nix/db";
|
|
return ($store, $sourcePath) if
|
|
system("@bindir@/nix-store --check-validity $storePath") == 0;
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
|
|
if ($ARGV[0] eq "--query") {
|
|
|
|
while (<STDIN>) {
|
|
chomp;
|
|
my ($cmd, @args) = split " ", $_;
|
|
|
|
if ($cmd eq "have") {
|
|
foreach my $storePath (@args) {
|
|
print "$storePath\n" if defined findStorePath($storePath);
|
|
}
|
|
print "\n";
|
|
}
|
|
|
|
elsif ($cmd eq "info") {
|
|
foreach my $storePath (@args) {
|
|
my ($store, $sourcePath) = findStorePath($storePath);
|
|
next unless defined $store;
|
|
|
|
$ENV{"NIX_DB_DIR"} = "$store/var/nix/db";
|
|
|
|
my $deriver = `@bindir@/nix-store --query --deriver $storePath`;
|
|
die "cannot query deriver of `$storePath'" if $? != 0;
|
|
chomp $deriver;
|
|
$deriver = "" if $deriver eq "unknown-deriver";
|
|
|
|
my @references = split "\n",
|
|
`@bindir@/nix-store --query --references $storePath`;
|
|
die "cannot query references of `$storePath'" if $? != 0;
|
|
|
|
my $narSize = `@bindir@/nix-store --query --size $storePath`;
|
|
die "cannot query size of `$storePath'" if $? != 0;
|
|
chomp $narSize;
|
|
|
|
print "$storePath\n";
|
|
print "$deriver\n";
|
|
print scalar @references, "\n";
|
|
print "$_\n" foreach @references;
|
|
print "$narSize\n";
|
|
print "$narSize\n";
|
|
}
|
|
|
|
print "\n";
|
|
}
|
|
|
|
else { die "unknown command `$cmd'"; }
|
|
}
|
|
}
|
|
|
|
|
|
elsif ($ARGV[0] eq "--substitute") {
|
|
die unless scalar @ARGV == 3;
|
|
my $storePath = $ARGV[1];
|
|
my $destPath = $ARGV[2];
|
|
my ($store, $sourcePath) = findStorePath $storePath;
|
|
die unless $store;
|
|
print STDERR "\n*** Copying `$storePath' from `$sourcePath'\n\n";
|
|
system("$binDir/nix-store --dump $sourcePath | $binDir/nix-store --restore $destPath") == 0
|
|
or die "cannot copy `$sourcePath' to `$storePath'";
|
|
print "\n"; # no hash to verify
|
|
}
|
|
|
|
|
|
else { die; }
|