Maison > Article > développement back-end > Pourquoi \'setns\' échoue-t-il avec EINVAL dans un environnement multithread Go ?
Lors de la tentative d'appel de 'setns' depuis Go pour entrer dans le MNT espace de noms, l'appel renvoie systématiquement EINVAL. Ce problème est observé malgré le bon fonctionnement d'une implémentation C de la même fonctionnalité.
Le problème vient du fait que Go est un langage multithread, alors que 'setns' s'attend à être appelé à partir d’un contexte à thread unique. Lorsqu'il est appelé depuis un environnement multithread, 'setns' ne parvient pas à associer correctement le thread actuel à l'espace de noms cible.
Une solution à ce problème consiste à utiliser le "Astuce du constructeur CGO." Cette technique vous permet de spécifier une fonction C à exécuter avant l'initialisation du runtime Go. En utilisant cette approche, votre fonction C peut appeler « setns » avant la création des threads Go, garantissant ainsi que l'appel est effectué dans un contexte à thread unique.
<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>
N'oubliez pas de remplacer l'espace réservé
Cette approche présente certaines limites :
Un correctif pour 'setns(2)' confirme la nécessité d'une exécution monothread dans les environnements multithread. Les processus dotés de fonctionnalités doivent également posséder CAP_SYS_CHROOT et CAP_SYS_ADMIN dans leur propre espace de noms utilisateur et CAP_SYS_ADMIN dans l'espace de noms de montage cible.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!