rustix/thread/
setns.rs

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