Як findmnt може перелічити прив'язуючі кріплення?


11

Дуже багато людей говорять про те, що Linux не зберігає інформацію про прив'язування кріплень, тому немає можливості отримати список їх та їх джерел. Ось кілька прикладів:

  • з одного з коментарів тут :

    IIRC ця інформація ніде не зберігається: після того mount --bind, як дві копії є рівнозначними, не існує жодної, яка є "оригінальнішою", ніж інша. Зрештою, оригіналу не могло бути, якби ви його вже відключили /mnt.

  • з відповіді на цьому сайті :

    Таким чином, єдиний спосіб запам'ятати, які кріплення були прив’язаними кріпленнями - це журнал команд монтування, що залишилися /etc/mtab. Операція кріплення прив’язки позначається параметром прив'язки (що призводить до ігнорування типу файлової системи). Але mount не має можливості перелічити лише файлові системи, встановлені з певним набором наборів параметрів.

  • з звіту про помилку Debian :

    Це навмисно. Обидві точки монтажу повністю рівні в усіх відношеннях, тому ядро ​​не зберігає жодних прапорів для їх розмежування.

Все вище - це нісенітниця. Інструмент findmntможе перелічити вихідні шляхи прив'язки кріплення (у вигляді device[source-path]; я також намагаюся дозволити йому вказати лише вихідний шлях, а не пристрій). Якщо ядро ​​Linux має підтримувати прив'язку, то ця інформація повинна зберігатися десь , інакше воно не могло б знати, на що /homeце пов'язано /users. То де ж ці дані? Чи зберігається вона в якомусь незрозумілому регіоні оперативної пам’яті? Є чи findmntдивитися в /procде - небудь?


Яку версію findmntзапущено та які варіанти ви надаєте? Шахта не роздруковує його таким чином і, дивлячись на вихідний код, який він, як видається, використовує, _PATH_PROC_MOUNTINFOякий виглядає, /proc/self/mountinfoякий також не містить цієї інформації.
Братчлі

Гаразд, я думаю, /proc/self/mountinfoвідносно недавно була реструктурована Я був на моїй машині RHEL6, перед якою не було інформації про шлях, але моя машина RHEL7 так і є, як згадується у вашому посиланні.
Братчлі

Це не дурниці: це було правдою і для старих ядер, але новіші ядра відслідковують інформацію.
Жил "ТАК - перестань бути злим"

@Gilles Тоді як може зберігатись прив'язка, якщо інформація про те, що один каталог встановлений в інший, не відслідковується?
Мелаб

@Melab Насправді, кріплення прив'язки простіше зберігатись, якщо ви не відстежуєте, що це кріплення прив’язки. Коли /dev/Aце встановлено у /Bвас, ви mount --bind /B /Cстаріші ядра пам’ятаєте лише, /B → /dev/Aі /C → /dev/Aвони не пам’ятають жодних зв’язків між /Bі /C. Тож відключення /Bприродно ніяк не впливає /C. Новіші ядра пам’ятають, що це /Cбула прив'язка /B, але таким чином, який не заважає /Cпродовжувати працювати, якщо /Bвін відключений, я не знаю, як саме.
Жил "ТАК - перестань бути злим"

Відповіді:


12

Ви трохи не зрозуміли; дві точки монтажу рівні за дозволом, прапорами тощо, тому що зв'язування ефективно перенаправляє доступ з одного шляху в інший. Але вони все одно виразні .

Якщо ви подивитесь, /proc/self/mountinfoви побачите в цьому ядрі вигляд ядра світу монтування (простори імен ускладнюють справи; немає лише одного виду таблиці кріплення).

man 5 procпояснить формат цього файлу, але ви можете бачити ієрархію дерев і де вбудовані файли мають "батьківський". Це файл, який findmntаналізує.


9

Linux не зберігає інформацію про те, яке кріплення було прив’язаним . Він зберігає інформацію про всі кріплення, включаючи прив'язки .

Це досить схоже на жорсткі посилання. Встановлює посилання на файлові системи, як посилання на файли файлів на inode. Єдині відмінності полягають у тому, що версії також мають прапори за точкою монтажу та можуть посилатися на підкаталог цільової файлової системи замість кореня файлової системи.

Під час створення жорсткого посилання файлова система не зберігає, яке ім'я файлу було оригінальним, а яке - жорстким. Обидва просто посилаються на один і той же індед. Якщо ви від'єднаєте оригінальний файл, ситуація не відрізняється від того, якщо ви безпосередньо створили файл із другим іменем файлу.

Назад, щоб прив’язати кріплення: Ядро зберігає таблицю, яка містить файлову систему (ідентифіковану основною: пара мінорних чисел), точку кріплення, шлях відносно кореня файлової системи та деякі прапори. Ви можете отримати доступ до цього списку, переглянувши /proc/self/mountinfo. (Це ускладнюється при залученні просторів імен, як згадував @ stephen-harris). findmntаналізує цей список.

Якщо ваш корінь /dev/sda1з основним: мінор, 8:1і ви запустите, mount --bind /a /b /proc/self/mountinfoбуде містити рядки, подібні до цього:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro

Якщо ваш /homeє /dev/sda2з головним: неповнолітнім 8:2і запустити mount --bind /home /usersце буде виглядати наступним чином :

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:2 / /home rw - ext4 /dev/sda2 rw
3 1 8:2 / /users rw - ext4 /dev/sda2 rw

Відповідні стовпці вашого запитання - третя, четверта та п'ята. Це ідентифікатор файлової системи (для реальних файлових систем це те саме, що і основний пристрій: мінор; для віртуальних файлових систем, таких як tmpfs, це [0: counter ]), шлях відносно кореня файлової системи, який прив’язаний до точки монтування (зазвичай / для нормальної кріплення, може бути будь-що для прив'язки кріплення) та точки монтажу.
Значення решти стовпців див. У документації на ядро ​​Linux .

findmntвикликає вихідний шлях відносно кореня файлової системи "FSROOT". Ви можете використовувати, findmnt -o TARGET,FSROOTщоб отримати його. Якщо ви хочете абсолютного шляху до джерела, вам, ймовірно, потрібно розібратися /proc/self/mountinfoсамостійно та об'єднати інформацію про кріплення для тієї ж файлової системи.

Для отримання додаткової інформації дивіться мою відповідь на "Список лише кріплення кріплення" .


Якщо /proc/self/mountinfoможуть містити такі рядки 2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro, то Linux, безумовно , зберігає деяку інформацію про прив'язування кріплень.
Мелаб

Ні. Подивіться на мій другий приклад. Він зберігає інформацію, яка файлова система була встановлена ​​та який шлях відносно кореня файлової системи . Таким чином , для mount --bind /home/melab /mntрезультуючого рядка може виглядати будь-який з наступних в залежності від того, який з /homeі /home/melabє точкою монтування: 3 1 8:1 /home/melab /mnt rw - ext4 /dev/sda1 rw, 3 1 8:2 /melab /mnt rw - ext4 /dev/sda2 rw,3 1 8:3 / /mnt rw - ext4 /dev/sda3 rw
cg909

Це правда, що щось інше /в четвертому стовпчику часто вказує на прив'язку. Але це також може бути підпункт Btrfs.
cg909

Чи /dev/sda3повинен бути встановлений /home/melab?
Мелаб

Так. У своєму прикладі я використовував /dev/sda1як /, /dev/sda2як /homeі /dev/sda3як/home/melab
cg909
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.