Package: dpkg Version: 1.17.27 Followup-For: Bug #837051 Dear Maintainer,
find attached a patch to fix the mentioned bug. The patch still applied to master=1.18.8. To reproducte this: tar xf 41965_dpkg-divert.tar.xz cd bug41965.1 && dpkg-buildpackage -uc -us -b cd bug41965.2 && dpkg-buildpackage -uc -us -b dpkg -i bug41965-a_1_all.deb dpkg-divert --local --rename --divert /etc/bug41965/compat.moved --add /etc/bug41965/compat dpkg -i bug41965-?_2_all.deb -- System Information: Debian Release: 8.6 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable'), (90, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages dpkg depends on: ii libbz2-1.0 1.0.6-7+b3 ii libc6 2.24-5 ii liblzma5 5.1.1alpha+20120614-2+b3 ii libselinux1 2.3-2 ii tar 1.27.1-2+deb8u1 ii zlib1g 1:1.2.8.dfsg-2+b1 dpkg recommends no packages. Versions of packages dpkg suggests: ii apt 1.0.9.8.3 -- no debconf information
>From 557ad2681c947515cc52f933158473f440d65ee9 Mon Sep 17 00:00:00 2001 Message-Id: <557ad2681c947515cc52f933158473f440d65ee9.1481286674.git.h...@univention.de> From: Philipp Hahn <h...@univention.de> Date: Fri, 9 Dec 2016 13:11:59 +0100 Subject: [PATCH] Fix update of diverted conffile moved between packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Organization: Univention GmbH, Bremen, Germany If a conffile is diverted and it gets moved from one package to another, dpkg still considers it owned by the original package and aborts the upgrade: > Unpacking libpython2.7-minimal:amd64 (from > libpython2.7-minimal_2.7.9-2_amd64.deb) ... > dpkg: error processing libpython2.7-minimal_2.7.9-2_amd64.deb (--install): > trying to overwrite '/etc/python2.7/sitecustomize.py', which is also in > package python2.7-minimal 2.7.9-2 Running dpkg with --debug=03773 shows this difference (using an artificial package for testing) - left is diverted, right side not: > tarobject ti->name='./etc/bug41965/compat' mode=100644 owner=0.0 type=48(-) > ti->linkname='' name…| tarobject ti->name='./etc/bug41965/compat' mode=100644 > owner=0.0 type=48(-) ti->linkname='' namenode='/etc/b… > namenodetouse namenode='/etc/bug41965/compat' pkg=bug41965-b:all > | > ------------------------------------------------------------------------------------------------------------- > namenodetouse ... useinstead=/etc/bug41965/compat.moved camefrom=<none> > pkg=<none> return /etc/b…| > ------------------------------------------------------------------------------------------------------------- > > | > conffderef in='etc/bug41965/compat.moved' current > working='/etc/bug41965/compat.moved' | conffderef > in='etc/bug41965/compat' current working='/etc/bug41965/compat' > conffderef in='etc/bug41965/compat.moved' result='/etc/bug41965/compat.moved' > | conffderef in='etc/bug41965/compat' > result='/etc/bug41965/compat' > tarobject fnnf_new_conff deref='etc/bug41965/compat.moved' > | tarobject fnnf_new_conff deref='etc/bug41965/compat' > setupvnamevbs main='/etc/bug41965/compat.moved' > tmp='/etc/bug41965/compat.moved.dpkg-tmp' new='/…| setupvnamevbs > main='/etc/bug41965/compat' tmp='/etc/bug41965/compat.dpkg-tmp' > new='/etc/bug41965/compat.dpkg… > tarobject already exists > | tarobject already exists > tarobject ... found in bug41965-a:all > | tarobject ... found in bug41965-a:all > tarobject ... diverted, divpkgset=<none> > | tarobject other's obsolete conffile In the un-diverted case (right side) you see the message from src/archives.c:911, which is missing in the diverted case (left side), finally leading to the package being rejected: > /* Is the file an obsolete conffile in the other package > * and a conffile in the new package? */ > if ((nifd->namenode->flags & fnnf_new_conff) && > !statr && S_ISREG(stab.st_mode)) { > for (conff = otherpkg->installed.conffiles; > conff; > conff = conff->next) { > if (!conff->obsolete) > continue; > if (stat(conff->name, &stabtmp)) { Here conff->name='./etc/bug41965/compat' is the original file name, not the diverted one; So it stat()s *my* alternative file and not the diverted file, ... > if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP) > continue; > else > ohshite(_("cannot stat file '%s'"), conff->name); > } > if (stabtmp.st_dev == stab.st_dev && > stabtmp.st_ino == stab.st_ino) > break; ... so the loop is not aborted ... > } > if (conff) { > debug(dbg_eachfiledetail, "tarobject other's obsolete conffile"); > /* process_archive() will have copied its hash already. */ > continue; ... and that case is not detected. > } > } Instead of always checking the original file, we switch to use the diverted file if ... > confname = ( > nifd->namenode->divert && nifd->namenode->divert->useinstead && we are currently processing a diverted conffile > strcmp(conff->name, nifd->namenode->name) == 0 && whose name matches the conffile of the other-packages conffile > divpkgset != otherpkg->set where that package is not the diverting package > ) ? nifd->namenode->divert->useinstead->name : conff->name; Signed-off-by: Philipp Hahn <h...@univention.de> --- src/archives.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/archives.c b/src/archives.c index d05a589..d858bf0 100644 --- a/src/archives.c +++ b/src/archives.c @@ -915,13 +915,19 @@ tarobject(void *ctx, struct tar_entry *ti) for (conff = otherpkg->installed.conffiles; conff; conff = conff->next) { + char *confname; if (!conff->obsolete) continue; - if (stat(conff->name, &stabtmp)) { + confname = ( + nifd->namenode->divert && nifd->namenode->divert->useinstead && + strcmp(conff->name, nifd->namenode->name) == 0 && + divpkgset != otherpkg->set + ) ? nifd->namenode->divert->useinstead->name : conff->name; + if (stat(confname, &stabtmp)) { if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP) continue; else - ohshite(_("cannot stat file '%s'"), conff->name); + ohshite(_("cannot stat file '%s'"), confname); } if (stabtmp.st_dev == stab.st_dev && stabtmp.st_ino == stab.st_ino) -- 2.1.4
41965_dpkg-divert.tar.xz
Description: application/xz