1#![allow(unsafe_code)] 2 3use bitflags::bitflags; 4use linux_raw_sys::general::{ 5 CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, 6 CLONE_NEWTIME, CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SYSVSEM, 7}; 8 9use crate::backend::c::c_int; 10use crate::backend::thread::syscalls; 11use crate::fd::BorrowedFd; 12use crate::io; 13 14bitflags! { 15 /// Thread name space type. 16 pub struct ThreadNameSpaceType: u32 { 17 /// Time name space. 18 const TIME = CLONE_NEWTIME; 19 /// Mount name space. 20 const MOUNT = CLONE_NEWNS; 21 /// Control group (CGroup) name space. 22 const CONTROL_GROUP = CLONE_NEWCGROUP; 23 /// `Host name` and `NIS domain name` (UTS) name space. 24 const HOST_NAME_AND_NIS_DOMAIN_NAME = CLONE_NEWUTS; 25 /// Inter-process communication (IPC) name space. 26 const INTER_PROCESS_COMMUNICATION = CLONE_NEWIPC; 27 /// User name space. 28 const USER = CLONE_NEWUSER; 29 /// Process ID name space. 30 const PROCESS_ID = CLONE_NEWPID; 31 /// Network name space. 32 const NETWORK = CLONE_NEWNET; 33 } 34} 35 36/// Type of name space referred to by a link. 37#[derive(Copy, Clone, Debug, Eq, PartialEq)] 38#[repr(u32)] 39pub enum LinkNameSpaceType { 40 /// Time name space. 41 Time = CLONE_NEWTIME, 42 /// Mount name space. 43 Mount = CLONE_NEWNS, 44 /// Control group (CGroup) name space. 45 ControlGroup = CLONE_NEWCGROUP, 46 /// `Host name` and `NIS domain name` (UTS) name space. 47 HostNameAndNISDomainName = CLONE_NEWUTS, 48 /// Inter-process communication (IPC) name space. 49 InterProcessCommunication = CLONE_NEWIPC, 50 /// User name space. 51 User = CLONE_NEWUSER, 52 /// Process ID name space. 53 ProcessID = CLONE_NEWPID, 54 /// Network name space. 55 Network = CLONE_NEWNET, 56} 57 58bitflags! { 59 /// `CLONE_*` for use with [`unshare`]. 60 pub struct UnshareFlags: u32 { 61 /// `CLONE_FILES`. 62 const FILES = CLONE_FILES; 63 /// `CLONE_FS`. 64 const FS = CLONE_FS; 65 /// `CLONE_NEWCGROUP`. 66 const NWCGROUP = CLONE_NEWCGROUP; 67 /// `CLONE_NEWIPC`. 68 const NEWIPC = CLONE_NEWIPC; 69 /// `CLONE_NEWNET`. 70 const NEWNET = CLONE_NEWNET; 71 /// `CLONE_NEWNS`. 72 const NEWNS = CLONE_NEWNS; 73 /// `CLONE_NEWPID`. 74 const NEWPID = CLONE_NEWPID; 75 /// `CLONE_NEWTIME`. 76 const NEWTIME = CLONE_NEWTIME; 77 /// `CLONE_NEWUSER`. 78 const NEWUSER = CLONE_NEWUSER; 79 /// `CLONE_SYSVSEM`. 80 const SYSVSEM = CLONE_SYSVSEM; 81 } 82} 83 84/// Reassociate the calling thread with the namespace associated with link referred to by `fd`. 85/// 86/// `fd` must refer to one of the magic links in a `/proc/[pid]/ns/` directory, or a bind mount 87/// to such a link. 88/// 89/// # References 90/// - [`setns`] 91/// 92/// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html 93pub fn move_into_link_name_space( 94 fd: BorrowedFd, 95 allowed_type: Option<LinkNameSpaceType>, 96) -> io::Result<()> { 97 let allowed_type = allowed_type.map_or(0, |t| t as c_int); 98 syscalls::setns(fd, allowed_type).map(|_r| ()) 99} 100 101/// Atomically move the calling thread into one or more of the same namespaces as the thread 102/// referred to by `fd`. 103/// 104/// `fd` must refer to a thread ID. See: `pidfd_open` and `clone`. 105/// 106/// # References 107/// - [`setns`] 108/// 109/// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html 110pub fn move_into_thread_name_spaces( 111 fd: BorrowedFd, 112 allowed_types: ThreadNameSpaceType, 113) -> io::Result<()> { 114 syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r| ()) 115} 116 117/// `unshare(flags)`—Disassociate parts of the current thread's execution 118/// context with other threads. 119/// 120/// # References 121/// - [`unshare`] 122/// 123/// [`unshare`]: https://man7.org/linux/man-pages/man2/unshare.2.html 124pub fn unshare(flags: UnshareFlags) -> io::Result<()> { 125 syscalls::unshare(flags) 126} 127