Определить, на каком устройстве находится каталог

Определить, на каком устройстве находится каталог

Если я сделаю

# cd /
# ln -s /home test
# cd test
# mount --bind $PWD /mnt

запись в /proc/mountsэто

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

какое устройство смонтировано /homeи из которого нелегко вывести, $PWDкакое /test. Как я могу определить, какое устройство (например, /dev/sda2) будет отображаться в /proc/mountsв целом, учитывая, что монтирование привязки может быть к каталогу/файлу, который потенциально «скрыт» символическими ссылками, другими монтированиями привязки и т. д.?

решение1

Если я правильно понял ваш вопрос, вы хотите узнать, какое устройство использовалось для данного монтирования. Для этого вы можете использовать команду df:

$ df -h 
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/fedora_greeneggs-root   50G   21G   27G  44% /
devtmpfs                           3.8G     0  3.8G   0% /dev
tmpfs                              3.8G   14M  3.8G   1% /dev/shm
tmpfs                              3.8G  984K  3.8G   1% /run
tmpfs                              3.8G     0  3.8G   0% /sys/fs/cgroup
tmpfs                              3.8G  3.4M  3.8G   1% /tmp
/dev/sda1                          477M   99M  349M  23% /boot
/dev/mapper/fedora_greeneggs-home  402G  184G  198G  49% /home

Чтобы узнать, на каком устройстве находится определенный файл/каталог, укажите файл в качестве аргумента df. Используя ваш пример:

$ df -h /mnt
Filesystem                         Size  Used Avail Use% Mounted on
/dev/sda1                          477M   99M  349M  23% /

Вы также можете использовать mountкоманду:

$ mount | grep '^/dev'
/dev/mapper/fedora_greeneggs-root on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
/dev/mapper/fedora_greeneggs-home on /home type ext4 (rw,relatime,seclabel,data=ordered)

Каталог, смонтированный для каждого устройства, является третьим аргументом в выводе выше. Таким образом, для устройства /dev/sda1будет /boot. Другие устройства используют LVM (Logical Volume Management) и должны быть дополнительно опрошены, чтобы узнать, какое фактическое устройство используется LVM.

решение2

В Linux у нас есть findmntот util-linux, как раз для этого и предназначенный

findmnt -n -o SOURCE --target /path/to/FILE

Преимущество других решений в том, что они по-прежнему работают, даже если пути скрыты символическими ссылками или дублирующими привязками.

решение3

Самый точный метод, который я знаю, — это использовать вывод системного вызова lstat(). А именно, поле st_dev. Существует утилита командной строки stat(1), которую можно использовать для просмотра этой информации. Например, вывод "stat /etc/issue" на моем ноутбуке:

File: ‘/etc/issue’
  Size: 65          Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 1610916043  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Обратите внимание на третью строку, первое поле "Устройство". Здесь указано 801h. Это значение можно разделить на два байта, 8 и 1. Первый байт известен как старший номер, второй байт — младший номер. Итак, следующим шагом будет выяснить, какое устройство старший 8, младший 1.

Я считаю, что самым быстрым способом является просмотр /proc/partitions. В моем случае /proc/partitions имеет следующее содержимое:

major minor  #blocks  name

   8       16  234431064 sdb
   8       17   33554432 sdb1
   8       18  200875608 sdb2
   8        0  500107608 sda
   8        1  500106584 sda1

Из этого вывода довольно ясно, что major 8, minor 1 — это sda1. Мы можем подтвердить это с помощью ls -l /dev/sda1

brw-rw---- 1 root disk 8, 1 May  8 05:33 /dev/sda1

Обратите внимание на цифры 8, 1 перед датой.

Важно понимать/помнить, что имя файла устройства, например /dev/sda1, — это всего лишь метка. Старшие и младшие номера — это значимые, важные значения файла устройства. Если вам интересно, ознакомьтесь с утилитой mknod(1), используемой для создания файлов устройств. Я мог бы создать новую запись /dev под названием aardvark с главным номером 8 и младшим номером 18 с помощью следующего синтаксиса:

mknod /dev/aardvark b 8 18

Затем я мог бы легко его смонтировать:

mount /dev/aardvark /mnt

и если мы посмотрим на вывод команды mount или содержимое /proc/mounts, то увидим:

/dev/aardvark on /mnt type xfs (rw,relatime,attr2,inode64,noquota)

df -h показывает:

/dev/aardvark   192G  154G   38G  81% /mnt

... В любом случае, смысл всего этого в том, чтобы проиллюстрировать, что важными данными для идентификации блочного устройства являются основные и второстепенные номера, а не метка файла устройства, и что использование системного вызова lstat() является наилучшим способом запроса этих значений.

В качестве последнего комментария, я только что перечитал ваш вопрос, чтобы убедиться, что я на него отвечаю, и я понял, что вы спрашиваете, какая метка исходного устройства будет отображаться в /proc/mounts для монтирования bind. Это будет та же метка исходного устройства, которая использовалась в исходном вызове mount(2) для точки монтирования файловой системы source для монтирования bind. Возможно, пример поможет:

У меня есть /dev/sdb2 и /dev/aardvark (то же самое, что и выше). Они оба имеют старший номер 8, младший номер 18. Обратите внимание, я буду монтировать одну и ту же файловую систему дважды. Я делаю следующее:

mkdir /mnt1 /mnt2 /foo

mount /dev/aardvark /mnt1
mount /dev/sdb2 /mnt2

Обратите внимание, что я создаю каталог somedir в /mnt1. Но поскольку /mnt1 и /mnt2 имеют одну и ту же смонтированную файловую систему, somedir также будет доступен через /mnt2.

mkdir /mnt1/somedir

mkdir /foo/left /foo/right

mount -o bind /mnt1/somedir /foo/left
mount -o bind /mnt2/somedir /foo/right

Теперь, если мы проверим /proc/mounts, то увидим:

/dev/aardvark /mnt1 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /mnt2 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/aardvark /foo/left xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /foo/right xfs rw,relatime,attr2,inode64,noquota 0 0

Метка исходного устройства на монтированиях /foo/... bind совпадает со значением, изначально предоставленным в вызове mount(2) файловой системы. Помните, /dev/aardvark и /dev/sdb2 в моем примере — это одно и то же устройство.

Я понимаю, что только что напечатал роман, и первая половина вообще не отвечает на ваш вопрос, но мне показалось такой пустой тратой времени удалять его. Возможно, это поможет кому-то еще.

Удачи.

P.S. Имейте в виду, что некоторые файловые системы являются сетевыми - например, NFS или CIFS - или виртуальными - например, procfs или sysfs и не имеют исходного блочного устройства. Я не знаю, что будет возвращено в качестве устройства в выводе stat, просто для того, чтобы это имело значение.

решение4

Команду duможно вызвать с -xпараметром, позволяющим игнорировать содержимое других смонтированных файловых систем.

Коммутатор -kотображает размеры каталогов в КБ.

Для отображения каталогов размером >~ 1 МБ.

du -xk / | awk ' $1 > 1000000 { print } '

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