Определить раздел по точке монтирования

Определить раздел по точке монтирования

Как определить, на каком разделе смонтирована файловая система в Linux, если в выводе раздел напрямую не указан df?

Например, fdiskвывод нашей системы:

   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

И вывод 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

Из этого списка единственным очевидным разделом является /dev/sda2; для остальных мы не можем видеть, на каком разделе они находятся (мы хотим сделать это с помощью скрипта bash).

Например, мы знаем, что /dev/rootсмонтировано, /dev/sda1поскольку они оба имеют одинаковый размер 20 ГБ, но как мы можем определить это с помощью скрипта?

Вывод из 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

решение1

Этот вывод вводит в заблуждение.
На самом деле у вас 2 разные файловые системы, смонтированные в /.

rootfsэто файловая система, созданная initramfs. Когда загрузчик загружает ядро, он может загрузить initramfs, который распаковывается в файловую систему tmpfs. Эту файловую систему нельзя размонтировать. Когда initramfs завершает свою работу, он просто монтирует настоящую корневую файловую систему поверх нее.

Причина, по которой dfон отображается как 20 ГБ, заключается в том, что он не может добраться до этой файловой системы tmpfs. Когда dfон переходит к отображению файловых систем, он сначала получает список текущих монтирований из /etc/mtab. Это дает ему 2 монтирования с использованием /. Затем он делает statfs()системный вызов на каждой точке монтирования. Но поскольку текущая корневая файловая система находится поверх tmpfs initramfs, он в конечном итоге дважды stats текущей корневой файловой системы.

Дополнительно /dev/rootна самом деле является символической ссылкой. Чтобы узнать, куда она на самом деле указывает, используя скрипт оболочки, можно использовать readlink -f /dev/root.


Обновление: Хорошо, в этом случае readlink -f /dev/rootне работает, так как /dev/rootбольше не существует. Потому что initramfs — это то, что смонтировало вашу настоящую корневую файловую систему, и /dev/rootтам бы существовало. Но поскольку initramfs похоронен, /dev/rootбольше не существует.

В этом случае все становится намного сложнее.
Что вы можете сделать, так это использовать stat, чтобы получить номер устройства для точки монтирования, а затем выполнить поиск /devпо нему.

Например, в моей системе это даст:

$ 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

В основном это делает, использует statдля получения старшего и младшего номера устройства /. Затем мы перебираем все известные блочные устройства, ища одно с тем же старшим и младшим номером устройства. Это некрасиво, но по сути запись /devимеет другое имя, и поэтому нам нужно ее искать.

Это можно было бы сделать эффективнее, но я хотел сохранить простоту кода.

решение2

/dev/root — это символическая ссылка на реальное устройство. Вы должны иметь возможность получить местоположение с помощью ls /dev/root, realink или поиска root= в /proc/cmdline.

Связанный контент