[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

dpkg: fix erranous "directory not empty" warnings



Hi,

since the BTS is down a small lookahead of what is stuck:

--- Begin Message ---
Package: dpkg
Version: 1.10.28
Severity: normal
Tags: patch

Hi,

sometimes dpkg warns about directories not being empty when purging
packages while it shouldn't. The reason for this is that dpkg removes
directories from package.list even though the package has still files
(always conffiles?) in that directory (if the directory is also used
by another package). The directory then only belongs to that other
package (pkg2) and when pkg2 is purged it warns about the directory
not being empty.

Example:

mrvn@frosties:~$ dpkg -S /etc/defoma
ttf-bitstream-vera, defoma: /etc/defoma

mrvn@frosties:~$ sudo dpkg --remove defoma ttf-bitstream-vera
(Reading database ... 10232 files and directories currently installed.)
Removing ttf-bitstream-vera ...
Removing defoma ...

mrvn@frosties:~$ dpkg -S /etc/defoma
defoma: /etc/defoma

mrvn@frosties:~$ cat /var/lib/dpkg/info/ttf-bitstream-vera.list 
/etc/defoma/hints
/etc/defoma/hints/ttf-bitstream-vera.hints

^^^ Notice how /etc and /etc/defoma are missing now.

mrvn@frosties:~$ sudo dpkg --purge defoma ttf-bitstream-vera
(Reading database ... 10125 files and directories currently installed.)
Removing defoma ...
Purging configuration files for defoma ...
dpkg - warning: while removing defoma, directory `/etc/defoma' not empty so not removed.
Removing ttf-bitstream-vera ...
Purging configuration files for ttf-bitstream-vera ...

^^^ when ttf-bitstream-vera the directory actualy becomes empty but
since ttf-bitstream-vera does not own that directory it is not
removed.


The patch is quite simple. Before writing the reduced file list after
removal listclosure(&leftover) is called. This function generates the
closure of the list by recursively adding all parent directories of
all entries that don't already exist in the list. It doesn't re-add an
entry for the root dir (/. entry) though. Lets hope / is never going
to be removed. :)

MfG
	Goswin


-- System Information:
Debian Release: 3.1
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.8-frosties-1
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages dpkg depends on:
ii  dselect                     1.10.28      a user tool to manage Debian packa
ii  libc6                       2.3.2.ds1-22 GNU C Library: Shared libraries an

-- no debconf information
diff -Nru /tmp/I6mUpNOPoU/dpkg-1.13.9/debian/changelog /tmp/2Ksog51tfC/dpkg-1.13.9/debian/changelog
--- /tmp/I6mUpNOPoU/dpkg-1.13.9/debian/changelog	2005-06-12 17:16:59.000000000 +0200
+++ /tmp/2Ksog51tfC/dpkg-1.13.9/debian/changelog	2005-07-18 00:15:08.000000000 +0200
@@ -1,3 +1,11 @@
+dpkg (1.13.9-0.0.0.1.mrvn) unstable; urgency=low
+  
+  The "Fix dir removal!" Release.
+
+  * Don't remove dirs with files from package left from the package.list
+
+ -- Scott James Remnant <scott@netsplit.com>  Mon, 18 Jul 2005 00:14:10 +0200
+
 dpkg (1.13.9) unstable; urgency=low
   
   The "On like Donkey Kong" Release.
diff -Nru /tmp/I6mUpNOPoU/dpkg-1.13.9/src/remove.c /tmp/2Ksog51tfC/dpkg-1.13.9/src/remove.c
--- /tmp/I6mUpNOPoU/dpkg-1.13.9/src/remove.c	2005-06-06 06:07:12.000000000 +0200
+++ /tmp/2Ksog51tfC/dpkg-1.13.9/src/remove.c	2005-07-18 01:04:29.000000000 +0200
@@ -188,6 +188,41 @@
   *leftoverp= newentry;
 }
 
+/* Generate closure of list by recursively adding all parent directories that
+ * don't already exist
+ */
+void listclosure(struct fileinlist **list) {
+  struct fileinlist *tmp1= *list;
+  struct filenamenode *namenode;
+  while(tmp1) {
+    char *dirname= m_malloc(strlen(tmp1->namenode->name)+1);
+    char *p = dirname + strlen(tmp1->namenode->name);
+    strcpy(dirname,tmp1->namenode->name);
+    while(p > dirname) {
+      struct fileinlist *tmp2= *list;
+      debug(dbg_eachfiledetail, "removal_bulk reinclude test `%s'", dirname);
+      while(p > dirname && *p != '/') { // get dirname
+        *p = 0;
+	--p;
+      }
+      *p = 0;
+      while(tmp2) {
+	debug(dbg_eachfiledetail, "removal_bulk reinclude cmp `%s'", tmp2->namenode->name);
+        if (strcmp(dirname, tmp2->namenode->name) == 0)
+	  break;
+	tmp2= tmp2->next;
+      }
+      if (!tmp2) {
+	debug(dbg_eachfiledetail, "removal_bulk reinclude add `%s'", dirname);
+	namenode= findnamenode(dirname,0);
+	push_leftover(&list,namenode);
+      }
+    }
+    free(dirname);
+    tmp1= tmp1->next;
+  }
+}
+
 static void removal_bulk_remove_files(
     struct pkginfo *pkg, 
     int *out_foundpostrm) 
@@ -275,6 +310,7 @@
       }
       if (unlink(fnvb.buf)) ohshite(_("cannot remove file `%.250s'"),fnvb.buf);
     }
+    listclosure(&leftover);
     write_filelist_except(pkg,leftover,0);
     maintainer_script_installed(pkg, POSTRMFILE, "post-removal",
                                 "remove", (char*)0);
@@ -373,6 +409,7 @@
     push_leftover(&leftover,namenode);
     continue;
   }
+  listclosure(&leftover);
   write_filelist_except(pkg,leftover,0);
 
   modstatdb_note(pkg);

--- End Message ---

Reply to: