use alloc::sync::{Arc, Weak}; use core::cmp::Ordering; use core::fmt::Debug; use crate::libs::spinlock::SpinLock; use crate::process::ProcessManager; use super::nsproxy::NsCommon; use super::{NamespaceOps, NamespaceType}; use alloc::vec::Vec; lazy_static! { pub static ref INIT_USER_NAMESPACE: Arc = UserNamespace::new_root(); } pub struct UserNamespace { parent: Option>, nscommon: NsCommon, self_ref: Weak, _inner: SpinLock, } pub struct InnerUserNamespace { _children: Vec>, } impl NamespaceOps for UserNamespace { fn ns_common(&self) -> &NsCommon { &self.nscommon } } impl UserNamespace { /// 创建root user namespace fn new_root() -> Arc { Arc::new_cyclic(|self_ref| Self { self_ref: self_ref.clone(), nscommon: NsCommon::new(0, NamespaceType::User), parent: None, _inner: SpinLock::new(InnerUserNamespace { _children: Vec::new(), }), }) } /// 获取层级 pub fn level(&self) -> u32 { self.nscommon.level } /// 检查当前用户命名空间是否是另一个用户命名空间的祖先 /// /// # 参数 /// * `other` - 要检查的目标用户命名空间 /// /// # 返回值 /// * `true` - 如果当前命名空间是 `other` 的祖先 /// * `false` - 如果当前命名空间不是 `other` 的祖先 /// /// # 说明 /// 该方法通过遍历 `other` 的父命名空间链来判断当前命名空间是否为其祖先。 /// 如果两个命名空间处于同一层级且指向同一个对象,则认为是祖先关系。 /// 如果当前命名空间的层级大于目标命名空间,则不可能是祖先关系。 pub fn is_ancestor_of(&self, other: &Arc) -> bool { let mut current = other.clone(); let self_level = self.level(); loop { let current_level = current.level(); match current_level.cmp(&self_level) { Ordering::Greater => { if let Some(parent) = current.parent.as_ref().and_then(|p| p.upgrade()) { current = parent; continue; } else { return false; } } Ordering::Equal => return Arc::ptr_eq(&self.self_ref.upgrade().unwrap(), ¤t), Ordering::Less => return false, } } } } impl Debug for UserNamespace { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("UserNamespace").finish() } } impl ProcessManager { /// 获取当前进程的 user_ns pub fn current_user_ns() -> Arc { if Self::initialized() { ProcessManager::current_pcb().cred().user_ns.clone() } else { INIT_USER_NAMESPACE.clone() } } }