L'appel de setns depuis Go renvoie EINVAL pour l'espace de noms mnt
Description du problème
Dans le code Go , en essayant d'entrer dans l'espace de noms mnt à l'aide de la fonction syscall.RawSyscall pour appeler l'appel système setns, renvoie une erreur EINVAL. Ce problème persiste malgré une configuration correcte et une implémentation C fonctionnelle qui entre avec succès dans l'espace de noms.
Cause et solution
La cause première du problème réside dans les multiples nature filetée de Go. L'appel système setns doit être exécuté à partir d'un contexte monothread pour réussir. Étant donné que les applications Go sont multithread par défaut, l'appel setns doit être effectué avant le démarrage des threads d'exécution Go.
Pour résoudre ce problème, "l'astuce du constructeur cgo" peut être utilisée. Cette technique permet d'exécuter du code C avant le début du runtime Go. En utilisant la macro __attribute__((constructor)) dans le code C, une fonction peut être décorée pour s'exécuter dans un contexte C monothread avant l'initialisation de Go.
Code Go modifié
Le code Go modifié suivant utilise l'astuce du constructeur pour résoudre le problème :
<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>
En tirant parti de Astuce du constructeur cgo, l'application Go peut désormais entrer avec succès dans l'espace de noms mnt à l'aide de l'appel système setns.
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!