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