[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: Automatic deletion of loopback device upon umount?
From:       Denys Vlasenko <vda.linux () googlemail ! com>
Date:       2017-03-16 16:51:54
Message-ID: CAK1hOcNgwTsuGOzrbmidVH_kPZTg+F-KM6YgJUT1mnopcFQ+aA () mail ! gmail ! com
[Download RAW message or body]

On Wed, Mar 15, 2017 at 7:16 PM, Denys Vlasenko
<vda.linux@googlemail.com> wrote:
> On Wed, Mar 15, 2017 at 3:16 AM, Denys Vlasenko
> <vda.linux@googlemail.com> wrote:
>> On Tue, Mar 7, 2017 at 6:12 PM, Mirko Vogt <busybox@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.
>
> I propose this as the fix:

Pushed fixes to git.
Please let me know whether the problem still exists.
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic