xref: /DragonOS/kernel/src/namespaces/mod.rs (revision f5b2038871d3441e1c7f32439ff422957e7ab828)
1 use alloc::sync::Arc;
2 use mnt_namespace::{FsStruct, MntNamespace};
3 use pid_namespace::PidNamespace;
4 use system_error::SystemError;
5 use user_namespace::UserNamespace;
6 
7 use crate::{
8     libs::spinlock::SpinLock,
9     process::{fork::CloneFlags, ProcessControlBlock},
10 };
11 
12 pub mod mnt_namespace;
13 pub mod namespace;
14 pub mod pid_namespace;
15 pub mod syscall;
16 pub mod ucount;
17 pub mod user_namespace;
18 
19 /// 管理 namespace,包含了所有namespace的信息
20 #[derive(Clone)]
21 pub struct NsSet {
22     flags: u64,
23     nsproxy: NsProxy,
24     pub fs: Arc<SpinLock<FsStruct>>,
25 }
26 #[derive(Debug, Clone)]
27 pub struct NsProxy {
28     pub pid_namespace: Arc<PidNamespace>,
29     pub mnt_namespace: Arc<MntNamespace>,
30 }
31 impl Default for NsProxy {
default() -> Self32     fn default() -> Self {
33         Self::new()
34     }
35 }
36 
37 impl NsProxy {
new() -> Self38     pub fn new() -> Self {
39         Self {
40             pid_namespace: Arc::new(PidNamespace::new()),
41             mnt_namespace: Arc::new(MntNamespace::new()),
42         }
43     }
set_pid_namespace(&mut self, new_pid_ns: Arc<PidNamespace>)44     pub fn set_pid_namespace(&mut self, new_pid_ns: Arc<PidNamespace>) {
45         self.pid_namespace = new_pid_ns;
46     }
47 
set_mnt_namespace(&mut self, new_mnt_ns: Arc<MntNamespace>)48     pub fn set_mnt_namespace(&mut self, new_mnt_ns: Arc<MntNamespace>) {
49         self.mnt_namespace = new_mnt_ns;
50     }
51 }
52 
create_new_namespaces( clone_flags: u64, pcb: &Arc<ProcessControlBlock>, user_ns: Arc<UserNamespace>, ) -> Result<NsProxy, SystemError>53 pub fn create_new_namespaces(
54     clone_flags: u64,
55     pcb: &Arc<ProcessControlBlock>,
56     user_ns: Arc<UserNamespace>,
57 ) -> Result<NsProxy, SystemError> {
58     let mut nsproxy = NsProxy::new();
59     // pid_namespace
60     let new_pid_ns = if (clone_flags & CloneFlags::CLONE_NEWPID.bits()) != 0 {
61         Arc::new(PidNamespace::new().create_pid_namespace(
62             pcb.get_nsproxy().read().pid_namespace.clone(),
63             user_ns.clone(),
64         )?)
65     } else {
66         pcb.get_nsproxy().read().pid_namespace.clone()
67     };
68     nsproxy.set_pid_namespace(new_pid_ns);
69 
70     // mnt_namespace
71     let new_mnt_ns = if clone_flags & CloneFlags::CLONE_NEWNS.bits() != 0 {
72         Arc::new(MntNamespace::new().create_mnt_namespace(user_ns.clone(), false)?)
73     } else {
74         pcb.get_nsproxy().read().mnt_namespace.clone()
75     };
76     nsproxy.set_mnt_namespace(new_mnt_ns);
77 
78     Ok(nsproxy)
79 }
80 
81 #[macro_export]
82 macro_rules! container_of {
83     ($ptr:expr, $struct:path, $field:ident) => {
84         unsafe {
85             let dummy = core::mem::MaybeUninit::<$struct>::uninit();
86             let dummy_ptr = dummy.as_ptr();
87             let field_ptr = &(*dummy_ptr).$field as *const _ as usize;
88             let offset = field_ptr - dummy_ptr as usize;
89             Arc::from_raw(($ptr as *const u8).wrapping_sub(offset) as *mut $struct)
90         }
91     };
92 }
93