¿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 df
la salida?
Por ejemplo, fdisk
la 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 df
es:
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/root
está montado /dev/sda1
porque 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 /
.
rootfs
es 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 df
lo muestra como 20 GB es porque no puede acceder a ese sistema de archivos tmpfs. Cuando df
muestra 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/root
en 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/root
no funciona porque /dev/root
ya no existe. Debido a que initramfs es lo que montó su sistema de archivos raíz real, /dev/root
habría existido allí. Pero como el initramfs está enterrado, /dev/root
ya no está allí.
En este caso se vuelve mucho más difícil.
Lo que puede hacer es utilizar stat
para 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 stat
para 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 /dev
entrada 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.