Hi!

On Wed, 2011-05-04 at 11:11:10 +0200, Ondřej Surý wrote:
> The attached patch keeps the directory in the <pkg>.list (aka add it
> to the leftover) if the children directory is found on the leftover
> list.

The problem is that the check is not correct, isdirectoryinuse (now
dir_is_used_by_others) checks for the directory being referenced by
other packages, and here we only care if it's owned by the package
being acted on.

> There could be a slight modification to keep /. in the list as well to
> be formally correct, but IMO it's not needed.

Right, and it actually needs to be ignored on removal or dpkg fails on
non dpkg native systems (or fake environments), where the last package
can be easily removed.

Anyway I'm attaching a modified version, but I've only build tested
it. If you could test it that'd be nice. It would be nice to have a
test case for our functional test-suite too. :)

  <http://git.debian.org/?p=dpkg/pkg-tests.git>

> Also I have found a small bug in the matching function
> hasdirectoryconffiles and I am inheriting it (since I don't think it's
> major)...
> 
> If there is a conffile named:
> 
> /etc/pkg/foobar/foo.conf
> 
> and directory
> 
> /etc/pkg/foo
> 
> then the /etc/pkg/foo is matched and not removed.
> 
> If you want this fixed, just ping me, it's easy to add something like
> "&& (....->name[namelen] == \0 or ...->name[namelen] == '/')", and
> I'll fix it at both places.

Ah nice catch! I've pushed a fix for this (commit
2c9a342dc4e1ad3e9e58ac89957b9068664d1930). Thanks!

regards,
guillem
From ceb32da57317215d9f4635ca801537546f058827 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Fri, 6 May 2011 06:08:30 +0200
Subject: [PATCH] dpkg: Keep parent directories of directories kept during
 removal
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When a directory is kept during removal to be later dealt with during
purge, it might be due to the directory containing conffiles from the
same package, it not being empty, etc. In any case we should keep all
its parent to make sure when the subsequent trial is performed they
are properly cleaned up.

Closes: #316521, #348133, #454694, #538429, #625241

Based-on-patch-by: Ondřej Surý <ond...@debian.org>
---
 src/help.c   |   26 ++++++++++++++++++++++++++
 src/main.h   |    2 ++
 src/remove.c |    8 ++++++++
 3 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/src/help.c b/src/help.c
index 4a2256f..5b0fd39 100644
--- a/src/help.c
+++ b/src/help.c
@@ -512,6 +512,32 @@ dir_is_used_by_others(struct filenamenode *file, struct pkginfo *pkg)
   return false;
 }
 
+bool
+dir_is_used_by_pkg(struct filenamenode *file, struct pkginfo *pkg,
+                   struct fileinlist *list)
+{
+  struct fileinlist *node;
+  size_t namelen;
+
+  debug(dbg_veryverbose, "dir_is_used_by_pkg '%s' (by %s)",
+        file->name, pkg ? pkg->name : "<none>");
+
+  namelen = strlen(file->name);
+
+  for (node = list; node; node = node->next) {
+    debug(dbg_veryverbose, "dir_is_used_by_pkg considering %s ...",
+          node->namenode->name);
+
+    if (strncmp(file->name, node->namenode->name, namelen) == 0 &&
+        node->namenode->name[namelen] == '/')
+      return true;
+  }
+
+  debug(dbg_veryverbose, "dir_is_used_by_pkg no");
+
+  return false;
+}
+
 void oldconffsetflags(const struct conffile *searchconff) {
   struct filenamenode *namenode;
 
diff --git a/src/main.h b/src/main.h
index 12d12e7..3b8e094 100644
--- a/src/main.h
+++ b/src/main.h
@@ -249,6 +249,8 @@ void post_postinst_tasks(struct pkginfo *pkg, enum pkgstatus new_status);
 
 void clear_istobes(void);
 bool dir_is_used_by_others(struct filenamenode *namenode, struct pkginfo *pkg);
+bool dir_is_used_by_pkg(struct filenamenode *namenode, struct pkginfo *pkg,
+                        struct fileinlist *list);
 bool dir_has_conffiles(struct filenamenode *namenode, struct pkginfo *pkg);
 
 void log_action(const char *action, struct pkginfo *pkg);
diff --git a/src/remove.c b/src/remove.c
index a33518d..9e2e3a9 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -257,6 +257,10 @@ removal_bulk_remove_files(struct pkginfo *pkg)
 	  push_leftover(&leftover,namenode);
 	  continue;
 	}
+        if (dir_is_used_by_pkg(namenode, pkg, leftover)) {
+          push_leftover(&leftover, namenode);
+          continue;
+        }
         if (dir_is_used_by_others(namenode, pkg))
           continue;
       }
@@ -337,6 +341,10 @@ static void removal_bulk_remove_leftover_dirs(struct pkginfo *pkg) {
 	push_leftover(&leftover,namenode);
 	continue;
       }
+      if (dir_is_used_by_pkg(namenode, pkg, leftover)) {
+        push_leftover(&leftover, namenode);
+        continue;
+      }
       if (dir_is_used_by_others(namenode, pkg))
         continue;
     }
-- 
1.7.5

Reply via email to