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.260
1 files changed, 29 insertions, 31 deletions
diff --git a/man2/pivot_root.2 b/man2/pivot_root.2
index d56ad996c..a4077ef73 100644
--- a/man2/pivot_root.2
+++ b/man2/pivot_root.2
@@ -4,7 +4,7 @@
.\"
.\" SPDX-License-Identifier: Linux-man-pages-copyleft
.\"
-.TH pivot_root 2 2023-02-05 "Linux man-pages 6.03"
+.TH pivot_root 2 2023-05-03 "Linux man-pages 6.05.01"
.SH NAME
pivot_root \- change the root mount
.SH LIBRARY
@@ -151,12 +151,10 @@ is a mount point and has the propagation type
The calling process does not have the
.B CAP_SYS_ADMIN
capability.
-.SH VERSIONS
-.BR pivot_root ()
-was introduced in Linux 2.3.41.
.SH STANDARDS
-.BR pivot_root ()
-is Linux-specific and hence is not portable.
+Linux.
+.SH HISTORY
+Linux 2.3.41.
.SH NOTES
A command-line interface for this system call is provided by
.BR pivot_root (8).
@@ -302,7 +300,7 @@ hello world
.\" SRC BEGIN (pivot_root.c)
.EX
/* pivot_root_demo.c */
-
+\&
#define _GNU_SOURCE
#include <err.h>
#include <limits.h>
@@ -316,15 +314,15 @@ hello world
#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)
{
@@ -332,70 +330,70 @@ child(void *arg)
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