Ответы:
Bind mounts не является типом файловой системы или параметром смонтированной файловой системы; это параметры операции монтирования . Насколько я знаю, следующие последовательности команд приводят к практически одинаковым системным состояниям в отношении ядра:
mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one
Таким образом, единственный способ вспомнить, какие монтирования были bind mounts - это журнал mount
оставленных команд /etc/mtab
. Операция монтирования с привязкой указывается опциейbind
монтирования (которая приводит к игнорированию типа файловой системы). Но не имеет возможности перечислять только файловые системы, смонтированные с определенным набором опций. Поэтому вам нужно сделать свою собственную фильтрацию.mount
mount | grep -E '[,(]bind[,)]'
</etc/mtab awk '$4 ~ /(^|,)bind(,|$)/'
Обратите внимание, что /etc/mtab
это полезно только в том случае, если текстовый файл поддерживается mount
. Некоторые дистрибутивы настроены вместо этого /etc/mtab
как символическая ссылка /proc/mounts
; /proc/mounts
в основном эквивалентно, /etc/mtab
но имеет несколько отличий, одно из которых не отслеживает привязки.
Одна часть информации, которая сохраняется ядром, но не отображается в этом случае /proc/mounts
, - это когда точка монтирования показывает только часть дерева каталогов в смонтированной файловой системе. На практике это в основном происходит с креплениями:
mount --bind /mnt/one/sub /mnt/partial
В /proc/mounts
и записи для /mnt/one
и /mnt/partial
имеют одинаковое устройство, тот же тип файловой системы и те же параметры. Информация, которая /mnt/partial
показывает только ту часть файловой системы, в которой /sub
находится корень, видна в информации о точке монтирования для каждого процесса в /proc/$pid/mountinfo
(столбец 4). Записи там выглядят так:
12 34 56:78 / /mnt/one rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
12 34 56:78 /sub /mnt/partial rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
mount --version
вы используете для записи какой-либо bind
информации /etc/mtab
? Я использую версию 2.20.1, и я посмотрел последние версии источников, и ни в одном из случаев я не вижу информацию о привязке, записанную где-либо, что позволит вам использовать grep bind
. С другой стороны, то, что я предложил в своем ответе , на самом деле включает в себя список привязок, созданных с --bind
использованием bind
опции .
</etc/mtab awk …
является POSIX-совместимым (я забываю, поддерживается ли он в Bourne). Пожалуйста, проверьте ваши факты. Я могу подтвердить, что /etc/mtab
имеет bind
опцию для файловой системы, смонтированной mount --bind /source /target
в стабильной версии Debian (смонтировать из util-linux-ng 2.17.2).
mount
и /etc/mtab
. Вы используете стабильную версию Debian, которая имеет более старую версию util-linux-ng; Я не буду с помощью тестирования Debian , который имеет более новую версию , которая больше не кажется, то же самое /etc/mtab
поведение, которое может быть , почему @rozcietrzewiacz не видела bind
в в /etc/mtab
случае его распределения также использует более новую версию?
findmnt
как ответ. Между прочим, это работает, только если целевой каталог не является другой точкой монтирования. Попробуйте напримерsudo mount --bind / foo && findmnt | grep foo
Может быть, это может сделать трюк:
findmnt | grep "\["
Пример:
$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep "\["
│ └─/tmp/foo /dev/sda2[/media] ext4 rw,relatime,data=ordered
/
Например, если сам подключен, то у вывода нет [...]
.
Ядро не обрабатывает привязку монтирования, отличную от обычной монтировки после факта. Разница лишь в том, что происходит во время mount
пробежек.
Когда вы монтируете файловую систему (например, с помощью mount -t ext4 /dev/sda1 /mnt
), ядро (немного упрощенное) выполняет три шага:
-t
или используете, -t auto
mount
угадывает тип для вас и предоставляет ядру предполагаемый тип)nodev
например, это опция для точки монтирования, а не для файловой системы. Вы можете использовать монтирование с привязкой nodev
и без нее )Если вы выполняете привязку (например, с помощью mount --bind /a /b
), происходит следующее:
(Я пропущу mount --move
, потому что это не имеет отношения к вопросу.)
Это очень похоже на то, как файлы создаются в Linux:
Если вы сделаете жесткую ссылку, произойдет следующее:
Как видите, созданный файл и жесткая ссылка неразличимы:
$ touch first
$ ln first second
$ ls -li
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/first
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/second
Но , поскольку вы можете идентифицировать все жесткие ссылки на файл, сравнивая номера инодов, вы можете идентифицировать все монтирования в файловой системе, сравнивая основные: второстепенные номера монтирований.
Вы можете сделать это с помощью findmnt -o TARGET,MAJ:MIN
или, посмотрев напрямую /proc/self/mountinfo
( см. Документацию ядра Linux для получения дополнительной информации ).
Следующий скрипт Python перечисляет все монтируемые привязки. Предполагается, что самая старая точка монтирования с кратчайшим относительным путем к корню смонтированной файловой системы является исходной.
#!/usr/bin/python3
import os.path, re
from collections import namedtuple
MountInfo = namedtuple('MountInfo', ['mountid', 'parentid', 'devid', 'root', 'mountpoint', 'mountoptions', 'extra', 'fstype', 'source', 'fsoptions'])
mounts = {}
def unescape(string):
return re.sub(r'\\([0-7]{3})', (lambda m: chr(int(m.group(1), 8))), string)
with open('/proc/self/mountinfo', 'r') as f:
for line in f:
# Parse line
mid, pid, devid, root, mp, mopt, *tail = line.rstrip().split(' ')
extra = []
for item in tail:
if item != '-':
extra.append(item)
else:
break
fstype, src, fsopt = tail[len(extra)+1:]
# Save mount info
mount = MountInfo(int(mid), int(pid), devid, unescape(root), unescape(mp), mopt, extra, fstype, unescape(src), fsopt)
mounts.setdefault(devid, []).append(mount)
for devid, mnts in mounts.items():
# Skip single mounts
if len(mnts) <= 1:
continue
# Sort list to get the first mount of the device's root dir (if still mounted)
mnts.sort(key=lambda x: x.root)
src, *binds = mnts
# Print bind mounts
for bindmount in binds:
if src.root == bindmount.root:
srcstring = src.mountpoint
else:
srcstring = src.mountpoint+':/'+os.path.relpath(bindmount.root, src.root)
print('{0} -> {1.mountpoint} ({1.mountoptions})'.format(srcstring, bindmount))
unset DONE1FSES
FSES=$(findmnt -vUPno SOURCE,FSROOT,TARGET,MAJ:MIN)
FSES=${FSES//MAJ:MIN/MAJ_MIN}
while read SEARCH1FS
do
unset DONE2FSES
eval "$SEARCH1FS"
SEARCH1SOURCE=$SOURCE
SEARCH1FSROOT=$FSROOT
SEARCH1TARGET=$TARGET
SEARCH1MAJMIN=$MAJ_MIN
FS1WASHANDLED=0
while read DONE1FS
do
if [[ $DONE1FS == $MAJ_MIN ]]
then
FS1WASHANDLED=1
break
fi
done < <(echo "$DONE1FSES")
if [[ ($SEARCH1FSROOT == /) && ($FS1WASHANDLED == 0) ]]
then
DONE1FSES+=$MAJ_MIN$'\n'
while read SEARCH2FS
do
eval "$SEARCH2FS"
SEARCH2SOURCE=$SOURCE
SEARCH2FSROOT=$FSROOT
SEARCH2TARGET=$TARGET
SEARCH2MAJMIN=$MAJ_MIN
FS2WASHANDLED=0
while read DONE2FS
do
if [[ $DONE2FS == $SEARCH2FS ]]
then
FS2WASHANDLED=1
break
fi
done < <(echo "$DONE2FSES")
if [[ ($SEARCH1MAJMIN == $SEARCH2MAJMIN) && ($SEARCH1TARGET != $SEARCH2TARGET ) && ($FS2WASHANDLED == 0 ) ]]
then
DONE2FSES+=$SEARCH2FS$'\n'
echo "$SEARCH1TARGET$SEARCH2FSROOT --> $SEARCH2TARGET"
fi
done < <(echo "$FSES")
fi
done < <(echo "$FSES")
Это похоже на другой ответ findmnt, но позволяет избежать проблемы форматирования.
Чтобы показать все субмонтирования:
findmnt --kernel -n --list | grep '\['
Чтобы показать все субмонтирования файловых систем типа ext4:
findmnt --kernel -t ext4 -n --list | grep '\['
Чтобы показать все монтирования, кроме субмаунтов:
findmnt --kernel -n --list | grep -v '\['
Чтобы показать все монтирования файловых систем типа ext4, кроме submounts:
findmnt --kernel -t ext4 -n --list | grep -v '\['
«-N» удаляет заголовки, а «--list» удаляет строки формата «дерево».
Протестировано на Debian Stretch.
findmnt | fgrep [
как описано здесь .