Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

btrfs-progs: remove loopback device resolution #940

Open
wants to merge 1 commit into
base: devel
Choose a base branch
from

Conversation

adam900710
Copy link
Collaborator

[BUG]
mkfs.btrfs has a built-in loopback device resolution, to avoid the same file being added to the same fs, using loopback device and the file itself.

But it has one big bug:

  • It doesn't detect partition on loopback devices correctly The function is_loop_device() only utilize major number to detect a loopback device. But partitions on loopback devices doesn't use the same major number as the loopback device:

    NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
    loop0 7:0 0 5G 0 loop
    |-loop0p1 259:3 0 128M 0 part
    `-loop0p2 259:4 0 4.9G 0 part

    Thus /dev/loop0p1 will not be treated as a loopback device, thus it will not even resolve the source file.

    And this can not even be fixed, as if we do extra "/dev/loop*" based file lookup, /dev/loop0p1 and /dev/loop0p2 will resolve to the same source file, and refuse to mkfs on two different partitions.

[FIX]
The loopback file detection is the baby sitting that no one asks for.

Just as I explained, it only brings new bugs, and we will never fix all ways that an experienced user can come up with.
And I didn't see any other mkfs tool doing such baby sitting.

So remove the loopback file resolution, just regular is_same_blk_file() is good enough.

[BUG]
mkfs.btrfs has a built-in loopback device resolution, to avoid the same
file being added to the same fs, using loopback device and the file
itself.

But it has one big bug:

- It doesn't detect partition on loopback devices correctly
  The function is_loop_device() only utilize major number to detect a
  loopback device.
  But partitions on loopback devices doesn't use the same major number
  as the loopback device:

  NAME            MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
  loop0             7:0    0    5G  0 loop
  |-loop0p1       259:3    0  128M  0 part
  `-loop0p2       259:4    0  4.9G  0 part

  Thus `/dev/loop0p1` will not be treated as a loopback device, thus it
  will not even resolve the source file.

  And this can not even be fixed, as if we do extra "/dev/loop*" based
  file lookup, `/dev/loop0p1` and `/dev/loop0p2` will resolve to the
  same source file, and refuse to mkfs on two different partitions.

[FIX]
The loopback file detection is the baby sitting that no one asks for.

Just as I explained, it only brings new bugs, and we will never fix all
ways that an experienced user can come up with.
And I didn't see any other mkfs tool doing such baby sitting.

So remove the loopback file resolution, just regular is_same_blk_file()
is good enough.

Signed-off-by: Qu Wenruo <wqu@suse.com>
@DaanDeMeyer
Copy link

@adam900710 Same problem it seems:

~/systemd (main)> sudo SYSTEMD_LOG_LEVEL=debug ~/.local/bin/mkosi --runtime-size=15G boot
...
Opened '/work/home/daandemeyer/systemd/build/mkosi.output/image' in O_RDONLY access mode, with O_DIRECT enabled.
Determined sector size 512 based on discovered partition table.
loop7: Acquired exclusive lock.
Successfully acquired /dev/loop7, devno=7:7, nr=7, diskseq=164
Kernel was quicker than us in adding partition 1.
Dissecting esp partition with label esp and UUID 1a42d708-b379-42a1-a4fe-352671054494
Opened /dev/loop7p1 (fd=3, whole_block_devnum=7:7, diskseq=164).
Kernel was quicker than us in adding partition 2.
Dissecting root partition with label root-x86-64 and UUID 8f26912a-a13a-4155-91b1-00229a0e558b
Opened /dev/loop7p2 (fd=4, whole_block_devnum=7:7, diskseq=164).
Probed fstype 'btrfs' on partition /dev/loop7p2.
Mounting /proc/self/fd/4 (btrfs) on /run/systemd/mount-rootfs (MS_RDONLY|MS_NODEV "")...
Mounting /proc/self/fd/3 (vfat) on /run/systemd/mount-rootfs/boot (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_NOSYMFOLLOW "fmask=0177,dmask=0077")...
No machine ID set, using randomized partition UUIDs.
File '/work/home/daandemeyer/systemd/build/mkosi.output/image' already is of requested size or larger, not growing. (15G >= 15G)
Determined sector size 512 based on discovered partition table.
Sector size of device is 512 bytes. Using filesystem sector size of 4096 and grain size of 4096.
Applying changes to /work/home/daandemeyer/systemd/build/mkosi.output/image.
Successfully wiped file system signatures from future partition 2.
Successfully discarded data from future partition 2.
Successfully discarded gap after partition 2.
loop9: Acquired exclusive lock.
Successfully acquired /dev/loop9, devno=7:9, nr=9, diskseq=165
Formatting future partition 2.
Executing mkfs command: mkfs.btrfs -L usr-x86-64 -U f3267595-6a80-4d84-83f1-ee182490edec --sectorsize=4096 /dev/loop9
Successfully forked off '(mkfs)' as PID 3944793.
WARNING: eprecated, use -O|--atures instead
btrfs-progs v6.12 
See https://btrfs.readthedocs.io for more information.

ERROR: /dev/loop9 is mounted
(mkfs) failed with exit status 1.
Failed to umount /run/systemd/mount-rootfs, ignoring: Device or resource busy
‣ "systemd-repart --image /work/home/daandemeyer/systemd/build/mkosi.output/image --size=16106127360 --no-pager --dry-run=no --offline=no --pretty=no /work/home/daandemeyer/systemd/build/mkosi.output/image" returned non-zero exit code 1.

@adam900710
Copy link
Collaborator Author

@DaanDeMeyer Mind to share what's needed to reproduce the problem?

On my environment (Archlinux) it doesn't seems to fail at all (and created the rootfs using ext4)

Is there anyway to force it to use btrfs instead?

@DaanDeMeyer
Copy link

@adam900710 Apologies, a full reproducer can be found in systemd/systemd#36264. Note that this reproduces both btrfs issues we're seeing. You'll first encounter the issue described in https://lore.kernel.org/linux-fsdevel/20250115185608.GA2223535@zen.localdomain/T/#u, and if that one is fixed (or you're not running a kernel with the change that triggers that issue), mkfs.btrfs will start failing after that due to the loopback device error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants