summaryrefslogtreecommitdiffstats
path: root/man2/pivot_root.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/pivot_root.2')
-rw-r--r--man2/pivot_root.2409
1 files changed, 0 insertions, 409 deletions
diff --git a/man2/pivot_root.2 b/man2/pivot_root.2
deleted file mode 100644
index 3e0e55e..0000000
--- a/man2/pivot_root.2
+++ /dev/null
@@ -1,409 +0,0 @@
-.\" Copyright (C) 2019 Michael Kerrisk <mtk.manpages@gmail.com>
-.\" A very few fragments remain from an earlier page written by
-.\" Werner Almesberger in 2000
-.\"
-.\" SPDX-License-Identifier: Linux-man-pages-copyleft
-.\"
-.TH pivot_root 2 2024-02-25 "Linux man-pages 6.7"
-.SH NAME
-pivot_root \- change the root mount
-.SH LIBRARY
-Standard C library
-.RI ( libc ", " \-lc )
-.SH SYNOPSIS
-.nf
-.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
-.B #include <unistd.h>
-.P
-.BI "int syscall(SYS_pivot_root, const char *" new_root \
-", const char *" put_old );
-.fi
-.P
-.IR Note :
-glibc provides no wrapper for
-.BR pivot_root (),
-necessitating the use of
-.BR syscall (2).
-.SH DESCRIPTION
-.BR pivot_root ()
-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.
-.P
-.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
-if they point to the old root directory.
-(See also NOTES.)
-On the other hand,
-.BR pivot_root ()
-does not change the caller's current working directory
-(unless it is on the old root directory),
-and thus it should be followed by a
-\fBchdir("/")\fP call.
-.P
-The following restrictions apply:
-.IP \[bu] 3
-.I new_root
-and
-.I put_old
-must be directories.
-.IP \[bu]
-.I new_root
-and
-.I put_old
-must not be on the same mount as the current root.
-.IP \[bu]
-\fIput_old\fP must be at or underneath \fInew_root\fP;
-that is, adding some nonnegative
-number of "\fI/..\fP" suffixes to the pathname pointed to by
-.I put_old
-must yield the same directory as \fInew_root\fP.
-.IP \[bu]
-.I new_root
-must be a path to a mount point, but can't be
-.IR \[dq]/\[dq] .
-A path that is not already a mount point can be converted into one by
-bind mounting the path onto itself.
-.IP \[bu]
-The propagation type of the parent mount of
-.I new_root
-and the parent mount of the current root directory must not be
-.BR MS_SHARED ;
-similarly, if
-.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 \[bu]
-The current root directory must be a mount point.
-.SH RETURN VALUE
-On success, zero is returned.
-On error, \-1 is returned, and
-\fIerrno\fP is set to indicate the error.
-.SH ERRORS
-.BR pivot_root ()
-may fail with any of the same errors as
-.BR stat (2).
-Additionally, it may fail with the following errors:
-.TP
-.B EBUSY
-.\" Reconfirmed that the following error occurs on Linux 5.0 by
-.\" specifying 'new_root' as "/rootfs" and 'put_old' as
-.\" "/rootfs/oldrootfs", and *not* bind mounting "/rootfs" on top of
-.\" 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
-.\" 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,
-.\" the EBUSY check in the kernel does still seem necessary to prevent
-.\" that case. Furthermore, the "or put_old" piece is probably
-.\" redundant text (although the check is in the kernel), since,
-.\" in another check, 'put_old' is required to be under 'new_root'.
-.I new_root
-or
-.I put_old
-is on the current root mount.
-(This error covers the pathological case where
-.I new_root
-is
-.IR \[dq]/\[dq] .)
-.TP
-.B EINVAL
-.I new_root
-is not a mount point.
-.TP
-.B EINVAL
-\fIput_old\fP is not at or underneath \fInew_root\fP.
-.TP
-.B EINVAL
-The current root directory is not a mount point
-(because of an earlier
-.BR chroot (2)).
-.TP
-.B EINVAL
-The current root is on the rootfs (initial ramfs) mount; see NOTES.
-.TP
-.B EINVAL
-Either the mount point at
-.IR new_root ,
-or the parent mount of that mount point,
-has propagation type
-.BR MS_SHARED .
-.TP
-.B EINVAL
-.I put_old
-is a mount point and has the propagation type
-.BR MS_SHARED .
-.TP
-.B ENOTDIR
-\fInew_root\fP or \fIput_old\fP is not a directory.
-.TP
-.B EPERM
-The calling process does not have the
-.B CAP_SYS_ADMIN
-capability.
-.SH STANDARDS
-Linux.
-.SH HISTORY
-Linux 2.3.41.
-.SH NOTES
-A command-line interface for this system call is provided by
-.BR pivot_root (8).
-.P
-.BR pivot_root ()
-allows the caller to switch to a new root filesystem while at the same time
-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
-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.)
-.P
-One use of
-.BR pivot_root ()
-is during system startup, when the
-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.
-.P
-The fact that
-.BR pivot_root ()
-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 mount busy with their root and current working directories,
-even if they never access
-the filesystem in any way.
-.P
-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])
-.I new_root
-and
-.I put_old
-may be the same directory.
-In particular, the following sequence allows a pivot-root operation
-without needing to create and remove a temporary directory:
-.P
-.in +4n
-.EX
-chdir(new_root);
-pivot_root(".", ".");
-umount2(".", MNT_DETACH);
-.EE
-.in
-.P
-This sequence succeeds because the
-.BR pivot_root ()
-call stacks the old root mount point
-on top of the new root mount point at
-.IR / .
-At that point, the calling process's root directory and current
-working directory refer to the new root mount point
-.RI ( new_root ).
-During the subsequent
-.BR umount ()
-call, resolution of
-.I \[dq].\[dq]
-starts with
-.I new_root
-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
-.P
-.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
-.P
-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 EXAMPLES
-.\" FIXME
-.\" Would it be better, because simpler, to use unshare(2)
-.\" rather than clone(2) in the example below?
-The program below demonstrates the use of
-.BR pivot_root ()
-inside a mount namespace that is created using
-.BR clone (2).
-After pivoting to the root directory named in the program's
-first command-line argument, the child created by
-.BR clone (2)
-then executes the program named in the remaining command-line arguments.
-.P
-We demonstrate the program by creating a directory that will serve as
-the new root filesystem and placing a copy of the (statically linked)
-.BR busybox (1)
-executable in that directory.
-.P
-.in +4n
-.EX
-$ \fBmkdir /tmp/rootfs\fP
-$ \fBls \-id /tmp/rootfs\fP # Show inode number of new root directory
-319459 /tmp/rootfs
-$ \fBcp $(which busybox) /tmp/rootfs\fP
-$ \fBPS1=\[aq]bbsh$ \[aq] sudo ./pivot_root_demo /tmp/rootfs /busybox sh\fP
-bbsh$ \fBPATH=/\fP
-bbsh$ \fBbusybox ln busybox ln\fP
-bbsh$ \fBln busybox echo\fP
-bbsh$ \fBln busybox ls\fP
-bbsh$ \fBls\fP
-busybox echo ln ls
-bbsh$ \fBls \-id /\fP # Compare with inode number above
-319459 /
-bbsh$ \fBecho \[aq]hello world\[aq]\fP
-hello world
-.EE
-.in
-.SS Program source
-\&
-.P
-.\" SRC BEGIN (pivot_root.c)
-.EX
-/* 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 /* Startup function for cloned child */
-child(void *arg)
-{
- char path[PATH_MAX];
- char **args = arg;
- char *new_root = args[0];
- const char *put_old = "/oldrootfs";
-\&
- /* Ensure that \[aq]new_root\[aq] and its parent mount don\[aq]t have
- shared propagation (which would cause pivot_root() to
- return an error), and prevent propagation of mount
- events to the initial mount namespace. */
-\&
- if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) == \-1)
- err(EXIT_FAILURE, "mount\-MS_PRIVATE");
-\&
- /* Ensure that \[aq]new_root\[aq] is a mount point. */
-\&
- if (mount(new_root, new_root, NULL, MS_BIND, NULL) == \-1)
- err(EXIT_FAILURE, "mount\-MS_BIND");
-\&
- /* Create directory to which old root will be pivoted. */
-\&
- snprintf(path, sizeof(path), "%s/%s", new_root, put_old);
- if (mkdir(path, 0777) == \-1)
- err(EXIT_FAILURE, "mkdir");
-\&
- /* And pivot the root filesystem. */
-\&
- if (pivot_root(new_root, path) == \-1)
- err(EXIT_FAILURE, "pivot_root");
-\&
- /* Switch the current working directory to "/". */
-\&
- if (chdir("/") == \-1)
- err(EXIT_FAILURE, "chdir");
-\&
- /* Unmount old root and remove mount point. */
-\&
- if (umount2(put_old, MNT_DETACH) == \-1)
- perror("umount2");
- if (rmdir(put_old) == \-1)
- perror("rmdir");
-\&
- /* Execute the command specified in argv[1]... */
-\&
- execv(args[1], &args[1]);
- err(EXIT_FAILURE, "execv");
-}
-\&
-int
-main(int argc, char *argv[])
-{
- char *stack;
-\&
- /* Create a child process in a new mount namespace. */
-\&
- 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");
-\&
- /* Parent falls through to here; wait for child. */
-\&
- if (wait(NULL) == \-1)
- err(EXIT_FAILURE, "wait");
-\&
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
-.SH SEE ALSO
-.BR chdir (2),
-.BR chroot (2),
-.BR mount (2),
-.BR stat (2),
-.BR initrd (4),
-.BR mount_namespaces (7),
-.BR pivot_root (8),
-.BR switch_root (8)