Editar

Editar

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 /boote /homeé um subvolume btrfs de sda2).

Editar

Eu precisaria ser capaz de fazer isso sem saber o caminho do arquivo. Acima usei os.statcomo exemplo, porém a informação é na verdade recuperada de uma ioctlchamada 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_info64estrutura que possui um limite de 63 caracteres no lo_file_namecampo.

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 dfcomando.

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-direstá 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.)

informação relacionada