Quando eu coloco um arquivo em um subvolume btrfs, recebo um número de dispositivo principal de 0
. Existe uma maneira confiável de encontrar o ponto de montagem deste dispositivo, sem saber antecipadamente que é um subvolume Btrfs?
por exemplo, eu gostaria de poder fazer isso em 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'
(no meu caso sda1
( /sys/dev/block/8:1
) está montado /boot
e /home
é um subvolume btrfs de sda2
).
Editar
Eu precisaria ser capaz de fazer isso sem saber o caminho do arquivo. Acima usei os.stat
como exemplo, porém a informação é na verdade recuperada de uma ioctl
chamada para um dispositivo de loop que retorna:
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];
};
Existe o campo lo_file_name
, mas ele tem um comprimento máximo de 63 caracteres, portanto não pode ser confiável aberto. Também estou ciente /sys/block/loopX/loop/backing_file
, mas isso só está disponível no Linux >= 2.6.37 e meu código precisa ser executado no CentOS 6 (2.6.32).
Editar #2
Meu objetivo final aqui é encontrar o arquivo de backup para um dispositivo de loop de maneira confiável. Mesmo o util-linux não faz isso em kernels <2.6.37, por exemplo
> 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_*)
Observe que o nome do arquivo está truncado, isso ocorre porque o util-linux usa a loop_info64
estrutura que possui um limite de 63 caracteres no lo_file_name
campo.
O que posso obter com segurança é o ID do dispositivo e o número do inode do arquivo de backup. Foi aqui que bati na parede, pois o arquivo de backup está armazenado em um subvolume btrfs.
Responder1
Examinei o código-fonte do Gnu core-utils, principalmente o df
comando.
Ele desce recursivamente na hierarquia até que os IDs dos dispositivos sejam alterados. No ponto onde os IDs mudam está o ponto de montagem.
Eu apenas tentei encontrar o ponto de montagem do sistema de arquivos que ~/home/me/a-dir/another-dir
está dentro. Eu fiz:
stat . #noting device IDs
while id not changes and root not hit
do
cd ..
stat .
done
if root not hit
then
cd -
fi
(este código é pseudo bash, todas as condicionais e loops foram feitos manualmente. É apenas para provar o conceito. Deixarei a programação e tradução para python como no exercício para o leitor.)