W jaki sposób findmnt jest w stanie wyświetlić listę montowań powiązań?

11

Wiele osób twierdzi, że Linux nie przechowuje informacji o łączeniach bindów, więc nie ma sposobu na uzyskanie listy ich i ich źródeł. Oto kilka przykładów:

  • z jednego z komentarzy tutaj :

    IIRC ta informacja nie jest nigdzie przechowywana: po tym mount --bind, dwie kopie są równoważne, nie ma jednej, która byłaby bardziej „oryginalna” niż druga. W końcu nie byłoby oryginału, gdybyś już odmontował /mnt.

  • z odpowiedzi na tej stronie :

    Jedynym sposobem, aby zapamiętać, które montowania były powiązaniami, jest dziennik poleceń montowania, które pozostały /etc/mtab. Operacja łączenia z łączeniem jest wskazywana przez opcję łączenia z łączeniem (co powoduje ignorowanie typu systemu plików). Ale mount nie ma opcji, aby wyświetlić listę tylko systemów plików zamontowanych z określonym zestawem opcji.

  • z raportu o błędzie Debiana :

    To celowe. Oba punkty montowania są w pełni równe pod każdym względem, więc jądro nie utrzymuje żadnych flag, aby je rozróżnić.

Powyższe jest jednak nonsensem. Narzędzie findmntjest w stanie wyświetlić listę ścieżek źródłowych montowań powiązań (w formie device[source-path]; Próbuję też, aby wyświetlała tylko ścieżkę źródłową, a nie urządzenie). Jeśli jądro Linuksa ma utrzymywać mocowanie do wiązania, to informacje te muszą być gdzieś przechowywane , w przeciwnym razie nie wiedziałby, że /homejest to związane /users. Więc gdzie są te dane? Czy jest przechowywany w jakimś niejasnym regionie w pamięci RAM? Czy gdzieś findmntzagląda /proc?

Melab
źródło
Z której wersji korzystasz findmnti jakie masz opcje? Mój nie drukuje go w ten sposób i patrząc na kod źródłowy, _PATH_PROC_MOUNTINFOktórego używa, który /proc/self/mountinfonie zawiera tych informacji.
Bratchley,
OK. Myślę, że /proc/self/mountinfostosunkowo niedawno został zrestrukturyzowany. Byłem na mojej maszynie RHEL6, przed którą nie miałem informacji o ścieżce, ale moja maszyna RHEL7 ma i jak wspomniano w twoim linku, Wheezy również.
Bratchley,
To nie jest nonsens: tak było w przypadku starszych jąder, ale nowsze jądra śledzą informacje.
Gilles „SO- przestań być zły”
@Gilles W jaki sposób można utrzymać podłączenie wiązania, jeśli informacje, że jeden katalog jest podłączony w innym, nie są śledzone?
Melab
@Melab W rzeczywistości łatwiej jest zachować mocowanie wiązania, jeśli nie śledzisz, że jest to mocowanie wiązania. Kiedy /dev/Ajest zamontowany w, /Ba ty robisz mount --bind /B /C, starsze jądra pamiętają tylko /B → /dev/Ai /C → /dev/Anie pamiętają żadnych relacji między /Bi /C. Zatem odmontowanie w /Bnaturalny sposób nie ma wpływu /C. Nowsze jądra pamiętają, że /Cbył to montaż typu bind /B, ale w sposób, który nie przeszkadza w /Ckontynuowaniu pracy, jeśli /Bjest odmontowany, nie wiem dokładnie jak.
Gilles „SO- przestań być zły”

Odpowiedzi:

12

Trochę źle zrozumiałeś; dwa punkty montowania są równe pod względem uprawnień, flag itp., ponieważ powiązanie skutecznie przekierowuje dostęp z jednej ścieżki do drugiej. Ale wciąż są odrębne .

Jeśli spojrzysz na /proc/self/mountinfoto, zobaczysz widok jądra świata montowania dla tego procesu (przestrzenie nazw komplikują sprawę; nie ma tylko jednego widoku tabeli montowania).

