retitle 575891 dpkg makes wrong assumption about readdir() and lose metadata 
files with btrfs
severity 575891 important
tag 575891 confirmed
thanks

On Tue, 30 Mar 2010, Raphael Hertzog wrote:
> I'm sorry, there's no way that we as dpkg maintainers are going to
> investigate problems that are likely to come from the filesystem itself at
> this point.

Fortunately other people stepped in (cwillu aka Carey Underwood) and asked
the btrfs authors.

The problem appears to be in dpkg itself, it is assuming that readdir()
will not return the same filename twice but with btrfs it does when one
of the files in the directory is replaced while readdir() is still
happening.

The problematic code is in src/processarc.c after line 828:

What it does in pseudo-code:
opendir("/var/lib/dpkg/info");
while(readdir() != NULL) {
    if (rename(newer_version_in_tmp, file_in_info_dir) == 0) {
        // file updated with newer version
    } else if (errno == ENOENT) {
        // file not found in newer version, assume it's removed
        unlink(file_in_info_dir);
    }
}

Now considers that after a successfull rename(), btrfs will return the
newly replaced file again because it's not the same file (different inode
even though it has a filename that has already been returned)
and it's treated like an added file (and POSIX doesn't specify what
implementations are supposed to do:
http://www.opengroup.org/onlinepubs/9699919799/functions/readdir.html)

The second time we see the file, the original temporary file is gone and
we decide to unlink the just installed file...

Thus the rename() needs to happen after the whole readdir() loop is finished.

Cheers,
-- 
Raphaƫl Hertzog

Like what I do? Sponsor me: http://ouaza.com/wp/2010/01/05/5-years-of-freexian/
My Debian goals: http://ouaza.com/wp/2010/01/09/debian-related-goals-for-2010/



--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to