]> git.ipfire.org Git - thirdparty/man-pages.git/blobdiff - man2/pivot_root.2
des_crypt.3: Minor wording fix in VERSIONS
[thirdparty/man-pages.git] / man2 / pivot_root.2
index 7d3423c6690fb201430105ccf6a7eb00ba5f3b01..1995361616b0153117a7dc31c46f67a084caae09 100644 (file)
@@ -1,16 +1,32 @@
-.\" Copyright (C) 2000 by Werner Almesberger
-.\" and Copyright (C) 2019 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" Copyright (C) 2019 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" A very few fragments remain from an earlier page written by
+.\" Werner Almesberger in 2000
 .\"
 .\"
-.\" %%%LICENSE_START(GPL_NOVERSION_ONELINE)
-.\" May be distributed under GPL
-.\" %%%LICENSE_END
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
 .\"
 .\"
-.\" Written 2000-02-23 by Werner Almesberger
-.\" Modified 2004-06-17 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
 .\"
 .\"
-.TH PIVOT_ROOT 2 2019-08-02 "Linux" "Linux Programmer's Manual"
+.TH PIVOT_ROOT 2 2019-11-19 "Linux" "Linux Programmer's Manual"
 .SH NAME
 .SH NAME
-pivot_root \- change the root filesystem
+pivot_root \- change the root mount
 .SH SYNOPSIS
 .BI "int pivot_root(const char *" new_root ", const char *" put_old );
 .PP
 .SH SYNOPSIS
 .BI "int pivot_root(const char *" new_root ", const char *" put_old );
 .PP
@@ -18,41 +34,14 @@ pivot_root \- change the root filesystem
 There is no glibc wrapper for this system call; see NOTES.
 .SH DESCRIPTION
 .BR pivot_root ()
 There is no glibc wrapper for this system call; see NOTES.
 .SH DESCRIPTION
 .BR pivot_root ()
-changes the root filesystem in the mount namespace of the calling process.
-More precisely, it moves the root filesystem to the
-directory \fIput_old\fP and makes \fInew_root\fP the new root filesystem.
+changes the root mount in the mount namespace of the calling process.
+More precisely, it moves the root mount to the
+directory \fIput_old\fP and makes \fInew_root\fP the new root mount.
 The calling process must have the
 .B CAP_SYS_ADMIN
 capability in the user namespace that owns the caller's mount namespace.
 .PP
 .BR pivot_root ()
 The calling process must have the
 .B CAP_SYS_ADMIN
 capability in the user namespace that owns the caller's mount namespace.
 .PP
 .BR pivot_root ()
-may or may not change the current root and the current
-working directory of any processes or threads that
-use the old root directory and which are in
-the same mount namespace as the caller of
-.BR pivot_root ().
-The caller of
-.BR pivot_root ()
-should ensure that processes with root or current working directory
-at the old root operate correctly in either case.
-An easy way to ensure this is to change their
-root and current working directory to \fInew_root\fP before invoking
-.BR pivot_root ().
-Note also that
-.BR pivot_root ()
-may or may not affect the calling process's current working directory.
-It is therefore recommended to call
-\fBchdir("/")\fP immediately after
-.BR pivot_root ().
-.PP
-The paragraph above is intentionally vague because at the time when
-.BR pivot_root ()
-was first implemented, it was unclear whether its affect
-on other process's root and current working directories\(emand
-the caller's current working directory\(emmight change in the future.
-However, the behavior has remained consistent since this system call
-was first implemented:
-.BR pivot_root ()
 changes the root directory and the current working directory
 of each process or thread in the same mount namespace to
 .I new_root
 changes the root directory and the current working directory
 of each process or thread in the same mount namespace to
 .I new_root
@@ -72,24 +61,22 @@ and
 .IR put_old
 must be directories.
 .IP \-
 .IR put_old
 must be directories.
 .IP \-
-\fInew_root\fP and \fIput_old\fP must not be on the same filesystem as
-the current root.
-In particular,
-.IR new_root
-can't be
-.IR """/"""
-(but can be a bind mounted directory on the current root filesystem).
+.I new_root
+and
+.I put_old
+must not be on the same mount as the current root.
 .IP \-
 \fIput_old\fP must be at or underneath \fInew_root\fP;
 .IP \-
 \fIput_old\fP must be at or underneath \fInew_root\fP;
-that is, adding a nonnegative
-number of \fI/..\fP to the string pointed to by \fIput_old\fP must yield
-the same directory as \fInew_root\fP.
+that is, adding some nonnegative
+number of "\fI/..\fP" prefixes to the pathname pointed to by
+.I put_old
+must yield the same directory as \fInew_root\fP.
 .IP \-
 .I new_root
 .IP \-
 .I new_root
