When I stat a file on a btrfs subvolume I get a major device number of 0
.
Is there a reliable way to find the mount point of this device, without knowing in advance it is a btrfs subvolume?
e.g. I'd like to be able to do this in python:
>>> st = os.stat('a file')
>>> os.major(st.st_dev)
0
>>> os.minor(st.st_dev)
38
>>> os.path.exists('/sys/dev/block/0:38')
False
>>> magic_method_that_gets_mount_point(0, 38)
'/home'
>>> magic_method_that_gets_mount_point(8, 1)
'/boot'
(in my case sda1
(/sys/dev/block/8:1
) is mounted on /boot
, and /home
is a btrfs subvolume of sda2
).
Edit
I'd need to be able to do this without knowing the path of the file. Above I used os.stat
as an example however the information is actually retrieved from an ioctl
call to a loop device which returns:
struct loop_info64 {
uint64_t lo_device;
uint64_t lo_inode;
uint64_t lo_rdevice;
uint64_t lo_offset;
uint64_t lo_sizelimit;
uint32_t lo_number;
uint32_t lo_encrypt_type;
uint32_t lo_encrypt_key_size;
uint32_t lo_flags;
uint8_t lo_file_name[64];
uint8_t lo_crypt_name[64];
uint8_t lo_encrypt_key[32];
uint64_t lo_init[2];
};
There is the field lo_file_name
however it has a max length of 63 chars so cannot be relied open. I am also aware of /sys/block/loopX/loop/backing_file
, however this is only available in Linux >= 2.6.37 and my code needs to run on CentOS 6 (2.6.32).
Edit #2
My ultimate goal here is to be able to find the backing file for a loop device reliably. Even util-linux does not do this on kernels < 2.6.37, e.g.
> dd if=/dev/urandom bs=4096 count=256 of=/root/a_really_really_really_really_really_really_really_long_file_name.img
256+0 records in
256+0 records out
1048576 bytes (1.0 MB) copied, 0.137397 s, 7.6 MB/s
> LD=`losetup -f --show /root/a_really_really_really_really_really_really_really_long_file_name.img`
> losetup $LD
/dev/loop1: [fd00]:922372 (/root/a_really_really_really_really_really_really_really_long_*)
Notice that the filename is truncated, this is because util-linux uses the loop_info64
struct which has a 63 char limit on the lo_file_name
field.
What I can get reliably is the device ID and the inode number of the backing file. This is where I hit a wall, as the backing file is stored on a btrfs subvolume.
Best Answer
I looked at the Gnu core-utils source code, particularly at the
df
command.It recursively descends the hierarchy until the device IDs change. At the point where the IDs change is the mount point.
I just tried to find the mount point of the filesystem that
~/home/me/a-dir/another-dir
is in. I did:(this code is pseudo bash, all the conditional and loops where done manually. It just to prove the concept. I will leave the programming and translation to python as on exercise for the reader.)