| #![allow(unsafe_code)] |
| |
| use bitflags::bitflags; |
| use linux_raw_sys::general::{ |
| CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, |
| CLONE_NEWTIME, CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SYSVSEM, |
| }; |
| |
| use crate::backend::c::c_int; |
| use crate::backend::thread::syscalls; |
| use crate::fd::BorrowedFd; |
| use crate::io; |
| |
| bitflags! { |
| /// Thread name space type. |
| pub struct ThreadNameSpaceType: u32 { |
| /// Time name space. |
| const TIME = CLONE_NEWTIME; |
| /// Mount name space. |
| const MOUNT = CLONE_NEWNS; |
| /// Control group (CGroup) name space. |
| const CONTROL_GROUP = CLONE_NEWCGROUP; |
| /// `Host name` and `NIS domain name` (UTS) name space. |
| const HOST_NAME_AND_NIS_DOMAIN_NAME = CLONE_NEWUTS; |
| /// Inter-process communication (IPC) name space. |
| const INTER_PROCESS_COMMUNICATION = CLONE_NEWIPC; |
| /// User name space. |
| const USER = CLONE_NEWUSER; |
| /// Process ID name space. |
| const PROCESS_ID = CLONE_NEWPID; |
| /// Network name space. |
| const NETWORK = CLONE_NEWNET; |
| } |
| } |
| |
| /// Type of name space referred to by a link. |
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
| #[repr(u32)] |
| pub enum LinkNameSpaceType { |
| /// Time name space. |
| Time = CLONE_NEWTIME, |
| /// Mount name space. |
| Mount = CLONE_NEWNS, |
| /// Control group (CGroup) name space. |
| ControlGroup = CLONE_NEWCGROUP, |
| /// `Host name` and `NIS domain name` (UTS) name space. |
| HostNameAndNISDomainName = CLONE_NEWUTS, |
| /// Inter-process communication (IPC) name space. |
| InterProcessCommunication = CLONE_NEWIPC, |
| /// User name space. |
| User = CLONE_NEWUSER, |
| /// Process ID name space. |
| ProcessID = CLONE_NEWPID, |
| /// Network name space. |
| Network = CLONE_NEWNET, |
| } |
| |
| bitflags! { |
| /// `CLONE_*` for use with [`unshare`]. |
| pub struct UnshareFlags: u32 { |
| /// `CLONE_FILES`. |
| const FILES = CLONE_FILES; |
| /// `CLONE_FS`. |
| const FS = CLONE_FS; |
| /// `CLONE_NEWCGROUP`. |
| const NWCGROUP = CLONE_NEWCGROUP; |
| /// `CLONE_NEWIPC`. |
| const NEWIPC = CLONE_NEWIPC; |
| /// `CLONE_NEWNET`. |
| const NEWNET = CLONE_NEWNET; |
| /// `CLONE_NEWNS`. |
| const NEWNS = CLONE_NEWNS; |
| /// `CLONE_NEWPID`. |
| const NEWPID = CLONE_NEWPID; |
| /// `CLONE_NEWTIME`. |
| const NEWTIME = CLONE_NEWTIME; |
| /// `CLONE_NEWUSER`. |
| const NEWUSER = CLONE_NEWUSER; |
| /// `CLONE_SYSVSEM`. |
| const SYSVSEM = CLONE_SYSVSEM; |
| } |
| } |
| |
| /// Reassociate the calling thread with the namespace associated with link referred to by `fd`. |
| /// |
| /// `fd` must refer to one of the magic links in a `/proc/[pid]/ns/` directory, or a bind mount |
| /// to such a link. |
| /// |
| /// # References |
| /// - [`setns`] |
| /// |
| /// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html |
| pub fn move_into_link_name_space( |
| fd: BorrowedFd, |
| allowed_type: Option<LinkNameSpaceType>, |
| ) -> io::Result<()> { |
| let allowed_type = allowed_type.map_or(0, |t| t as c_int); |
| syscalls::setns(fd, allowed_type).map(|_r| ()) |
| } |
| |
| /// Atomically move the calling thread into one or more of the same namespaces as the thread |
| /// referred to by `fd`. |
| /// |
| /// `fd` must refer to a thread ID. See: `pidfd_open` and `clone`. |
| /// |
| /// # References |
| /// - [`setns`] |
| /// |
| /// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html |
| pub fn move_into_thread_name_spaces( |
| fd: BorrowedFd, |
| allowed_types: ThreadNameSpaceType, |
| ) -> io::Result<()> { |
| syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r| ()) |
| } |
| |
| /// `unshare(flags)`—Disassociate parts of the current thread's execution |
| /// context with other threads. |
| /// |
| /// # References |
| /// - [`unshare`] |
| /// |
| /// [`unshare`]: https://man7.org/linux/man-pages/man2/unshare.2.html |
| pub fn unshare(flags: UnshareFlags) -> io::Result<()> { |
| syscalls::unshare(flags) |
| } |