-must be a mount point.
-(If it is not otherwise a mount point, it suffices to bind mount
-.I new_root
-on top of itself.)
+must be a path to a mount point, but can't be
+.IR """/""" .
+A path that is not already a mount point can be converted into one by
+bind mounting the path onto itself.
 .IP \-
 The propagation type of the parent mount of
 .IR new_root
 .IP \-
 The propagation type of the parent mount of
 .IR new_root
@@ -99,6 +86,9 @@ similarly, if
 .I put_old
 is an existing mount point, its propagation type must not be
 .BR MS_SHARED .
 .I put_old
 is an existing mount point, its propagation type must not be
 .BR MS_SHARED .
+These restrictions ensure that
+.BR pivot_root ()
+never propagates any changes to another mount namespace.
 .IP \-
 The current root directory must be a mount point.
 .SH RETURN VALUE
 .IP \-
 The current root directory must be a mount point.
 .SH RETURN VALUE
@@ -118,7 +108,7 @@ Additionally, it may fail with the following errors:
 .\" itself. Of course, this is an odd situation, since a later check
 .\" in the kernel code will in any case yield EINVAL if 'new_root' is
 .\" not a mount point. However, when the system call was first added,
 .\" itself. Of course, this is an odd situation, since a later check
 .\" in the kernel code will in any case yield EINVAL if 'new_root' is
 .\" not a mount point. However, when the system call was first added,
-.\" 'new_root' was not required to be a mount point. So, this this
+.\" 'new_root' was not required to be a mount point. So, this
 .\" error is nowadays probably just the result of crufty accumulation.
 .\" This error can also occur if we bind mount "/" on top of itself
 .\" and try to specify "/" as the 'new' (again, an odd situation). So,
 .\" error is nowadays probably just the result of crufty accumulation.
 .\" This error can also occur if we bind mount "/" on top of itself
 .\" and try to specify "/" as the 'new' (again, an odd situation). So,
@@ -129,7 +119,7 @@ Additionally, it may fail with the following errors:
 .I new_root
 or
 .I put_old
 .I new_root
 or
 .I put_old
-is on the current root filesystem.
+is on the current root mount.
 (This error covers the pathological case where
 .I new_root
 is
 (This error covers the pathological case where
 .I new_root
 is
@@ -140,7 +130,7 @@ is
 is not a mount point.
 .TP
 .B EINVAL
 is not a mount point.
 .TP
 .B EINVAL
-\fIput_old\fP is not underneath \fInew_root\fP.
+\fIput_old\fP is not at or underneath \fInew_root\fP.
 .TP
 .B EINVAL
 The current root directory is not a mount point
 .TP
 .B EINVAL
 The current root directory is not a mount point
@@ -148,7 +138,7 @@ The current root directory is not a mount point
 .BR chroot (2)).
 .TP
 .B EINVAL
 .BR chroot (2)).
 .TP
 .B EINVAL
-The current root is on the rootfs (initial ramfs) filesystem; see NOTES.
+The current root is on the rootfs (initial ramfs) mount; see NOTES.
 .TP
 .B EINVAL
 Either the mount point at
 .TP
 .B EINVAL
 Either the mount point at
@@ -188,16 +178,17 @@ placing the old root mount at a location under
 .I new_root
 from where it can subsequently be unmounted.
 (The fact that it moves all processes that have a root directory
 .I new_root
 from where it can subsequently be unmounted.
 (The fact that it moves all processes that have a root directory
-or current working directory on the old root filesystem to the
-new root filesystem frees the old root filesystem of users,
-allowing it to be unmounted more easily.)
+or current working directory on the old root directory to the
+new root frees the old root directory of users,
+allowing the old root mount to be unmounted more easily.)
 .PP
 .PP
-A typical use of
+One use of
 .BR pivot_root ()
 is during system startup, when the
 .BR pivot_root ()
 is during system startup, when the
-system mounts a temporary root filesystem (e.g., an \fBinitrd\fP), then
-mounts the real root filesystem, and eventually turns the latter into
-the current root of all relevant processes or threads.
+system mounts a temporary root filesystem (e.g., an
+.BR initrd (4)),
+then mounts the real root filesystem, and eventually turns the latter into
+the root directory of all relevant processes and threads.
 A modern use is to set up a root filesystem during
 the creation of a container.
 .PP
 A modern use is to set up a root filesystem during
 the creation of a container.
 .PP
@@ -206,10 +197,24 @@ The fact that
 modifies process root and current working directories in the
 manner noted in DESCRIPTION
 is necessary in order to prevent kernel threads from keeping the old
 modifies process root and current working directories in the
 manner noted in DESCRIPTION
 is necessary in order to prevent kernel threads from keeping the old
