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
104pub fn move_into_link_name_space(
105 fd: BorrowedFd<'_>,
106 allowed_type: Option<LinkNameSpaceType>,
107) -> io::Result<()> {
108 let allowed_type: i32 = allowed_type.map_or(default:0, |t: LinkNameSpaceType| t as c_int);
109 syscalls::setns(fd, allowed_type).map(|_r: i32| ())
110}
111
112/// Atomically move the calling thread into one or more of the same namespaces
113/// as the thread referred to by `fd`.
114///
115/// `fd` must refer to a thread ID. See: `pidfd_open` and `clone`.
116///
117/// # References
118/// - [Linux]
119///
120/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html
121pub fn move_into_thread_name_spaces(
122 fd: BorrowedFd<'_>,
123 allowed_types: ThreadNameSpaceType,
124) -> io::Result<()> {
125 syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r: i32| ())
126}
127
128/// `unshare(flags)`—Disassociate parts of the current thread's execution
129/// context with other threads.
130///
131/// # References
132/// - [Linux]
133///
134/// [Linux]: https://man7.org/linux/man-pages/man2/unshare.2.html
135pub fn unshare(flags: UnshareFlags) -> io::Result<()> {
136 syscalls::unshare(flags)
137}
138