Provided by: manpages-de_4.27.0-1_all 

BEZEICHNUNG
pid_namespaces - Überblick über PID-Namensräume
BESCHREIBUNG
Für einen Überblick über Namensräume, siehe namespaces(7).
PID-Namensräume isolieren den Raum der Prozesskennungen. Das bedeutet, dass Prozesse in verschiedenen
PID-Namensräumen die gleiche PID haben können. PID-Namensräume erlauben Containern, Funktionalitäten wie
Suspendierung/Wiederaufnahme der Gruppe an Prozessen in dem Container und der Migration des Containers
auf einen neuen Rechner bereitzustellen, bei denen die Prozesse innerhalb des Containers die gleiche PID
behalten.
PIDs in einem neuen PID-Namensraum beginnen bei 1, ähnlich wie in autonomen Systemen. Aufrufe von
fork(2), vfork(2) oder clone(2) werden Prozesse mit PIDs erstellen, die innerhalb des Namensraums
eindeutig sind.
Die Verwendung von PID-Namensräumen benötigt einen Kernel, der mit der Option CONFIG_PID_NS konfiguriert
wurde.
Der Init-Prozess des Namensraums
Der erste in einem neuen Namensraum erstellte Prozess (d.h. der mittels clone(2) mit dem Schalter
CLONE_NEWPID erstellte Prozess oder der erste Prozess, der durch einen Prozess nach einem Aufruf von
unshare(2) mittels des Schalters CLONE_NEWPID erstellt wurde) hat die PID 1 und ist der »Init«-Prozess
für den Namensraum (siehe init(1)). Dieser Prozess wird der Elternprozess jedes Kindprozesses, die
verwaist wurden, da sich ein Prozess, der sich in diesem Namensraum befindet, beendet hat (weitere
Details finden Sie weiter unten).
Falls sich der »Init«-Prozess eines PID-Namensraums beendet, beendet der Kernel mittels des Signals
SIGKILL alle Prozesse in dem Namensraum. Dieses Verhalten spiegelt die Tatsache wieder, dass der
»Init«-Prozess für das korrekte Funktionieren eines PID-Namensraums wesentlich ist. In diesem Fall wird
ein nachfolgender fork(2) in den Namensraum mit dem Fehler ENOMEM fehlschlagen; es ist nicht möglich,
einen neuen Prozess in einem PID-Namensraum zu erstellen, dessen »Init«-Prozess sich beendet hat. Solche
Szenarien können auftreten, wenn beispielsweise ein Prozess einen offenen Dateideskriptor für eine Datei
/proc/PID/ns/pid verwendet, der einem Prozess entspricht, der in einem Namensraum war und der mit
setns(2) in einen Namensraum soll, nachdem sich der »Init«-Prozess beendet hat. Ein anderes mögliches
Szenario kann direkt nach dem Aufruf von unshare(2) auftreten: Falls sich der erste Kindprozess, der nach
einem fork(2) nachfolgend erstellt wurde, beendet, dann schlagen nachfolgende Aufrufe von fork(2) mit
ENOMEM fehl.
Nur Signale, für die der »Init«-Prozess einen Signal-Handler etabliert hat, können durch andere
Mitglieder des PID-Namensraums an den »Init«-Prozess gesandt werden. Diese Einschränkung gilt sogar für
privilegierte Prozesse und verhindert, dass andere Mitglieder des PID-Namensraums versehentlich den
»Init«-Prozess töten.
Entsprechend kann ein Prozess in einem Vorgängernamensraum – gemäß der gewöhnlichen, in kill(2)
beschriebenen Berechtigungsprüfungen – nur Signale an den »Init«-Prozess eines Nachfolge-PID-Namensraums
senden, falls der »Init«-Prozess einen Handler für das Signal etabliert hat. (Innerhalb des Handlers wird
das sigaction(2) siginfo_t-Feld si_pid Null sein.) SIGKILL oder SIGSTOP werden besonders behandelt: diese
Signale werden zwangsweise zugestellt, wenn sie von einem Vorgänger-PID-Namensraum gesandt werden. Keines
dieser Signale kann durch den »Init«-Prozess abgefangen werden. Daher führen sie zu den gewöhnlichen
Aktionen, die diesen Signalen zugeordnet sind (beenden bzw. stoppen des Prozesses).
Seit Linux 3.4 führt der Systemaufruf reboot(2) zum Senden eines Signales an den »Init«-Prozess des
Namensraumes. Siehe reboot(2) für weitere Details.
Verschachtelung von PID-Namensräumen
PID-Namensräume können verschachtelt werden: jeder PID-Namensraum hat einen Vorgänger, außer für den
anfänglichen (»Wurzel-«) PID-Namensraum. Der Vorgänger eines PID-Namensraums ist der PID-Namensraum des
Prozesses, der den Namensraum mittels clone(2) oder unshare(2) erstellte. PID-Namensräume formen somit
einen Baum, wobei alle Namensräume in letzter Instanz ihren Vorgänger auf den Wurzelnamensraum
zurückführen. Seit Linux 3.7 begrenzt der Kernel die maximale Schachtelungstiefe für PID-Namensräume auf
32.
Ein Prozess ist für andere Prozesse in seinem PID-Namensraum sichtbar und für Prozesse in jedem direkten
Vorgänger-PID-Namensraum, direkt zurück bis zum Wurzel-PID-Namensraum. In diesem Zusammenhang bedeutet
»sichtbar«, dass ein Prozess das Ziel von Aktionen eines anderen Prozesses durch Verwendung von
Systemaufrufen sein kann, die eine Prozesskennung angeben können. Umgekehrt kann ein Prozess in einem
Nachfolge-PID-Namensraum die Prozesse in dem Vorgänger und weiter entfernten Vorgänger-Namensräumen nicht
sehen. Kurz gesagt: Ein Prozess kann nur Prozesse, die in seinem eigenen PID-Namensraum und in
Nachfolgern dieses Namensraums sind, sehen (z.B. ihnen Signale mit kill(2) senden, ihren Nice-Wert mit
setpriority(2) ändern usw.).
Ein Prozess hat eine Prozesskennung in jedem der Ebenen der PID-Namensraum-Hierarchie, in der er sichtbar
ist, sowie rückwärts durch jeden direkten Vorgängernamensraum bis zum Wurzel-PID-Namensraum.
Systemaufrufe, die auf Prozesskennungen agieren, agieren immer auf Prozesskennungen, die in dem
PID-Namensraum des aufrufenden Prozesses sichtbar sind. Ein Aufruf von getpid(2) liefert immer die PID
zurück, die dem Namensraum zugeordnet ist, in dem der Prozess erstellt wurde.
Einige Prozesse in einem PID-Namensraum können Elternprozesse haben, die sich außerhalb des Namensraums
befinden. Der Elternprozess des anfänglichen Prozesses in dem Namensraum (d.h. der init(1)-Prozess mit
der PID 1) befindet sich beispielsweise notwendigerweise in einem anderen Namensraum. Entsprechend sind
die direkten Kindprozesses eines Prozesses, der setns(2) verwendet, damit seine Kindprozesse einem
PID-Namensraum beitreten, in einem anderen PID-Nemsraum als der Aufrufende von setns(2). Wird für solche
Prozesse getppid(2) aufgerufen, dann wird 0 zurückgeliefert.
Während Prozesse frei in Nachfolge-PID-Namensräume absteigen können (z.B. mittels setns(2) mit einem
PID-Namensraum-Dateideskriptor), können sie sich nicht in die andere Richtung bewegen. Das bedeutet,
Prozesse dürfen keine Vorgängernamensräume (direkte, zweiter Stufe, usw.) betreten. Das Ändern von
PID-Namensräumen ist eine Einwegaktion.
Die Aktion NS_GET_PARENT ioctl(2) kann zum Erkennen der hierarchischen Beziehung zwischen
PID-Namensräumen verwandt werden; siehe ioctl_nfs(2).
Semantik von setns und unshare(2)
Aufrufe von setns(2), die einen PID-Namensraum-Dateideskriptor festlegen und Aufrufe von unshare(2) mit
dem Schalter CLONE_NEWPID führen dazu, dass nachfolgend durch den Aufrufenden erstellte Kindprozesse in
einem anderen PID-Namensraum als dem des Aufrufenden abgelegt werden. (Seit Linux 4.12 wird dieser
PID-Namensraum über die Datei /proc/PID/ns/pid_for_children gezeigt, wie in namespaces(7) beschrieben.)
Diese Aufrufe ändern allerdings nicht den PID-Namensraum des aufrufenden Prozesses, da dies das
Verständnis des Aufrufenden über seine eigene PID (wie sie mit getpid() berichtet wird) ändern würde,
wodurch viele Anwendungen und Bibliotheken beschädigt würden.
Um es anders zu sagen: die Mitgliedschaft eines Prozesses in einem PID-Namensraum wird bei der Erstellung
des Prozesses bestimmt und kann danach nicht mehr geändert werden. Unter anderem bedeutet dies, dass die
Eltern-Kind-Beziehung zwischen Prozessen die Vorgänger-Nachfolger-Beziehung zwischen PID-Namensräumen
spiegelt: der Elternprozess ist entweder im gleichen Namensraum oder befindet sich im direkten
Vorgänger-PID-Namensraum.
Ein Prozess kann unshare(2) mit dem Schalter CLONE_NEWPID nur einmal aufrufen. Nachdem er diese Aktion
durchgeführt hat, wird sein symbolischer Link /proc/PID/ns/pid_for_children leer sein, bis der erste
Kindprozess in dem Namensraum erstellt wurde.
Adoption von verwaisten Kindprozessen
Wenn ein Kindprozess verwaist wird, wird der »Init«-Prozess in dem PID-Namensraum seines Elternprozesses
sein neuer Elternprozess (außer einer der Vorfahrprozesse des Elternprozesses, der näher dran ist, setzt
den Befehl prctl(2) PR_SET_CHILD_SUBREAPER ein, um sich selbst als Auffänger des verwaisten
Nachfahrprozesses zu markieren.) Beachten Sie, dass aufgrund der oben beschriebenen Semantik von setns(2)
und unshare(2) dies der »Init«-Prozess in dem PID-Namensraum sein kann, der Vorgänger des PID-Namensraums
des Kindprozesses sein kann, statt des »Init«-Prozesses in dem eigenen PID-Namensraum des Kindprozesses.
Kompatibilität von CLONE_NEWPID zu anderen CLONE_*-Schaltern
In den aktuellen Versionen von Linux kann CLONE_NEWPID nicht mit CLONE_THREAD kombiniert werden. Threads
müssen im gleichen PID-Namensraum sein, damit die Threads in einem Prozess sich gegenseitig Signale
senden können. Entsprechend muss es möglich sein, alle Threads eines Prozesses in dem Dateisystem proc(5)
zu sehen. Ergänzend kommt hinzu, dass die Prozesskennung des Prozesses, der ein Signal sendet, nicht beim
Senden eines Signals aussagekräftig kodiert werden könnte, falls die zwei Threads in verschiedenen
PID-Namensräumen wären (siehe die Beschreibung des Typs siginfo_t in sigaction(2)). Da diese berechnet
wird, wenn ein Signal in die Warteschlange gestellt wird, würde eine Signalwarteschlange, die von
Prozessen in mehreren PID-Namensräumen gemeinsam benutzt würde, dies vereiteln.
In früheren Versionen von Linux war zusätzlich CLONE_NEWPID verboten (schlug mit dem Fehler EINVAL fehl)
zusammen mit CLONE_SIGHAND (vor Linux 4.3) sowie CLONE_VM (vor Linux 3.12). Die Änderungen, die diese
Beschränkungen aufhoben, wurden auch in ältere stabile Kernel portiert.
/proc und PID-Namensräume
Ein Dateisystem /proc zeigt (in den Verzeichnissen /proc/PID) nur Prozesse, die in dem PID-Namensraum des
Prozesses sichtbar sind, der die Einhängung durchführte, selbst falls das Dateisystem /proc von Prozessen
in anderen Namensräumen betrachtet wird.
Nach dem Erstellen eines neuen PID-Namensraumes ist es für den Kindprozess nützlich, sein
Wurzelverzeichnis zu ändern und eine neue Procfs-Instanz unter /proc einzuhängen, so dass Werkzeuge wie
ps(1) korrekt funktionieren. Falls ein neuer Einhängenamensraum gleichzeitig durch Aufnahme von
CLONE_NEWNS in dem Argument flags von clone(2) oder unshare(2) erstellt wird, dann ist es nicht
notwendig, das Wurzelverzeichnis zu ändern: eine neue Procfs-Instanz kann direkt über /proc eingehängt
werden.
In einer Shell lautet der Einhängebefehl für /proc:
$ mount -t proc proc /proc
Der Aufruf von readlink(2) auf dem Pfad /proc/self liefert die Prozesskennung des Aufrufenden in dem
PID-Namensraum der Procfs-Einhängung (d.h. des PID-Namensraums, der Procfs einhängte). Dies kann zu
Untersuchungszwecken nützlich sein, wenn ein Prozess seine PID in anderen Namensräumen herausfinden
möchte.
/proc-Dateien
/proc/sys/kernel/ns_last_pid (seit Linux 3.3)
Diese Datei (die pro PID-Namensraum virtualisiert ist) zeigt die letzte PID, die in diesem
PID-Namensraum zugewiesen wurde. Wenn die nächste PID zugewiesen wird, wird der Kernel nach der
kleinsten nicht zugewiesenen PID suchen, die größer als dieser Wert ist, und wenn danach diese
Datei gelesen wird, wird diese PID dann gezeigt.
Diese Datei ist für einen Prozess, der über die Capability CAP_SYS_ADMIN oder (seit Linux 5.9)
CAP_CHECKPOINT_RESTORE innerhalb des Benutzernamensraums, der den PID-Namensraum besitzt, verfügt,
schreibbar. Dies ermöglicht es, die PID zu bestimmen, die dem nächsten Prozess, der innerhalb des
PID-Namensraums erstellt wird, zugewiesen wird.
Verschiedenes
Wenn eine Prozesskennung über einen UNIX-Domain-Socket an einen Prozess in einem anderen PID-Namensraum
übergeben wird (siehe die Beschreibung von SCM_CREDENTIALS in unix(7)), dann wird sie in den
entsprechenden PID-Wert in dem PID-Namensraum des empfangenen Prozesses übersetzt.
STANDARDS
Linux.
BEISPIELE
siehe user_namespaces(7)
SIEHE AUCH
clone(2), reboot(2), setns(2), unshare(2), proc(5), capabilities(7), credentials(7), mount_namespaces(7),
namespaces(7), user_namespaces(7), switch_root(8)
ÜBERSETZUNG
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: debian-l10n-german@lists.debian.org.
Linux man-pages 6.9.1 13. Juni 2024 pid_namespaces(7)