7

I'm playing with some disk images via loopback devices (e.g. /dev/loop0). When viewed in the Disks (Disk Utility) application there's a setting labeled "Auto-clear" which is currently set to OFF.

What does this setting do? Is it specific to loop-back devices?

(And how could I have found the answer myself? Tried Disks > Help, but it doesn't appear to support searching in a sensible way, and I didn't know which of the top-level choices to select (.. table of contents anyone?))

RobM
  • 330

3 Answers3

3

Yes, it is specific to loop devices. It means that when the loop device is unmounted, it will automatically be disassociated from the backing file.

psusi
  • 38,031
1

Minimal runnable example

First we create a test filesystem as explained here:

mkdir sysroot
dd if=/dev/urandom of=sysroot/myfile bs=1024 count=1024
virt-make-fs --format=raw --type=ext2 sysroot sysroot.ext2

Now:

$ mkdir mnt
$ # mount can deduce "-o loop -t ext2" nowadays.
$ sudo mount sysroot.ext2 mnt
$ # Mount worked fine.
$ cmp mnt/myfile sysroot/myfile
$ losetup
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE               DIO LOG-SEC
/dev/loop0         0      0         1  0 /home/ciro/sysroot.ext2   0     512
$ # I don't trust userland.
$ cat /sys/devices/virtual/block/loop0/loop/autoclear
1
$ sudo umount
$ losetp
$

Therefore we see that mount:

  • creates a loop device
  • sets AUTOCLEAR for it by default-o loop -t ext2

and then when umount sees AUTOCLEAR is set, it automatically destroys the file.

Minimal counter example

By creating the loop device manually with losetup, we can see what happens when AUTOCLEAR is not set:

$ sudo losetup /dev/loop0 sysroot.ext2
losetup: sysroot.ext2: Warning: file does not fit into a 512-byte sector; the end of the file will be ignored.
$ losetup
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE               DIO LOG-SEC
/dev/loop0         0      0         0  0 /home/ciro/sysroot.ext2   0     512
$ cat /sys/devices/virtual/block/loop0/loop/autoclear
0
$ sudo mount /dev/loop0 mnt
$ cmp mnt/myfile sysroot/myfile
$ sudo umount mnt
$ losetup
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE               DIO LOG-SEC
/dev/loop0         0      0         0  0 /home/ciro/sysroot.ext2   0     512
$ sudo mount /dev/loop0 mnt
$ sudo umount -d mnt
$ losetup

So we see that:

  • umount without options did not clear the loop device for us
  • umount -d did clear it

Alternatively, we can also detach the loop device with:

sudo mount /dev/loop0 mnt
sudo umount mnt
sudo losetup -d /dev/loop0

Automatic losetup on used filesystem

man losetup says:

-d Detach the file or device associated with the specified loop device(s). Note that since Linux v3.7 kernel uses "lazy device destruction". The detach operation does not return EBUSY error anymore if device is actively used by system, but it is marked by autoclear flag and destroyed later.

and we verify with:

$ sudo losetup /dev/loop0 sysroot.ext2
$ sudo mount /dev/loop0 mnt
$ cat /sys/devices/virtual/block/loop0/loop/autoclear
0
$ sudo losetup -d /dev/loop0
$ cat /sys/devices/virtual/block/loop0/loop/autoclear
1
$ # Still mounted.
$ cmp mnt/myfile sysroot/myfile
$ sudo umount mnt
$ losetup
$

So we see that if you do losetup -d befor umount, it sets autoclear automatically.

Low level view

A quick:

sudo strace mount sysroot.ext2 mnt

shows that the main system calls are:

openat(AT_FDCWD, "/dev/loop0", O_RDWR|O_CLOEXEC) = 4
ioctl(4, LOOP_SET_STATUS64, {lo_offset=0, lo_number=0, lo_flags=LO_FLAGS_AUTOCLEAR, lo_file_name="/home/ciro/sysroot.ext2", ...}) = 0
mount("/dev/loop0", "/home/ciro/test/libguestfs/mnt", "ext2", MS_MGC_VAL, NULL) = 0

so we see that losetup operations are basically done through ioctl.

The kernel source v4.17 of interest is:

Have a look at this minimal example If you are not familiar with ioctl: https://stackoverflow.com/questions/2264384/how-do-i-use-ioctl-to-manipulate-my-kernel-module/44613896#44613896

Tested on Ubuntu 18.04.

1

I am not an expert on loop devices, but I can walk you through what I did to find some things out.

After searching for "auto-clear loop" in a well-known search engine, I found -- apart from this question -- the patch that added the feature to gnome-disk-utility.

I couldn't really understand the code, but I decided the crucial part probably involved the function udisks_loop_call_set_autoclear.

I searched for this, found the UDisks Reference Manual, and saw that it invoked something called SetAutoclear, which it turns out, sets the "AutoClear" property. Which apparently means:

If TRUE, the kernel will automatically clear the loop device when the last closer closes the device. This typically happens when the loop device is unmounted.

Searching for "clear loop device" (or searching man losetup for 'clear') wasn't excessively helpful, so at this point I'm guessing "clear" is just a synonym for "detach".

I couldn't find anything about auto-detaching loops in the manpage, so decided perhaps it happens on the mount level.

Looking at man mount and searching for 'loop', I found this sentence:

Since Linux 2.6.25 auto-destruction of loop devices is supported, meaning that any loop device allocated by mount will be freed by umount independently of /etc/mtab.

I'm guessing "auto-destruction" is basically another synonym for "auto-clear".

So as of a 2008 kernel release, any loops created automatically by mount will be cleared automatically when unmounted. But apparently you can bypass that by flipping a switch in the Gnome Disk Utility.

I'm presuming there is a way to control this from the command line as well, and that would be the answer I'd want to give you, but I can't easily find it.

I would probably have to wade through more code (maybe look for other projects where similar functions are called), or learn more about loop devices or the kernel.

mwfearnley
  • 3,497