Como podemos identificar em qual partição um sistema de arquivos está montado no Linux quando a partição não é referenciada diretamente na df
saída?
Por exemplo, fdisk
a saída do nosso sistema é:
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
E a saída de df
é:
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
Dessa lista, a única partição óbvia é /dev/sda2
; para os outros não podemos ver em qual partição eles residem (queremos fazer isso através de um script bash).
Por exemplo, sabemos que /dev/root
está montado /dev/sda1
porque ambos têm o mesmo tamanho de 20 GB, mas como podemos identificar isso em um script?
Saída 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
Responder1
Essa saída é enganosa.
Na verdade, você tem 2 sistemas de arquivos diferentes montados em /
.
rootfs
é o sistema de arquivos criado por um initramfs. Quando os bootloaders carregam o kernel, ele tem a capacidade de carregar um initramfs que é descompactado em um sistema de arquivos tmpfs. Este sistema de arquivos não pode ser desmontado. Quando o initramfs termina de fazer seu trabalho, ele simplesmente monta o sistema de arquivos raiz real sobre ele.
A razão pela qual df
mostra 20 GB é porque ele não consegue acessar o sistema de arquivos tmpfs. Quando df
vai mostrar os sistemas de arquivos, primeiro obtém uma lista das montagens atuais do /etc/mtab
. Isso dá 2 montagens usando /
. Em seguida, ele faz um statfs()
syscall em cada ponto de montagem. Mas como o sistema de arquivos raiz atual fica sobre o initramfs tmpfs, ele acaba declarando o sistema de arquivos raiz atual duas vezes.
Além disso, /dev/root
é na verdade um link simbólico. Para descobrir para onde ele realmente aponta usando um script de shell, você pode usar readlink -f /dev/root
.
Atualização: Ok, então neste caso readlink -f /dev/root
não funciona porque /dev/root
não existe mais. Porque o initramfs é o que montou seu sistema de arquivos raiz real, /dev/root
teria existido lá. Mas como o initramfs está enterrado, /dev/root
não existe mais.
Neste caso fica muito mais difícil.
O que você pode fazer é usar stat
para obter o número do dispositivo para o ponto de montagem e, em seguida, pesquisar /dev
por ele.
Por exemplo, no meu sistema isso produz:
$ 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
Basicamente, o que isso faz é stat
obter o número maior e menor do dispositivo /
. Em seguida, iteramos por todos os dispositivos de bloco conhecidos, procurando um com o mesmo dispositivo principal e secundário. Não é bonito, mas basicamente a /dev
entrada tem um nome diferente e por isso temos que procurá-la.
Isso poderia ser feito de forma mais eficiente, mas eu queria manter o código simples
Responder2
/dev/root é um link simbólico para o dispositivo real. Você deve conseguir obter o local com ls /dev/root, realink ou procurar root= em /proc/cmdline.