Re: Removing directories/files in RPM erase

Jeff Johnson <[email protected]> Wed, 21 May 2008 20:03:51 -0400
Newsgroups gmane.linux.redhat.rpm.general
Message-ID <[email protected]>
On May 21, 2008, at 7:27 PM, Tim Mooney wrote:

>
>> However, when I remove the RPM, it doesn't remove the directories  
>> because
>> they aren't empty.  Should I setup a post uninstall to see if this  
>> is the
>> last instance of the package and if it is, manually remove those
>> directories?
>
> Look up the %ghost attribute (?, token?, I'm not sure what it should  
> be
> classified as) and see if that does what you need.
>

%ghost won't solve removing nonempty directories. The %ghost directive,
with its mysterious name, claims ownership for a package of a pre- 
existing path. If the
path happens to be a directory, the erase behavior will be identical to
that when the directory is explicitly part of a package.

On erase, rpm runs rmdir(2) on "owned" (i.e. directories that are  
explcitly
part of a package) directories. rmdir(2) will fail with ENOTEMPTY
if there are files within the directory. That behavior is (imho)  
exactly what  one wishes: rpm
already removes files in reverse order, i.e. members of the directory  
before parent directory,
so any remaining files are from other packages (which will eventually  
succeed with rmdir(2)),
or from side effects (in which case the unknown files should not be  
touched).

If the directory contents are created outside of rpm, then its up to  
something
other than rpm to manage the directory contents.

If the directory contents are being created by %post scripts, then the  
additionally created
files should be removed in %preun for symmetry.

If the directory contents are within other packages you need  pin down  
which package
should "own" the directory, and arrange through dependencies for that  
package to be installed
first (and removed last if you have erasure ordering). The "best  
effort" rmdir(2) will
eventually succeed when all other contents are removed. The number of  
files
within the directory works as a defacto reference count, the only  
difference from
a true reference count is that a rmdir(2) is attempted, but silently/ 
harmlessly fails.

Establishing ownership of a directory in packaging, particularly for  
some public path in which, say, modules
are installed, can be quite complicated. Putting the specific  
directory path in its own package, or in
a directory path skeleton package like filesystem, or adding a  
Requires: /path/to/directory (or other
ordering hint no matter how expressed) may help establish which  
package is responsible for
removing a given directory.

73 de Jeff