-root directory busy with their root and current working directory,
+root mount busy with their root and current working directories,
 even if they never access
 the filesystem in any way.
 .PP
 even if they never access
 the filesystem in any way.
 .PP
+The rootfs (initial ramfs) cannot be
+.BR pivot_root ()ed.
+The recommended method of changing the root filesystem in this case is
+to delete everything in rootfs, overmount rootfs with the new root, attach
+.IR stdin / stdout / stderr
+to the new
+.IR /dev/console ,
+and exec the new
+.BR init (1).
+Helper programs for this process exist; see
+.BR switch_root (8).
+.\"
+.SS pivot_root(\(dq.\(dq, \(dq.\(dq)
+.PP
 .I new_root
 and
 .I put_old
 .I new_root
 and
 .I put_old
@@ -220,8 +225,6 @@ without needing to create and remove a temporary directory:
 .in +4n
 .EX
 chdir(new_root);
 .in +4n
 .EX
 chdir(new_root);
-mount("", ".", MS_SLAVE | MS_REC, NULL);
-        /* Or: MS_PRIVATE | MS_REC */
 pivot_root(".", ".");
 umount2(".", MNT_DETACH);
 .EE
 pivot_root(".", ".");
 umount2(".", MNT_DETACH);
 .EE
@@ -230,7 +233,6 @@ umount2(".", MNT_DETACH);
 This sequence succeeds because the
 .BR pivot_root ()
 call stacks the old root mount point
 This sequence succeeds because the
 .BR pivot_root ()
 call stacks the old root mount point
-.RI ( old_root )
 on top of the new root mount point at
 .IR / .
 At that point, the calling process's root directory and current
 on top of the new root mount point at
 .IR / .
 At that point, the calling process's root directory and current
@@ -244,22 +246,35 @@ starts with
 .I new_root
 and then moves up the list of mounts stacked at
 .IR / ,
 .I new_root
 and then moves up the list of mounts stacked at
 .IR / ,
-with the result that
-.IR old_root
-is unmounted.
+with the result that old root mount point is unmounted.
+.\"
+.SS Historical notes
+For many years, this manual page carried the following text:
+.RS
 .PP
 .PP
-The rootfs (initial ramfs) cannot be
-.BR pivot_root ()ed.
-The recommended method of changing the root filesystem in this case is
-to delete everything in rootfs, overmount rootfs with the new root, attach
-.IR stdin / stdout / stderr
-to the new
-.IR /dev/console ,
-and exec the new
-.BR init (1).
-Helper programs for this process exist; see
-.BR switch_root (8).
+.BR pivot_root ()
+may or may not change the current root and the current
+working directory of any processes or threads which use the old
+root directory.
+The caller of
+.BR pivot_root ()
+must ensure that processes with root or current working directory
+at the old root operate correctly in either case.
+An easy way to ensure this is to change their
+root and current working directory to \fInew_root\fP before invoking
+.BR pivot_root ().
+.RE
+.PP
+This text, written before the system call implementation was
+even finalized in the kernel, was probably intended to warn users
+at that time that the implementation might change before final release.
+However, the behavior stated in DESCRIPTION
+has remained consistent since this system call
+was first implemented and will not change now.
 .SH EXAMPLE
 .SH EXAMPLE
+.\" FIXME
+.\" Would it be better, because simpler, to use unshare(2)
+.\" rather than clone(2) in the example below?
 .PP
 The program below demonstrates the use of
 .BR pivot_root ()
 .PP
 The program below demonstrates the use of
 .BR pivot_root ()
@@ -310,6 +325,7 @@ hello world
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <limits.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); \e
                         } while (0)
 
 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \e
                         } while (0)
@@ -354,7 +370,7 @@ child(void *arg)
     if (pivot_root(new_root, path) == \-1)
         errExit("pivot_root");
 
     if (pivot_root(new_root, path) == \-1)
         errExit("pivot_root");
 
-    /* Switch the current working working directory to "/" */
+    /* Switch the current working directory to "/" */
 
     if (chdir("/") == \-1)
         errExit("chdir");
 
     if (chdir("/") == \-1)
         errExit("chdir");
@@ -377,9 +393,10 @@ main(int argc, char *argv[])
 {
     /* Create a child process in a new mount namespace */
 
 {
     /* Create a child process in a new mount namespace */
 
-    char *stack = malloc(STACK_SIZE);
-    if (stack == NULL)
-        errExit("malloc");
+    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)
 
     if (clone(child, stack + STACK_SIZE,
                 CLONE_NEWNS | SIGCHLD, &argv[1]) == \-1)