Listen Sie nur Bindungs-Reittiere auf

24

Anstatt zu verwenden mount | grep, würde ich gerne verwenden mount -l -t bind, aber das funktioniert nicht und -t nonezeigt alle Reittiere.

l0b0
quelle

Antworten:

28

Bindungsbereitstellungen sind weder ein Dateisystemtyp noch ein Parameter eines bereitgestellten Dateisystems. Sie sind Parameter einer Mount- Operation . Soweit mir bekannt ist, führen die folgenden Befehlsfolgen zu im Wesentlichen identischen Systemzuständen für den Kernel:

mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one

Die einzige Möglichkeit, sich daran zu erinnern, welche Mounts Bind-Mounts waren, ist das Protokoll der mountBefehle, die in verbleiben /etc/mtab. Ein Bind-Mount-Vorgang wird durch die bindMount- Option angezeigt (wodurch der Dateisystemtyp ignoriert wird). Es mountgibt jedoch keine Option, nur Dateisysteme aufzulisten, die mit einem bestimmten Optionssatz gemountet sind. Daher müssen Sie Ihre eigene Filterung durchführen.

mount | grep -E '[,(]bind[,)]'
</etc/mtab awk '$4 ~ /(^|,)bind(,|$)/'

Beachten Sie, dass dies /etc/mtabnur sinnvoll ist, wenn es sich um eine Textdatei handelt, die von verwaltet wird mount. Einige Distributionen wurden stattdessen /etc/mtabals symbolische Verknüpfung zu eingerichtet /proc/mounts. /proc/mountsist größtenteils äquivalent zu /etc/mtab, weist jedoch einige Unterschiede auf, von denen einer Bindungs-Mounts nicht verfolgt.

Eine Information, die vom Kernel beibehalten, aber nicht in angezeigt wird /proc/mounts, ist, wenn ein Mount-Punkt nur einen Teil der Verzeichnisstruktur auf dem angehängten Dateisystem anzeigt. In der Praxis passiert dies meistens mit Bindemounts:

mount --bind /mnt/one/sub /mnt/partial

