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