Відповіді:
Встановити прив'язки - це не тип файлової системи, ані параметр встановленої файлової системи; вони параметри операції кріплення . Наскільки я знаю, наступні послідовності команд призводять до фактично однакових системних станів, що стосується ядра:
mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one
Тож єдиний спосіб запам'ятати, які кріплення були прив’язаними кріпленнями - це журнал 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, і я переглянув останні джерела, і ні в якому разі не бачу прив’язаної інформації, записаної в будь-якому місці, яка б дозволила вам отримати греп 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
Але , як ви можете ідентифікувати всі тверді посилання на файл, порівнюючи номери inode, ви можете ідентифікувати всі кріплення до файлової системи, порівнюючи головне: незначне число монтів.
Це можна зробити за допомогою 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 --kernel -n --list | grep '\['
Щоб показати всі підмножини файлових систем типу ext4:
findmnt --kernel -t ext4 -n --list | grep '\['
Щоб показати всі кріплення, виключаючи підмножини:
findmnt --kernel -n --list | grep -v '\['
Щоб показати всі версії файлових систем типу ext4, виключаючи підмножини:
findmnt --kernel -t ext4 -n --list | grep -v '\['
"-N" видаляє заголовки, а "--list" видаляє рядки формату "дерево".
Випробуваний на розтяжці Debian.
findmnt | fgrep [
як описано тут .