Package: dpkg
Version: 1.13.2
Severity: serious
Tags: patch
User: d...@packages.debian.org
Usertags: conffile

Hi!

Riku Voipio found out while dealing with some transition in maemo that
in some cases when installing two new packages with a conffile, one of
the packages Replacing the other, the conffile completely disappeared
from the system.

After investigating I found out that if pkg A and B provide the same
conffile pathname, and B Replaces A, if B gets installed first and
then A, the conffile does not get properly installed. In the same
install run (as in «dpkg -i pkg-B pkg-A»), the conffile completely
disappears. In two runs (as in «dpkg -i pkg-B; dpkg -i pkg-A»), the
conffile does not get updated, so the old one remains.


On one hand this seems pretty nasty (thus the current severity), as
packages might stop working, it interrupts possibly unattended
installations with unneeded prompts, the user might get really
confused, and the fix is quite small, just moving two lines of code
around. But then it's also kind of self healing, as when upgrading B to
a new version the conffile should reappear or get updated, so I would
not complain if the release-team would like to lower this to important.


The relevant test-cases[0] (and results w/ unpatched dpkg) are:

  $ make -C t-conffile-replaces test
  $ make -C t-conffile-replaces-existing test

  etch: Fail on test-one-run-reverse and test-two-run-reverse (not
        checked yet, but I guess the latter only due to 508392)
  lenny: Fail on test-one-run-reverse.

  $ make -C t-conffile-replaces-upgrade test
  $ make -C t-conffile-replaces-existing-and-upgrade test

  etch: Pass, although prompts unneedingly on test-one-run-ordered and
        test-one-run-reverse (not checked yet, but I guess the latter
        only due to 508392).
  lenny: Pass, although prompts unneedingly on test-one-run-ordered.


regards,
guillem

[0] git://git.hadrons.org/git/debian/dpkg/pkg-tests.git
>From 06a4219e277d5b945b988bbac784510da0a0df04 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Sun, 1 Feb 2009 20:16:29 +0200
Subject: [PATCH] Do not lose a conffile while replacing it on the same install run

Only do the ensure_pathname_nonexisting calls when we are not going to
return due to an already existing directory or a file not to be
overwritten.

Those calls are making sure that .dpkg-tmp and .dpkg-new files do not
exist, and will remove them if they do, which messes with the way
conffiles are handled by keeping those and acting on them later on.

Closes: #80416, #NNNNNN
---
 ChangeLog        |    5 +++++
 debian/changelog |    6 ++++++
 src/archives.c   |   12 ++++++------
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6cccc74..9b96240 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-02-01  Guillem Jover  <guil...@debian.org>
+
+	* src/archives.c (tarobject): Do not call ensure_pathname_nonexisting
+	if we are going to return due to file or directory already existing.
+
 2008-12-29  Guillem Jover  <guil...@debian.org>
 
 	* configure.ac: Bump version to 1.14.25~.
diff --git a/debian/changelog b/debian/changelog
index a028cd8..677417f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,12 @@ dpkg (1.14.25) UNRELEASED; urgency=low
   [ Guillem Jover ]
   * Fix typo in package description ('privides' -> 'provides').
     Thanks to Pascal De Vuyst <pascal.devu...@gmail.com>. Closes: #510755
+  * Do not lose conffiles while replacing them from another package on the
+    same install run. Closes: #NNNNNN
+    As a side effect this fixes the following symptoms:
+    - Do not do unneeded conffile prompts when it wasn't locally changed.
+    - Do not ensure (and thus do not output debug information) that an
+      existing dir does not exist. Closes: #80416
 
   [ Updated dpkg translations ]
   * Basque (Piarres Beobide). Closes: #506092, #509851
diff --git a/src/archives.c b/src/archives.c
index fcbe166..70f630a 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -577,12 +577,6 @@ int tarobject(struct TarInfo *ti) {
     }
   }
        
-  /* Now, at this stage we want to make sure neither of .dpkg-new and .dpkg-tmp
-   * are hanging around.
-   */
-  ensure_pathname_nonexisting(fnamenewvb.buf);
-  ensure_pathname_nonexisting(fnametmpvb.buf);
-
   if (existingdirectory) return 0;
   if (keepexisting) {
     obstack_free(&tar_obs, nifd);
@@ -602,6 +596,12 @@ int tarobject(struct TarInfo *ti) {
     return 0;
   }
 
+  /* Now, at this stage we want to make sure neither of .dpkg-new and .dpkg-tmp
+   * are hanging around.
+   */
+  ensure_pathname_nonexisting(fnamenewvb.buf);
+  ensure_pathname_nonexisting(fnametmpvb.buf);
+
   /* Now we start to do things that we need to be able to undo
    * if something goes wrong.  Watch out for the CLEANUP comments to
    * keep an eye on what's installed on the disk at each point.
-- 
1.6.0.6

Reply via email to