LinuxCommandLibrary

pivot_root

Change the root filesystem

SYNOPSIS

pivot_root NEW_ROOT PUT_OLD

PARAMETERS

NEW_ROOT
    The directory that will become the new root filesystem. This directory must be a mount point (i.e., the root of another mounted filesystem).

PUT_OLD
    A directory inside NEW_ROOT where the original root filesystem will be moved. This directory must be empty and must be a subdirectory of NEW_ROOT. After the pivot, the old root filesystem will be accessible at this path.

DESCRIPTION

The pivot_root command (which wraps the pivot_root(2) system call) is used to change the root filesystem of the current process. It allows a process to move its current root filesystem to a new location and make a different mount point the new root.

Unlike chroot, which merely changes the apparent root directory for future operations within a process, pivot_root fundamentally alters the root of the entire mount namespace. This means that all processes in the current mount namespace will see the new filesystem as their root, and the old root filesystem becomes available at a specified mount point within the new root.

This functionality is crucial for several Linux operations, most notably during the system boot process (e.g., when transitioning from an initramfs to the real root filesystem) and in containerization technologies. It provides a robust mechanism for isolating processes and managing filesystem hierarchies.

CAVEATS

The command requires CAP_SYS_ADMIN capability to execute.

NEW_ROOT must be a mount point itself, not just a directory.

PUT_OLD must be an empty directory residing within NEW_ROOT.

The old root filesystem must not be identical to NEW_ROOT.

It's often necessary to ensure that mounts are made private (mount --make-rprivate /) before using pivot_root to prevent unintended propagation of mount events.

Any files open on the old root filesystem will continue to refer to their original inodes, even after the root has changed.

The old root filesystem (now at PUT_OLD) typically needs to be explicitly unmounted later to free up resources.

DIFFERENCES FROM CHROOT

While both pivot_root and chroot modify the root directory, they operate differently.

chroot: Changes the root directory for the current process and its children. The old root remains accessible to the parent process and any other processes not affected by the chroot. It's primarily a security and isolation tool, but less robust for full system transitions.

pivot_root: Changes the root of the entire mount namespace. The old root is moved to a specified location within the new root and becomes part of the new hierarchy. This makes it more suitable for situations like booting from an initramfs to the actual root filesystem, or setting up a full container environment where the old root needs to be effectively "hidden" or unmounted from the new environment.

TYPICAL USAGE PATTERN

A common sequence for using pivot_root involves the following steps:
1. Prepare the new root filesystem (e.g., mount it):
mount /dev/sda1 /mnt/new_root
2. Create a directory within the new root for the old root to be moved to:
mkdir /mnt/new_root/old_root_dir
3. Execute pivot_root:
pivot_root /mnt/new_root /mnt/new_root/old_root_dir
After this, /mnt/new_root becomes /, and the original root filesystem (e.g., the initramfs root) is now accessible at /old_root_dir.
4. Clean up the old root (optional, but usually desired):
umount /old_root_dir

HISTORY

The pivot_root(2) system call was introduced in Linux kernel version 2.2, released in early 1999. It was developed to address limitations of the older chroot(2) system call, particularly in scenarios where the old root filesystem needed to be unmounted or remained accessible from within the new root.

Its primary initial use cases revolved around the boot process, allowing systems to transition smoothly from a minimal initial ramdisk (initramfs) environment to the full root filesystem without complex unmounting procedures. Over time, with the rise of containerization technologies like Docker and LXC, pivot_root became a fundamental building block for creating isolated execution environments.

SEE ALSO

chroot(1), mount(8), umount(8), initramfs(7), namespaces(7)

Copied to clipboard