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