Obter dispositivo com o número principal 0 (subvolume btrfs)

4

Quando eu declaro 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 de antemão se trata de 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 ) é montado em /boot e /home é um subvolume btrfs de sda2 ).

Editar

Eu precisaria ser capaz de fazer isso sem saber o caminho do arquivo. Acima eu usei os.stat como exemplo, mas a informação é realmente recuperada de uma chamada ioctl 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 , no entanto, ele tem um tamanho máximo de 63 caracteres, portanto, não é possível confiar nele. Eu também estou ciente de /sys/block/loopX/loop/backing_file , no entanto, 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 é poder encontrar o arquivo de apoio para um dispositivo de loop de forma confiável. Mesmo 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 é truncado, isto porque o util-linux usa a estrutura loop_info64 que tem um limite de 63 caracteres no campo lo_file_name .

O que posso obter de forma confiável é o ID do dispositivo e o número do inode do arquivo de apoio. Este é o lugar onde eu bati em uma parede, como o arquivo de apoio é armazenado em um subvolume btrfs.

    
por Jez 16.06.2014 / 06:55

1 resposta

1

Eu olhei o código-fonte do Gnu core-utils, particularmente no comando df .

Ele desce a hierarquia recursivamente até que as IDs de dispositivo sejam alteradas. No ponto em que os IDs mudam é o ponto de montagem.

Eu apenas tentei encontrar o ponto de montagem do sistema de arquivos em que ~/home/me/a-dir/another-dir está. 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, todos os condicionais e loops são feitos manualmente. Apenas para provar o conceito. Vou deixar a programação e a tradução para python como no exercício para o leitor.)

    
por 16.06.2014 / 16:40