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 /boot
y /home
es un subvolumen btrfs de sda2
).
Editar
Necesitaría poder hacer esto sin conocer la ruta del archivo. Lo que usé arriba os.stat
como ejemplo, sin embargo, la información en realidad se recupera de una ioctl
llamada 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_info64
estructura que tiene un límite de 63 caracteres en el lo_file_name
campo.
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 df
comando.
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-dir
se 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).