* Impose a configurable time limit on patch generation. This is
necessary because bsdiff has some pathological worst-case behaviour, e.g. O(n^2) on files consisting only of 0s.
This commit is contained in:
parent
703e5a2ce2
commit
bd48fd97f6
1 changed files with 12 additions and 6 deletions
|
@ -15,6 +15,9 @@ $maxNarSize = 100 * 1024 * 1024 if !defined $maxNarSize;
|
||||||
my $maxPatchFraction = $ENV{"NIX_PATCH_FRACTION"};
|
my $maxPatchFraction = $ENV{"NIX_PATCH_FRACTION"};
|
||||||
$maxPatchFraction = 0.60 if !defined $maxPatchFraction;
|
$maxPatchFraction = 0.60 if !defined $maxPatchFraction;
|
||||||
|
|
||||||
|
my $timeLimit = $ENV{"NIX_BSDIFF_TIME_LIMIT"};
|
||||||
|
$timeLimit = 180 if !defined $timeLimit;
|
||||||
|
|
||||||
|
|
||||||
die unless scalar @ARGV == 5;
|
die unless scalar @ARGV == 5;
|
||||||
|
|
||||||
|
@ -29,8 +32,6 @@ my $dstManifest = $ARGV[4];
|
||||||
my $tmpDir = tempdir("nix-generate-patches.XXXXXX", CLEANUP => 1, TMPDIR => 1)
|
my $tmpDir = tempdir("nix-generate-patches.XXXXXX", CLEANUP => 1, TMPDIR => 1)
|
||||||
or die "cannot create a temporary directory";
|
or die "cannot create a temporary directory";
|
||||||
|
|
||||||
print "TEMP = $tmpDir\n";
|
|
||||||
|
|
||||||
#END { rmdir $tmpDir; }
|
#END { rmdir $tmpDir; }
|
||||||
|
|
||||||
my %srcNarFiles;
|
my %srcNarFiles;
|
||||||
|
@ -223,7 +224,7 @@ foreach my $p (keys %dstOutPaths) {
|
||||||
|
|
||||||
foreach my $q (keys %srcOutPaths) {
|
foreach my $q (keys %srcOutPaths) {
|
||||||
(my $name2, my $version2) = getNameVersion $q;
|
(my $name2, my $version2) = getNameVersion $q;
|
||||||
next unless defined $name2 && defined $version2;
|
next unless defined $name2 && defined $version2;
|
||||||
|
|
||||||
if ($name eq $name2) {
|
if ($name eq $name2) {
|
||||||
|
|
||||||
|
@ -312,8 +313,13 @@ foreach my $p (keys %dstOutPaths) {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
system("@libexecdir@/bsdiff $tmpDir/A $tmpDir/B $tmpDir/DIFF") == 0
|
my $time1 = time();
|
||||||
or die "cannot compute binary diff";
|
my $res = system("ulimit -t $timeLimit; @libexecdir@/bsdiff $tmpDir/A $tmpDir/B $tmpDir/DIFF");
|
||||||
|
my $time2 = time();
|
||||||
|
if ($res) {
|
||||||
|
warn "binary diff computation aborted after ", $time2 - $time1, " seconds\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
my $baseHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/A` or die;
|
my $baseHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/A` or die;
|
||||||
chomp $baseHash;
|
chomp $baseHash;
|
||||||
|
@ -327,7 +333,7 @@ foreach my $p (keys %dstOutPaths) {
|
||||||
my $narDiffSize = (stat "$tmpDir/DIFF")[7];
|
my $narDiffSize = (stat "$tmpDir/DIFF")[7];
|
||||||
my $dstNarBz2Size = (stat $dstNarBz2)[7];
|
my $dstNarBz2Size = (stat $dstNarBz2)[7];
|
||||||
|
|
||||||
print " size $narDiffSize; full size $dstNarBz2Size\n";
|
print " size $narDiffSize; full size $dstNarBz2Size; ", $time2 - $time1, " seconds\n";
|
||||||
|
|
||||||
if ($narDiffSize >= $dstNarBz2Size) {
|
if ($narDiffSize >= $dstNarBz2Size) {
|
||||||
print " rejecting; patch bigger than full archive\n";
|
print " rejecting; patch bigger than full archive\n";
|
||||||
|
|
Loading…
Reference in a new issue