Man page - pivot_root(2)

Packages contains this manual

Available languages:

en fr ja de

Manual

pivot_root

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
ERREURS
STANDARDS
HISTORIQUE
NOTES
pivot_root(".", ".")
Remarques historiques
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION

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 .

STANDARDS

Linux.

HISTORIQUE

Linux 2.3.41.

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 I "." 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 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 .