setns(2) | System Calls Manual | setns(2) |
setns - Réassocier un thread avec un espace de noms
Bibliothèque C standard (libc, -lc)
#define _GNU_SOURCE /* Consultez feature_test_macros(7) */ #include <sched.h>
int setns(int fd, int nstype);
L'appel système setns() permet au thread appelant de se déplacer dans divers espaces de noms. Le paramètre fd est un des suivants :
La paramètre nstype est interprété différemment dans chaque cas.
Si fd renvoie à un /proc/pid/ns/, setns() ré-associe le thread appelant à l'espace de noms associé à ce lien, dans les contraintes posées par le paramètre nstype. Dans cet utilisation, l'appel setns() ne change qu'un des membres de l'espace de noms de l'appelant.
L'argument nstype indique les types d'espaces de noms auxquels le thread appelant peut être réassocié. Cet argument peut prendre une des valeurs suivantes :
Définir la valeur de nstype à zéro est suffisant si le thread appelant connaît (ou n'a pas besoin de connaître) le type d'espace de noms auquel fd fait référence. Définir nstype à une valeur non nulle est utile si l'appelant ne connaît pas le type de l'espace de noms référencé par fd et veut s'assurer que l'espace de noms est du type souhaité. L'appelant pourrait ne pas connaître le type de l'espace de noms auquel fd fait référence si le descripteur de fichiers a été ouvert par un autre processus et qu'il a, par exemple, été passé à l'appelant par un socket UNIX.
Depuis Linux 5.8, fd peut renvoyer à un descripteur de fichier de PID qu'on récupère avec pidfd_open(2) ou clone(2). Dans cette utilisation, setns() déplace de manière atomique le thread appelant dans un ou plusieurs espaces de noms en tant que thread auquel fd renvoie.
Le paramètre nstype est un masque de bits indiqué par une liaison et une ou plusieurs des constantes d'espace de noms CLONE_NEW* listées ci-dessus. L'appelant est déplacé dans chacun des espaces de nom du thread cible indiqué dans nstype ; l'appartenance de l'appelant aux autres espaces de noms demeure inchangée.
Par exemple, le code suivant déplace l'appelant dans les mêmes espace de noms utilisateur, réseau et UTS sous le PID 1234, mais les autres appartenances à l'espace de noms de l'appelant ne changent pas :
int fd = pidfd_open(1234, 0); setns(fd, CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWUTS);
Notez les détails et les restrictions suivantes lors de la ré-association à certains types d'espace de noms spécifiques :
S'il réussit, setns() renvoie 0, sinon il renvoie -1 et errno est positionné pour indiquer l'erreur.
L'appel système setns() est apparu dans Linux 3.0 ; sa prise en charge a été ajoutée dans la glibc 2.14.
L'appel système setns() est spécifique à Linux.
Pour obtenir plus d'informations sur les liens magiques /proc/pid/ns/, consultez namespaces(7).
Certains des attributs qui peuvent être partagés avec un nouveau thread créé avec clone(2) ne peuvent pas être modifiés en utilisant setns().
Le programme ci-dessous attend au moins deux arguments. Le premier précise le chemin d'un fichier d'espace de noms dans un répertoire /proc/pid/ns/ qui doit exister préalablement. Les arguments suivants précisent une commande et ses arguments. Le programme ouvre le fichier d'espace de noms, s'associe à l'espace de noms en utilisant setns(), et exécute la commande indiquée dans cet espace de noms.
La session d'invite de commandes suivante présente l'utilisation du programme (compilé en un binaire appelé ns_exec) en lien avec le programme CLONE_NEWUTS donné en exemple dans la page de manuel clone(2) (compilé en un binaire appelé newuts).
Nous commençons par exécuter le programme donné à titre d'exemple dans clone(2) en tâche de fond. Ce programme crée un processus enfant dans un espace de noms UTS distinct. Le processus enfant change le nom d'hôte dans son espace de noms, puis les deux processus affichent leur noms d'hôte dans leurs espaces de noms UTS respectifs, de façon à bien montrer leur différence.
$ su # Privilèges nécessaires aux opérations sur l'espace de noms Mot de passe : # ./newuts bizarro & [1] 3549 clone() a renvoyé 3550 uts.nodename dans l'enfant : bizarro uts.nodename dans le parent : antero # uname -n # Vérifier le nom d'hôte dans l'invite de commande antero
Nous appelons alors le programme présenté ci-dessous afin de lancer une invite de commande. Dans cette invite, on vérifie que le nom d'hôte est bien celui défini par le processus enfant créé dans le premier programme :
# ./ns_exec /proc/3550/ns/uts /bin/bash # uname -n # Exécuté dans l'invite lancée par ns_exec bizarro
#define _GNU_SOURCE #include <err.h> #include <fcntl.h> #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int fd; if (argc < 3) { fprintf(stderr, "%s /proc/PID/ns/FILE cmd args...\n", argv[0]); exit(EXIT_FAILURE); } /* Récupérer le descripteur de fichier de l'espace de noms ; le descripteur de fichier est ouvert avec O_CLOEXEC pour garantir qu'il n'est pas récupéré par le programme exécuté en dernier. */ fd = open(argv[1], O_RDONLY | O_CLOEXEC); if (fd == -1) err(EXIT_FAILURE, "open"); if (setns(fd, 0) == -1) /* Rejoindre cet espace de noms */ err(EXIT_FAILURE, "setns"); execvp(argv[2], &argv[2]); /* Exécuter une commande dans l'espace de noms */ err(EXIT_FAILURE, "execvp"); }
nsenter(1), clone(2), fork(2), unshare(2), vfork(2), namespaces(7), unix(7)
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Philippe MENGUAL <jpmengual@debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.
5 février 2023 | Pages du manuel de Linux 6.03 |