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

Re: Question about dpkg -r



--- Ian Jackson <ian@davenant.greenend.org.uk> wrote:

> > But when rmdir() is used on a symlink, it just
> > removes the symlink
> 
> WTF?  Have you verified this with strace ?  rmdir(2)
> on a symlink should give ENOTDIR.

Sorry, I read the following in a man-page for
rmdir(2):

If path refers to a symbolic link, rmdir() does not
affect any file or directory named by the contents of
the symbolic link.

And assumed it meant it would remove the link (while
leaving the pointed-to stuff alone). Bad assumption.
As it turns out, it's not rmdir() that's removing the
link, it's unlink(), called later in remove.c. Both
strace and dpkg -D100 -r show that's the case (should
have run those before posting, sorry).

Here's the relevant bit from the -D100 output:

D000100: removal_bulk removing `/usr'
D000100: removal_bulk unlinking `/usr'

And here's the relevant bit from strace output:

rmdir("/usr")                           = -1 ENOTDIR
(Not a directory)
lstat64("/usr", {st_mode=S_IFLNK|0777, st_size=18,
...}) = 0
unlink("/usr")   

> /usr as a symlink should work properly.

What defines "properly"? From what I can tell (which
could well be wrong), dpkg wants to "clean up"
anything referred to in a package. A 'dpkg -L zlib'
(the package (which I created) that I installed, in my
little test environment -- and the only package I
installed, then subsequently removed) outputs:

/.
/usr
/usr/include
/usr/include/zlib.h
/usr/include/zconf.h
/usr/lib
/usr/lib/libz.so.1.2.3
/usr/share
/usr/share/man
/usr/share/man/man3
/usr/share/man/man3/zlib.3
/usr/lib/libz.so
/usr/lib/libz.so.1

dpkg did not need to create /usr (the symlink), but it
wants to -- and does -- remove it just the same. As I
mentioned before, there are plenty of other files
under there, but none that came from a debian package.
And from what I can tell, that's the criteria it uses
(in the call to isdirectoryinuse()) to decide whether
to include it in the clean-up -- not whether it (or
any other debian package) created it, but simply
whether any currently installed package "uses it"
(ie., installed -into- it, and since I only installed
the one package, no other package did).

This particular test-case may be a bit artificial, but
my environment is full of symlinks, not all of which
necessarily contain any files. So even if dpkg did
check to see if the dir wasn't empty, it could still
end up removing links it didn't create, if someone
were to install a package the put files into one of
those (symlink) dirs, then removed that package.
That's why my thought was to either have a way to tell
dpkg to remove only files/symlinks-to-files (which
might be easier, but maybe not a great solution, since
it does have the potential for the clean-up to leave
cruft lying around), or, probably better (although I
can't say how complicated it might be to implement),
have dpkg keep a global record of
dirs/symlinks-to-dirs it actually did create, and have
it check that when it's deciding what to remove (along
with the current "in use" check), so if dpkg didn't
create it (for any package it installed), it wouldn't
remove it.

Thanks,
Hope


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



Reply to: