mount_namespaces(7) | Miscellaneous Information Manual | mount_namespaces(7) |
mount_namespaces - Überblick über Linux-Einhänge-Namensräume
Für einen Überblick über Namensräume, siehe namespaces(7).
Einhängenamensräume ermöglichen es, die Listen der von Prozessen in jeder Namensrauminstanz gesehenen Einhängungen voneinander zu isolieren. Daher wird jeder Prozess in jeder der Einhänge-Namensrauminstanzen eine individuelle Einzelverzeichnis-Hierarchie sehen.
Die von den Dateien /proc/PID/mounts, /proc/PID/mountinfo und /proc/PID/mountstats (alle In proc(5) beschrieben) bereitgestellten Ansichten entsprechen den Einhängenamensräumen, in denen sich der Prozess mit der PID PID befindet. (Alle Prozesse, die sich in dem gleichen Einhängenamensraum befinden, werden die gleiche Ansicht auf diese Dateien sehen.)
Ein neuer Einhängenamensraum wird entweder mittels clone(2) oder mittels unshare(2) mit dem Schalter CLONE_NEWNS erstellt. Wenn ein neuer Einhängenamensraum erstellt wird, wird seine Einhängeliste wie folgt initialisiert:
Nachfolgende Änderungen an der Einhängeliste (mount(2) und umount(2)) in jedem der Namensräume wird (standardmäßig) die Einhängeliste, die in den anderen Namensräumen gesehen wird, nicht betreffen (lesen Sie allerdings auch die nachfolgende Diskussion von gemeinsamen Unterbäumen).
Nachdem die Implementierung von Einhängenamensräumen abgeschlossen war, zeigte die Erfahrung, dass die bereitgestellte Isolierung in einigen Fällen zu weit ging. Um beispielsweise eine frisch geladene optische Platte in allen Einhängenamensräumen zur Verfügung zu stellen, war in jedem der Namensräume eine Einhängeaktion notwendig. Für diesen und andere Anwendungsfälle wurde die Funktionalität gemeinsamer Unterbäume in Linux 2.6.15 eingeführt. Diese Funktionalität erlaubt die automatische, kontrollierte Weiterleitung von mount(2)- und umount(2)-Ereignissen zwischen Namensräumen (oder genauer, zwischen Einhängungen, die Mitglied einer Gemeinschaftsgruppe sind, die Ereignisse aneinander weiterleiten).
Jede Einhängung wird (mittels mount(2)) markiert, dass sie eine der folgenden Weiterleitungstypen hat:
Bitte lesen Sie die HINWEISE für eine Diskussion der Weiterleitungstypen, die einer neuen Einhängung zugeordnet sind.
Der Weiterleitungstyp ist eine einhängungsbezogene Einstellung: einige Einhängungen könnten als gemeinsam gekennzeichnet sein (wobei jede gemeinsame Einhängung ein Mitglied einer unterschiedlichen Gemeinschaftsgruppe ist), während andere privat (oder abhängig oder nicht-bind-fähig) sind.
Beachten Sie, dass der Weiterleitungstyp einer Einhängung bestimmt, ob mount(2)- und umount(2) von Einhängungen direkt unter der Einhängung weitergeleitet werden. Daher betrifft der Einhängungstyp nicht die Weiterleitung von Ereignissen für weiter unten liegende Einhängungen. Was passiert, wenn die Einhängung selbst ausgehängt wird, wird durch den Weiterleitungstyp bestimmt, der für die übergeordnete Einhängung wirksam ist.
Mitglieder werden zu einer Gemeinschaftsgruppe hinzugefügt, wenn eine Einhängung als gemeinsam markiert ist und entweder:
In beiden Fällen tritt die neue Einhängung der Gemeinschaftsgruppe bei, bei der die bestehende Einhängung bereits Mitglied ist.
Eine neue Gemeinschaftsgruppe wird auch erstellt, wenn eine nachfolgende Einhängung unter einer bestehenden Einhängung, die als gemeinsam markiert ist, erstellt wird. In diesem Fall wird die nachfolgende Einhängung als gemeinsam markiert und die entstehende Gemeinschaftsgruppe besteht aus allen Einhängungen, die unterhalb der Mitglieder der übergeordneten Einhängung repliziert werden.
Eine Einhängung hört auf, Mitglied einer Gemeinschaftsgruppe zu sein, wenn die Einhängung entweder explizit ausgehängt wird oder wenn die Einhängung implizit ausgehängt wird, da der Einhängenamensraum entfernt wird (da er keinen Mitgliedsprozess mehr hat).
Der Weiterleitungstyp der Einhängungen in einem Einhängenamensraum kann mittels der »optionalen Felder« in /proc/PID/mountinfo offengelegt werden. (Siehe proc(5) für Details zu dieser Datei.) Die folgenden Markierungen können in den optionalen Feldern für einen Datensatz in dieser Datei auftauchen:
Falls keine der obigen Markierungen vorhanden ist, dann ist dies eine private Einhängung.
Nehmen wir an, dass wir im Terminal des anfänglichen Einhängenamensraums eine Einhängung als gemeinsam und eine andere als privat markieren, und uns dann die Einhängungen in /proc/self/mountinfo anschauen:
sh1# mount --make-shared /mntS sh1# mount --make-private /mntP sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 77 61 8:17 / /mntS rw,relatime shared:1 83 61 8:15 / /mntP rw,relatime
In der Ausgabe in /proc/self/mountinfo können wir sehen, dass /mntS eine gemeinsame Einhängung in der Gemeinschaftsgruppe 1 ist und dass /mntP keine optionalen Markierungen hat und damit anzeigt, dass es eine private EInhängung ist. Die ersten zwei Felder in jedem Datensatz in dieser Datei sind die eindeutige Kennung für diese Einhängung und die Einhängungskennung der Elterneinhängung. Wir können diese Datei weiter untersuchen, um zu sehen, dass die Elterneinhängung von /mntS und /mntP das Wurzelverzeichnis / ist, das privat eingehängt wurde:
sh1# cat /proc/self/mountinfo | awk '$1 == 61' | sed 's/ - .*//' 61 0 8:2 / / rw,relatime
In einem zweiten Terminal erstellen wir einen neuen Einhängenamensraum, in dem wir eine zweite Shell ausführen und die Einhängungen untersuchen:
$ PS1='sh2# ' sudo unshare -m --propagation unchanged sh sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 222 145 8:17 / /mntS rw,relatime shared:1 225 145 8:15 / /mntP rw,relatime
Der neue Einhängenamensraum erhielt eine Kopie der Einhängungen des anfänglichen Einhängenamensraumes. Diese neuen Einhängungen behalten die gleichen Weiterleitungstypen bei, haben aber eindeutige Einhängekennungen. (Die Option --propagation unchanged verhindert, dass unshare(1) alle Einhängungen als privat markiert, wenn ein neuer Einhängenamensraum erstellt wird, wie er es sonst standardmäßig machen würde.)
In dem zweiten Terminal erstellen wir jetzt Untereinhängungen unter sowohl /mntS als auch /mntP und untersuchen das Ergebnis:
sh2# mkdir /mntS/a sh2# mount /dev/sdb6 /mntS/a sh2# mkdir /mntP/b sh2# mount /dev/sdb7 /mntP/b sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 222 145 8:17 / /mntS rw,relatime shared:1 225 145 8:15 / /mntP rw,relatime 178 222 8:22 / /mntS/a rw,relatime shared:2 230 225 8:23 / /mntP/b rw,relatime
In obiger Ausgabe kann erkannt werden, dass /mntS/a als gemeinsame Einhängung (die Einstellung wurde von der Elterneinhängung übernommen) und /mntP/b als private Einhängung erstellt wurde.
Wird zum ersten Terminal zurückgekehrt und das Ergebnis untersucht, können wir sehen, dass die neue Einhängung, die unterhalb der gemeinsamen Einhängung /mntS erstellt wurde, an die Einhängungen in seiner Gemeinschaftsgruppe weitergeleitet wurde (im anfänglichen Einhängenamensraum), aber die Einhängung, die unter der privaten Einhängung /mntP erstellt wurde, nicht weitergeleitet wurde:
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 77 61 8:17 / /mntS rw,relatime shared:1 83 61 8:15 / /mntP rw,relatime 179 77 8:22 / /mntS/a rw,relatime shared:2
Wird eine Einhängung eine Abhängige, ist es möglich, weitergeleitete mount(2)- und umount(2)-Ereignisse von einer gemeinsamen Master-Gemeinschaftsgruppe zu erhalten und zugleich sie daran zu hindern, Ereignisse zu diesem Master weiterzuleiten. Dies ist nützlich, wenn Sie (beispielsweise) ein Einhängeereignis erhalten möchten, wenn eine optische Platte in der gemeinsamen Gemeinschaftsgruppe des Masters eingehängt wird (in einem anderen Einhängenamensraum), aber Sie verhindern möchten, dass mount(2)- und umount(2)-Ereignisse unter der Einhängung der Abhängigen zu Seiteneffekten in anderen Namensräumen führen.
Wir zeigen die Auswirkung der Abhängigen, indem wir zuerst zwei Einhängungen als gemeinsam im anfänglichen Namensraum markieren:
sh1# mount --make-shared /mntX sh1# mount --make-shared /mntY sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 132 83 8:23 / /mntX rw,relatime shared:1 133 83 8:22 / /mntY rw,relatime shared:2
Auf einem zweiten Terminal erstellen wir einen neuen Einhängenamensraum und untersuchen die Einhängungen:
sh2# unshare -m --propagation unchanged sh sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 168 167 8:23 / /mntX rw,relatime shared:1 169 167 8:22 / /mntY rw,relatime shared:2
In dem neuen Einhängenamensraum können wir eine Einhängung als Abhängige markieren:
sh2# mount --make-slave /mntY sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 168 167 8:23 / /mntX rw,relatime shared:1 169 167 8:22 / /mntY rw,relatime master:2
Aus der obigen Ausgabe kann gesehen werden, dass /mntY jetzt eine abhängige Einhängung ist, die Weiterleitungsereignisse von der gemeinsamen Gemeinschaftsgruppe mit der Kennung 2 erhält.
Im neuen Namensraum wird jetzt fortgefahren und Untereinhängungen unter sowohl /mntX als auch /mntY erstellt:
sh2# mkdir /mntX/a sh2# mount /dev/sda3 /mntX/a sh2# mkdir /mntY/b sh2# mount /dev/sda5 /mntY/b
Wenn wir den Zustand der Einhängungen in den neuen Einhängenamensräumen untersuchen, sehen wir, dass /mntX/a als eine neue gemeinsame Einhängung erstellt wurde (die die Einstellung »shared« ihrer Elterneinhängung geerbt hat) und dass /mntY/b als eine private Einhängung erstellt wurde:
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 168 167 8:23 / /mntX rw,relatime shared:1 169 167 8:22 / /mntY rw,relatime master:2 173 168 8:3 / /mntX/a rw,relatime shared:3 175 169 8:5 / /mntY/b rw,relatime
Zurück im ersten Terminal (im anfänglichen Einhängenamensraum) sehen wir, dass die Einhängung /mntX/a zu dem Mitglied der Gemeinschaftsgruppe weitergeleitet wurde (der gemeinsame /mntX), aber dass die Einhängung /mntY/b nicht weitergeleitet wurde:
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 132 83 8:23 / /mntX rw,relatime shared:1 133 83 8:22 / /mntY rw,relatime shared:2 174 132 8:3 / /mntX/a rw,relatime shared:3
Jetzt erstellen wir eine neue Einhängung unter /mntY in der ersten Shell:
sh1# mkdir /mntY/c sh1# mount /dev/sda1 /mntY/c sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 132 83 8:23 / /mntX rw,relatime shared:1 133 83 8:22 / /mntY rw,relatime shared:2 174 132 8:3 / /mntX/a rw,relatime shared:3 178 133 8:1 / /mntY/c rw,relatime shared:4
Wenn wir die Einhängungen in dem zweiten Einhängenamensraum untersuchen, sehen wir, dass in diesem Fall die Einhängung zu der abhängigen Einhängung weitergeleitet wurde und dass die neue Einhängung selbst eine Abhängige ist (von der Gemeinschaftsgruppe 4):
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 168 167 8:23 / /mntX rw,relatime shared:1 169 167 8:22 / /mntY rw,relatime master:2 173 168 8:3 / /mntX/a rw,relatime shared:3 175 169 8:5 / /mntY/b rw,relatime 179 169 8:1 / /mntY/c rw,relatime master:4
Einer der Hauptzwecke der nicht-bindfähigen Einhängungen ist die Vermeidung des Problems der »Einhängeexplosionen«, bei der wiederholt durchgeführte Einhängungen mit der Option bind eines Unterbaums auf einer höheren Ebene in einer Einhängung auf niedrigeren Ebene ausgeführt werden. Das Problem wird in der nachfolgenden Shell-Sitzung dargestellt.
Nehmen wir an, wir haben ein System mit folgenden Einhängungen:
# mount | awk '{print $1, $2, $3}' /dev/sda1 on / /dev/sdb6 on /mntX /dev/sdb7 on /mntY
Nehmen wir weiterhin an, dass wir das Wurzelverzeichnis rekursiv unter den Home-Verzeichnissen verschiedener Benutzer mit der Option bind einhängen möchten. Wir machen dies für den ersten Benutzer und untersuchen die Einhängungen:
# mount --rbind / /home/cecilia/ # mount | awk '{print $1, $2, $3}' /dev/sda1 on / /dev/sdb6 on /mntX /dev/sdb7 on /mntY /dev/sda1 on /home/cecilia /dev/sdb6 on /home/cecilia/mntX /dev/sdb7 on /home/cecilia/mntY
Wenn wir diese Aktion für den zweiten Benutzer wiederholen, beginnen wir, das Explosionsproblem zu sehen:
# mount --rbind / /home/henry # mount | awk '{print $1, $2, $3}' /dev/sda1 on / /dev/sdb6 on /mntX /dev/sdb7 on /mntY /dev/sda1 on /home/cecilia /dev/sdb6 on /home/cecilia/mntX /dev/sdb7 on /home/cecilia/mntY /dev/sda1 on /home/henry /dev/sdb6 on /home/henry/mntX /dev/sdb7 on /home/henry/mntY /dev/sda1 on /home/henry/home/cecilia /dev/sdb6 on /home/henry/home/cecilia/mntX /dev/sdb7 on /home/henry/home/cecilia/mntY
Unter /home/henry haben wir nicht nur die Einhängungen /mntX und /mntY rekursiv hinzugefügt, sondern auch die rekursiven Einhängungen dieser Verzeichnisse unter /home/cecilia, die im vorherigen Schritt erstellt wurden. Bei der Wiederholung dieses Schrittes für einen dritten Benutzer wird es offensichtlich, dass die Explosion von exponentieller Natur ist:
# mount --rbind / /home/otto # mount | awk '{print $1, $2, $3}' /dev/sda1 on / /dev/sdb6 on /mntX /dev/sdb7 on /mntY /dev/sda1 on /home/cecilia /dev/sdb6 on /home/cecilia/mntX /dev/sdb7 on /home/cecilia/mntY /dev/sda1 on /home/henry /dev/sdb6 on /home/henry/mntX /dev/sdb7 on /home/henry/mntY /dev/sda1 on /home/henry/home/cecilia /dev/sdb6 on /home/henry/home/cecilia/mntX /dev/sdb7 on /home/henry/home/cecilia/mntY /dev/sda1 on /home/otto /dev/sdb6 on /home/otto/mntX /dev/sdb7 on /home/otto/mntY /dev/sda1 on /home/otto/home/cecilia /dev/sdb6 on /home/otto/home/cecilia/mntX /dev/sdb7 on /home/otto/home/cecilia/mntY /dev/sda1 on /home/otto/home/henry /dev/sdb6 on /home/otto/home/henry/mntX /dev/sdb7 on /home/otto/home/henry/mntY /dev/sda1 on /home/otto/home/henry/home/cecilia /dev/sdb6 on /home/otto/home/henry/home/cecilia/mntX /dev/sdb7 on /home/otto/home/henry/home/cecilia/mntY
Das Einhänge-Explosionsproblem im obigen Szenario kann vermieden werden, indem jede der neuen Einhängungen nicht-bindfähig gemacht wird. Die Auswirkung ist, dass rekursive Einhängungen des Wurzelverzeichnisses sich nicht bei nicht-bindfähigen Einhängungen replizieren werden. Wir machen eine solche Einhängung für den ersten Benutzer:
# mount --rbind --make-unbindable / /home/cecilia
Bevor wir fortfahren, zeigen wir, dass die nicht-bindfähigen Einhängungen in der Tat nicht bindfähig sind:
# mkdir /mntZ # mount --bind /home/cecilia /mntZ mount: wrong fs type, bad option, bad superblock on /home/cecilia,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so.
Jetzt erstellen wir nicht bindfähige rekursive Einhängungen mit der Option bind für die anderen zwei Benutzer:
# mount --rbind --make-unbindable / /home/henry # mount --rbind --make-unbindable / /home/otto
Bei der Untersuchung der Liste der Einhängungen sehen wir, dass es keine Explosion der Einhängungen gab, da die nicht bindfähigen Einhängungen nicht unter den Verzeichnissen der jeweiligen Benutzer repliziert wurden:
# mount | awk '{print $1, $2, $3}' /dev/sda1 on / /dev/sdb6 on /mntX /dev/sdb7 on /mntY /dev/sda1 on /home/cecilia /dev/sdb6 on /home/cecilia/mntX /dev/sdb7 on /home/cecilia/mntY /dev/sda1 on /home/henry /dev/sdb6 on /home/henry/mntX /dev/sdb7 on /home/henry/mntY /dev/sda1 on /home/otto /dev/sdb6 on /home/otto/mntX /dev/sdb7 on /home/otto/mntY
Die nachfolgende Tabelle zeigt die Auswirkung, die die Anwendung eines neuen Weiterleitungstyps (d.h. mount --make-xxxx) auf bestehende Weiterleitungstypen einer Einhängung hat. Die Zeilen entsprechen den bestehenden Weiterleitungstypen und die Spalten sind die neuen Weiterleitungseinstellungen. Aus Platzgründen ist »private« (privat) mit »priv« und »unbindable« (nicht bindfähig) mit »unbind« abgekürzt.
make-shared | make-slave | make-priv | make-unbind | |
shared | shared | slave/priv [1] | priv | unbind |
slave | slave+shared | slave [2] | priv | unbind |
slave+shared | slave+shared | slave | priv | unbind |
private | shared | priv [2] | priv | unbind |
unbindable | shared | unbind [2] | priv | unbind |
Beachten Sie die folgenden Details zu der Tabelle:
Nehmen wir an, dass der folgende Befehl ausgeführt wird:
mount --bind A/a B/b
Hier ist A die Quelleinhängung, B die Zieleinhängung, a ist ein Unterverzeichnispfad unter dem Einhängungspunkt A und b ist ein Unterverzeichnispfad unter dem Einhängungspunkt B. Der Weiterleitungstyp der resultierenden Einhängung B/b hängt von den Weiterleitungstypen der Einhängungen A und B ab und wird in der folgenden Tabelle zusammengefasst.
Quelle(A) | |||||
shared | private | slave | unbind | ||
Ziel(B) | shared | shared | shared | slave+shared | ungültig |
nicht gemeinsam | shared | private | slave | ungültig |
Beachten Sie, dass ein rekursives Bind eines Unterbaums der gleichen Semantik wie der Bind-Aktion auf jede Einhängung im Unterbaum folgt. (Nicht-Bind-fähige Einhängungen werden automatisch am Zieleinhängepunkt abgeschnitten.)
Für weitere Details siehe Documentation/filesystems/sharedsubtree.rst in dem Kernelquellbaum.
Nehmen wir an, dass der folgende Befehl ausgeführt wird:
mount --move A B/b
Hier ist A die Quelleinhängung, B die Zieleinhängung und b ist der Unterverzeichnispfad unter dem Einhängepunkt B. Der Weiterleitungstyp der entstehenden Einhängung B/b hängt von den Weiterleitungstypen der Einhängungen A und B ab und wird in der nachfolgenden Tabelle zusammengefasst.
Quelle(A) | |||||
shared | private | slave | unbind | ||
Ziel(B) | shared | shared | shared | slave+shared | ungültig |
nicht gemeinsam | shared | private | slave | unbindable |
Hinweis: Das Verschieben einer Einhängung, die sich unter einer gemeinsamen Einhängung befindet, ist ungültig.
Für weitere Details siehe Documentation/filesystems/sharedsubtree.rst in dem Kernelquellbaum.
Angenommen, wir verwenden folgenden Befehl, um eine Einhängung zu erstellen:
mount Gerät B/b
Hier ist B die Zieleinhängung und b der Unterverzeichnispfad unter dem Einhängepunkt B. Der Weiterleitungstyp der entstehenden Einhängung B/b folgt den gleichen Regeln wie für eine Einhängung mit der Option bind, bei der der Weiterleitungstyp der Quelleinhängung immer als privat betrachtet wird.
Angenommen, wir verwenden folgenden Befehl, um eine Einhängung aufzulösen:
umount A
Hier ist A eine Einhängung auf B/b, wobei B die Elterneinhängung und b ein Unterverzeichnispfad unterhalb des Einhängepunkts B ist. Falls B gemeinsam ist, dann werden alle kürzlich eingehängten Einhängungen ausgehängt, die sich bei b befinden, die Weiterleitungen von der Einhängung B erhalten und keine Untereinhängungen haben.
Die Markierung propagate_from:X wird in den optionalen Feldern des Datensatzes /proc/PID/mountinfo gezeigt, falls es einen Prozess gibt, der den Master der direkt Abhängigen nicht sehen kann (d.h. der Pfadname vom Master ist von dem Dateisystemwurzelverzeichnis aus nicht erreichbar) und so nicht die Weiterleitungskette zwischen Einhängungen, die er sehen kann, bestimmen kann.
In dem folgenden Beispiel erstellen wir zuerst eine Kette aus zwei Gliedern zwischen Master und Abhängiger, zwischen den Einhängungen /mnt, /tmp/etc und /mnt/tmp/etc. Dann wird der Befehl chroot(1) verwandt, um den Einhängepunkt /tmp/etc vom Wurzelverzeichnis unerreichbar zu bekommen und damit eine Situation zu erstellen, bei der der Master von /mnt/tmp/etc nicht vom (neuen) Wurzelverzeichnis des Prozesses aus erreichbar ist.
Zuerst machen wir eine Einhängung mit der Option bind des Wurzelverzeichnisses auf /mnt und dann eine Einhängung mit der Option bind von /proc bei /mnt/proc, so dass nach einem späteren chroot(1) das Dateisystem proc(5) an dem korrekten Ort in der Umgebung innerhalb des Chroots sichtbar bleibt.
# mkdir -p /mnt/proc # mount --bind / /mnt # mount --bind /proc /mnt/proc
Als nächstes stellen wir sicher, dass die Einhängung /mnt eine gemeinsame Einhängung in der neuen Gemeinschaftsgruppe (ohne weitere Mitglieder) ist:
# mount --make-private /mnt # Von jeder vorherigen Gemeinschaftsgruppe isolieren # mount --make-shared /mnt # cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//' 239 61 8:2 / /mnt … shared:102 248 239 0:4 / /mnt/proc … shared:5
Als nächstes hängen wir /mnt/etc auf /tmp/etc mit der Option bind ein:
# mkdir -p /tmp/etc # mount --bind /mnt/etc /tmp/etc # cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//' 239 61 8:2 / /mnt … shared:102 248 239 0:4 / /mnt/proc … shared:5 267 40 8:2 /etc /tmp/etc … shared:102
Anfänglich sind diese zwei Einhängungen in der gleichen Gemeinschaftsgruppe, aber dann machen wir /tmp/etc eine Abhängige von /mnt/etc, und dann machen wir /tmp/etc auch gemeinsam, so dass es Ereignisse an die nächste Abhängige in der Kette weiterleiten kann:
# mount --make-slave /tmp/etc # mount --make-shared /tmp/etc # cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//' 239 61 8:2 / /mnt … shared:102 248 239 0:4 / /mnt/proc … shared:5 267 40 8:2 /etc /tmp/etc … shared:105 master:102
Dann hängen wir /tmp/etc auf /mnt/tmp/etc mit der Option bind ein. Wieder sind die zwei Einhängungen anfänglich in der gleichen Gemeinschaftsgruppe, aber wir machen /mnt/tmp/etc eine Abhängige von /tmp/etc:
# mkdir -p /mnt/tmp/etc # mount --bind /tmp/etc /mnt/tmp/etc # mount --make-slave /mnt/tmp/etc # cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//' 239 61 8:2 / /mnt … shared:102 248 239 0:4 / /mnt/proc … shared:5 267 40 8:2 /etc /tmp/etc … shared:105 master:102 273 239 8:2 /etc /mnt/tmp/etc … master:105
In vorhergehender Ausgabe können wir sehen, dass /mnt der Master der Abhängigen /tmp/etc ist, die wiederum der Master der Abhängigen /mnt/tmp/etc ist.
Dann wechseln wir mit chroot(1) zu dem Verzeichnis /mnt, wodurch die Einhängung mit der Kennung 267 vom (neuen) Wurzelverzeichnis aus nicht mehr erreichbar ist:
# chroot /mnt
Wenn wir den Zustand der Einhängungen innerhalb der Chroot-Umgebung untersuchen, sehen wir folgendes:
# cat /proc/self/mountinfo | sed 's/ - .*//' 239 61 8:2 / / … shared:102 248 239 0:4 / /proc … shared:5 273 239 8:2 /etc /tmp/etc … master:105 propagate_from:102
Oben sehen wir, dass die Einhängung mit der Kennung 273 eine Abhängige ist, deren Master die Gemeinschaftsgruppe 105 ist. Der Einhängepunkt für diesen Master kann nicht erreicht werden, und daher wird eine Markierung propagate_from angezeigt, die darauf aufmerksam macht, dass die nahest-liegende dominante Gemeinschaftsgruppe (d.h. der nächste erreichbare Einhängepunkt in der Abhängigkeitskette) die Gemeinschaftsgruppe mit der Kennung 102 ist (die dem Einhängepunkt /mnt entspricht, bevor der chroot(1) durchgeführt wurde.)
Einhängenamensräume erschienen erstmalig in Linux 2.4.19.
Namensräume sind eine Linux-spezifische Funktionalität.
Der einer neuen Einhängung zugewiesene Weiterleitungstyp hängt vom Weiterleitungstyp der Elterneinhängung ab. Falls die Einhängung eine Elterneinhängung hat (d.h. der Einhängungspunkt ist nicht die Wurzel) und der Weiterleitungstyp der Elterneinhängung MS_SHARED ist, dann ist der Weiterleitungstyp der neuen Einhängung auch MS_SHARED. Andernfalls ist der Einhängungstyp der neuen Einhängung MS_PRIVATE.
Unbenommen der Tatsache, dass der Standard-Weiterleitungstyp für neue Einhängungen in vielen Fällen MS_PRIVATE ist, ist MS_SHARED normalerweise nützlicher. Aus diesem Grund hängt systemd(1) beim Systemstart alle Einhängungen neu mit MS_SHARED ein. Daher ist auf modernen Systemen der Standard-Weiterleitungstyp in der Praxis MS_SHARED.
Da bei der Verwendung von unshare(1) typischerweise das Ziel darin besteht, vollständige Isolierung der Einhängungen in dem neuen Namensraum zu erreichen, kehrt unshare(1) (seit util-linux 2.27) den durch systemd(1) durchgeführten Schritt um, indem es in dem neuen Namensraum alle Einhängungen zu privaten macht. Das bedeutet, unshare(1) führt das Äquivalent des folgenden Befehls im neuen Namensraum aus:
mount --make-rprivate /
Um dies zu verhindern, können Sie die Option --propagation unchanged für unshare(1) verwenden.
Eine Anwendung, die einen neuen Einhängenamensraum direkt mit clone(2) oder unshare(2) erzeugt, könnte den Wunsch haben, die Weiterleitung von Einhängeereignissen in andere Einhängenamensräume zu verhindern (wie dies durch unshare(1) erfolgt). Dies kann durch Änderung des Einhängetyps von Einhängungen in dem neuen Namensraum auf entweder MS_SLAVE oder MS_PRIVATE erfolgen, indem ein Aufruf folgender Art erfolgt:
mount(NULL, "/", MS_SLAVE | MS_REC, NULL);
Für eine Diskussion von Weiterleitungstypen beim Verschieben von Einhängungen (MS_MOVE) und der Erstellung von Einhängungen mit der Option bind (MS_BIND) siehe Documentation/filesystems/sharedsubtree.rst.
Beachten Sie die folgenden Punkte in Hinblick auf Einhängenamensräume:
$ sudo sh # mount --bind /dev/null /etc/shadow # cat /etc/shadow # Ergibt keine Ausgabe
# unshare --user --map-root-user --mount \
strace -o /tmp/log \
umount /mnt/dir umount: /etc/shadow: nicht eingehängt. # grep '^umount' /tmp/log umount2("/etc/shadow", 0) = -1 EINVAL (Invalid argument)
# echo 'aaaaa' > /tmp/a # Datei, die auf /etc/shadow eingehängt werden soll # unshare --user --map-root-user --mount \
sh -c 'mount --bind /tmp/a /etc/shadow; cat /etc/shadow' aaaaa # umount /etc/shadow
$ PS1='ns1# ' sudo unshare --user --map-root-user \
--mount --propagation private bash ns1# echo $$ # Wir benötigen die PID dieser Shell später 778501 ns1# mount --make-shared --bind /mnt /mnt ns1# mkdir /mnt/x ns1# mount --make-private -t tmpfs none /mnt/x ns1# mkdir /mnt/x/y ns1# mount --make-private -t tmpfs none /mnt/x/y ns1# grep /mnt /proc/self/mountinfo | sed 's/ - .*//' 986 83 8:5 /mnt /mnt rw,relatime shared:344 989 986 0:56 / /mnt/x rw,relatime 990 989 0:57 / /mnt/x/y rw,relatime
ns1# PS1='ns2# ' unshare --user --map-root-user \
--mount --propagation unchanged bash ns2# grep /mnt /proc/self/mountinfo | sed 's/ - .*//' 1239 1204 8:5 /mnt /mnt rw,relatime master:344 1240 1239 0:56 / /mnt/x rw,relatime 1241 1240 0:57 / /mnt/x/y rw,relatime
$ PS1='ns3# ' sudo nsenter -t 778501 --user --mount ns3# mount --rbind --make-private /mnt/x /mnt/ppp ns3# grep /mnt /proc/self/mountinfo | sed 's/ - .*//' 986 83 8:5 /mnt /mnt rw,relatime shared:344 989 986 0:56 / /mnt/x rw,relatime 990 989 0:57 / /mnt/x/y rw,relatime 1242 986 0:56 / /mnt/ppp rw,relatime 1243 1242 0:57 / /mnt/ppp/y rw,relatime shared:518
ns2# grep /mnt /proc/self/mountinfo | sed 's/ - .*//' 1239 1204 8:5 /mnt /mnt rw,relatime master:344 1240 1239 0:56 / /mnt/x rw,relatime 1241 1240 0:57 / /mnt/x/y rw,relatime 1244 1239 0:56 / /mnt/ppp rw,relatime 1245 1244 0:57 / /mnt/ppp/y rw,relatime master:518
ns2# umount /mnt/ppp/y umount: /mnt/ppp/y: nicht eingehängt. ns2# umount -l /mnt/ppp | sed 's/ - .*//' # Erfolgreich… ns2# grep /mnt /proc/self/mountinfo 1239 1204 8:5 /mnt /mnt rw,relatime master:344 1240 1239 0:56 / /mnt/x rw,relatime 1241 1240 0:57 / /mnt/x/y rw,relatime
$ sudo mkdir /mnt/dir $ sudo mount --bind -o ro /some/path /mnt/dir $ sudo unshare --user --map-root-user --mount \
mount -o remount,rw /mnt/dir mount: /mnt/dir: Zugriff verweigert.
Siehe pivot_root(2).
unshare(1), clone(2), mount(2), mount_setattr(2), pivot_root(2), setns(2), umount(2), unshare(2), proc(5), namespaces(7), user_namespaces(7), findmnt(8), mount(8), pam_namespace(8), pivot_root(8), umount(8)
Documentation/filesystems/sharedsubtree.rst im Kernelquellbaum.
Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann <debian@helgefjell.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer.
10. Februar 2023 | Linux man-pages 6.03 |