Список только связывает, монтируется

/.. точки к /:

$ ls -id /
2 /
$ ls -id /..
2 /..

У обоих есть то же inode число, которое, оказывается, 2 в этой системе. (Точное значение не имеет значения.)

Это сделано для непротиворечивости. Таким образом, не должно быть кода в ядре для проверки, где это в настоящее время - когда это обрабатывает a .. в пути. Можно сказать cd .. навсегда, и никогда не идите глубже, чем корень.

25
06.01.2015, 01:06
5 ответов

Свяжите монтирование, не тип файловой системы, ни параметр смонтированной файловой системы; они - параметры операции монтирования. Насколько я знаю, следующие последовательности вывода команд к чрезвычайно идентичным состояниям системы, что касается ядра:

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
28
27.01.2020, 19:40
  • 1
    @Gilles На самом деле, можно сделать это просто использование findmnt | fgrep [ как объяснено здесь. –  aculich 06.03.2012, 18:39
  • 2
    @Gilles, Что mount --version Вы используете, который записывает кого-либо bind информация в /etc/mtab? Я использую версию 2.20.1, и я посмотрел на последние источники, и ни в том, ни в другом случае сделайте я вижу, связывают информацию, зарегистрированную где угодно, который позволит Вам grep для bind. С другой стороны, то, что я предложил в своем ответе, действительно на самом деле перечисляет, связывают, монтируется созданный с --bind а также использование bind опция. –  aculich 06.03.2012, 20:16
  • 3
    @aculich </etc/mtab awk … совместимо POSIX (я забываю, поддерживается ли это в Bourne). Проверьте свои факты. Я могу подтвердить это /etc/mtab имеет bind опция для файловой системы, смонтированной с mount --bind /source /target на стабильном Debian (монтируются из util-linux-ng 2.17.2). –  Gilles 'SO- stop being evil' 06.03.2012, 23:10
  • 4
    @Gilles я удалил свой ошибочный комментарий для удаления беспорядка. Вы правы, это действительно совместимо POSIX. Также теперь я понимаю основания, из которых мы видим другое поведение mount и /etc/mtab. Вы используете Debian, стабильный, который имеет более старую версию util-linux-ng; я использую тестирование Debian, которое имеет более новую версию, которая больше, кажется, не имеет того же /etc/mtab поведение, которое является, возможно, почему @rozcietrzewiacz не видел bind в в /etc/mtab если его распределение также использует более новую версию? –  aculich 06.03.2012, 23:44
  • 5
    @aculich необходимо отправить findmnt как ответ. Это только работает, если целевой каталог не является другой точкой монтирования, между прочим. Попробуйте, например, sudo mount --bind / foo && findmnt | grep foo –  l0b0 20.11.2013, 00:56

Может быть, это могло бы сделать трюк:

findmnt | grep  "\["

Пример:

$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep  "\["
│ └─/tmp/foo                     /dev/sda2[/media] ext4            rw,relatime,data=ordered
32
20.08.2021, 13:34
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")
0
20.08.2021, 13:34

Ядро не обрабатывает монтирование привязки, отличное от нормального монтирования после факт. Единственное отличие состоит в том, что происходит во время работы mount .

Когда вы монтируете файловую систему (например, с помощью mount -t ext4 / dev / sda1 / mnt ), ядро ​​(немного упрощенное) выполняет три шага:

  1. Ядро ищет драйвер файловой системы для указанного типа файловой системы (если вы опустите -t или используете -t auto mount угадывает тип за вас и предоставляет предполагаемый тип ядру)
  2. Ядро указывает драйверу файловой системы получить доступ к файловой системе, используя путь к исходному тексту и любые предоставленные параметры. На данный момент файловая система идентифицируется только парой старший: младший номер.
  3. Файловая система привязана к пути (точке монтирования). Ядро также использует здесь некоторые параметры монтирования. ( nodev , например, опция в точке монтирования, а не в файловой системе. У вас может быть монтирование с привязкой с nodev и без него)

Если вы выполняете монтирование с привязкой ( например, с mount --bind / a / b ) происходит следующее:

  1. Ядро решает, какая файловая система содержит исходный путь и относительный путь от точки монтирования до каталога.
  2. Файловая система привязана к новой точке монтирования с использованием параметров и относительного пути.

(Я пропущу mount --move , потому что это не имеет отношения к вопросу.)

Это очень похоже на то, как файлы создаются в Linux:

  1. Ядро решает, какая файловая система отвечает за каталог, в котором должен быть создан файл.
  2. Создается новый файл в файловой системе. На данный момент у файла есть только номер inode.
  3. Новый файл связан с именем файла в каталоге.

Если вы сделаете жесткую ссылку, произойдет следующее:

  1. Ядро разрешит номер inode исходного файла.
  2. Файл связан с целевым именем файла.

Как видите, созданный файл и жесткая ссылка неотличимы:

$ 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))
14
20.08.2021, 13:34

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

Для отображения всех подкреплений:

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» удаляет заголовки, а «--список» удаляет строки формата «дерево».

Протестировано на растяжке Debian.

2
20.08.2021, 13:34

Теги

Похожие вопросы