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
move_into_link_name_space( fd: BorrowedFd<'_>, allowed_type: Option<LinkNameSpaceType>, ) -> io::Result<()>104 pub fn move_into_link_name_space(
105 fd: BorrowedFd<'_>,
106 allowed_type: Option<LinkNameSpaceType>,
107 ) -> io::Result<()> {
108 let allowed_type = allowed_type.map_or(0, |t| t as c_int);
109 syscalls::setns(fd, allowed_type).map(|_r| ())
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
move_into_thread_name_spaces( fd: BorrowedFd<'_>, allowed_types: ThreadNameSpaceType, ) -> io::Result<()>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| ())
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
unshare(flags: UnshareFlags) -> io::Result<()>135 pub fn unshare(flags: UnshareFlags) -> io::Result<()> {
136 syscalls::unshare(flags)
137 }
138