@@ -3,14 +3,80 @@ use linux_raw_sys::general::{
33 CLONE_FILES , CLONE_FS , CLONE_NEWCGROUP , CLONE_NEWIPC , CLONE_NEWNET , CLONE_NEWNS , CLONE_NEWPID ,
44 CLONE_NEWTIME , CLONE_NEWUSER , CLONE_NEWUTS , CLONE_SYSVSEM ,
55} ;
6+ use linux_raw_sys:: ioctl:: { NS_GET_NSTYPE , NS_GET_OWNER_UID , NS_GET_PARENT , NS_GET_USERNS } ;
67
78use crate :: backend:: c:: c_int;
89use crate :: backend:: thread:: syscalls;
910use crate :: fd:: BorrowedFd ;
11+ use crate :: fd:: { AsFd , FromRawFd , OwnedFd } ;
1012use 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+ }
1176
1277bitflags ! {
1378 /// Thread name space type.
79+ #[ deprecated( since = "1.1.0" , note = "Use NamespaceType instead" ) ]
1480 #[ repr( transparent) ]
1581 #[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
1682 pub struct ThreadNameSpaceType : u32 {
@@ -37,6 +103,7 @@ bitflags! {
37103}
38104
39105/// Type of name space referred to by a link.
106+ #[ deprecated( since = "1.1.0" , note = "Use NamespaceType instead" ) ]
40107#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
41108#[ repr( u32 ) ]
42109pub enum LinkNameSpaceType {
@@ -58,37 +125,28 @@ pub enum LinkNameSpaceType {
58125 Network = CLONE_NEWNET ,
59126}
60127
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 ) ?;
88148
89- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
90- const _ = !0 ;
91- }
149+ Ok ( ( ) )
92150}
93151
94152/// Reassociate the calling thread with the namespace associated with link
@@ -101,7 +159,9 @@ bitflags! {
101159/// - [Linux]
102160///
103161/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html
162+ #[ deprecated( since = "1.1.0" , note = "Use setns instead" ) ]
104163#[ doc( alias = "setns" ) ]
164+ #[ allow( deprecated) ]
105165pub fn move_into_link_name_space (
106166 fd : BorrowedFd < ' _ > ,
107167 allowed_type : Option < LinkNameSpaceType > ,
@@ -119,7 +179,9 @@ pub fn move_into_link_name_space(
119179/// - [Linux]
120180///
121181/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html
182+ #[ deprecated( since = "1.1.0" , note = "Use setns instead" ) ]
122183#[ doc( alias = "setns" ) ]
184+ #[ allow( deprecated) ]
123185pub fn move_into_thread_name_spaces (
124186 fd : BorrowedFd < ' _ > ,
125187 allowed_types : ThreadNameSpaceType ,
@@ -137,3 +199,63 @@ pub fn move_into_thread_name_spaces(
137199pub fn unshare ( flags : UnshareFlags ) -> io:: Result < ( ) > {
138200 syscalls:: unshare ( flags)
139201}
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