Если я сделаю
# 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 } '