In /proc/mountshaben die Einträge für /mnt/oneund /mnt/partialdasselbe Gerät, denselben Dateisystemtyp und dieselben Optionen. Die Informationen, die /mnt/partialnur den Teil des Dateisystems anzeigen, auf dem sich das Stammverzeichnis /subbefindet, werden in den prozessbezogenen Mountpunktinformationen in angezeigt/proc/$pid/mountinfo (Spalte 4) . Einträge dort sehen so aus:

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
Gilles 'SO - hör auf böse zu sein'
quelle
1
@ Gilles Eigentlich können Sie dies einfach findmnt | fgrep [wie hier erklärt tun .
ACULICH
@ Gilles Worin mount --versionzeichnen Sie bindInformationen auf /etc/mtab? Ich verwende Version 2.20.1 und habe mir die neuesten Quellen angesehen. In keinem Fall sehe ich Bindungsinformationen, die irgendwo aufgezeichnet wurden, nach denen Sie suchen könnten bind. Auf der anderen Seite listet das, was ich in meiner Antwort vorgeschlagen habe , Mount-Objekte auf, die sowohl mit --bindals auch mit der bind Option erstellt wurden .
ACULICH
@aculich </etc/mtab awk …ist POSIX-kompatibel (ich vergesse, ob es in Bourne unterstützt wird). Bitte überprüfen Sie Ihre Fakten. Ich kann bestätigen, dass /etc/mtabes die bindOption für ein Dateisystem gibt, das mit mount --bind /source /targetDebian stable gemountet wurde (mount von util-linux-ng 2.17.2).
Gilles 'SO- hör auf böse zu sein'
@ Gilles Ich habe meinen fehlerhaften Kommentar gelöscht, um Verwirrung zu vermeiden. Sie haben recht, es ist tatsächlich POSIX-konform. Auch jetzt verstehe ich den Grund, warum wir ein unterschiedliches Verhalten von mountund sehen /etc/mtab. Sie verwenden Debian Stable mit der älteren Version von util-linux-ng. Ich verwende Debian-Tests, die eine neuere Version haben, die nicht mehr das gleiche /etc/mtabVerhalten zu haben scheint. Vielleicht hat @rozcietrzewiacz deshalb nicht bindin gesehen, /etc/mtabob seine Distribution auch eine neuere Version verwendet?
ACULICH
1
@aculich Du solltest findmntals Antwort posten . Dies funktioniert übrigens nur, wenn das Zielverzeichnis kein anderer Mount-Punkt ist. Versuchen Sie zum Beispielsudo mount --bind / foo && findmnt | grep foo
l0b0
21

Vielleicht könnte dies den Trick machen:

findmnt | grep  "\["

Beispiel:

$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep  "\["
│ └─/tmp/foo                     /dev/sda2[/media] ext4            rw,relatime,data=ordered
olopopo
quelle
1
Anscheinend funktioniert dies nur, wenn ein Unterverzeichnis eines Mountpunkts gebunden gemountet ist. Wenn es /sich zum Beispiel um eine Bindung handelt, hat die Ausgabe kein [...].
Muru
8

Der Kernel handhabt keine Bindungs-Reittiere, die sich von normalen Reittieren unterscheiden . Die unterscheiden sich nur darin, was beim Laufen passiert mount.

Wenn Sie ein Dateisystem mounten (zB mit mount -t ext4 /dev/sda1 /mnt), führt der Kernel (etwas vereinfacht) drei Schritte aus:

  1. Der Kernel sucht nach einem Dateisystemtreiber für den angegebenen Dateisystemtyp (wenn Sie diesen auslassen -toder verwenden, wird -t auto mountder Typ erraten und der erratene Typ dem Kernel bereitgestellt).
  2. Der Kernel weist den Dateisystemtreiber an, über den Quellpfad und alle verfügbaren Optionen auf das Dateisystem zuzugreifen. Zu diesem Zeitpunkt wird das Dateisystem nur durch ein Major: Minor-Zahlenpaar identifiziert.
  3. Das Dateisystem ist an einen Pfad (den Mountpoint) gebunden. Der Kernel verwendet hier auch einige der Mount-Optionen. ( nodevDies ist beispielsweise eine Option auf dem Mountpoint und nicht auf dem Dateisystem. Sie können einen Bind-Mount mit nodevund einen ohne haben.)

Wenn Sie ein Bind-Mount durchführen (z. B. mit mount --bind /a /b), geschieht Folgendes:

  1. Der Kernel ermittelt, welches Dateisystem den Quellpfad und den relativen Pfad vom Mountpunkt zum Verzeichnis enthält.
  2. Das Dateisystem wird über die Optionen und den relativen Pfad an den neuen Mountpoint gebunden.

(Ich werde überspringen mount --move, weil es für die Frage nicht relevant ist.)

Dies ähnelt der Erstellung von Dateien unter Linux:

  1. Der Kernel legt fest, welches Dateisystem für das Verzeichnis verantwortlich ist, in dem die Datei erstellt werden soll.
  2. Eine neue Datei im Dateisystem wird erstellt. Zu diesem Zeitpunkt hat die Datei nur eine Inode-Nummer.
  3. Die neue Datei ist mit einem Dateinamen im Verzeichnis verknüpft.

Wenn Sie einen festen Link erstellen, geschieht Folgendes:

  1. Der Kernel löst die Inode-Nummer der Quelldatei auf.
  2. Die Datei ist mit dem Zieldateinamen verknüpft.

Wie Sie sehen können, sind die erstellte Datei und der feste Link nicht zu unterscheiden:

$ 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

Da Sie jedoch alle Hardlinks zu einer Datei durch Vergleichen der Inode-Nummern identifizieren können, können Sie alle Bereitstellungen zu einem Dateisystem durch Vergleichen der Major: Minor-Nummern von Bereitstellungen identifizieren.

Sie können dies mit findmnt -o TARGET,MAJ:MINoder direkt über tun /proc/self/mountinfo( weitere Informationen finden Sie in der Dokumentation zum Linux-Kernel ).

Das folgende Python-Skript listet alle Bindungsbereitstellungen auf. Es wird davon ausgegangen, dass der älteste Einhängepunkt mit dem kürzesten relativen Pfad zum Stammverzeichnis des eingebundenen Dateisystems der ursprüngliche Einhängepunkt ist.

#!/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))
cg909
quelle
0
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")
n3rdopolis
quelle
0

Dies ähnelt der anderen Antwort, vermeidet jedoch das Formatierungsproblem.

So zeigen Sie alle Submounts an:

findmnt --kernel -n --list | grep '\['

So zeigen Sie alle Submounts von Dateisystemen des Typs ext4 an:

findmnt --kernel -t ext4 -n --list | grep '\['

So zeigen Sie alle Reittiere ohne Submounts an:

findmnt --kernel -n --list | grep -v '\['

So zeigen Sie alle Mounts von Dateisystemen des Typs ext4 mit Ausnahme von Submounts an:

findmnt --kernel -t ext4 -n --list | grep -v '\['

Das "-n" entfernt die Überschriften und die "--list" entfernt die Zeilen des "tree" -Formats.

Auf Debian-Stretch getestet.

sg23
quelle