On Tue, Mar 7, 2017 at 6:12 PM, Mirko Vogt <busy...@nanl.de> 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.
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to