Редактировать

Редактировать

Когда я stat файла на подтоме btrfs, я получаю основной номер устройства 0. Есть ли надежный способ найти точку монтирования этого устройства, не зная заранее, что это подтом btrfs?

например, я хотел бы иметь возможность сделать это в 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'

(в моем случае sda1( /sys/dev/block/8:1) смонтирован на /bootи /homeявляется подразделом btrfs sda2).

Редактировать

Мне нужно было бы иметь возможность сделать это, не зная пути к файлу. Выше я использовал os.statв качестве примера, однако информация на самом деле извлекается из ioctlвызова устройства цикла, которое возвращает:

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];
};

Поле есть lo_file_name, однако его максимальная длина составляет 63 символа, поэтому его нельзя считать открытым. Я также знаю о /sys/block/loopX/loop/backing_file, однако он доступен только в Linux >= 2.6.37, а мой код должен работать на CentOS 6 (2.6.32).

Редактировать №2

Моя конечная цель здесь — иметь возможность надежно найти файл поддержки для устройства loop. Даже util-linux не делает этого на ядрах < 2.6.37, например

> 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_*)

Обратите внимание, что имя файла усечено, так как util-linux использует loop_info64структуру, которая имеет ограничение в 63 символа на lo_file_nameполе.

Что я могу получить надежно, так это идентификатор устройства и номер инода резервного файла. Вот тут я и наткнулся на стену, поскольку резервный файл хранится на подтоме btrfs.

решение1

Я посмотрел исходный код Gnu core-utils, в частности команду df.

Он рекурсивно спускается по иерархии до тех пор, пока не изменятся идентификаторы устройств. В точке, где меняются идентификаторы, находится точка монтирования.

Я просто попытался найти точку монтирования файловой системы, которая ~/home/me/a-dir/another-dirнаходится в. Я сделал:

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

(Этот код — псевдо-bash, все условные операторы и циклы были сделаны вручную. Он просто доказывает концепцию. Я оставлю программирование и перевод на Python в качестве упражнения для читателя.)

Связанный контент