Provided by: manpages-fr-dev_4.13-4_all bug

NOM

       pivot_root - Modifier le montage racine

SYNOPSIS

       int pivot_root(const char *new_root, const char *put_old);

       Note : il n'existe pas d'enveloppe pour cet appel système dans la glibc ; voir NOTES.

DESCRIPTION

       pivot_root()  modifie  le  montage  racine  dans  l'espace de noms de montage du processus
       appelant. Plus précisément, il déplace le montage racine dans le répertoire put_old et  il
       fait  de  new_root le nouveau montage racine. Le processus appelant doit avoir la capacité
       CAP_SYS_ADMIN dans l'espace de noms de l'utilisateur à qui appartient l'espace de noms  de
       montage de l'appelant.

       pivot_root()  change  le répertoire racine et le répertoire de travail de chaque processus
       ou de chaque thread du même espace de noms de montage  en  new_root  s'ils  pointent  vers
       l'ancien  répertoire  de  montage (voir aussi les NOTES). D'un autre côté, pivot_root() ne
       modifie pas le répertoire de travail de l'appelant (sauf s'il est sur l'ancien  répertoire
       racine), ainsi, il doit être suivi d'un appel chdir("/").

       Les restrictions suivantes s'appliquent :

       -  new_root et put_old doivent être des répertoires.

       -  new_root et put_old ne doivent pas être sur le même montage que la racine actuelle.

       -  put_old  doit  être  sur new_root ou un descendant de new_root : à savoir qu'ajouter un
          nombre positif de préfixes « /.. » au chemin vers lequel pointe put_old doit ramener au
          même répertoire que new_root.

       -  new_root doit être un chemin vers un point de montage ; mais il ne peut pas être « / ».
          Un chemin qui n'est pas un point de montage peut le devenir en  montant  en  miroir  le
          point sur lui-même.

       -  Le type de propagation du montage parent de new_root et le montage parent du répertoire
          racine actuel ne doivent pas être MS_SHARED ; de même,  si  put_old  est  un  point  de
          montage  existant, son type de propagation ne doit pas être MS_SHARED. Ces restrictions
          garantissent que pivot_root() ne propage jamais de changement sur un  autre  espace  de
          noms de montage.

       -  Le répertoire racine actuel doit être un point de montage.

VALEUR RENVOYÉE

       En  cas  de  succès, zéro est renvoyé. En cas d'erreur, -1 est renvoyé et errno reçoit une
       valeur adéquate.

ERREURS

       pivot_root() peut échouer avec une des erreurs de stat(2). Il peut aussi échouer avec  les
       erreurs suivantes :

       EBUSY  new_root ou put_old est sur le montage racine actuel (cette erreur vaut pour le cas
              pathologique où new_root est « / ».

       EINVAL new_root n'est pas un point de montage.

       EINVAL put_old n'est pas sur new_root ou un descendant.

       EINVAL Le répertoire racine actuel n'est pas un point de montage (du fait  d'un  précédent
              chroot(2)).

       EINVAL La racine actuelle est sur le montage rootfs (ramfs initial) ; voir les NOTES.

       EINVAL Soit  le  point  de  montage  sur  new_root,  soit le montage parent de ce point de
              montage, a un type de propagation MS_SHARED.

       EINVAL put_old est un point de montage et il a le type de propagation MS_SHARED.

       ENOTDIR
              new_root ou put_old n'est pas un répertoire.

       EPERM  Le processus appelant n'a pas la capacité CAP_SYS_ADMIN.

VERSIONS

       pivot_root() a été introduit dans Linux 2.3.41.

CONFORMITÉ

       pivot_root() est spécifique à Linux et donc non portable.

