table of contents
SETNS(2) | Manuel du programmeur Linux | SETNS(2) |
NOM¶
setns - Réassocier un thread avec un espace de noms
SYNOPSIS¶
#define _GNU_SOURCE /* Consultez feature_test_macros(7) */ #include <sched.h>
int setns(int fd, int nstype);
DESCRIPTION¶
Étant donné un descripteur de fichiers faisant référence à un espace de noms, réassocier le thread appelant à cet espace de noms.
L'argument fd est un descripteur de fichier faisant référence à un des espaces de noms présents sous la forme d'entrées dans un répertoire /proc/[pid]/ns/. Consultez namespaces(5) pour plus d'informations sur /proc/[pid]/ns. Le thread appelant sera réassocié avec l'espace de noms correspondant, si les contraintes imposées par l'argument nstype sont satisfaites.
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 :
- 0
- fd peut faire référence à n'importe quel type d'espace de noms.
- CLONE_NEWCGROUP (depuis Linux 4.6)
- fd doit faire référence à un espace de noms cgroup.
- CLONE_NEWIPC (à partir de Linux 3.0)
- fd doit faire référence à un espace de noms IPC.
- CLONE_NEWNET (à partir de Linux 3.0)
- fd doit faire référence à un espace de noms réseau.
- CLONE_NEWNS (à partir de Linux 3.8)
- fd doit faire référence à un espace de noms de montage.
- CLONE_NEWPID (depuis Linux 3.8)
- fd doit faire référence à un espace de noms de PID descendant.
- CLONE_NEWUSER (depuis Linux 3.8)
- fd doit faire référence à un espace de noms utilisateur.
- CLONE_NEWUTS (à partir de Linux 3.0)
- fd doit faire référence à un espace de noms UTS.
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.
Si fd se réfère à un espace de noms PID, la sémantique est un peu différente des autres types d'espaces de noms : la ré-association du thread appelant avec un espace de noms de PID change seulement l'espace de noms de PID dans lequel les processus enfant de l'appelant seront créés ; cela ne change pas l'espace de noms PID de l'appelant. Cette ré-association est seulement autorisée si l'espace de noms PID indiqué dans fd est un descendant (enfant, petit-enfant, etc.) de l'espace de noms PID de l'appelant. Pour plus d'informations sur les espaces de noms PID, consultez pid_namespaces(7).
Pour qu'un processus se ré-associe lui-même à un espace de noms utilisateur, il doit avoir la capacité CAP_SYS_ADMIN dans l'espace de noms cible. Si l'arrivée dans un espace de noms utilisateur réussit, toutes les capacités de cet espace de noms sont accordées au processus indpéendamment de ses identifiants de groupe et d'utilisateur. Un processus multi-threadé ne peut pas changer d'espace de noms utilisateur avec setns(). Il n'est pas autorisé d'utiliser setns() pour revenir dans l'espace de noms utilisateur actuel de l'appelant. Cela empêche un appelant ayant perdu ses capacités de les retrouver à l'aide d'un appel à setns(). Pour des raisons de sécurité, un processus ne peut pas rejoindre un nouvel espace de noms utilisateur s'il partage des attributs relatifs au système de fichiers (ceux dont le partage est géré par l'attribut CLONE_FS de clone(2)) avec un autre processus. Pour plus de détails sur les espaces de noms utilisateur, voir user_namespaces(7).
Un processus ne doit pas être ré-associé avec un nouvel espace de noms de montage s'il est multi-threadé. Pour pouvoir changer d'espace de noms de montage, l'appelant doit disposer des capacités CAP_SYS_CHROOT et CAP_SYS_ADMIN dans son propre espace de noms utilisateur, et de la capacité CAP_SYS_ADMIN dans l'espace de noms de montage cible. Consultez user_namespaces(7) pour obtenir plus d'informations sur les liens entre les espaces de noms de montage et utilisateur.
L'utilisation de setns() pour changer d'espace de noms cgroup ne change pas l'appartenance cgroup de l'appelant.
VALEUR RENVOYÉE¶
S'il réussit, setns() renvoie 0, sinon il renvoie -1 et errno est positionné pour indiquer l'erreur.
ERREURS¶
- EBADF
- fd n'est pas un descripteur de fichier valable.
- EINVAL
- fd fait référence à un espace de noms dont le type ne correspond pas à celui indiqué dans nstype.
- EINVAL
- Il y a un problème pour ré-associer le thread avec l'espace de noms indiqué.
- EINVAL
- L'appelant a essayé d'atteindre un espace de noms PID ancêtre (parent, grand-parent, etc).
- EINVAL
- L'appelant a tenté d'intégrer un espace de noms utilisateur dont il est déjà membre.
- EINVAL
- L'appelant partage un état de système de fichiers (CLONE_FS), notamment le répertoire racine, avec d'autres processus et a tenté d'intégrer un nouvel espace de noms.
- EINVAL
- L'appelant est multi-threadé et a tenté d'intégrer un nouvel espace de noms utilisateur.
- ENOMEM
- Impossible d'allouer suffisamment de mémoire pour changer l'espace de noms indiqué.
- EPERM
- Le processus appelant n'avait pas la capacité appropriée pour effectuer cette opération.
VERSIONS¶
L'appel système setns() est apparu dans Linux 3.0 ; sa prise en charge a été ajoutée dans la version 2.14 de la glibc.
CONFORMITɶ
L'appel système setns() est spécifique à Linux.
NOTES¶
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().
EXEMPLE¶
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
Source du programme¶
#define _GNU_SOURCE #include <fcntl.h> #include <sched.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0) 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);
}
fd = open(argv[1], O_RDONLY); /* Récupérer le descripteur de fichier pour l'espace de noms */
if (fd == -1)
errExit("open");
if (setns(fd, 0) == -1) /* Rejoindre cet espace de noms */
errExit("setns");
execvp(argv[2], &argv[2]); /* Exécuter une commande dans l'espace de noms */
errExit("execvp"); }
VOIR AUSSI¶
nsenter(1), clone(2), fork(2), unshare(2), vfork(2), namespaces(7), unix(7)
COLOPHON¶
Cette page fait partie de la publication 4.16 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.
TRADUCTION¶
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.
15 septembre 2017 | Linux |