The implementation is behind the fs feature, like chroot.
It is only enabled on Linux. The manpages for FreeBSD, OpenBSD, and NetBSD show no results. And, according to https://github.com/nginx/unit/issues/737, macOS implements the syscall, but it is undocumented, and its signature is very different.
Test Program
I tested the syscall with the following program:
// Cargo.toml
//
// [dependencies]
// rustix = { version = "0.38.34", path = "../rustix", features = ["fs", "mount", "process", "thread"] }
use std::{fs, io::ErrorKind};
use rustix::{
fs::{mount, unmount, MountFlags, UnmountFlags},
process::{chdir, pivot_root},
thread::{unshare, UnshareFlags},
};
fn main() {
unshare(UnshareFlags::NEWNS | UnshareFlags::NEWUSER).expect("unshare");
fs::write("/proc/self/uid_map", "0 1000 1").expect("write uid_map");
fs::write("/proc/self/setgroups", "deny").expect("write setgroups");
fs::write("/proc/self/gid_map", "0 1000 1").expect("write gid_map");
// tmpfs on /tmp
mount(c"none", c"/tmp", c"tmpfs", MountFlags::empty(), c"").expect("mount tmpfs");
fs::write("/tmp/file0", "").expect("write file0");
fs::write("/tmp/file1", "").expect("write file1");
// pivot_root to /tmp
chdir(c"/tmp").expect("cd /tmp");
pivot_root(c".", c".").expect("pivot_root");
unmount(c".", UnmountFlags::DETACH).expect("unmount");
// See the contents in root.
chdir(c"/").expect("cd /");
for entry in std::fs::read_dir("/").expect("read_dir /") {
println!("{:?}", entry);
}
// Detect errors.
assert_eq!(
pivot_root(c"bad", c"path").unwrap_err().kind(),
ErrorKind::NotFound,
)
}
This pull-request adds the
pivot_root
syscall.The implementation is behind the
fs
feature, likechroot
.It is only enabled on Linux. The manpages for FreeBSD, OpenBSD, and NetBSD show no results. And, according to https://github.com/nginx/unit/issues/737, macOS implements the syscall, but it is undocumented, and its signature is very different.
Test Program
I tested the syscall with the following program:
Output:
From
strace
: