xref: /DragonOS/kernel/src/namespaces/pid_namespace.rs (revision 7b0ef10895108a0de5ff5ef3d2f93f40cf2e33a5)
1 #![allow(dead_code, unused_variables, unused_imports)]
2 use alloc::vec::Vec;
3 
4 use super::namespace::Namespace;
5 use super::ucount::Ucount::PidNamespaces;
6 use super::NsSet;
7 use super::{namespace::NsCommon, ucount::UCounts, user_namespace::UserNamespace};
8 use crate::container_of;
9 use crate::filesystem::vfs::{IndexNode, ROOT_INODE};
10 use crate::namespaces::namespace::NsOperations;
11 use crate::process::fork::CloneFlags;
12 use crate::process::ProcessManager;
13 use crate::syscall::Syscall;
14 use crate::{libs::rwlock::RwLock, process::Pid};
15 use alloc::boxed::Box;
16 use alloc::string::String;
17 use alloc::string::ToString;
18 use alloc::sync::Arc;
19 use ida::IdAllocator;
20 use system_error::SystemError;
21 use system_error::SystemError::ENOSPC;
22 
23 const INT16_MAX: u32 = 32767;
24 const MAX_PID_NS_LEVEL: usize = 32;
25 const PIDNS_ADDING: u32 = 1 << 31;
26 const PID_MAX: usize = 4096;
27 static PID_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX).unwrap();
28 #[derive(Debug)]
29 #[repr(C)]
30 pub struct PidNamespace {
31     id_alloctor: RwLock<IdAllocator>,
32     /// 已经分配的进程数
33     pid_allocated: u32,
34     /// 当前的pid_namespace所在的层数
35     pub level: usize,
36     /// 父命名空间
37     parent: Option<Arc<PidNamespace>>,
38     /// 资源计数器
39     ucounts: Arc<UCounts>,
40     /// 关联的用户namespace
41     user_ns: Arc<UserNamespace>,
42     /// 回收孤儿进程的init进程
43     child_reaper: Arc<RwLock<Pid>>,
44     /// namespace共有部分
45     pub ns_common: Arc<NsCommon>,
46 }
47 
48 impl Default for PidNamespace {
49     fn default() -> Self {
50         Self::new()
51     }
52 }
53 
54 #[derive(Debug, Clone)]
55 pub struct PidStrcut {
56     pub level: usize,
57     pub numbers: Vec<UPid>,
58     pub stashed: Arc<dyn IndexNode>,
59 }
60 
61 impl Default for PidStrcut {
62     fn default() -> Self {
63         Self::new()
64     }
65 }
66 #[derive(Debug, Clone)]
67 pub struct UPid {
68     pub nr: Pid, // 在该pid_namespace 中的pid
69     pub ns: Arc<PidNamespace>,
70 }
71 
72 impl PidStrcut {
73     pub fn new() -> Self {
74         Self {
75             level: 0,
76             numbers: vec![UPid {
77                 nr: Pid::new(0),
78                 ns: Arc::new(PidNamespace::new()),
79             }],
80             stashed: ROOT_INODE(),
81         }
82     }
83 
84     pub fn put_pid(pid: PidStrcut) {
85         let ns = pid.numbers[pid.level].ns.clone();
86         let id = pid.numbers[pid.level].nr.data();
87         ns.id_alloctor.write().free(id);
88     }
89     pub fn alloc_pid(ns: Arc<PidNamespace>, set_tid: Vec<usize>) -> Result<PidStrcut, SystemError> {
90         let mut set_tid_size = set_tid.len();
91         if set_tid_size > ns.level + 1 {
92             return Err(SystemError::EINVAL);
93         }
94 
95         let mut numbers = Vec::<UPid>::with_capacity(ns.level + 1);
96         let mut tid_iter = set_tid.into_iter().rev();
97         let mut pid_ns = ns.clone(); // 当前正在处理的命名空间
98         for i in (0..=ns.level).rev() {
99             let tid = tid_iter.next().unwrap_or(0);
100             if set_tid_size > 0 {
101                 if tid < 1 || tid > INT16_MAX as usize {
102                     return Err(SystemError::EINVAL);
103                 }
104                 set_tid_size -= 1;
105             }
106             let mut nr = tid;
107 
108             if tid == 0 {
109                 nr = pid_ns
110                     .id_alloctor
111                     .write()
112                     .alloc()
113                     .expect("PID allocation failed.");
114             }
115 
116             numbers.insert(
117                 i,
118                 UPid {
119                     nr: Pid::from(nr),
120                     ns: pid_ns.clone(),
121                 },
122             );
123 
124             if let Some(parent_ns) = &pid_ns.parent {
125                 pid_ns = parent_ns.clone();
126             } else {
127                 break; // 根命名空间,无需继续向上。
128             }
129         }
130         Ok(PidStrcut {
131             level: ns.level,
132             numbers,
133             stashed: ROOT_INODE(),
134         })
135     }
136 
137     pub fn ns_of_pid(&self) -> Arc<PidNamespace> {
138         self.numbers[self.level].ns.clone()
139     }
140 }
141 #[derive(Debug)]
142 struct PidNsOperations {
143     name: String,
144     clone_flags: CloneFlags,
145 }
146 impl PidNsOperations {
147     pub fn new(name: String) -> Self {
148         Self {
149             name,
150             clone_flags: CloneFlags::CLONE_NEWPID,
151         }
152     }
153 }
154 impl Namespace for PidNamespace {
155     fn ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self> {
156         container_of!(Arc::as_ptr(&ns_common), PidNamespace, ns_common)
157     }
158 }
159 
160 impl NsOperations for PidNsOperations {
161     fn put(&self, ns_common: Arc<NsCommon>) {
162         let _pid_ns = PidNamespace::ns_common_to_ns(ns_common);
163         // pid_ns 超出作用域自动drop 同时递归drop
164     }
165 
166     fn owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace> {
167         let pid_ns = PidNamespace::ns_common_to_ns(ns_common);
168         pid_ns.user_ns.clone()
169     }
170 
171     fn get_parent(&self, ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError> {
172         let current = ProcessManager::current_pid();
173         let pcb = ProcessManager::find(current).unwrap();
174         let active = pcb.pid_strcut().read().ns_of_pid();
175         let mut pid_ns = &PidNamespace::ns_common_to_ns(ns_common).parent;
176 
177         while let Some(ns) = pid_ns {
178             if Arc::ptr_eq(&active, ns) {
179                 return Ok(ns.ns_common.clone());
180             }
181             pid_ns = &ns.parent;
182         }
183         Err(SystemError::EPERM)
184     }
185 
186     fn get(&self, pid: Pid) -> Option<Arc<NsCommon>> {
187         let pcb = ProcessManager::find(pid);
188         pcb.map(|pcb| pcb.get_nsproxy().read().pid_namespace.ns_common.clone())
189     }
190     fn install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError> {
191         let nsproxy = &mut nsset.nsproxy;
192         let current = ProcessManager::current_pid();
193         let pcb = ProcessManager::find(current).unwrap();
194         let active = pcb.pid_strcut().read().ns_of_pid();
195         let mut pid_ns = PidNamespace::ns_common_to_ns(ns_common);
196         if pid_ns.level < active.level {
197             return Err(SystemError::EINVAL);
198         }
199         while pid_ns.level > active.level {
200             if let Some(ns) = &pid_ns.parent {
201                 pid_ns = ns.clone();
202             } else {
203                 break;
204             }
205         }
206         if Arc::ptr_eq(&pid_ns, &active) {
207             return Err(SystemError::EINVAL);
208         }
209         nsproxy.pid_namespace = pid_ns.clone();
210         Ok(())
211     }
212 }
213 impl PidNamespace {
214     pub fn new() -> Self {
215         Self {
216             id_alloctor: RwLock::new(IdAllocator::new(1, PID_MAX).unwrap()),
217             pid_allocated: 1,
218             level: 0,
219             child_reaper: Arc::new(RwLock::new(Pid::from(1))),
220             parent: None,
221             ucounts: Arc::new(UCounts::new()),
222             user_ns: Arc::new(UserNamespace::new()),
223             ns_common: Arc::new(NsCommon::new(Box::new(PidNsOperations::new(
224                 "pid".to_string(),
225             )))),
226         }
227     }
228 
229     pub fn create_pid_namespace(
230         &self,
231         parent: Arc<PidNamespace>,
232         user_ns: Arc<UserNamespace>,
233     ) -> Result<Self, SystemError> {
234         let level = parent.level + 1;
235         if level > MAX_PID_NS_LEVEL {
236             return Err(ENOSPC);
237         }
238         let ucounts = self.inc_pid_namespaces(user_ns.clone())?;
239 
240         if ucounts.is_none() {
241             return Err(SystemError::ENOSPC);
242         }
243         let ucounts = ucounts.unwrap();
244 
245         let ns_common = Arc::new(NsCommon::new(Box::new(PidNsOperations::new(
246             "pid".to_string(),
247         ))));
248         let child_reaper = parent.child_reaper.clone();
249         Ok(Self {
250             id_alloctor: RwLock::new(IdAllocator::new(1, PID_MAX).unwrap()),
251             pid_allocated: PIDNS_ADDING,
252             level,
253             ucounts,
254             parent: Some(parent),
255             user_ns,
256             ns_common,
257             child_reaper,
258         })
259     }
260 
261     pub fn inc_pid_namespaces(
262         &self,
263         user_ns: Arc<UserNamespace>,
264     ) -> Result<Option<Arc<UCounts>>, SystemError> {
265         Ok(self
266             .ucounts
267             .inc_ucounts(user_ns, Syscall::geteuid()?, PidNamespaces))
268     }
269 
270     pub fn dec_pid_namespaces(&mut self, uc: Arc<UCounts>) {
271         UCounts::dec_ucount(uc, PidNamespaces)
272     }
273 }
274