Warum schlägt „setns' mit EINVAL in einer Go-Multithread-Umgebung fehl?

Linda Hamilton
Freigeben: 2024-11-01 09:23:30
Original
666 Leute haben es durchsucht

Why Does 'setns' Fail with EINVAL in a Go Multithreaded Environment?

Aufruf von „setns“ von Go aus schlägt mit EINVAL für MNT-Namespace fehl

Problem

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.

Ursache

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.

Lösung – CGO-Konstruktor-Trick

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.

  1. Konstruieren Sie eine C-Funktion, die „setns“ aufruft ' mit den gewünschten Parametern. Tun Sie dies, indem Sie die Funktion mit dem Makro __attribute__((constructor)) dekorieren.
  2. Fügen Sie die C-Funktion in Ihren Go-Code ein, indem Sie sie mit import „C“ importieren.

Arbeitsbeispiel

<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>
Nach dem Login kopieren

Denken Sie daran, den Platzhalter mit der tatsächlichen PID des Zielprozesses.

Einschränkungen

Dieser Ansatz weist einige Einschränkungen auf:

  • Die PID muss innerhalb der C-Funktion als Go fest codiert werden Der Code ist zum Zeitpunkt der Ausführung der C-Funktion möglicherweise nicht verfügbar.
  • Es ist nicht möglich, „setns“ mehrmals aus dem Go-Code heraus aufzurufen, da der C-Code vor der Go-Laufzeitinitialisierung ausgeführt wird.

Zusätzliche Hinweise

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!