Comment 3 for bug 2015400

Revision history for this message
Mauricio Faria de Oliveira (mfo) wrote :

Simpler workarounds:

For non-existing /dev/loopN devices, `losetup /dev/loopN image` should work (i.e., don't do `mknod /dev/loopN`).

For /dev/non-loopN devices, it doesn't (different code path), so the utility attached should help for now.

Details below.

...

# lsb_release -cs
jammy

# uname -rv
5.15.0-69-generic #76-Ubuntu SMP Fri Mar 17 17:19:29 UTC 2023

# cat /sys/module/loop/parameters/max_loop
8

# ls -1 /dev/loop*
/dev/loop-control
/dev/loop0
/dev/loop1
/dev/loop2
/dev/loop3
/dev/loop4
/dev/loop5
/dev/loop6
/dev/loop7

# grep loop /proc/devices
  7 loop

# truncate -s 1g test

Case 1) Existing /dev/loopN: LOOP_CTL_ADD is not called, open() fails (non-init mutex, apparently).

# mknod /dev/loop8 b 7 8
# strace -e openat,ioctl losetup /dev/loop8 test 2>&1 | grep -i loop
openat(AT_FDCWD, "/dev/loop8", O_RDWR|O_CLOEXEC) = -1 ENXIO (No such device or address)
openat(AT_FDCWD, "/dev/loop8", O_RDWR|O_CLOEXEC) = -1 ENXIO (No such device or address)
losetup: /dev/loop8: failed to set up loop device

Case 2) Non-existing /dev/loopN: LOOP_CTL_ADD is called, open() works.

# rm /dev/loop8

# strace -e openat,ioctl losetup /dev/loop8 test 2>&1 | grep -i loop
openat(AT_FDCWD, "/dev/loop-control", O_RDWR|O_CLOEXEC) = 3
ioctl(3, LOOP_CTL_ADD, 8) = 8
openat(AT_FDCWD, "/dev/loop8", O_RDWR|O_CLOEXEC) = 4
ioctl(4, LOOP_CONFIGURE, {fd=3, block_size=0, info={lo_offset=0, lo_number=0, lo_flags=0, lo_file_name="/root/test", ...}}) = 0

Case 3) Non-existing /dev/non-loopN: LOOP_CTL_ADD is not called, open() fails.

# strace -e openat,ioctl losetup /dev/mynameX test 2>&1 | grep -i loop
losetup: /dev/mynameX: failed to set up loop device

Case 4) Existing /dev/non-loopN with workaround tool (attached)

# gcc -o loop-ctl-add loop-ctl-add.c

# mknod /dev/mynameX b 7 42

# losetup /dev/mynameX test
losetup: /dev/mynameX: failed to set up loop device: No such device or address

# ./loop-ctl-add 42
Success on ioctl('/dev/loop-control', LOOP_CTL_ADD, 42)

# losetup /dev/mynameX test
#

works!