Editar

Editar

Cuando establezco un archivo en un subvolumen btrfs, obtengo un número de dispositivo principal de 0. ¿Existe una manera confiable de encontrar el punto de montaje de este dispositivo, sin saber de antemano que es un subvolumen btrfs?

por ejemplo, me gustaría poder hacer esto en 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'

(en mi caso sda1( /sys/dev/block/8:1) está montado en /booty /homees un subvolumen btrfs de sda2).

Editar

Necesitaría poder hacer esto sin conocer la ruta del archivo. Lo que usé arriba os.statcomo ejemplo, sin embargo, la información en realidad se recupera de una ioctlllamada a un dispositivo de bucle que devuelve:

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 el campo lo_file_name, sin embargo, tiene una longitud máxima de 63 caracteres, por lo que no se puede confiar en que esté abierto. También lo sé /sys/block/loopX/loop/backing_file, sin embargo, esto solo está disponible en Linux >= 2.6.37 y mi código debe ejecutarse en CentOS 6 (2.6.32).

Edición #2

Mi objetivo final aquí es poder encontrar el archivo de respaldo para un dispositivo de bucle de manera confiable. Incluso util-linux no hace esto en kernels <2.6.37, por ejemplo

> 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 el nombre del archivo está truncado, esto se debe a que util-linux usa la loop_info64estructura que tiene un límite de 63 caracteres en el lo_file_namecampo.

Lo que puedo obtener de forma fiable es el ID del dispositivo y el número de inodo del archivo de respaldo. Aquí es donde choqué contra una pared, ya que el archivo de respaldo está almacenado en un subvolumen btrfs.

Respuesta1

Miré el código fuente de Gnu core-utils, particularmente el dfcomando.

Desciende recursivamente en la jerarquía hasta que cambian los ID de los dispositivos. En el punto donde cambian las ID es el punto de montaje.

Intenté encontrar el punto de montaje del sistema de archivos en el que ~/home/me/a-dir/another-dirse encuentra. Lo hice:

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 es pseudo bash, todos los condicionales y bucles se hicieron manualmente. Es solo para probar el concepto. Dejaré la programación y la traducción a Python como ejercicio para el lector).

información relacionada