setns(2) System Calls Manual setns(2) NOM setns - Reassocier un thread avec un espace de noms BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #define _GNU_SOURCE /* Consultez feature_test_macros(7) */ #include int setns(int fd, int nstype); DESCRIPTION L'appel systeme setns() permet au thread appelant de se deplacer dans divers espaces de noms. Le parametre fd est un des suivants : - un descripteur de fichier renvoyant a un des liens magiques du repertoire /proc/pid/ns/ (ou un montage en boucle vers un tel lien) ; - un descripteur de fichier de PID (pidfd_open(2)). La parametre nstype est interprete differemment dans chaque cas. fd renvoie a un lien /proc/pid/ns/ Si fd renvoie a un /proc/pid/ns/, setns() re-associe le thread appelant a l'espace de noms associe a ce lien, dans les contraintes posees par le parametre 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 etre reassocie. Cet argument peut prendre une des valeurs suivantes : 0 fd peut faire reference a n'importe quel type d'espace de noms. CLONE_NEWCGROUP (depuis Linux 4.6) fd doit faire reference a un espace de noms cgroup. CLONE_NEWIPC (a partir de Linux 3.0) fd doit faire reference a un espace de noms IPC. CLONE_NEWNET (a partir de Linux 3.0) fd doit faire reference a un espace de noms reseau. CLONE_NEWNS (a partir de Linux 3.8) fd doit faire reference a un espace de noms de montage. CLONE_NEWPID (depuis Linux 3.8) fd doit faire reference a un espace de noms de PID descendant. CLONE_NEWIPC (depuis Linux 5.8) fd doit faire reference a un espace de noms de temps. CLONE_NEWUSER (depuis Linux 3.8) fd doit faire reference a un espace de noms utilisateur. CLONE_NEWUTS (a partir de Linux 3.0) fd doit faire reference a un espace de noms UTS. Definir la valeur de nstype a zero est suffisant si le thread appelant connait (ou n'a pas besoin de connaitre) le type d'espace de noms auquel fd fait reference. Definir nstype a une valeur non nulle est utile si l'appelant ne connait pas le type de l'espace de noms reference par fd et veut s'assurer que l'espace de noms est du type souhaite. L'appelant pourrait ne pas connaitre le type de l'espace de noms auquel fd fait reference si le descripteur de fichiers a ete ouvert par un autre processus et qu'il a, par exemple, ete passe a l'appelant par un socket UNIX. fd est un descripteur de fichier de PID Depuis Linux 5.8, fd peut renvoyer a un descripteur de fichier de PID qu'on recupere avec pidfd_open(2) ou clone(2). Dans cette utilisation, setns() deplace de maniere atomique le thread appelant dans un ou plusieurs espaces de noms en tant que thread auquel fd renvoie. Le parametre nstype est un masque de bits indique par une liaison et une ou plusieurs des constantes d'espace de noms CLONE_NEW* listees ci-dessus. L'appelant est deplace dans chacun des espaces de nom du thread cible indique dans nstype ; l'appartenance de l'appelant aux autres espaces de noms demeure inchangee. Par exemple, le code suivant deplace l'appelant dans les memes espace de noms utilisateur, reseau et UTS sous le PID 1234, mais les autres appartenances a l'espace de noms de l'appelant ne changent pas : int fd = pidfd_open(1234, 0); setns(fd, CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWUTS); Details sur des types d'espace de noms specifiques Notez les details et les restrictions suivantes lors de la re-association a certains types d'espace de noms specifiques : Espaces de nom utilisateur Un processus qui se re-associe a un espace de noms utilisateur doit disposer de la capacite CAP_SYS_ADMIN dans l'espace de noms utilisateur cible (donc, necesairement, il n'est possible d'atteindre qu'un espace de noms descendant). Lorsque le deplacement reussit, un processus se voit accorder toutes les capacites de cet espace de noms, quels que soient ses IDentifiants d'utilisateur et de groupe. Un processus de plusieurs threads ne peut pas changer d'espace de noms utilisateur avec setns(). Il n'est pas permis d'utiliser setns() pour revenir dans l'espace de noms utilisateur de l'appelant. Cela empeche un appelant n'ayant plus ces capacites de les retrouver a l'aide d'un appel a setns(). Pour des raisons de securite, un processus ne peut pas atteindre un nouvel espace de noms utilisateur s'il partage des attributs lies a un systeme de fichiers (dont le partage est controle avec le drapeau CLONE_FS de clone(2)) avec un autre processus. Pour obtenir plus d'informations sur les espaces de noms utilisateur, consultez user_namespaces(7). Espaces de noms montage Pour pouvoir changer d'espace de noms de montage, l'appelant doit disposer des capacites CAP_SYS_CHROOT et CAP_SYS_ADMIN dans son propre espace de noms utilisateur, et de la capacite CAP_SYS_ADMIN dans l'espace de noms de montage cible. Un processus ne peut pas atteindre un nouvel espace de noms de montage s'il partage des attributs relatifs a un systeme de fichiers (dont le partage est controle par le drapeau CLONE_FS de clone(2)) avec un autre processus. Voir user_namespaces(7) pour des details sur l'interaction entre les espaces de noms utilisateur et de montage. Espaces de noms PID Pour se re-associer a un nouvel espace de noms PID, l'appelant doit avoir la capacite CAP_SYS_ADMIN dans son espace de noms utilisateur et dans celui auquel appartient l'espace de noms PID cible. Reassocier l'espace de noms d'un PID a un comportement different des autres types d'espace de noms. La re-association du thread appelant avec un espace de noms de PID change seulement l'espace de noms de PID dans lequel les processus enfants de l'appelant seront crees ; cela ne change pas l'espace de noms PID de l'appelant. La re-association a un espace de noms PID n'est autorisee que si l'espace de noms PID cible est un descendant (l'enfant, le petit-enfant, etc) ou est le meme que celui de l'appelant. Pour plus d'informations sur les espaces de noms des PIDs, reportez vous a namespaces(7). Espaces de noms cgroup Pour se re-associer a un nouvel espace de noms cgroup, l'appelant doit avoir la capacite CAP_SYS_ADMIN dans son propre espace de noms utilisateur et dans celui auquel appartient l'espace de noms cgroup cible. L'utilisation de setns() pour changer d'espace de noms cgroup ne change pas l'appartenance cgroup de l'appelant. Espaces de noms reseau, IPC, de temps et UTS Pour se re-associer a un nouvel espace de noms reseau, IPC, de temps ou UTS, l'appelant doit disposer des capacites CAP_SYS_ADMIN dans son propre espace de noms utilisateur et dans l'espace de noms utilisateur qui possede l'espace de noms cible. VALEUR RENVOYEE S'il reussit, setns() renvoie 0, sinon il renvoie -1 et errno est positionne pour indiquer l'erreur. ERREURS EBADF fd n'est pas un descripteur de fichier valable. EINVAL fd fait reference a un espace de noms dont le type ne correspond pas a celui indique dans nstype. EINVAL Il y a un probleme pour re-associer le thread avec l'espace de noms indique. EINVAL L'appelant a essaye d'atteindre un espace de noms PID ancetre (parent, grand-parent, etc). EINVAL L'appelant a tente d'integrer un espace de noms utilisateur dont il est deja membre. EINVAL L'appelant partage un etat de systeme de fichiers (CLONE_FS), notamment le repertoire racine, avec d'autres processus et a tente d'integrer un nouvel espace de noms. EINVAL L'appelant est multi-threade et a tente d'integrer un nouvel espace de noms utilisateur. EINVAL fd est un descripteur de fichier de PID et nstype n'est pas valable (il vaut par exemple 0). ENOMEM Impossible d'allouer suffisamment de memoire pour changer l'espace de noms indique. EPERM Le processus appelant n'avait pas la capacite appropriee pour effectuer cette operation. ESRCH fd est un descripteur de fichier PID mais le processus auquel il renvoie n'existe plus (c'est-a-dire qu'il s'est termine et attend). STANDARDS Linux. VERSIONS Linux 3.0, glibc 2.14. NOTES Pour obtenir plus d'informations sur les liens magiques /proc/pid/ns/, consultez namespaces(7). Certains des attributs qui peuvent etre partages avec un nouveau thread cree avec clone(2) ne peuvent pas etre modifies en utilisant setns(). EXEMPLES Le programme ci-dessous attend au moins deux arguments. Le premier precise le chemin d'un fichier d'espace de noms dans un repertoire /proc/pid/ns/ qui doit exister prealablement. Les arguments suivants precisent une commande et ses arguments. Le programme ouvre le fichier d'espace de noms, s'associe a l'espace de noms en utilisant setns(), et execute la commande indiquee dans cet espace de noms. La session d'invite de commandes suivante presente l'utilisation du programme (compile en un binaire appele ns_exec) en lien avec le programme CLONE_NEWUTS donne en exemple dans la page de manuel clone(2) (compile en un binaire appele newuts). Nous commencons par executer le programme donne a titre d'exemple dans clone(2) en tache de fond. Ce programme cree un processus enfant dans un espace de noms UTS distinct. Le processus enfant change le nom d'hote dans son espace de noms, puis les deux processus affichent leur noms d'hote dans leurs espaces de noms UTS respectifs, de facon a bien montrer leur difference. $ su # Privileges necessaires aux operations sur l'espace de noms Mot de passe : # ./newuts bizarro & [1] 3549 clone() a renvoye 3550 uts.nodename dans l'enfant : bizarro uts.nodename dans le parent : antero # uname -n # Verifier le nom d'hote dans l'invite de commande antero Nous appelons alors le programme presente ci-dessous afin de lancer une invite de commande. Dans cette invite, on verifie que le nom d'hote est bien celui defini par le processus enfant cree dans le premier programme : # ./ns_exec /proc/3550/ns/uts /bin/bash # uname -n # Execute dans l'invite lancee par ns_exec bizarro Source du programme #define _GNU_SOURCE #include #include #include #include #include #include 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); } /* Recuperer 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 recupere par le programme execute 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]); /* Executer une commande dans l'espace de noms */ err(EXIT_FAILURE, "execvp"); } VOIR AUSSI nsenter(1), clone(2), fork(2), unshare(2), vfork(2), namespaces(7), unix(7) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Cedric Boutillier , Frederic Hantrais et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 setns(2)