@@ -3,14 +3,80 @@ use linux_raw_sys::general::{
3
3
CLONE_FILES , CLONE_FS , CLONE_NEWCGROUP , CLONE_NEWIPC , CLONE_NEWNET , CLONE_NEWNS , CLONE_NEWPID ,
4
4
CLONE_NEWTIME , CLONE_NEWUSER , CLONE_NEWUTS , CLONE_SYSVSEM ,
5
5
} ;
6
+ use linux_raw_sys:: ioctl:: { NS_GET_NSTYPE , NS_GET_OWNER_UID , NS_GET_PARENT , NS_GET_USERNS } ;
6
7
7
8
use crate :: backend:: c:: c_int;
8
9
use crate :: backend:: thread:: syscalls;
9
10
use crate :: fd:: BorrowedFd ;
11
+ use crate :: fd:: { AsFd , FromRawFd , OwnedFd } ;
10
12
use crate :: io;
13
+ use crate :: ioctl;
14
+
15
+ use super :: { RawUid , Uid } ;
16
+
17
+ bitflags ! {
18
+ /// Namespace type.
19
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
20
+ #[ repr( transparent) ]
21
+ pub struct NamespaceType : u32 {
22
+ /// Control group (CGroup) namespace.
23
+ const CGROUP = CLONE_NEWCGROUP ;
24
+ /// System V IPC and POSIX message queue namespace.
25
+ const IPC = CLONE_NEWIPC ;
26
+ /// Mount namespace.
27
+ const MOUNT = CLONE_NEWNS ;
28
+ /// Network namespace.
29
+ const NETWORK = CLONE_NEWNET ;
30
+ /// Process ID namespace.
31
+ const PID = CLONE_NEWPID ;
32
+ /// Time namespace.
33
+ const TIME = CLONE_NEWTIME ;
34
+ /// User and group ID namespace.
35
+ const USER = CLONE_NEWUSER ;
36
+ /// `Host name` and `NIS domain name` (UTS) namespace.
37
+ const UTS = CLONE_NEWUTS ;
38
+
39
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
40
+ const _ = !0 ;
41
+ }
42
+ }
43
+
44
+ bitflags ! {
45
+ /// `CLONE_*` for use with [`unshare`].
46
+ #[ repr( transparent) ]
47
+ #[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
48
+ pub struct UnshareFlags : u32 {
49
+ /// `CLONE_FILES`
50
+ const FILES = CLONE_FILES ;
51
+ /// `CLONE_FS`
52
+ const FS = CLONE_FS ;
53
+ /// `CLONE_NEWCGROUP`
54
+ const NEWCGROUP = CLONE_NEWCGROUP ;
55
+ /// `CLONE_NEWIPC`
56
+ const NEWIPC = CLONE_NEWIPC ;
57
+ /// `CLONE_NEWNET`
58
+ const NEWNET = CLONE_NEWNET ;
59
+ /// `CLONE_NEWNS`
60
+ const NEWNS = CLONE_NEWNS ;
61
+ /// `CLONE_NEWPID`
62
+ const NEWPID = CLONE_NEWPID ;
63
+ /// `CLONE_NEWTIME`
64
+ const NEWTIME = CLONE_NEWTIME ;
65
+ /// `CLONE_NEWUSER`
66
+ const NEWUSER = CLONE_NEWUSER ;
67
+ /// `CLONE_NEWUTS`
68
+ const NEWUTS = CLONE_NEWUTS ;
69
+ /// `CLONE_SYSVSEM`
70
+ const SYSVSEM = CLONE_SYSVSEM ;
71
+
72
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
73
+ const _ = !0 ;
74
+ }
75
+ }
11
76
12
77
bitflags ! {
13
78
/// Thread name space type.
79
+ #[ deprecated( since = "1.1.0" , note = "Use NamespaceType instead" ) ]
14
80
#[ repr( transparent) ]
15
81
#[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
16
82
pub struct ThreadNameSpaceType : u32 {
@@ -37,6 +103,7 @@ bitflags! {
37
103
}
38
104
39
105
/// Type of name space referred to by a link.
106
+ #[ deprecated( since = "1.1.0" , note = "Use NamespaceType instead" ) ]
40
107
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
41
108
#[ repr( u32 ) ]
42
109
pub enum LinkNameSpaceType {
@@ -58,37 +125,28 @@ pub enum LinkNameSpaceType {
58
125
Network = CLONE_NEWNET ,
59
126
}
60
127
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 ;
128
+ /// Move the calling thread into different namespaces
129
+ ///
130
+ /// This function has two different semantics depending on the `fd` argument.
131
+ ///
132
+ /// - If `fd` refers to one of the magic links in a `/proc/[pid]/ns/` directory
133
+ /// or a bind mount to such a link, the calling thread is moved to the namespaces
134
+ /// referred to by `fd`. `namespace_type` must either be [`NamespaceType::empty()`]
135
+ /// in which case all namespace types can be joined or a single [`NamespaceType`]
136
+ /// bit in which case only namespaces of this type can be joined.
137
+ /// - If `fd` refers to a pidfd, the calling thread is moved to all namespaces of this
138
+ /// process that are specified in `namespace_type`.
139
+ ///
140
+ /// # References
141
+ /// - [Linux]
142
+ ///
143
+ /// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html
144
+ #[ deprecated( since = "1.1.0" , note = "Use setns instead" ) ]
145
+ #[ doc( alias = "setns" ) ]
146
+ pub fn set_namespace ( fd : BorrowedFd < ' _ > , namespace_type : NamespaceType ) -> io:: Result < ( ) > {
147
+ syscalls:: setns ( fd, namespace_type. bits ( ) as c_int ) ?;
88
148
89
- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
90
- const _ = !0 ;
91
- }
149
+ Ok ( ( ) )
92
150
}
93
151
94
152
/// Reassociate the calling thread with the namespace associated with link
@@ -101,7 +159,9 @@ bitflags! {
101
159
/// - [Linux]
102
160
///
103
161
/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html
162
+ #[ deprecated( since = "1.1.0" , note = "Use setns instead" ) ]
104
163
#[ doc( alias = "setns" ) ]
164
+ #[ allow( deprecated) ]
105
165
pub fn move_into_link_name_space (
106
166
fd : BorrowedFd < ' _ > ,
107
167
allowed_type : Option < LinkNameSpaceType > ,
@@ -119,7 +179,9 @@ pub fn move_into_link_name_space(
119
179
/// - [Linux]
120
180
///
121
181
/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html
182
+ #[ deprecated( since = "1.1.0" , note = "Use setns instead" ) ]
122
183
#[ doc( alias = "setns" ) ]
184
+ #[ allow( deprecated) ]
123
185
pub fn move_into_thread_name_spaces (
124
186
fd : BorrowedFd < ' _ > ,
125
187
allowed_types : ThreadNameSpaceType ,
@@ -137,3 +199,63 @@ pub fn move_into_thread_name_spaces(
137
199
pub fn unshare ( flags : UnshareFlags ) -> io:: Result < ( ) > {
138
200
syscalls:: unshare ( flags)
139
201
}
202
+
203
+ /// `ioctl(ns_fd, NS_GET_USERNS)`
204
+ ///
205
+ /// # Safety
206
+ ///
207
+ /// `fd` must refer to a `/proc/pid/ns/*` file.
208
+ #[ inline]
209
+ #[ doc( alias = "NS_GET_USERNS" ) ]
210
+ pub fn ioctl_ns_get_userns < FD : AsFd > ( fd : FD ) -> io:: Result < OwnedFd > {
211
+ #[ allow( unsafe_code) ]
212
+ unsafe {
213
+ let ctl = ioctl:: NoArgGetter :: < { NS_GET_USERNS } > :: new ( ) ;
214
+ ioctl:: ioctl ( fd, ctl) . map ( |fd| OwnedFd :: from_raw_fd ( fd) )
215
+ }
216
+ }
217
+
218
+ /// `ioctl(ns_fd, NS_GET_PARENT)`
219
+ ///
220
+ /// # Safety
221
+ ///
222
+ /// `fd` must refer to a `/proc/pid/ns/*` file.
223
+ #[ inline]
224
+ #[ doc( alias = "NS_GET_PARENT" ) ]
225
+ pub fn ioctl_ns_get_parent < FD : AsFd > ( fd : FD ) -> io:: Result < OwnedFd > {
226
+ #[ allow( unsafe_code) ]
227
+ unsafe {
228
+ let ctl = ioctl:: NoArgGetter :: < { NS_GET_PARENT } > :: new ( ) ;
229
+ ioctl:: ioctl ( fd, ctl) . map ( |fd| OwnedFd :: from_raw_fd ( fd) )
230
+ }
231
+ }
232
+
233
+ /// `ioctl(ns_fd, NS_GET_NSTYPE)`
234
+ ///
235
+ /// # Safety
236
+ ///
237
+ /// `fd` must refer to a `/proc/pid/ns/*` file.
238
+ #[ inline]
239
+ #[ doc( alias = "NS_GET_NSTYPE" ) ]
240
+ pub fn ioctl_ns_get_nstype < FD : AsFd > ( fd : FD ) -> io:: Result < NamespaceType > {
241
+ #[ allow( unsafe_code) ]
242
+ unsafe {
243
+ let ctl = ioctl:: NoArgGetter :: < { NS_GET_NSTYPE } > :: new ( ) ;
244
+ ioctl:: ioctl ( fd, ctl) . map ( |ns| NamespaceType :: from_bits_retain ( ns as u32 ) )
245
+ }
246
+ }
247
+
248
+ /// `ioctl(ns_fd, NS_GET_OWNER_UID)`
249
+ ///
250
+ /// # Safety
251
+ ///
252
+ /// `fd` must refer to a `/proc/pid/ns/*` file.
253
+ #[ inline]
254
+ #[ doc( alias = "NS_GET_OWNER_UID" ) ]
255
+ pub fn ioctl_ns_get_owner_uid < FD : AsFd > ( fd : FD ) -> io:: Result < Uid > {
256
+ #[ allow( unsafe_code) ]
257
+ unsafe {
258
+ let ctl = ioctl:: Getter :: < { NS_GET_OWNER_UID } , RawUid > :: new ( ) ;
259
+ ioctl:: ioctl ( fd, ctl) . map ( Uid :: from_raw)
260
+ }
261
+ }
0 commit comments