-.\" 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
pivot_root \- change the root mount
.SH SYNOPSIS
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
must not be on the same mount as the current root.
.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
must be a path to a mount point, but can't be
.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
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
.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
new root frees the old root directory of users,
allowing the old root mount to be unmounted more easily.)
.PP
-A typical use of
+One use of
.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
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
+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
and then moves up the list of mounts stacked at
.IR / ,
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
-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
.\" FIXME
.\" Would it be better, because simpler, to use unshare(2)
#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)
{
/* 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)