man 5 procwyjaśni format tego pliku, ale możesz zobaczyć hierarchię drzewa i miejsca, w których montowania powiązań mają swoje „elementy nadrzędne”. To jest plik, który findmntanalizuje.

Stephen Harris
źródło
9

Linux nie przechowuje informacji o tym, które podłączenie było podłączeniem . Przechowuje informacje o wszystkich mocowaniach, w tym mocowaniach powiązań .

Jest dość podobny do twardych linków. Montuje łącze do systemów plików, takich jak nazwy plików, łącza do i-węzłów. Jedyne różnice polegają na tym, że podłączenia mają również flagi poszczególnych punktów podłączenia i mogą odnosić się do podkatalogu docelowego systemu plików zamiast katalogu głównego systemu plików.

Podczas tworzenia twardego łącza system plików nie zapisuje, która nazwa pliku była oryginalna, a która stała. Oba odnoszą się po prostu do tego samego i-węzła. Jeśli odłączysz oryginalny plik, sytuacja będzie nie do odróżnienia od tego, czy bezpośrednio utworzyłeś plik z drugą nazwą pliku.

Powrót do wiązania mountów: Jądro przechowuje tabelę zawierającą system plików (identyfikowany przez parę major: minor number), punkt montowania, ścieżkę względem katalogu głównego systemu plików i niektóre flagi. Możesz uzyskać dostęp do tej listy, patrząc na /proc/self/mountinfo. (Staje się to bardziej skomplikowane, gdy w grę wchodzą przestrzenie nazw, jak wspomniano @ stephen-harris). findmntanalizuje tę listę.

Jeśli twój katalog główny to /dev/sda1major: minor 8:1i uruchomisz mount --bind /a /b /proc/self/mountinfobędzie zawierać wiersze podobne do tego:

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

Jeśli /homejest /dev/sda2za główny: poboczny 8:2i uruchomieniu mount --bind /home /usersbędzie wyglądać następująco:

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

Odpowiednie kolumny dla twojego pytania to trzecia, czwarta i piąta. Są to identyfikator systemu plików (w prawdziwych systemach plików jest taki sam jak major urządzenia: minor; dla wirtualnych systemów plików, takich jak tmpfs, jest to [0: licznik ]), ścieżka względem katalogu głównego systemu plików, który jest powiązany z punktem montowania (zwykle / dla normalnego mounts, może być cokolwiek dla mount mountów) i mountpoint.
Znaczenie pozostałych kolumn można znaleźć w dokumentacji jądra systemu Linux .

findmntwywołuje ścieżkę źródłową względem katalogu głównego systemu plików „FSROOT”. Możesz użyć, findmnt -o TARGET,FSROOTaby go zdobyć. Jeśli chcesz mieć absolutną ścieżkę źródłową, prawdopodobnie musisz /proc/self/mountinfoją samodzielnie przeanalizować i połączyć informacje o podłączeniach dla tego samego systemu plików.

Aby uzyskać więcej informacji, zobacz moją odpowiedź na „Listuj tylko wiązania mountów” .

cg909
źródło
Jeśli /proc/self/mountinfomogą zawierać linie podoba 2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro, to Linux z pewnością robi zachować pewne informacje na temat powiązań wierzchowce.
Melab
Nie. Spójrz na mój drugi przykład. Przechowuje informacje o tym, który system plików został podłączony i która ścieżka względem katalogu głównego systemu plików została zamontowana . Więc dla mount --bind /home/melab /mntotrzymanej linii może wyglądać jedną z następujących czynności w zależności od tego, która z /homei /home/melabJEST montowania: 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
Prawdą jest, że coś innego niż /w czwartej kolumnie często wskazuje na oprawę łączenia. Ale może to być również podobjętość Btrfs.
cg909
Czy /dev/sda3ma być montowany na /home/melab?
Melab
Tak. W moim przykładzie użyłem /dev/sda1as /, /dev/sda2as /homei /dev/sda3as/home/melab
cg909