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 {
get(&self, pid: Pid) -> Option<Arc<NsCommon>>19 fn get(&self, pid: Pid) -> Option<Arc<NsCommon>>;
put(&self, ns_common: Arc<NsCommon>)20 fn put(&self, ns_common: Arc<NsCommon>);
install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError>21 fn install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError>;
owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace>22 fn owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace>;
get_parent(&self, ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError>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 {
new(ops: Box<dyn NsOperations>) -> Self32 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 {
ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self>53 fn ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self>;
54 }
55
check_unshare_flags(unshare_flags: u64) -> Result<usize, SystemError>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
unshare_nsproxy_namespaces(unshare_flags: u64) -> Result<Option<NsProxy>, SystemError>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
switch_task_namespace(pcb: Arc<ProcessControlBlock>, new_nsproxy: NsProxy)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
prepare_nsset(flags: u64) -> Result<NsSet, SystemError>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, ¤t, USER_NS.clone())?,
106 })
107 }
108
commit_nsset(nsset: NsSet)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