Heim >Backend-Entwicklung >Golang >Warum gibt der Aufruf von „setns' von Go „EINVAL' für den Mnt-Namespace zurück?
Aufruf von Sets aus Go gibt EINVAL für mnt-Namespace zurück
Problembeschreibung
Im Go-Code , gibt der Versuch, den mnt-Namespace mithilfe der Funktion syscall.RawSyscall aufzurufen, um den Systemaufruf setns aufzurufen, einen EINVAL-Fehler zurück. Dieses Problem besteht trotz einer korrekten Einrichtung und einer funktionierenden C-Implementierung, die erfolgreich in den Namespace gelangt, weiterhin.
Ursache und Lösung
Die Hauptursache des Problems liegt in der Multi- Gewindecharakter von Go. Der setns-Systemaufruf muss in einem Single-Threaded-Kontext ausgeführt werden, damit er erfolgreich ist. Da Go-Anwendungen standardmäßig Multithread-Anwendungen sind, muss der setns-Aufruf vor dem Start der Go-Laufzeitthreads erfolgen.
Um dieses Problem zu beheben, kann der „CGO-Konstruktor-Trick“ eingesetzt werden. Mit dieser Technik kann C-Code ausgeführt werden, bevor die Go-Laufzeit beginnt. Durch die Verwendung des Makros __attribute__((constructor)) im C-Code kann eine Funktion so gestaltet werden, dass sie vor der Initialisierung von Go in einem Single-Thread-C-Kontext ausgeführt wird.
Geänderter Go-Code
Der folgende modifizierte Go-Code verwendet den Konstruktor-Trick, um das Problem zu lösen:
<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>
Durch die Nutzung des cgo-Konstruktor-Tricks kann die Go-Anwendung nun mithilfe des Systemaufrufs setns erfolgreich in den mnt-Namespace gelangen.
Das obige ist der detaillierte Inhalt vonWarum gibt der Aufruf von „setns' von Go „EINVAL' für den Mnt-Namespace zurück?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!