Heim > Artikel > Backend-Entwicklung > Warum schlägt „setns“ mit EINVAL in einer Go-Multithread-Umgebung fehl?
Beim Versuch, „setns“ von Go aus aufzurufen, um den MNT einzugeben Namespace gibt der Aufruf konsistent EINVAL zurück. Dieses Problem wird beobachtet, obwohl eine C-Implementierung derselben Funktionalität ordnungsgemäß funktioniert.
Das Problem rührt von der Tatsache her, dass Go eine Multithread-Sprache ist, während „setns“ dies erwartet aus einem Single-Threaded-Kontext aufgerufen. Beim Aufruf aus einer Multithread-Umgebung kann „setns“ den aktuellen Thread nicht richtig mit dem Ziel-Namespace verknüpfen.
Eine Lösung für dieses Problem ist die Verwendung von „CGO-Konstruktor-Trick.“ Mit dieser Technik können Sie eine C-Funktion angeben, die ausgeführt werden soll, bevor die Go-Laufzeit initialisiert wird. Mit diesem Ansatz kann Ihre C-Funktion „setns“ aufrufen, bevor die Go-Threads erstellt werden, wodurch sichergestellt wird, dass der Aufruf in einem Single-Threaded-Kontext erfolgt.
<code class="go">/* #include <sched.h> #include <stdio.h> #include <fcntl.h> __attribute__((constructor)) void enter_namespace(void) { setns(open("/proc/<PID>/ns/mnt", O_RDONLY, 0644), 0); } */ import "C" ... rest of file is unchanged ... </code>
Denken Sie daran, den Platzhalter
Dieser Ansatz weist einige Einschränkungen auf:
Ein Patch für „setns(2)“ bestätigt die Anforderung für Single-Thread-Ausführung in Multi-Thread-Umgebungen. Prozesse mit Funktionen müssen außerdem CAP_SYS_CHROOT und CAP_SYS_ADMIN in ihrem eigenen Benutzernamensraum und CAP_SYS_ADMIN im Ziel-Mount-Namensraum besitzen.
Das obige ist der detaillierte Inhalt vonWarum schlägt „setns“ mit EINVAL in einer Go-Multithread-Umgebung fehl?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!