Hi, (regarding the previous posts in this thread:) while having a dpkg-maintscript-helper subcommand that cleans up files during purge may be nice to simplify writing maintainer scripts, I think the removal of (parent-) directories should stay dpkg's job.
(regarding the original problem:) I'm seeing a lot of owned directories remaining in the piuparts tests for sid (they are treated as error for sid and warning for other distributions): http://piuparts.debian.org/sid/owned_files_by_many_packages_error.html http://piuparts.debian.org/sid/owned_files_after_purge_error.html I tried to create a minimal package that triggers the behaviour. Looks like it is related to directories owned by multiple packages and their removal order. A minimal example package is attached: extract, debuild, and you get 2 .debs: foo and foobar both ship the empty /var/lib/foobar directory foobar.postinst configure creates a file there foobar.postrm purge cleans up the file created in the postinst foo.postrm purge cleans up a nonexisting file there # dpkg -i foo_1_all.deb foobar_1_all.deb Selecting previously unselected package foo. (Reading database ... 13543 files and directories currently installed.) Unpacking foo (from foo_1_all.deb) ... Selecting previously unselected package foobar. Unpacking foobar (from foobar_1_all.deb) ... Setting up foo (1) ... Setting up foobar (1) ... # dpkg -S $(find /var/lib/foobar) foo, foobar: /var/lib/foobar dpkg-query: no path found matching pattern /var/lib/foobar/state. # dpkg --remove foo foobar (Reading database ... 13550 files and directories currently installed.) Removing foo ... Removing foobar ... # dpkg -S $(find /var/lib/foobar) foobar: /var/lib/foobar dpkg-query: no path found matching pattern /var/lib/foobar/state. # dpkg --purge foo foobar (Reading database ... 13544 files and directories currently installed.) Removing foo ... Purging configuration files for foo ... Removing foobar ... Purging configuration files for foobar ... # find /var/lib/foobar find: `/var/lib/foobar': No such file or directory ### OK this went fine, let's permute some arguments # dpkg -i foobar_1_all.deb foo_1_all.deb Selecting previously unselected package foobar. (Reading database ... 13543 files and directories currently installed.) Unpacking foobar (from foobar_1_all.deb) ... Selecting previously unselected package foo. Unpacking foo (from foo_1_all.deb) ... Setting up foobar (1) ... Setting up foo (1) ... # dpkg -S $(find /var/lib/foobar) foo, foobar: /var/lib/foobar dpkg-query: no path found matching pattern /var/lib/foobar/state. # dpkg --remove foobar foo (Reading database ... 13550 files and directories currently installed.) Removing foobar ... Removing foo ... # dpkg -S $(find /var/lib/foobar) foo: /var/lib/foobar dpkg-query: no path found matching pattern /var/lib/foobar/state. # dpkg --purge foo foobar (Reading database ... 13544 files and directories currently installed.) Removing foo ... Purging configuration files for foo ... dpkg: warning: while removing foo, directory '/var/lib/foobar' not empty so not removed. Removing foobar ... Purging configuration files for foobar ... # find /var/lib/foobar /var/lib/foobar # dpkg -S $(find /var/lib/foobar) dpkg-query: no path found matching pattern /var/lib/foobar. The problem seems to be which package keeps ownership of a shared directory in the case of removal. As it is now, this stays with the package to be removed last. But that one is not necessarily the one purged last. IMO, during directory removal two cases are to be distinguished: a) really empty directories (that either do not exist any more or rmdir on the directory would succeed - not empty in the sense 'dpkg knows no file/dir inside this directory'): these can be unregistered during REMOVE (aka removed from the file list of the package being removed) and removed from the filesystem if the reference count drops to 0 b) not empty directories (rmdir would fail regardless of dpkg knowing any file below this path): these should be kept during REMOVE and should only be removed during PURGE (unregistered from the file list and eventually rmdir-ed, but a diagnostic that removal failed should only be emitted after 'postrm purge' was run, the reference count dropped to 0 but the directory still can't be removed) For packages without postrm and with no conffiles (where REMOVE implies PURGE) this would not change the current behavior. That way every package that has shipped some directory and cleans up something in there during postrm purge can be sure that it still owns the directory and dpkg will clean this up afterwards. If the directory was really empty earlier and dpkg decided to unregister (and possibly rmdir) it, there was also nothing left for the postrm purge to clean up. (And if files to be cleaned up during purge appear *after* the package was removed, this is a serious error elsewhere.) I would really like to see this fixed for wheezy. Andreas
foobar_1.tar.gz
Description: application/tgz