NOTES

       La glibc ne fournit pas  de  fonction  autour  de  cet  appel  système ;  appelez-le  avec
       syscall(2).

       Une interface en ligne de commande pour cet appel système est fournie par pivot_root(8).

       pivot_root()  permet  à un appelant de passer à un nouveau système de fichiers racine tout
       en mettant l'ancien montage racine dans new_root, d'où il peut être démonté  (le  fait  de
       déplacer tous les processus ayant un répertoire racine ou actuel dans le répertoire racine
       vers une nouvelle racine libère l'ancienne racine des utilisateurs, permettant de démonter
       plus facilement l'ancien montage racine).

       L'utilisation  typique  de  pivot_root()  est  durant  le démarrage du système, lorsque le
       système monte un système de fichiers temporaire (par exemple un initrd(4)) puis  monte  le
       véritable  système  de  fichiers  et  le transforme éventuellement en racine pour tous les
       processus et threads concernés. Une utilisation moderne consiste à définir un  système  de
       fichiers racine pendant la création d'un conteneur.

       Le  fait  que pivot_root() modifie les répertoires racine et de travail du processus comme
       indiqué dans la DESCRIPTION est nécessaire afin d'empêcher les threads du noyau  d'occuper
       l'ancien montage racine avec leurs répertoires racine et de travail, même s'ils n'accèdent
       jamais au système de fichiers en aucune manière.

       Le rootfs (initial ramfs) ne peut pas être  pivot_root()é.  La  méthode  recommandée  pour
       modifier  le système de fichiers racine dans ce cas consiste à tout effacer sur le rootfs,
       monter  par-dessus  la  nouvelle  racine,   rattacher   stdin/stdout/stderr   au   nouveau
       /dev/console  et  exécuter  le  nouvel  init(1).  Il  existe des programmes d'aide pour ce
       processus ; voir switch_root(8).

   pivot_root(".", ".")
       new_root et put_old peuvent être le même répertoire. En particulier, la séquence  suivante
       permet une opération pivot-root sans devoir créer et supprimer un répertoire temporaire :

           chdir(new_root);
           pivot_root(".", ".");
           umount2(".", MNT_DETACH);

       Cette  séquence réussit parce que l'appel pivot_root() place le point de montage racine au
       sommet du nouveau point de montage racine sur /. Alors, le répertoire racine et  celui  de
       travail du processus appelant se rapportent au nouveau point de montage racine (new_root).
       Lors de l'appel umount() suivant, la résolution de "." commence par new_root puis monte la
       liste  des points de montage empilés dans /, d'où il résulte que l'ancien point de montage
       est démonté.

   Remarques historiques
       Pendant de nombreuses années, cette page de manuel comportait le texte suivant :

              pivot_root() peut changer ou non les répertoires racine et de travail en  cours  de
              tous   les  processus  et  threads  qui  utilisaient  l'ancien  répertoire  racine.
              L'appelant de pivot_root() doit s'assurer que les processus ayant  pour  racine  ou
              répertoire  de  travail l'ancien répertoire se comportent correctement. Le meilleur
              moyen est de modifier leur répertoire de travail et répertoire racine pour new_root
              avant d'invoquer pivot_root().

       Ce  texte, écrit avant même la finalisation de l'implémentation de l'appel système dans le
       noyau, visait sans doute à avertir les utilisateurs à ce moment  là  que  l'implémentation
       pourrait  changer avant la publication définitive. Toutefois, le comportement indiqué dans
       DESCRIPTION est resté valable depuis la première implémentation de cet appel système et il
       ne changera pas maintenant.

EXEMPLES

       Le  programme  ci-dessous  montre  l'utilisation de pivot_root() dans un espace de noms de
       montage créé en utilisant clone(2). Après avoir changé le répertoire racine appelé dans le
       premier paramètre de la ligne de commande du programme, l'enfant créé par clone(2) exécute
       alors le programme nommé dans les autres paramètres de la ligne de commande.

       Nous montrons le programme en créant un répertoire  qui  servira  de  nouveau  système  de
       fichiers  racine  et  en  mettant une copie de l'exécutable busybox(1) (liée statiquement)
       dans ce répertoire.

           $ mkdir /tmp/rootfs
           $ ls -id /tmp/rootfs    # Numéro d’inœud dans le nouveau répertoire racine
           319459 /tmp/rootfs
           $ cp $(which busybox) /tmp/rootfs
           $ PS1='bbsh$ ' sudo ./pivot_root_demo /tmp/rootfs /busybox sh
           bbsh$ PATH=/
           bbsh$ busybox ln busybox ln
           bbsh$ ln busybox echo
           bbsh$ ln busybox ls
           bbsh$ ls
           busybox  echo     ln       ls
           bbsh$ ls -id /          # Comparaison avec le numéro d’inœud au-dessus
           319459 /
           bbsh$ echo 'hello world'
           hello world

   Source du programme

       /* pivot_root_demo.c */

       #define _GNU_SOURCE
       #include <sched.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <sys/wait.h>
       #include <sys/syscall.h>
       #include <sys/mount.h>
       #include <sys/stat.h>
       #include <limits.h>
       #include <sys/mman.h>

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       static int
       pivot_root(const char *new_root, const char *put_old)
       {
           return syscall(SYS_pivot_root, new_root, put_old);
       }

       #define STACK_SIZE (1024 * 1024)

       static int              /* Fonction de démarrage pour l’enfant cloné */
       child(void *arg)
       {
           char **args = arg;
           char *new_root = args[0];
           const char *put_old = "/oldrootfs";
           char path[PATH_MAX];

           /* S'assurer que 'new_root' et son point de montage parent
              n’aient pas une propagation partagée (ce qui ferait renvoyer une
              erreur à pivot_root()) et empêcher la propagation des événements
              de montage dans l'espace de noms de montage initial */

           if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) == -1)
               errExit("mount-MS_PRIVATE");

           /* S'assurer que 'new_root' soit un point de montage */

           if (mount(new_root, new_root, NULL, MS_BIND, NULL) == -1)
               errExit("mount-MS_BIND");

           /* Créer le répertoire où l'ancienne racine sera envoyée */

           snprintf(path, sizeof(path), "%s/%s", new_root, put_old);
           if (mkdir(path, 0777) == -1)
               errExit("mkdir");

           /* Et changer de système de fichiers racine */

           if (pivot_root(new_root, path) == -1)
               errExit("pivot_root");

           /* Déplacer le répertoire de travail dans "/" */

           if (chdir("/") == -1)
               errExit("chdir");

           /* Démonter l'ancienne racine et supprimer le point de montage */

           if (umount2(put_old, MNT_DETACH) == -1)
               perror("umount2");
           if (rmdir(put_old) == -1)
               perror("rmdir");

           /* Exécuter la commande indiquée dans argv[1]... */

           execv(args[1], &args[1]);
           errExit("execv");
       }

       int
       main(int argc, char *argv[])
       {
           /* Créer un processus enfant dans un nouvel espace de noms de montage */

           char *stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
                              MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
           if (stack == MAP_FAILED)
               errExit("mmap");

           if (clone(child, stack + STACK_SIZE,
                       CLONE_NEWNS | SIGCHLD, &argv[1]) == -1)
               errExit("clone");

           /* Le parent arrive ici ; attendre l'enfant */

           if (wait(NULL) == -1)
               errExit("wait");

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       chdir(2), chroot(2), mount(2),  stat(2),  initrd(4),  mount_namespaces(7),  pivot_root(8),
       switch_root(8)

COLOPHON

       Cette  page  fait partie de la publication 5.10 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>  et  Jean-Philippe  MENGUAL
       <jpmengual@debian.org>

       Cette  traduction  est  une  documentation libre ; veuillez vous reporter à la GNU General
       Public  License  version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   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 ⟨⟩.