xref: /DragonOS/kernel/src/namespaces/namespace.rs (revision 7b0ef10895108a0de5ff5ef3d2f93f40cf2e33a5)
1 #![allow(dead_code, unused_variables, unused_imports)]
2 use core::fmt::Debug;
3 
4 use crate::filesystem::procfs::ProcFSInode;
5 use crate::filesystem::vfs::{IndexNode, ROOT_INODE};
6 use crate::namespaces::user_namespace::UserNamespace;
7 use crate::process::fork::CloneFlags;
8 use crate::process::{Pid, ProcessControlBlock, ProcessManager};
9 use alloc::boxed::Box;
10 use alloc::sync::Arc;
11 use system_error::SystemError;
12 
13 // 目前无credit功能,采用全局静态的user_namespace
14 lazy_static! {
15     pub static ref USER_NS: Arc<UserNamespace> = Arc::new(UserNamespace::new());
16 }
17 use super::{create_new_namespaces, NsProxy, NsSet};
18 pub trait NsOperations: Send + Sync + Debug {
19     fn get(&self, pid: Pid) -> Option<Arc<NsCommon>>;
20     fn put(&self, ns_common: Arc<NsCommon>);
21     fn install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError>;
22     fn owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace>;
23     fn get_parent(&self, ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError>;
24 }
25 #[derive(Debug)]
26 pub struct NsCommon {
27     ops: Box<dyn NsOperations>,
28     stashed: Arc<dyn IndexNode>,
29 }
30 
31 impl NsCommon {
32     pub fn new(ops: Box<dyn NsOperations>) -> Self {
33         let inode = ROOT_INODE().find("proc").unwrap_or_else(|_| ROOT_INODE());
34         Self {
35             ops,
36             stashed: inode,
37         }
38     }
39 }
40 
41 pub enum NsType {
42     Pid,
43     User,
44     Uts,
45     Ipc,
46     Net,
47     Mnt,
48     Cgroup,
49     Time,
50 }
51 
52 pub trait Namespace {
53     fn ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self>;
54 }
55 
56 pub fn check_unshare_flags(unshare_flags: u64) -> Result<usize, SystemError> {
57     let valid_flags = CloneFlags::CLONE_THREAD
58         | CloneFlags::CLONE_FS
59         | CloneFlags::CLONE_NEWNS
60         | CloneFlags::CLONE_SIGHAND
61         | CloneFlags::CLONE_VM
62         | CloneFlags::CLONE_FILES
63         | CloneFlags::CLONE_SYSVSEM
64         | CloneFlags::CLONE_NEWUTS
65         | CloneFlags::CLONE_NEWIPC
66         | CloneFlags::CLONE_NEWNET
67         | CloneFlags::CLONE_NEWUSER
68         | CloneFlags::CLONE_NEWPID
69         | CloneFlags::CLONE_NEWCGROUP;
70 
71     if unshare_flags & !valid_flags.bits() != 0 {
72         return Err(SystemError::EINVAL);
73     }
74     Ok(0)
75 }
76 
77 pub fn unshare_nsproxy_namespaces(unshare_flags: u64) -> Result<Option<NsProxy>, SystemError> {
78     if (unshare_flags
79         & (CloneFlags::CLONE_NEWNS.bits()
80             | CloneFlags::CLONE_NEWUTS.bits()
81             | CloneFlags::CLONE_NEWIPC.bits()
82             | CloneFlags::CLONE_NEWNET.bits()
83             | CloneFlags::CLONE_NEWPID.bits()
84             | CloneFlags::CLONE_NEWCGROUP.bits()))
85         == 0
86     {
87         return Ok(None);
88     }
89     let current = ProcessManager::current_pid();
90     let pcb = ProcessManager::find(current).unwrap();
91     let new_nsproxy = create_new_namespaces(unshare_flags, &pcb, USER_NS.clone())?;
92     Ok(Some(new_nsproxy))
93 }
94 
95 pub fn switch_task_namespace(pcb: Arc<ProcessControlBlock>, new_nsproxy: NsProxy) {
96     let ns = pcb.get_nsproxy();
97     pcb.set_nsproxy(new_nsproxy);
98 }
99 
100 pub fn prepare_nsset(flags: u64) -> Result<NsSet, SystemError> {
101     let current = ProcessManager::current_pcb();
102     Ok(NsSet {
103         flags,
104         fs: current.fs_struct(),
105         nsproxy: create_new_namespaces(flags, &current, USER_NS.clone())?,
106     })
107 }
108 
109 pub fn commit_nsset(nsset: NsSet) {
110     let flags = CloneFlags::from_bits_truncate(nsset.flags);
111     let current = ProcessManager::current_pcb();
112     if flags.contains(CloneFlags::CLONE_NEWNS) {
113         let fs = current.fs_struct();
114         let nsset_fs = nsset.fs.lock();
115         fs.lock().set_pwd(nsset_fs.pwd.clone());
116         fs.lock().set_root(nsset_fs.root.clone());
117     }
118     switch_task_namespace(current, nsset.nsproxy); // 转移所有权
119 }
120