5

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.

4
  • This may be a good candidate for posting on Stack Overflow, though it is clearly *nix-focused.
    – HalosGhost
    Jun 16, 2014 at 6:04
  • 1
    I considered posting there but thought my SNR would be higher here. I'm not looking for an implementation of magic_method_that_gets_mount_point, just need to know where to look to find this info (/proc/ABC, /sys/XYZ, etc.)
    – Jez
    Jun 16, 2014 at 6:37
  • in bash I can type df 'a file' it produces a line like this /dev/sda6 119510112 67893632 45546216 60% /home. So we need to look at what df does. Jun 16, 2014 at 14:19
  • See gnu core utils for how they do it. searchcode.com/codesearch/view/17947138 Jun 16, 2014 at 14:24

1 Answer 1

1

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:

stat . #noting device IDs
while id not changes and root not hit
do
  cd ..
  stat .
done
if root not hit
then
  cd -
fi

(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.)

2
  • That's a pretty good suggestion however in this particular case I don't have a filename, just a device number and inode number. I'll update my question shortly.
    – Jez
    Jun 16, 2014 at 23:40
  • @jez OK you just changed the problem context. Can you elaborate on the context, it may help someone see a way. Some times the answer is “step back 3 paces, turn left and the exit will be on your right”, but without context we get focused on the wrong detail. Jun 17, 2014 at 9:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .