Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package udpkg I've added locking for the status file, so parallel udpkg invocations will not break the world. This fixes #987368. We definitely want this fix for Bullseye. I've CC:ed KiBi too. See attached debdiff. unblock udpkg/1.20 -- System Information: Debian Release: 10.10 APT prefers stable-debug APT policy: (500, 'stable-debug'), (500, 'stable'), (500, 'oldstable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 5.10.0-0.bpo.5-amd64 (SMP w/4 CPU cores) Kernel taint flags: TAINT_CPU_OUT_OF_SPEC Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), LANGUAGE=en_GB:en (charmap=UTF-8) Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled
diff -Nru udpkg-1.19/debian/changelog udpkg-1.20/debian/changelog --- udpkg-1.19/debian/changelog 2018-09-23 18:16:44.000000000 +0100 +++ udpkg-1.20/debian/changelog 2021-06-11 02:46:39.000000000 +0100 @@ -1,3 +1,19 @@ +udpkg (1.20) unstable; urgency=medium + + [ Holger Wansing ] + * Remove trailing whitespaces from changelog file, to fix lintian tag. + + [ Cyril Brulebois ] + * Remove Christian Perrier from Uploaders, with many thanks for all + his contributions over the years! (Closes: #927557) + + [ Steve McIntyre ] + * Add locking for the status file, so parallel udpkg invocations + will not break the world. Closes: #987368 + * Add myself to Uploaders + + -- Steve McIntyre <93...@debian.org> Fri, 11 Jun 2021 02:46:39 +0100 + udpkg (1.19) unstable; urgency=medium * Team upload. @@ -374,7 +390,7 @@ udpkg (0.004) unstable; urgency=low - * fixes builddeps (closes: #86934) + * fixes builddeps (closes: #86934) -- Randolph Chung <ta...@debian.org> Wed, 21 Feb 2001 21:00:45 -0700 @@ -397,5 +413,3 @@ * Non-release. -- Joey Hess <jo...@debian.org> Thu, 26 Oct 2000 12:02:04 -0700 - - diff -Nru udpkg-1.19/debian/control udpkg-1.20/debian/control --- udpkg-1.19/debian/control 2018-08-10 20:25:18.000000000 +0100 +++ udpkg-1.20/debian/control 2021-06-10 23:04:38.000000000 +0100 @@ -2,7 +2,7 @@ Section: debian-installer Priority: standard Maintainer: Debian Install System Team <debian-b...@lists.debian.org> -Uploaders: Bastian Blank <wa...@debian.org>, Christian Perrier <bubu...@debian.org> +Uploaders: Bastian Blank <wa...@debian.org>, Steve McIntyre <93...@debian.org> Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.7.0), libdebian-installer4-dev (>= 0.41), dh-autoreconf Vcs-Browser: https://salsa.debian.org/installer-team/udpkg Vcs-Git: https://salsa.debian.org/installer-team/udpkg.git diff -Nru udpkg-1.19/status.c udpkg-1.20/status.c --- udpkg-1.19/status.c 2018-08-10 20:25:18.000000000 +0100 +++ udpkg-1.20/status.c 2021-06-11 00:45:35.000000000 +0100 @@ -1,9 +1,11 @@ #include "udpkg.h" +#include <errno.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> +#include <sys/file.h> #include <debian-installer.h> /* Status file handling routines @@ -19,8 +21,15 @@ * control info from (new) packages is merged into the status file, * replacing any pre-existing entries. when a merge happens, status info * read using the status_read function is written back to the status file + * + * There is also a pair of functions to lock and unlock access to the + * status, to protect against multiple invocations of udpkg racing + * against each other. Callers are responsible for using this locking + * around any code that works with the status file. */ +static int lock_fd = -1; + static const char *statuswords[][10] = { { (char *)STATUS_WANTSTART, "unknown", "install", "hold", "deinstall", "purge", 0 }, @@ -208,6 +217,45 @@ } } +void status_lock(void) +{ + int error; + lock_fd = open(STATUSFILELOCK, O_WRONLY | O_CREAT, 0200); + if (lock_fd < 0) + { + fprintf(stderr, "Unable to open lockfile %s (%d), abort!", + STATUSFILELOCK, errno); + exit(1); + } + error = flock(lock_fd, LOCK_EX); + if (error < 0) + { + fprintf(stderr, "Unable to lock lockfile %s (%d), abort!", + STATUSFILELOCK, errno); + exit(1); + } +} + +void status_unlock(void) +{ + int error; + if (lock_fd < 0) + { + fprintf(stderr, "Trying to unlock when we don't have the lockfile %s open!", + STATUSFILELOCK); + exit(1); + } + error = flock(lock_fd, LOCK_UN); + if (error < 0) + { + fprintf(stderr, "Unable to unlock lockfile %s (%d), abort!", + STATUSFILELOCK, errno); + exit(1); + } + close(lock_fd); + lock_fd = -1; +} + void *status_read(void) { FILE *f; diff -Nru udpkg-1.19/udpkg.c udpkg-1.20/udpkg.c --- udpkg-1.19/udpkg.c 2018-08-10 20:25:18.000000000 +0100 +++ udpkg-1.20/udpkg.c 2021-06-11 02:17:34.000000000 +0100 @@ -15,6 +15,14 @@ #include <sys/utsname.h> #include <debian-installer.h> +#ifdef LOCK_DEBUG +# define STATUS_LOCK() fprintf(stderr, "%d(%d): trying to lock status file\n", getpid(),__LINE__); status_lock(); fprintf(stderr, "%d(%d): locked\n", getpid(),__LINE__) +# define STATUS_UNLOCK() fprintf(stderr, "%d(%d): trying to unlock status file\n", getpid(),__LINE__); status_unlock(); fprintf(stderr, "%d(%d): unlocked\n", getpid(),__LINE__) +#else +# define STATUS_LOCK() status_lock() +# define STATUS_UNLOCK() status_unlock() +#endif + static int force_configure = 0; static int loadtemplate = 1; @@ -450,12 +458,14 @@ { int r = 0; struct package_t *pkg; + STATUS_LOCK(); void *status = status_read(); if (di_exec_shell_log("rm -rf -- " DPKGCIDIR) != 0 || mkdir(DPKGCIDIR, S_IRWXU) != 0) { perror("mkdir"); + STATUS_UNLOCK(); return 1; } @@ -468,6 +478,7 @@ status_merge(status, pkgs); if (di_exec_shell_log("rm -rf -- " DPKGCIDIR) != 0) r = 1; + STATUS_UNLOCK(); return r; } @@ -476,7 +487,9 @@ int r = 0; void *found; struct package_t *pkg; + STATUS_LOCK(); void *status = status_read(); + STATUS_UNLOCK(); for (pkg = pkgs; pkg != 0 && r == 0; pkg = pkg->next) { found = tfind(pkg, &status, package_compare); @@ -492,18 +505,22 @@ r = dpkg_doconfigure(*(struct package_t **)found); } } + STATUS_LOCK(); status_merge(status, 0); + STATUS_UNLOCK(); return r; } static int dpkg_install(struct package_t *pkgs) { struct package_t *p, *ordered = 0; + STATUS_LOCK(); void *status = status_read(); if (di_exec_shell_log("rm -rf -- " DPKGCIDIR) != 0 || mkdir(DPKGCIDIR, S_IRWXU) != 0) { perror("mkdir"); + STATUS_UNLOCK(); return 1; } @@ -542,6 +559,7 @@ if (ordered != 0) status_merge(status, pkgs); + STATUS_UNLOCK(); return di_exec_shell_log("rm -rf -- " DPKGCIDIR); } @@ -602,6 +620,7 @@ struct package_t *p; char buf[1024], buf2[1024]; FILE *fp; + STATUS_LOCK(); void *status = status_read(); for (p = pkgs; p != 0; p = p->next) @@ -650,6 +669,7 @@ p->status |= STATUS_STATUSHALFINSTALLED; } status_merge(status, pkgs); + STATUS_UNLOCK(); return r; #else FPRINTF(stderr, "udpkg: No support for -r.\n"); diff -Nru udpkg-1.19/udpkg.h udpkg-1.20/udpkg.h --- udpkg-1.19/udpkg.h 2018-08-10 20:25:18.000000000 +0100 +++ udpkg-1.20/udpkg.h 2021-06-10 01:19:44.000000000 +0100 @@ -19,6 +19,7 @@ #define BUFSIZE 4096 #define STATUSFILE ADMINDIR "/status" +#define STATUSFILELOCK ADMINDIR "/status.lck" #define DPKGCIDIR ADMINDIR "/tmp.ci/" #define INFODIR ADMINDIR "/info/" #define UDPKG_QUIET "UDPKG_QUIET" @@ -95,6 +96,8 @@ void *status_read(void); void control_read(FILE *f, struct package_t *p); int status_merge(void *status, struct package_t *pkgs); +void status_lock(void); +void status_unlock(void); int package_compare(const void *p1, const void *p2); struct package_t *depends_resolve(struct package_t *pkgs, void *status);