summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog5
-rw-r--r--debian/control2
-rwxr-xr-xscripts/dpkg-distaddfile.pl13
-rwxr-xr-xscripts/dpkg-gencontrol.pl13
4 files changed, 32 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog
index d173a50..f01bf02 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -32,6 +32,11 @@ dpkg (1.16.2) UNRELEASED; urgency=low
too. Closes: #595144
* Rewrite architecture.mk with explicit loops instead of duplicating many
similar lines. Based on a patch by Thorsten Glaser <tg@mirbsd.de>.
+ * Modify dpkg-gencontrol and dpkg-distaddfile to grab a write lock
+ on debian/control before updating debian/files to avoid simultaneous
+ updates. Closes: #642608
+ Add libfile-fcntllock-perl to dpkg-dev's Depends since we use this module
+ to handle the locking.
[ Jonathan Nieder ]
* Bump po4a version in Build-Depends to 0.41, since earlier versions do
diff --git a/debian/control b/debian/control
index 390d9f1..5ad1e92 100644
--- a/debian/control
+++ b/debian/control
@@ -49,7 +49,7 @@ Package: dpkg-dev
Section: utils
Priority: optional
Architecture: all
-Depends: libdpkg-perl (= ${source:Version}), bzip2, xz-utils,
+Depends: libdpkg-perl (= ${source:Version}), libfile-fcntllock-perl, bzip2, xz-utils,
patch, make, binutils, base-files (>= 5.0.0), ${misc:Depends}
Recommends: gcc | c-compiler, build-essential, fakeroot, gnupg, gpgv, libalgorithm-merge-perl
Suggests: debian-keyring
diff --git a/scripts/dpkg-distaddfile.pl b/scripts/dpkg-distaddfile.pl
index 566698e..7b5274e 100755
--- a/scripts/dpkg-distaddfile.pl
+++ b/scripts/dpkg-distaddfile.pl
@@ -18,6 +18,7 @@
use strict;
use warnings;
+use File::FcntlLock;
use POSIX;
use POSIX qw(:errno_h :signal_h);
use Dpkg;
@@ -75,6 +76,15 @@ my ($file, $section, $priority) = @ARGV;
($file =~ m/\s/ || $section =~ m/\s/ || $priority =~ m/\s/) &&
error(_g("filename, section and priority may contain no whitespace"));
+# Obtain a lock on debian/control to avoid simultaneous updates
+# of debian/files when parallel building is in use
+my $fs = File::FcntlLock->new(l_type => F_WRLCK);
+my $lockfh;
+sysopen($lockfh, "debian/control", O_WRONLY) ||
+ syserr(_g("cannot write %s"), "debian/control");
+$fs->lock($lockfh, F_SETLKW) ||
+ syserr(_("failed to get a write lock on %s"), "debian/control");
+
$fileslistfile="./$fileslistfile" if $fileslistfile =~ m/^\s/;
open(Y, "> $fileslistfile.new") || syserr(_g("open new files list file"));
if (open(X,"< $fileslistfile")) {
@@ -91,3 +101,6 @@ print(Y "$file $section $priority\n")
close(Y) || syserr(_g("close new files list file"));
rename("$fileslistfile.new", $fileslistfile) ||
syserr(_g("install new files list file"));
+
+# Release the lock
+close($lockfh) || syserr(_g("cannot close %s"), "debian/control");
diff --git a/scripts/dpkg-gencontrol.pl b/scripts/dpkg-gencontrol.pl
index 14d6e48..1cf6945 100755
--- a/scripts/dpkg-gencontrol.pl
+++ b/scripts/dpkg-gencontrol.pl
@@ -18,6 +18,7 @@
use strict;
use warnings;
+use File::FcntlLock;
use POSIX;
use POSIX qw(:errno_h);
use Dpkg;
@@ -333,6 +334,15 @@ for my $f (keys %remove) {
delete $fields->{$f};
}
+# Obtain a lock on debian/control to avoid simultaneous updates
+# of debian/files when parallel building is in use
+my $fs = File::FcntlLock->new(l_type => F_WRLCK);
+my $lockfh;
+sysopen($lockfh, "debian/control", O_WRONLY) ||
+ syserr(_g("cannot write %s"), "debian/control");
+$fs->lock($lockfh, F_SETLKW) ||
+ syserr(_("failed to get a write lock on %s"), "debian/control");
+
$fileslistfile="./$fileslistfile" if $fileslistfile =~ m/^\s/;
open(Y, ">", "$fileslistfile.new") || syserr(_g("open new files list file"));
binmode(Y);
@@ -363,6 +373,9 @@ print(Y $substvars->substvars(sprintf("%s %s %s\n", $forcefilename,
close(Y) || syserr(_g("close new files list file"));
rename("$fileslistfile.new", $fileslistfile) || syserr(_g("install new files list file"));
+# Release the lock
+close($lockfh) || syserr(_g("cannot close %s"), "debian/control");
+
my $cf;
my $fh_output;
if (!$stdout) {