]> git.ipfire.org Git - thirdparty/util-linux.git/commit - libmount/docs/libmount-sections.txt
libmount: handle btrfs default subvolume mount
authorStanislav Brabec <sbrabec@suse.cz>
Thu, 21 Jan 2016 21:58:31 +0000 (22:58 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 26 Jan 2016 10:14:25 +0000 (11:14 +0100)
commit2cd28fc82d0c947472a4700d5e764265916fba1e
tree6ed461930795e9ae8ab84a6193d1248c40f9f3bf
parent46bf6eb2775230c2f803269d5040d1586d3c8de4
libmount: handle btrfs default subvolume mount

When mounting btrfs volume without subvol= and subvolid=, and the
btrfs volume has default subvolume defined, mount() mounts the default
subvolume and not the volume root as other filesystems do.

To handle this situation correctly (for example for "mount -a"),
libmount has to be capable to detect default subvolume.

Add btrfs.c and btrfs.h that implement needed functions.

This patch adds mnt_table_find_target_with_option() to the library API.

Known problems not covered by this patch:

- Use of subvolid= in fstab is not yet handled.

- Use of type auto in combination with subvol= in fstab is not yet
  handled.

- Use of btrfs in loop devices, where image file is specified in fstab is
  not yet handled (use of /dev/loop0 in fstab works).

- If fstab uses subvol=, and subvol path changes since last "mount -a",
  subsequent "mount -a" will not recognize that it is already mounted,
  and it will attempt to mount it second time. To fix it, libmount should
  remember subvolid in time of mount (subvolid is unique for the
  subvolume, subvol is not).

- mountinfo contains subvol and subvolid since kernel 4.2. Before kernel
  4.2, there is no reasonable way to solve this situation. (One would
  create temporary mount point, mount the default, call needed ioctl() to
  determine what was mounted, deduce the default subvolume, compare it
  with subvolume of mounted volume, unmount and return result.)

How to reproduce:
truncate -s1G btrfs_test.img
mkdir -p btrfs_mnt
/sbin/mkfs.btrfs -f -d single -m single ./btrfs_test.img
mount -o loop btrfs_test.img btrfs_mnt
pushd .
cd btrfs_mnt
mkdir -p d0/dd0/ddd0
cd d0/dd0/ddd0
touch file{1..5}
btrfs subvol create s1
cd s1
touch file{1..5}
mkdir -p d1/dd1/ddd1
cd d1/dd1/ddd1
btrfs subvol create s2
rid=$(btrfs inspect rootid s2)
echo new default $rid
btrfs subvol get-default .
btrfs subvol set-default $rid .
popd
umount btrfs_mnt
losetup /dev/loop0 $PWD/btrfs_test.img
echo "/dev/loop0 $PWD/btrfs_mnt btrfs defaults 0 0" >>/etc/fstab
mount -a
mount -a
umount btrfs_mnt
sed -i "/\/dev\/loop0/d" /etc/fstab
losetup -d /dev/loop0
rm btrfs_test.img
rmdir btrfs_mnt

Current behavior:
mount: /dev/loop0 is already mounted or /root/btrfs_mnt busy
       /dev/loop0 is already mounted on /root/btrfs_mnt

Expected behavior is to ignore already mounted FS.

[kzak@redhat.com: - make 'var' optional for mnt_table_find_target_with_option(),
                  - add mnt_table_find_target_with_option() to symbols table and docs
                  - add "btrfs" string between supported debug modes
                  - minor coding style changes]

Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
Cc: David Štěrba <dsterba@suse.cz>
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/docs/libmount-sections.txt
libmount/src/Makemodule.am
libmount/src/btrfs.c [new file with mode: 0644]
libmount/src/btrfs.h [new file with mode: 0644]
libmount/src/init.c
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h
libmount/src/tab.c