On Wed, Mar 15, 2017 at 7:16 PM, Denys Vlasenko <[email protected]> wrote: > On Wed, Mar 15, 2017 at 3:16 AM, Denys Vlasenko > <[email protected]> wrote: >> On Tue, Mar 7, 2017 at 6:12 PM, Mirko Vogt <[email protected]> wrote: >>>> "foo" is a cramfs filesystem file which might help illustrate the issue >>>> >>>> 1) loopback mount "foo" to mount /bar >>>> 2) umount /bar >>>> 3) append new files and re-generate the "foo" cramfs image >>>> 4) loopback mount "foo" to mount /bar >>>> 5) the contents of /bar are the same as in 1) and not 3) >>>> >>>> the reason for this is because busybox has not deleted the "foo" <-> >>>> loopback device mapping, so when we attempt to mount again "foo", the >>>> mapping is already there, so the loopback device is not deleted then >>>> re-created. >>>> >>>> Obviously using umount -d in 2) fixes the issue, but I was wondering >>>> whether it would not be preferable to unconditionnaly delete the >>>> loopback device upon umount? util-linux does this actually, so other >>>> users might also be puzzled by such a case. >>> >>> I'm quoting most of the mail since it has been a while.. this "feature" >>> hit me today, however from a different angle. >>> >>> It seems LOOP_CLR_FD called on a loop-*partition* removes the mapping of >>> the whole *device* - which results in the following: >>> >>> root@LEDE:/# loop=$(losetup -f) >>> root@LEDE:/# echo ${loop} >>> /dev/loop2 >>> root@LEDE:/# losetup ${loop} /IMAGE >>> root@LEDE:/# ls -l ${loop}* >>> brw------- 1 root root 7, 2 Mar 6 20:09 /dev/loop2 >>> root@LEDE:/# partprobe ${loop} >>> root@LEDE:/# ls -l ${loop}* >>> brw------- 1 root root 7, 2 Mar 6 20:09 /dev/loop2 >>> brw------- 1 root root 259, 8 Mar 6 21:59 /dev/loop2p1 >>> brw------- 1 root root 259, 9 Mar 6 21:59 /dev/loop2p2 >>> brw------- 1 root root 259, 10 Mar 6 21:59 /dev/loop2p3 >>> brw------- 1 root root 259, 11 Mar 6 21:59 /dev/loop2p4 >>> brw------- 1 root root 259, 12 Mar 6 21:59 /dev/loop2p5 >>> brw------- 1 root root 259, 13 Mar 6 21:59 /dev/loop2p6 >>> brw------- 1 root root 259, 14 Mar 6 21:59 /dev/loop2p7 >>> brw------- 1 root root 259, 15 Mar 6 21:59 /dev/loop2p8 >>> root@LEDE:/# mount ${loop}p8 /MOUNT # mount loop partition >>> root@LEDE:/# losetup -a | grep $loop # loop dev mapping still there >>> /dev/loop2: 0 /mnt/IMAGE >>> root@LEDE:/# strace umount /MOUNT 2> /log # unmount loop partition >>> root@LEDE:/# losetup -a | grep ${loop} # loop device mapping is gone >>> root@LEDE:/# grep -i loop /log >>> open("/dev/loop2p7", O_RDONLY|O_LARGEFILE) = 3 >>> ioctl(3, LOOP_CLR_FD) = 0 >>> root@LEDE:/# >>> >>> The strace was done to figure out, if maybe umount wrongly ioctl()'s the >>> parent device instead of the partition - it doesn't. >>> >>> I already wasn't a fan of umount implicitly removing the mapping in the >>> first place (as I usually setup and release loop devices with `losetup` >>> and scripts needed to call umount differently in order to work and >>> outside busybox). >>> >>> However taking above (kernel-)behaviour into account - umount calling >>> ioctl(LOOP_CLR_FD) unconditionally potentially causes some nasty side >>> effects, why I'd like to re-open that discussion. >> >> >> What a surprise. No one foresaw this to bite, right? ;) >> [to understand the snark, read the entire thread] >> >> Now seriously. >> You can use umount -D to suppress this. >> Unfortunately, util-linux's umount does not have that option, thus >> your scripts would become incompatible with util-linux if you go that route. >> >> Their manpage says: >> >> LOOP DEVICE >> The umount command will free the loop device associated with a mount >> when it finds the option loop=... in /etc/mtab, or when the -d option >> was given. Any still associated loop devices can be freed >> by using losetup -d; see losetup(8). >> >> We can try to match this description. However, it is lying: >> util-linux's umount somehow detects automatic loop mounts >> even when /etc/mtab does not contain "loop". >> >> First, I'm using util-linux's mount on a 1mbyte ext2 image: >> >> # mount -oloop z zz >> # ls -l /etc/mtab >> lrwxrwxrwx. 1 root root 19 May 24 2016 /etc/mtab -> ../proc/self/mounts >> # cat /etc/mtab | grep loop >> /dev/loop0 /home/srcdevel/bbox/fix/busybox.t6/zz ext2 >> rw,relatime,block_validity,barrier,user_xattr,acl 0 0 >> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no "loop" >> # umount zz >> # cat /etc/mtab | grep loop >> # losetup >> <nothing>: /dev/loop0 freed >> >> Now the same with bbox mount: >> >> # ./busybox mount -oloop z zz >> # cat /etc/mtab | grep loop >> /dev/loop0 /home/srcdevel/bbox/fix/busybox.t6/zz ext4 >> rw,relatime,block_validity,delalloc,barrier,user_xattr,acl 0 0 >> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no "loop" >> # umount zz >> # losetup >> NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE >> DIO >> /dev/loop0 0 0 0 0 >> /home/srcdevel/bbox/fix/busybox.t6/z 0 >> >> Clearly, util-linux umount looks somewhere else to determine whether >> to free the loop device. >> Hmm... >> >> # mount -oloop z zz >> # losetup >> NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE >> DIO >> /dev/loop0 0 0 1 0 >> /home/srcdevel/bbox/fix/busybox.t6/z 0 >> >> >> It's probably the "AUTOCLEAR" thing. > > I propose this as the fix:
Pushed fixes to git. Please let me know whether the problem still exists. _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
