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, ¤t, 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