1 | use bitflags::bitflags; |
2 | use 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 | |
7 | use crate::backend::c::c_int; |
8 | use crate::backend::thread::syscalls; |
9 | use crate::fd::BorrowedFd; |
10 | use crate::io; |
11 | |
12 | bitflags! { |
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)] |
42 | pub 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 | |
61 | bitflags! { |
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 | pub 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 |
121 | pub 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 |
135 | pub fn unshare(flags: UnshareFlags) -> io::Result<()> { |
136 | syscalls::unshare(flags) |
137 | } |
138 | |