[pacman-dev] Strange (critical) bug with checkspace
Hi! I've run into the following bug: $ df -h Filesystem Size Used Avail Use% Mounted on rootfs 44G 30G 13G 71% / /dev 501M 0 501M 0% /dev /run 503M 276K 503M 1% /run /dev/sda3 44G 30G 13G 71% / none 503M 0 503M 0% /dev/shm /dev/sda1 30G 29G 1.6G 95% /c /dev/sr0 4.2G 4.2G 0 100% /e [Don't laugh at my mountpoints.] $ sudo pacman -Su ... Total Installed Size: 900.93 MiB Net Upgrade Size: 139.47 MiB ... error: Partition /e is mounted read only error: not enough free disk space error: failed to commit transaction (not enough free disk space) Errors occurred, no packages were upgraded. What?! I think none of our packages wants to write to /e/... I've tried with both pacman 4.0.2-1 and pacman-git, the result is the same. I've also tried with "pacman -S randompkg", that worked fine. I don't want to umount /e, because I am afraid of the fact that I might not be able to reproduce this bug any more... The relevant part of --debug log says nothing: [04:19:41] debug: checking available disk space [04:19:41] debug: mountpoint: /sys [04:19:41] debug: mountpoint: /run [04:19:41] debug: mountpoint: /root/.gvfs [04:19:41] debug: mountpoint: /proc [04:19:41] debug: mountpoint: /e [04:19:41] debug: mountpoint: /dev/shm [04:19:41] debug: mountpoint: /dev/pts [04:19:41] debug: mountpoint: /dev [04:19:41] debug: mountpoint: /c [04:19:41] debug: mountpoint: / [04:19:41] debug: mountpoint: / [04:19:41] error: Partition /e is mounted read only [04:19:41] debug: partition /, needed 3897, cushion 5121, free 3727796 [04:19:41] debug: returning error 7 from _alpm_check_diskspace : not enough free disk space [04:19:41] error: not enough free disk space [04:19:41] error: failed to commit transaction (not enough free disk space) [04:19:41] debug: unregistering database 'local' NG
Hi!
I've run into the following bug: $ df -h Filesystem Size Used Avail Use% Mounted on rootfs 44G 30G 13G 71% / /dev 501M 0 501M 0% /dev /run 503M 276K 503M 1% /run /dev/sda3 44G 30G 13G 71% / none 503M 0 503M 0% /dev/shm /dev/sda1 30G 29G 1.6G 95% /c /dev/sr0 4.2G 4.2G 0 100% /e
[Don't laugh at my mountpoints.]
$ sudo pacman -Su ... Total Installed Size: 900.93 MiB Net Upgrade Size: 139.47 MiB ... error: Partition /e is mounted read only error: not enough free disk space error: failed to commit transaction (not enough free disk space) Errors occurred, no packages were upgraded.
What?! I think none of our packages wants to write to /e/... No, but the packages you were installing *did* want to write to /etc, and we fail hard because we apparently prefix match and don't make sure it ends in a directory separator. Working on a fix, will submit a
On Sun, Feb 19, 2012 at 9:25 PM, Nagy Gabor <ngaba@bibl.u-szeged.hu> wrote: patch soon. This is 100% reproducible: mkdir /e; mount something ro there, `pacman -S libao` or any other package that installs something in /etc.
I've tried with both pacman 4.0.2-1 and pacman-git, the result is the same. I've also tried with "pacman -S randompkg", that worked fine. I don't want to umount /e, because I am afraid of the fact that I might not be able to reproduce this bug any more...
The relevant part of --debug log says nothing: [04:19:41] debug: checking available disk space [04:19:41] debug: mountpoint: /sys [04:19:41] debug: mountpoint: /run [04:19:41] debug: mountpoint: /root/.gvfs [04:19:41] debug: mountpoint: /proc [04:19:41] debug: mountpoint: /e [04:19:41] debug: mountpoint: /dev/shm [04:19:41] debug: mountpoint: /dev/pts [04:19:41] debug: mountpoint: /dev [04:19:41] debug: mountpoint: /c [04:19:41] debug: mountpoint: / [04:19:41] debug: mountpoint: / [04:19:41] error: Partition /e is mounted read only [04:19:41] debug: partition /, needed 3897, cushion 5121, free 3727796 [04:19:41] debug: returning error 7 from _alpm_check_diskspace : not enough free disk space [04:19:41] error: not enough free disk space [04:19:41] error: failed to commit transaction (not enough free disk space) [04:19:41] debug: unregistering database 'local'
NG
If one had a mountpoint at '/e' (don't ask), a file being installed to '/etc' would map to it incorrectly. Ensure we do more than just prefix matching on paths by doing some more sanity checks once the simple strncmp() call succeeds. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/diskspace.c | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index d0f52a6..45908b2 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -179,8 +179,20 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, for(mp = mount_points; mp != NULL; mp = mp->next) { alpm_mountpoint_t *data = mp->data; + /* first, check if the prefix matches */ if(strncmp(data->mount_dir, real_path, data->mount_dir_len) == 0) { - return data; + /* now, the hard work- a file like '/etc/myconfig' shouldn't map to a + * mountpoint '/e', but only '/etc'. If the mountpoint ends in a trailing + * slash, we know we didn't have a mismatch, otherwise we have to do some + * more sanity checks. */ + if(data->mount_dir[data->mount_dir_len - 1] == '/') { + return data; + } else if(strlen(real_path) >= data->mount_dir_len) { + const char next = real_path[data->mount_dir_len]; + if(next == '/' || next == '\0') { + return data; + } + } } } -- 1.7.9.1
Well, I did some good old printf debugging: pacman simply thinks that /etc/... files will be installed to /e. I think there is a string comparison bug somewhere in the code, but I am too tired to find it now (and fully read diskspace.c). NG
participants (3)
-
Dan McGee
-
Dan McGee
-
Nagy Gabor