Identificar partición por punto de montaje

Identificar partición por punto de montaje

¿Cómo podemos identificar en qué partición está montado un sistema de archivos en Linux cuando no se hace referencia directa a la partición en dfla salida?

Por ejemplo, fdiskla salida de nuestro sistema es:

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1        2550    20478976   83  Linux
/dev/sda2            2550       60736   467378176   83  Linux
/dev/sda3           60736       60801      523264   82  Linux swap / Solaris

Y la salida de dfes:

Filesystem      Size  Used Avail Use% Mounted on
rootfs           20G  881M   18G   5% /
/dev/root        20G  881M   18G   5% /
devtmpfs        989M  216K  989M   1% /dev
/dev/sda2       443G  199M  420G   1% /home
tmpfs           990M     0  990M   0% /dev/shm
/dev/root        20G  881M   18G   5% /var/named/chroot/etc/named
/dev/root        20G  881M   18G   5% /var/named/chroot/var/named
/dev/root        20G  881M   18G   5% /var/named/chroot/etc/named.conf
/dev/root        20G  881M   18G   5% /var/named/chroot/etc/named.rfc1912.zones
/dev/root        20G  881M   18G   5% /var/named/chroot/etc/rndc.key
/dev/root        20G  881M   18G   5% /var/named/chroot/usr/lib64/bind
/dev/root        20G  881M   18G   5% /var/named/chroot/etc/named.iscdlv.key
/dev/root        20G  881M   18G   5% /var/named/chroot/etc/named.root.key

De esa lista, la única partición obvia es /dev/sda2; para los demás no podemos ver en qué partición residen (queremos hacer esto mediante un script bash).

Por ejemplo, sabemos que /dev/rootestá montado /dev/sda1porque ambos tienen el mismo tamaño de 20 GB, pero ¿cómo podemos identificar esto a partir de un script?

Salida de ls -l /dev/root /dev/sda1:

[root@server etc]# ls -l /dev/root /dev/sda1
ls: cannot access /dev/root: No such file or directory
brw-rw---- 1 root disk 8, 1 May  7 14:16 /dev/sda1

Respuesta1

Esa salida es engañosa.
En realidad, tienes 2 sistemas de archivos diferentes montados en /.

rootfses el sistema de archivos creado por initramfs. Cuando los cargadores de arranque cargan el kernel, tienen la capacidad de cargar un initramfs que se descomprime en un sistema de archivos tmpfs. Este sistema de archivos no se puede desmontar. Cuando initramfs termina de hacer su trabajo, simplemente monta el sistema de archivos raíz real encima de él.

La razón por la que dflo muestra como 20 GB es porque no puede acceder a ese sistema de archivos tmpfs. Cuando dfmuestra los sistemas de archivos, primero obtiene una lista de montajes actuales de /etc/mtab. Esto le da 2 montajes usando /. Luego realiza una statfs()llamada al sistema en cada punto de montaje. Pero dado que el sistema de archivos raíz actual se encuentra encima de tmpfs initramfs, termina estableciendo el sistema de archivos raíz actual dos veces.

Además, /dev/rooten realidad es un enlace simbólico. Para saber a dónde apunta realmente usando un script de shell, puedes usar readlink -f /dev/root.


Actualización: Ok, en este caso readlink -f /dev/rootno funciona porque /dev/rootya no existe. Debido a que initramfs es lo que montó su sistema de archivos raíz real, /dev/roothabría existido allí. Pero como el initramfs está enterrado, /dev/rootya no está allí.

En este caso se vuelve mucho más difícil.
Lo que puede hacer es utilizar statpara obtener el número de dispositivo para el punto de montaje y luego buscarlo /dev.

Por ejemplo, en mi sistema esto produce:

$ stat --format '%D' /
fd00

$ stat --format '%02t%02T' /dev/mapper/sys-root
fd00

$ for device in $(blkid -o device); do 
>   [ "$(stat --format '%04D' /)" = "$(stat --format '%02t%02T' "$device")" ] && \
>     echo "$device" && \
>     break
> done
/dev/mapper/sys-root

Básicamente, lo que esto hace es utilizar statpara obtener el número mayor y menor de /. Luego recorremos todos los dispositivos de bloque conocidos buscando uno con el mismo dispositivo mayor y menor. No es bonito, pero básicamente la /deventrada tiene un nombre diferente y por eso tenemos que buscarla.

Esto podría hacerse de manera más eficiente, pero quería mantener el código simple.

Respuesta2

/dev/root es un enlace simbólico al dispositivo real. Debería poder obtener la ubicación con ls /dev/root, realink o buscando root= en /proc/cmdline.

información relacionada