Provided by: manpages-fr-dev_4.21.0-2_all bug

NOM

       pivot_root - Modifier le montage racine

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <sys/syscall.h>      /* Définition des constantes SYS_* */
       #include <unistd.h>

       int syscall(SYS_pivot_root, const char *new_root, const char *put_old);

       Note: la glibc ne fournit pas d'enveloppe pour pivot_root(), nécessitant l'utilisation de syscall(2).

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
          suffixes « /.. » 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 est définie pour préciser
       l'erreur.

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.

STANDARDS

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

NOTES

       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 <err.h>
       #include <limits.h>
       #include <sched.h>
       #include <signal.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/mman.h>
       #include <sys/mount.h>
       #include <sys/stat.h>
       #include <sys/syscall.h>
       #include <sys/wait.h>
       #include <unistd.h>

       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        path[PATH_MAX];
           char        **args = arg;
           char        *new_root = args[0];
           const char  *put_old = "/oldrootfs";

           /* 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)
               err(EXIT_FAILURE, "mount-MS_PRIVATE");

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

           if (mount(new_root, new_root, NULL, MS_BIND, NULL) == -1)
               err(EXIT_FAILURE, "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)
               err(EXIT_FAILURE, "mkdir");

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

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

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

           if (chdir("/") == -1)
               err(EXIT_FAILURE, "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]);
           err(EXIT_FAILURE, "execv");
       }

       int
       main(int argc, char *argv[])
       {
           char *stack;

           /* Créer un processus enfant dans un nouvel espace de noms de montage. */

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

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

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

           if (wait(NULL) == -1)
               err(EXIT_FAILURE, "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)

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