dwww Home | Manual pages | Find package

pivot_root(2)                 System Calls Manual                pivot_root(2)

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écessi-
       tant 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éper-
       toire 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 : à sa-
          voir 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  garan-
          tissent  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  er-
              reur 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 fi-
       chiers  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 nou-
       velle 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 sys-
       tè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 fi-
       chiers 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écu-
       ter le nouvel init(1). Il existe des programmes d'aide pour ce  proces-
       sus ; 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 utili-
              saient 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'ap-
       pel système dans le noyau, visait sans doute à avertir les utilisateurs
       à ce moment là que l'implémentation pourrait changer avant la  publica-
       tion  définitive.  Toutefois,  le comportement indiqué dans DESCRIPTION
       est resté valable depuis la première implémentation de cet  appel  sys-
       tè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 com-
       mande.

       Nous montrons le programme en créant un répertoire qui servira de  nou-
       veau 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 Chris-
       tophe Blaess <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <ste-
       phan.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.cou-
       lon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>,  Thomas  Huriaux
       <thomas.huriaux@gmail.com>,  Nicolas François <nicolas.francois@centra-
       liens.net>, Florentin Duneau <fduneau@gmail.com>, Simon  Paillard  <si-
       mon.paillard@resel.enst-bretagne.fr>,    Denis   Barbier   <barbier@de-
       bian.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⟩.

Pages du manuel de Linux 6.03   5 février 2023                   pivot_root(2)

Generated by dwww version 1.15 on Sat Jun 29 01:44:04 CEST 2024.