Maison  >  Article  >  développement back-end  >  Pourquoi \'setns\' échoue-t-il avec EINVAL dans un environnement multithread Go ?

Pourquoi \'setns\' échoue-t-il avec EINVAL dans un environnement multithread Go ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-01 09:23:30646parcourir

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

L'appel de 'setns' depuis Go échoue avec EINVAL pour l'espace de noms MNT

Problème

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é.

Cause

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.

Solution - Astuce du constructeur CGO

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.

  1. Construisez une fonction C qui appelle « setns » ' avec les paramètres souhaités. Pour ce faire, décorez la fonction avec la macro __attribute__((constructor)).
  2. Incluez la fonction C dans votre code Go en l'important à l'aide de l'importation "C".

Exemple de travail

<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é avec le PID réel du processus cible.

Limitations

Cette approche présente certaines limites :

  • Le PID doit être codé en dur dans la fonction C, comme le Go Le code peut ne pas être disponible au moment de l'exécution de la fonction C.
  • Il n'est pas possible d'appeler 'setns' plusieurs fois à partir du code Go, car le code C s'exécute avant l'initialisation de l'exécution de Go.

Notes supplémentaires

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn