Identifique a partição por ponto de montagem

Identifique a partição por ponto de montagem

Como podemos identificar em qual partição um sistema de arquivos está montado no Linux quando a partição não é referenciada diretamente na dfsaída?

Por exemplo, fdiska 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/rootestá montado /dev/sda1porque 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 dfmostra 20 GB é porque ele não consegue acessar o sistema de arquivos tmpfs. Quando dfvai 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/rootnão funciona porque /dev/rootnão existe mais. Porque o initramfs é o que montou seu sistema de arquivos raiz real, /dev/rootteria existido lá. Mas como o initramfs está enterrado, /dev/rootnão existe mais.

Neste caso fica muito mais difícil.
O que você pode fazer é usar statpara obter o número do dispositivo para o ponto de montagem e, em seguida, pesquisar /devpor 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 é statobter 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 /deventrada 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.

informação relacionada