Browse Source

feat: implement basic mount namespace support (#1246)

Add initial mount namespace functionality with root namespace creation:
  - Create root mount namespace initialization and management
  - Implement basic mount namespace structure with root mountfs
  - Add namespace-aware mount/umount operations and VFS modifications
  - Update filesystem modules (devfs, procfs, sysfs, overlayfs) for namespace compatibility
  - Modify TTY and stdio for namespace support

Signed-off-by: longjin <longjin@DragonOS.org>
LoGin 2 weeks ago
parent
commit
91827fc04a

+ 6 - 4
kernel/src/driver/tty/pty/unix98pty.rs

@@ -12,12 +12,13 @@ use crate::{
         devpts::DevPtsFs,
         epoll::EPollEventType,
         vfs::{
-            file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE,
+            file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS,
             VFS_MAX_FOLLOW_SYMLINK_TIMES,
         },
     },
     libs::spinlock::SpinLockGuard,
     mm::VirtAddr,
+    process::ProcessManager,
     syscall::user_access::UserBufferWriter,
 };
 
@@ -216,11 +217,11 @@ impl TtyOperation for Unix98PtyDriverInner {
 
     fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
         let driver = tty.core().driver();
-
+        let root_inode = ProcessManager::current_mntns().root_inode();
         if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
             driver.ttys().remove(&tty.core().index());
             let pts_root_inode =
-                ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
+                root_inode.lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
             let _ = pts_root_inode.unlink(&tty.core().index().to_string());
         }
 
@@ -250,8 +251,9 @@ pub fn ptmx_open(
     mut data: SpinLockGuard<FilePrivateData>,
     mode: &FileMode,
 ) -> Result<(), SystemError> {
+    let root_inode = ProcessManager::current_mntns().root_inode();
     let pts_root_inode =
-        ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
+        root_inode.lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
 
     let fs = pts_root_inode
         .fs()

+ 9 - 7
kernel/src/filesystem/devfs/mod.rs

@@ -3,11 +3,8 @@ pub mod null_dev;
 pub mod zero_dev;
 
 use super::vfs::{
-    file::FileMode,
-    syscall::ModeType,
-    utils::DName,
-    vcore::{generate_inode_id, ROOT_INODE},
-    FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Magic, Metadata, SuperBlock,
+    file::FileMode, syscall::ModeType, utils::DName, vcore::generate_inode_id, FilePrivateData,
+    FileSystem, FileType, FsInfo, IndexNode, Magic, Metadata, SuperBlock,
 };
 use crate::{
     driver::base::{block::gendisk::GenDisk, device::device_number::DeviceNumber},
@@ -15,6 +12,7 @@ use crate::{
         once::Once,
         spinlock::{SpinLock, SpinLockGuard},
     },
+    process::ProcessManager,
     time::PosixTimeSpec,
 };
 use alloc::{
@@ -685,7 +683,10 @@ pub trait DeviceINode: IndexNode {
 /// @brief 获取devfs实例的强类型不可变引用
 macro_rules! devfs_exact_ref {
     () => {{
-        let devfs_inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().find("dev");
+        let devfs_inode: Result<Arc<dyn IndexNode>, SystemError> =
+            crate::process::ProcessManager::current_mntns()
+                .root_inode()
+                .find("dev");
         if let Err(e) = devfs_inode {
             error!("failed to get DevFS ref. errcode = {:?}", e);
             return Err(SystemError::ENOENT);
@@ -722,7 +723,8 @@ pub fn devfs_init() -> Result<(), SystemError> {
         // 创建 devfs 实例
         let devfs: Arc<DevFS> = DevFS::new();
         // devfs 挂载
-        ROOT_INODE()
+        let root_inode = ProcessManager::current_mntns().root_inode();
+        root_inode
             .mkdir("dev", ModeType::from_bits_truncate(0o755))
             .expect("Unabled to find /dev")
             .mount(devfs)

+ 3 - 3
kernel/src/filesystem/fs.rs

@@ -2,8 +2,8 @@ use alloc::sync::Arc;
 
 use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::IndexNode;
-use crate::filesystem::vfs::ROOT_INODE;
 use crate::libs::rwlock::RwLock;
+use crate::process::ProcessManager;
 #[derive(Debug, Clone)]
 struct PathContext {
     root: Arc<dyn IndexNode>,
@@ -13,8 +13,8 @@ struct PathContext {
 impl PathContext {
     pub fn new() -> Self {
         Self {
-            root: ROOT_INODE(),
-            pwd: ROOT_INODE(),
+            root: ProcessManager::current_mntns().root_inode(),
+            pwd: ProcessManager::current_mntns().root_inode(),
         }
     }
 }

+ 8 - 4
kernel/src/filesystem/overlayfs/mod.rs

@@ -3,14 +3,15 @@ pub mod copy_up;
 pub mod entry;
 
 use super::ramfs::{LockedRamFSInode, RamFSInode};
+use super::vfs::FSMAKER;
 use super::vfs::{
     self, FileSystem, FileType, FsInfo, IndexNode, Metadata, MountableFileSystem, SuperBlock,
 };
-use super::vfs::{FSMAKER, ROOT_INODE};
 use crate::driver::base::device::device_number::DeviceNumber;
 use crate::driver::base::device::device_number::Major;
 use crate::filesystem::vfs::{FileSystemMaker, FileSystemMakerData};
 use crate::libs::spinlock::SpinLock;
+use crate::process::ProcessManager;
 use crate::register_mountable_fs;
 use alloc::string::String;
 use alloc::sync::Arc;
@@ -146,8 +147,8 @@ impl MountableFileSystem for OverlayFS {
         let mount_data = data
             .and_then(|d| d.as_any().downcast_ref::<OverlayMountData>())
             .ok_or(SystemError::EINVAL)?;
-
-        let upper_inode = ROOT_INODE()
+        let root_inode = ProcessManager::current_mntns().root_inode();
+        let upper_inode = root_inode
             .lookup(&mount_data.upper_dir)
             .map_err(|_| SystemError::EINVAL)?;
         let upper_layer = OvlLayer {
@@ -165,7 +166,10 @@ impl MountableFileSystem for OverlayFS {
             .iter()
             .enumerate()
             .map(|(i, dir)| {
-                let lower_inode = ROOT_INODE().lookup(dir).map_err(|_| SystemError::EINVAL)?; // 处理错误
+                let lower_inode = ProcessManager::current_mntns()
+                    .root_inode()
+                    .lookup(dir)
+                    .map_err(|_| SystemError::EINVAL)?; // 处理错误
                 Ok(OvlLayer {
                     mnt: Arc::new(OvlInode::new(dir.clone(), None, Some(lower_inode))),
                     index: (i + 1) as u32,

+ 8 - 8
kernel/src/filesystem/procfs/mod.rs

@@ -14,10 +14,7 @@ use system_error::SystemError;
 use crate::{
     arch::mm::LockedFrameAllocator,
     driver::base::device::device_number::DeviceNumber,
-    filesystem::vfs::{
-        vcore::{generate_inode_id, ROOT_INODE},
-        FileType,
-    },
+    filesystem::vfs::{vcore::generate_inode_id, FileType},
     libs::{
         once::Once,
         rwlock::RwLock,
@@ -923,7 +920,8 @@ impl IndexNode for LockedProcFSInode {
 
 /// @brief 向procfs注册进程
 pub fn procfs_register_pid(pid: RawPid) -> Result<(), SystemError> {
-    let procfs_inode = ROOT_INODE().find("proc")?;
+    let root_inode = ProcessManager::current_mntns().root_inode();
+    let procfs_inode = root_inode.find("proc")?;
 
     let procfs_inode = procfs_inode
         .downcast_ref::<LockedProcFSInode>()
@@ -934,13 +932,14 @@ pub fn procfs_register_pid(pid: RawPid) -> Result<(), SystemError> {
     // 调用注册函数
     procfs.register_pid(pid)?;
 
-    return Ok(());
+    Ok(())
 }
 
 /// @brief 在ProcFS中,解除进程的注册
 pub fn procfs_unregister_pid(pid: RawPid) -> Result<(), SystemError> {
+    let root_inode = ProcessManager::current_mntns().root_inode();
     // 获取procfs实例
-    let procfs_inode: Arc<dyn IndexNode> = ROOT_INODE().find("proc")?;
+    let procfs_inode: Arc<dyn IndexNode> = root_inode.find("proc")?;
 
     let procfs_inode: &LockedProcFSInode = procfs_inode
         .downcast_ref::<LockedProcFSInode>()
@@ -959,8 +958,9 @@ pub fn procfs_init() -> Result<(), SystemError> {
         info!("Initializing ProcFS...");
         // 创建 procfs 实例
         let procfs: Arc<ProcFS> = ProcFS::new();
+        let root_inode = ProcessManager::current_mntns().root_inode();
         // procfs 挂载
-        ROOT_INODE()
+        root_inode
             .mkdir("proc", ModeType::from_bits_truncate(0o755))
             .expect("Unabled to find /proc")
             .mount(procfs)

+ 3 - 3
kernel/src/filesystem/sysfs/mod.rs

@@ -8,8 +8,8 @@ use super::{
 };
 use crate::{
     driver::base::kobject::KObject,
-    filesystem::vfs::ROOT_INODE,
     libs::{casting::DowncastArc, once::Once},
+    process::ProcessManager,
 };
 use alloc::sync::Arc;
 use log::{info, warn};
@@ -40,9 +40,9 @@ pub fn sysfs_init() -> Result<(), SystemError> {
         // let sysfs: Arc<OldSysFS> = OldSysFS::new();
         let sysfs = SysFS::new();
         unsafe { SYSFS_INSTANCE = Some(sysfs) };
-
+        let root_inode = ProcessManager::current_mntns().root_inode();
         // sysfs 挂载
-        ROOT_INODE()
+        root_inode
             .mkdir("sys", ModeType::from_bits_truncate(0o755))
             .expect("Unabled to find /sys")
             .mount(sysfs_instance().fs().clone())

+ 4 - 2
kernel/src/filesystem/vfs/mod.rs

@@ -25,11 +25,12 @@ use crate::{
         spinlock::{SpinLock, SpinLockGuard},
     },
     mm::{fault::PageFaultMessage, VmFaultReason},
+    process::ProcessManager,
     time::PosixTimeSpec,
 };
 
 use self::{file::FileMode, syscall::ModeType, utils::DName, vcore::generate_inode_id};
-pub use self::{file::FilePrivateData, mount::MountFS, vcore::ROOT_INODE};
+pub use self::{file::FilePrivateData, mount::MountFS};
 
 use super::page_cache::PageCache;
 
@@ -721,11 +722,12 @@ impl dyn IndexNode {
             return Err(SystemError::ENOTDIR);
         }
 
+        let root_inode = ProcessManager::current_mntns().root_inode();
         // 处理绝对路径
         // result: 上一个被找到的inode
         // rest_path: 还没有查找的路径
         let (mut result, mut rest_path) = if let Some(rest) = path.strip_prefix('/') {
-            (ROOT_INODE().clone(), String::from(rest))
+            (root_inode.clone(), String::from(rest))
         } else {
             // 是相对路径
             (self.find(".")?, String::from(path))

+ 114 - 55
kernel/src/filesystem/vfs/mount.rs

@@ -10,20 +10,27 @@ use alloc::{
     sync::{Arc, Weak},
     vec::Vec,
 };
+use hashbrown::HashMap;
+use ida::IdAllocator;
 use system_error::SystemError;
 
 use crate::{
     driver::base::device::device_number::DeviceNumber,
     filesystem::{
         page_cache::PageCache,
-        vfs::{fcntl::AtFlags, vcore::do_mkdir_at, ROOT_INODE},
+        vfs::{fcntl::AtFlags, vcore::do_mkdir_at},
     },
     libs::{
         casting::DowncastArc,
+        lazy_init::Lazy,
         rwlock::RwLock,
         spinlock::{SpinLock, SpinLockGuard},
     },
     mm::{fault::PageFaultMessage, VmFaultReason},
+    process::{
+        namespace::mnt::{MntNamespace, MountPropagation},
+        ProcessManager,
+    },
 };
 
 use super::{
@@ -31,11 +38,28 @@ use super::{
     IndexNode, InodeId, Magic, PollableInode, SuperBlock,
 };
 
+// MountId类型
+int_like!(MountId, usize);
+
+static MOUNT_ID_ALLOCATOR: SpinLock<IdAllocator> =
+    SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap());
+
+impl MountId {
+    fn alloc() -> Self {
+        let id = MOUNT_ID_ALLOCATOR.lock().alloc().unwrap();
+
+        MountId(id)
+    }
+
+    unsafe fn free(&mut self) {
+        MOUNT_ID_ALLOCATOR.lock().free(self.0);
+    }
+}
+
 const MOUNTFS_BLOCK_SIZE: u64 = 512;
 const MOUNTFS_MAX_NAMELEN: u64 = 64;
 /// @brief 挂载文件系统
 /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
-#[derive(Debug)]
 pub struct MountFS {
     // MountFS内部的文件系统
     inner_filesystem: Arc<dyn FileSystem>,
@@ -45,6 +69,18 @@ pub struct MountFS {
     self_mountpoint: Option<Arc<MountFSInode>>,
     /// 指向当前MountFS的弱引用
     self_ref: Weak<MountFS>,
+
+    namespace: Lazy<Weak<MntNamespace>>,
+    propagation: Arc<MountPropagation>,
+    mount_id: MountId,
+}
+
+impl Debug for MountFS {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("MountFS")
+            .field("mount_id", &self.mount_id)
+            .finish()
+    }
 }
 
 /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
@@ -63,13 +99,32 @@ impl MountFS {
     pub fn new(
         inner_filesystem: Arc<dyn FileSystem>,
         self_mountpoint: Option<Arc<MountFSInode>>,
+        propagation: Arc<MountPropagation>,
+        mnt_ns: Option<&Arc<MntNamespace>>,
     ) -> Arc<Self> {
-        return Arc::new_cyclic(|self_ref| MountFS {
+        let result = Arc::new_cyclic(|self_ref| MountFS {
             inner_filesystem,
             mountpoints: SpinLock::new(BTreeMap::new()),
             self_mountpoint,
             self_ref: self_ref.clone(),
+            namespace: Lazy::new(),
+            propagation,
+            mount_id: MountId::alloc(),
         });
+
+        if let Some(mnt_ns) = mnt_ns {
+            result.set_namespace(Arc::downgrade(mnt_ns));
+        }
+
+        result
+    }
+
+    pub fn propagation(&self) -> Arc<MountPropagation> {
+        self.propagation.clone()
+    }
+
+    pub fn set_namespace(&self, namespace: Weak<MntNamespace>) {
+        self.namespace.init(namespace);
     }
 
     /// @brief 用Arc指针包裹MountFS对象。
@@ -120,6 +175,15 @@ impl MountFS {
     }
 }
 
+impl Drop for MountFS {
+    fn drop(&mut self) {
+        // 释放MountId
+        unsafe {
+            self.mount_id.free();
+        }
+    }
+}
+
 impl MountFSInode {
     /// @brief 用Arc指针包裹MountFSInode对象。
     /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针
@@ -220,8 +284,9 @@ impl MountFSInode {
     fn do_absolute_path(&self) -> Result<String, SystemError> {
         let mut path_parts = Vec::new();
         let mut current = self.self_ref.upgrade().unwrap();
-
-        while current.metadata()?.inode_id != ROOT_INODE().metadata()?.inode_id {
+        let root_inode = ProcessManager::current_mntns().root_inode();
+        let inode_id = root_inode.metadata()?.inode_id;
+        while current.metadata()?.inode_id != inode_id {
             let name = current.dname()?;
             path_parts.push(name.0);
             current = current.do_parent()?;
@@ -459,15 +524,24 @@ impl IndexNode for MountFSInode {
             .downcast_arc::<MountFS>()
             .map(|it| it.inner_filesystem())
             .unwrap_or(fs);
-        let new_mount_fs = MountFS::new(to_mount_fs, Some(self.self_ref.upgrade().unwrap()));
+
+        let new_mount_fs = MountFS::new(
+            to_mount_fs,
+            Some(self.self_ref.upgrade().unwrap()),
+            MountPropagation::new_private(), // 暂时不支持传播,后续会补充完善挂载传播性
+            Some(&ProcessManager::current_mntns()),
+        );
+
         self.mount_fs
             .mountpoints
             .lock()
             .insert(metadata.inode_id, new_mount_fs.clone());
 
+        // todo: 这里也许不应该存储路径到MountList,而是应该存储inode的引用。因为同一个inner inode的路径在不同的mntns中可能是不一样的。
         let mount_path = self.absolute_path();
+        let mount_path = Arc::new(MountPath::from(mount_path?));
+        ProcessManager::current_mntns().add_mount(mount_path, new_mount_fs.clone())?;
 
-        MOUNT_LIST().insert(mount_path?, new_mount_fs.clone());
         return Ok(new_mount_fs);
     }
 
@@ -597,7 +671,7 @@ impl FileSystem for MountFS {
 /// assert_eq!(format!("{:?}", map), "{\"/\", \"/bin\", \"/dev\", \"/proc\", \"/sys\"}");
 /// // {"/", "/bin", "/dev", "/proc", "/sys"}
 /// ```
-#[derive(PartialEq, Eq, Debug)]
+#[derive(PartialEq, Eq, Debug, Hash)]
 pub struct MountPath(String);
 
 impl From<&str> for MountPath {
@@ -639,61 +713,45 @@ impl Ord for MountPath {
     }
 }
 
-// 维护一个挂载点的记录,以支持特定于文件系统的索引
-pub struct MountList(RwLock<BTreeMap<MountPath, Arc<MountFS>>>);
-// pub struct MountList(Option<Arc<MountListInner>>);
-static mut __MOUNTS_LIST: Option<Arc<MountList>> = None;
-
-/// # init_mountlist - 初始化挂载列表
-///
-/// 此函数用于初始化系统的挂载列表。挂载列表记录了系统中所有的文件系统挂载点及其属性。
-///
-/// ## 参数
-///
-/// - 无
-///
-/// ## 返回值
-///
-/// - 无
-#[inline(always)]
-pub fn init_mountlist() {
-    unsafe {
-        __MOUNTS_LIST = Some(Arc::new(MountList(RwLock::new(BTreeMap::new()))));
+impl MountPath {
+    pub fn as_str(&self) -> &str {
+        &self.0
     }
 }
 
-/// # MOUNT_LIST - 获取全局挂载列表
-///
-/// 该函数用于获取一个对全局挂载列表的引用。全局挂载列表是系统中所有挂载点的集合。
-///
-/// ## 返回值
-/// - &'static Arc<MountList>: 返回全局挂载列表的引用。
-#[inline(always)]
-#[allow(non_snake_case)]
-pub fn MOUNT_LIST() -> &'static Arc<MountList> {
-    unsafe {
-        return __MOUNTS_LIST.as_ref().unwrap();
-    }
+// 维护一个挂载点的记录,以支持特定于文件系统的索引
+pub struct MountList {
+    mounts: RwLock<HashMap<Arc<MountPath>, Arc<MountFS>>>,
 }
 
 impl MountList {
-    /// # insert - 将文件系统挂载点插入到挂载表中
+    /// # new - 创建新的MountList实例
     ///
-    /// 将一个新的文件系统挂载点插入到挂载表中。如果挂载点已经存在,则会更新对应的文件系统
+    /// 创建一个空的挂载点列表。
     ///
-    /// 此函数是线程安全的,因为它使用了RwLock来保证并发访问。
+    /// ## 返回值
     ///
-    /// ## 参数
+    /// - `MountList`: 新的挂载点列表实例
+    pub fn new() -> Arc<Self> {
+        Arc::new(MountList {
+            mounts: RwLock::new(HashMap::new()),
+        })
+    }
+
+    /// Inserts a filesystem mount point into the mount list.
     ///
-    /// - `path`: &str, 挂载点的路径。这个路径会被转换成`MountPath`类型。
-    /// - `fs`: Arc<MountFS>, 共享的文件系统实例。
+    /// This function adds a new filesystem mount point to the mount list. If a mount point
+    /// already exists at the specified path, it will be updated with the new filesystem.
     ///
-    /// ## 返回值
+    /// # Thread Safety
+    /// This function is thread-safe as it uses a RwLock to ensure safe concurrent access.
     ///
-    /// - 无
+    /// # Arguments
+    /// * `path` - The mount path where the filesystem will be mounted
+    /// * `fs` - The filesystem instance to be mounted at the specified path
     #[inline]
-    pub fn insert<T: AsRef<str>>(&self, path: T, fs: Arc<MountFS>) {
-        self.0.write().insert(MountPath::from(path.as_ref()), fs);
+    pub fn insert(&self, path: Arc<MountPath>, fs: Arc<MountFS>) {
+        self.mounts.write().insert(path, fs);
     }
 
     /// # get_mount_point - 获取挂载点的路径
@@ -715,11 +773,11 @@ impl MountList {
         &self,
         path: T,
     ) -> Option<(String, String, Arc<MountFS>)> {
-        self.0
+        self.mounts
             .upgradeable_read()
             .iter()
             .filter_map(|(key, fs)| {
-                let strkey = key.as_ref();
+                let strkey = key.as_str();
                 if let Some(rest) = path.as_ref().strip_prefix(strkey) {
                     return Some((strkey.to_string(), rest.to_string(), fs.clone()));
                 }
@@ -743,13 +801,13 @@ impl MountList {
     /// - `Option<Arc<MountFS>>`: 返回一个 `Arc<MountFS>` 类型的可选值,表示被移除的挂载点,如果挂载点不存在则返回 `None`。
     #[inline]
     pub fn remove<T: Into<MountPath>>(&self, path: T) -> Option<Arc<MountFS>> {
-        self.0.write().remove(&path.into())
+        self.mounts.write().remove(&path.into())
     }
 }
 
 impl Debug for MountList {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        f.debug_map().entries(MOUNT_LIST().0.read().iter()).finish()
+        f.debug_map().entries(self.mounts.read().iter()).finish()
     }
 }
 
@@ -791,7 +849,8 @@ pub fn do_mount_mkdir(
         mount_point,
         FileMode::from_bits_truncate(0o755),
     )?;
-    if let Some((_, rest, _fs)) = MOUNT_LIST().get_mount_point(mount_point) {
+    let result = ProcessManager::current_mntns().get_mount_point(mount_point);
+    if let Some((_, rest, _fs)) = result {
         if rest.is_empty() {
             return Err(SystemError::EBUSY);
         }

+ 3 - 2
kernel/src/filesystem/vfs/open.rs

@@ -7,7 +7,7 @@ use super::{
     file::{File, FileMode},
     syscall::{ModeType, OpenHow, OpenHowResolve},
     utils::{rsplit_path, user_path_at},
-    FileType, IndexNode, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES,
+    FileType, IndexNode, MAX_PATHLEN, VFS_MAX_FOLLOW_SYMLINK_TIMES,
 };
 use crate::{
     driver::base::block::SeekFrom, process::ProcessManager,
@@ -180,6 +180,7 @@ fn do_sys_openat2(
         },
     );
 
+    let root_inode = ProcessManager::current_mntns().root_inode();
     let inode: Arc<dyn IndexNode> = match inode {
         Ok(inode) => inode,
         Err(errno) => {
@@ -191,7 +192,7 @@ fn do_sys_openat2(
                 let (filename, parent_path) = rsplit_path(&path);
                 // 查找父目录
                 let parent_inode: Arc<dyn IndexNode> =
-                    ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
+                    root_inode.lookup(parent_path.unwrap_or("/"))?;
                 // 创建文件
                 let inode: Arc<dyn IndexNode> = parent_inode.create(
                     filename,

+ 19 - 15
kernel/src/filesystem/vfs/syscall/mod.rs

@@ -28,7 +28,7 @@ use super::{
     },
     utils::{rsplit_path, user_path_at},
     vcore::{do_mkdir_at, do_remove_dir, do_unlink_at},
-    FileType, IndexNode, SuperBlock, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES,
+    FileType, IndexNode, SuperBlock, MAX_PATHLEN, VFS_MAX_FOLLOW_SYMLINK_TIMES,
 };
 
 mod open_utils;
@@ -587,13 +587,15 @@ impl Syscall {
                 new_path = String::from("/");
             }
         }
-        let inode =
-            match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) {
-                Err(_) => {
-                    return Err(SystemError::ENOENT);
-                }
-                Ok(i) => i,
-            };
+
+        let root_inode = ProcessManager::current_mntns().root_inode();
+        let inode = match root_inode.lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES)
+        {
+            Err(_) => {
+                return Err(SystemError::ENOENT);
+            }
+            Ok(i) => i,
+        };
         let metadata = inode.metadata()?;
         if metadata.file_type == FileType::Dir {
             proc.basic_mut().set_cwd(new_path);
@@ -912,16 +914,17 @@ impl Syscall {
             return Err(SystemError::ENAMETOOLONG);
         }
 
+        let root_inode = ProcessManager::current_mntns().root_inode();
         //获取pcb,文件节点
         let pcb = ProcessManager::current_pcb();
         let (_old_inode_begin, old_remain_path) = user_path_at(&pcb, oldfd, &filename_from)?;
         let (_new_inode_begin, new_remain_path) = user_path_at(&pcb, newfd, &filename_to)?;
         //获取父目录
         let (old_filename, old_parent_path) = rsplit_path(&old_remain_path);
-        let old_parent_inode = ROOT_INODE()
+        let old_parent_inode = root_inode
             .lookup_follow_symlink(old_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
         let (new_filename, new_parent_path) = rsplit_path(&new_remain_path);
-        let new_parent_inode = ROOT_INODE()
+        let new_parent_inode = root_inode
             .lookup_follow_symlink(new_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
         old_parent_inode.move_to(old_filename, &new_parent_inode, new_filename)?;
         return Ok(0);
@@ -1177,9 +1180,11 @@ impl Syscall {
             .unwrap()
             .into_string()
             .map_err(|_| SystemError::EINVAL)?;
+
+        let root_inode = ProcessManager::current_mntns().root_inode();
         let pcb = ProcessManager::current_pcb();
         let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
-        let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
+        let inode = root_inode.lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
         let statfs = PosixStatfs::from(inode.fs().super_block());
         writer.copy_one_to_user(&statfs, 0)?;
         return Ok(0);
@@ -1252,9 +1257,8 @@ impl Syscall {
             .into_string()
             .map_err(|_| SystemError::EINVAL)?;
         let path = path.as_str().trim();
-
-        let inode: Result<Arc<dyn IndexNode>, SystemError> =
-            ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES);
+        let root_inode = ProcessManager::current_mntns().root_inode();
+        let inode = root_inode.lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES);
 
         if inode.is_ok() {
             return Err(SystemError::EEXIST);
@@ -1263,7 +1267,7 @@ impl Syscall {
         let (filename, parent_path) = rsplit_path(path);
 
         // 查找父目录
-        let parent_inode: Arc<dyn IndexNode> = ROOT_INODE()
+        let parent_inode: Arc<dyn IndexNode> = root_inode
             .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
         // 创建nod
         parent_inode.mknod(filename, mode, dev_t)?;

+ 4 - 3
kernel/src/filesystem/vfs/syscall/sys_mount.rs

@@ -3,8 +3,8 @@
 use crate::{
     arch::{interrupt::TrapFrame, syscall::nr::SYS_MOUNT},
     filesystem::vfs::{
-        fcntl::AtFlags, mount::MOUNT_LIST, produce_fs, utils::user_path_at, FileSystem, MountFS,
-        MAX_PATHLEN, VFS_MAX_FOLLOW_SYMLINK_TIMES,
+        fcntl::AtFlags, produce_fs, utils::user_path_at, FileSystem, MountFS, MAX_PATHLEN,
+        VFS_MAX_FOLLOW_SYMLINK_TIMES,
     },
     process::ProcessManager,
     syscall::{
@@ -127,7 +127,8 @@ pub fn do_mount(fs: Arc<dyn FileSystem>, mount_point: &str) -> Result<Arc<MountF
         mount_point,
     )?;
     let inode = current_node.lookup_follow_symlink(&rest_path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
-    if let Some((_, rest, _fs)) = MOUNT_LIST().get_mount_point(mount_point) {
+    let result = ProcessManager::current_mntns().get_mount_point(mount_point);
+    if let Some((_, rest, _fs)) = result {
         if rest.is_empty() {
             return Err(SystemError::EBUSY);
         }

+ 3 - 5
kernel/src/filesystem/vfs/syscall/sys_umount2.rs

@@ -2,9 +2,7 @@
 
 use crate::{
     arch::{interrupt::TrapFrame, syscall::nr::SYS_UMOUNT2},
-    filesystem::vfs::{
-        fcntl::AtFlags, mount::MOUNT_LIST, utils::user_path_at, MountFS, MAX_PATHLEN,
-    },
+    filesystem::vfs::{fcntl::AtFlags, utils::user_path_at, MountFS, MAX_PATHLEN},
     process::ProcessManager,
     syscall::{
         table::{FormattedSyscallParam, Syscall},
@@ -84,8 +82,8 @@ pub fn do_umount2(
 ) -> Result<Arc<MountFS>, SystemError> {
     let (work, rest) = user_path_at(&ProcessManager::current_pcb(), dirfd, target)?;
     let path = work.absolute_path()? + &rest;
-
-    if let Some(fs) = MOUNT_LIST().remove(path) {
+    let result = ProcessManager::current_mntns().remove_mount(&path);
+    if let Some(fs) = result {
         // Todo: 占用检测
         fs.umount()?;
         return Ok(fs);

+ 4 - 3
kernel/src/filesystem/vfs/utils.rs

@@ -5,9 +5,9 @@ use core::hash::Hash;
 use alloc::{string::String, sync::Arc};
 use system_error::SystemError;
 
-use crate::process::ProcessControlBlock;
+use crate::process::{ProcessControlBlock, ProcessManager};
 
-use super::{fcntl::AtFlags, FileType, IndexNode, ROOT_INODE};
+use super::{fcntl::AtFlags, FileType, IndexNode};
 
 /// @brief 切分路径字符串,返回最左侧那一级的目录名和剩余的部分。
 ///
@@ -42,7 +42,8 @@ pub fn user_path_at(
     dirfd: i32,
     path: &str,
 ) -> Result<(Arc<dyn IndexNode>, String), SystemError> {
-    let mut inode = ROOT_INODE();
+    let current_mntns = ProcessManager::current_mntns();
+    let mut inode = current_mntns.root_inode().clone();
     let ret_path;
     // 如果path不是绝对路径,则需要拼接
     if path.is_empty() || path.as_bytes()[0] != b'/' {

+ 16 - 34
kernel/src/filesystem/vfs/vcore.rs

@@ -11,17 +11,15 @@ use crate::{
         devfs::devfs_init,
         fat::fs::FATFileSystem,
         procfs::procfs_init,
-        ramfs::RamFS,
         sysfs::sysfs_init,
-        vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType},
+        vfs::{syscall::ModeType, AtomicInodeId, FileSystem, FileType, MountFS},
     },
     mm::truncate::truncate_inode_pages,
-    process::ProcessManager,
+    process::{namespace::mnt::mnt_namespace_init, ProcessManager},
 };
 
 use super::{
     file::FileMode,
-    mount::init_mountlist,
     stat::LookUpFlags,
     utils::{rsplit_path, user_path_at},
     IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
@@ -41,28 +39,10 @@ pub fn generate_inode_id() -> InodeId {
     return INO.fetch_add(InodeId::new(1), Ordering::SeqCst);
 }
 
-static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None;
-
-/// @brief 获取全局的根节点
-#[inline(always)]
-#[allow(non_snake_case)]
-pub fn ROOT_INODE() -> Arc<dyn IndexNode> {
-    unsafe {
-        return __ROOT_INODE.as_ref().unwrap().clone();
-    }
-}
-
 /// 初始化虚拟文件系统
 #[inline(never)]
 pub fn vfs_init() -> Result<(), SystemError> {
-    // 使用Ramfs作为默认的根文件系统
-    let ramfs = RamFS::new();
-    let mount_fs = MountFS::new(ramfs, None);
-    let root_inode = mount_fs.root_inode();
-    init_mountlist();
-    unsafe {
-        __ROOT_INODE = Some(root_inode.clone());
-    }
+    mnt_namespace_init();
 
     procfs_init().expect("Failed to initialize procfs");
 
@@ -70,7 +50,10 @@ pub fn vfs_init() -> Result<(), SystemError> {
 
     sysfs_init().expect("Failed to initialize sysfs");
 
-    let root_entries = ROOT_INODE().list().expect("VFS init failed");
+    let root_entries = ProcessManager::current_mntns()
+        .root_inode()
+        .list()
+        .expect("VFS init failed");
     if !root_entries.is_empty() {
         info!("Successfully initialized VFS!");
     }
@@ -82,35 +65,34 @@ pub fn vfs_init() -> Result<(), SystemError> {
 fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> {
     info!("VFS: Migrating filesystems...");
 
-    let new_fs = MountFS::new(new_fs, None);
+    let current_mntns = ProcessManager::current_mntns();
+    let old_root_inode = current_mntns.root_inode();
+    let old_mntfs = current_mntns.root_mntfs().clone();
+    let new_fs = MountFS::new(new_fs, None, old_mntfs.propagation(), Some(&current_mntns));
+
     // 获取新的根文件系统的根节点的引用
     let new_root_inode = new_fs.root_inode();
-
     // ==== 在这里获取要被迁移的文件系统的inode并迁移 ===
     // 因为是换根所以路径没有变化
     // 不需要重新注册挂载目录
     new_root_inode
         .mkdir("proc", ModeType::from_bits_truncate(0o755))
         .expect("Unable to create /proc")
-        .mount_from(ROOT_INODE().find("proc").expect("proc not mounted!"))
+        .mount_from(old_root_inode.find("proc").expect("proc not mounted!"))
         .expect("Failed to migrate filesystem of proc");
     new_root_inode
         .mkdir("dev", ModeType::from_bits_truncate(0o755))
         .expect("Unable to create /dev")
-        .mount_from(ROOT_INODE().find("dev").expect("dev not mounted!"))
+        .mount_from(old_root_inode.find("dev").expect("dev not mounted!"))
         .expect("Failed to migrate filesystem of dev");
     new_root_inode
         .mkdir("sys", ModeType::from_bits_truncate(0o755))
         .expect("Unable to create /sys")
-        .mount_from(ROOT_INODE().find("sys").expect("sys not mounted!"))
+        .mount_from(old_root_inode.find("sys").expect("sys not mounted!"))
         .expect("Failed to migrate filesystem of sys");
 
     unsafe {
-        // drop旧的Root inode
-        let old_root_inode = __ROOT_INODE.take().unwrap();
-        // 设置全局的新的ROOT Inode
-        __ROOT_INODE = Some(new_root_inode.clone());
-        drop(old_root_inode);
+        current_mntns.force_change_root_mountfs(new_fs);
     }
 
     info!("VFS: Migrate filesystems done!");

+ 257 - 0
kernel/src/process/namespace/mnt.rs

@@ -0,0 +1,257 @@
+use crate::{
+    filesystem::vfs::{
+        mount::{MountList, MountPath},
+        FileSystem, IndexNode, MountFS,
+    },
+    libs::{once::Once, spinlock::SpinLock},
+    process::{fork::CloneFlags, namespace::NamespaceType, ProcessManager},
+};
+use alloc::string::String;
+use alloc::sync::{Arc, Weak};
+use alloc::vec::Vec;
+
+use system_error::SystemError;
+
+use super::{nsproxy::NsCommon, user_namespace::UserNamespace, NamespaceOps};
+
+static mut INIT_MNT_NAMESPACE: Option<Arc<MntNamespace>> = None;
+
+/// 初始化root mount namespace
+pub fn mnt_namespace_init() {
+    static ONCE: Once = Once::new();
+    ONCE.call_once(|| unsafe {
+        INIT_MNT_NAMESPACE = Some(MntNamespace::new_root());
+    });
+}
+
+int_like!(MntSharedGroupId, usize);
+
+/// 获取全局的根挂载namespace
+pub fn root_mnt_namespace() -> Arc<MntNamespace> {
+    unsafe {
+        INIT_MNT_NAMESPACE
+            .as_ref()
+            .expect("Mount namespace not initialized")
+            .clone()
+    }
+}
+
+pub struct MntNamespace {
+    ns_common: NsCommon,
+    self_ref: Weak<MntNamespace>,
+    /// 父namespace的弱引用
+    _parent: Option<Weak<MntNamespace>>,
+    _user_ns: Arc<UserNamespace>,
+    root_mountfs: Arc<MountFS>,
+    inner: SpinLock<InnerMntNamespace>,
+}
+
+pub struct InnerMntNamespace {
+    _dead: bool,
+    mount_list: Arc<MountList>,
+}
+
+impl NamespaceOps for MntNamespace {
+    fn ns_common(&self) -> &NsCommon {
+        &self.ns_common
+    }
+}
+
+impl MntNamespace {
+    fn new_root() -> Arc<Self> {
+        let mount_list = MountList::new();
+
+        let ramfs = crate::filesystem::ramfs::RamFS::new();
+        let ramfs = MountFS::new(ramfs, None, MountPropagation::new_private(), None);
+
+        let result = Arc::new_cyclic(|self_ref| Self {
+            ns_common: NsCommon::new(0, NamespaceType::Mount),
+            self_ref: self_ref.clone(),
+            _parent: None,
+            _user_ns: super::user_namespace::INIT_USER_NAMESPACE.clone(),
+            root_mountfs: ramfs.clone(),
+            inner: SpinLock::new(InnerMntNamespace {
+                mount_list,
+                _dead: false,
+            }),
+        });
+        ramfs.set_namespace(Arc::downgrade(&result));
+
+        return result;
+    }
+
+    /// 强制替换本MountNamespace的根挂载文件系统
+    ///
+    /// 本方法仅供dragonos初始化时使用
+    pub unsafe fn force_change_root_mountfs(&self, new_root: Arc<MountFS>) {
+        let ptr = self as *const Self as *mut Self;
+        let self_mut = (ptr).as_mut().unwrap();
+        self_mut.root_mountfs = new_root;
+    }
+
+    /// Creates a copy of the mount namespace for process cloning.
+    ///
+    /// This function is called during process creation to determine whether to create
+    /// a new mount namespace or share the existing one based on the clone flags.
+    ///
+    /// # Arguments
+    /// * `clone_flags` - Flags that control namespace creation behavior
+    /// * `user_ns` - The user namespace to associate with the new mount namespace
+    ///
+    /// # Returns
+    /// * `Ok(Arc<MntNamespace>)` - The appropriate mount namespace for the new process
+    /// * `Err(SystemError)` - If namespace creation fails
+    ///
+    /// # Behavior
+    /// - If `CLONE_NEWNS` is not set, returns the current mount namespace
+    /// - If `CLONE_NEWNS` is set, creates a new mount namespace (currently unimplemented)
+    pub fn copy_mnt_ns(
+        &self,
+        clone_flags: &CloneFlags,
+        _user_ns: Arc<UserNamespace>,
+    ) -> Result<Arc<MntNamespace>, SystemError> {
+        if !clone_flags.contains(CloneFlags::CLONE_NEWNS) {
+            // Return the current mount namespace if CLONE_NEWNS is not set
+            return Ok(self.self_ref.upgrade().unwrap());
+        }
+
+        todo!("Implement MntNamespace::copy_mnt_ns");
+    }
+
+    pub fn root_mntfs(&self) -> &Arc<MountFS> {
+        &self.root_mountfs
+    }
+
+    /// 获取该挂载命名空间的根inode
+    pub fn root_inode(&self) -> Arc<dyn IndexNode> {
+        self.root_mountfs.root_inode()
+    }
+
+    pub fn add_mount(
+        &self,
+        mount_path: Arc<MountPath>,
+        mntfs: Arc<MountFS>,
+    ) -> Result<(), SystemError> {
+        self.inner.lock().mount_list.insert(mount_path, mntfs);
+        return Ok(());
+    }
+
+    pub fn remove_mount(&self, mount_path: &str) -> Option<Arc<MountFS>> {
+        return self.inner.lock().mount_list.remove(mount_path);
+    }
+
+    pub fn get_mount_point(&self, mount_point: &str) -> Option<(String, String, Arc<MountFS>)> {
+        self.inner.lock().mount_list.get_mount_point(mount_point)
+    }
+}
+
+/// Manages mount propagation relationships and state for mount points.
+///
+/// This struct tracks how mount events (mount, unmount, remount) propagate between
+/// mount points according to their propagation types. It maintains relationships
+/// between shared mounts, slave mounts, and their propagation groups.
+#[derive(Clone)]
+pub struct MountPropagation {
+    /// The type of propagation behavior for this mount
+    pub prop_type: PropagationType,
+    /// Group ID for shared mounts that can propagate events to each other
+    pub shared_group_id: Option<MntSharedGroupId>,
+    /// Reference to the master mount for slave mounts
+    pub master: Option<Weak<MountFS>>,
+    /// List of slave mounts that receive events from this mount
+    pub slaves: Vec<Weak<MountFS>>,
+    /// Peer group ID for complex propagation relationships
+    pub peer_group_id: Option<MntSharedGroupId>,
+    /// Counter to prevent infinite loops during event propagation
+    pub propagation_count: u32,
+}
+
+/// Defines the propagation type for mount points, controlling how mount events are shared.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum PropagationType {
+    /// Mount events do not propagate to or from this mount
+    Private,
+    /// Mount events propagate bidirectionally with other mounts in the same peer group
+    Shared,
+    /// Mount events propagate from the master mount to this slave mount
+    Slave,
+    /// Mount cannot be bind mounted and events do not propagate
+    Unbindable,
+}
+
+impl MountPropagation {
+    pub fn new_private() -> Arc<Self> {
+        Arc::new(Self {
+            prop_type: PropagationType::Private,
+            shared_group_id: None,
+            master: None,
+            slaves: Vec::new(),
+            peer_group_id: None,
+            propagation_count: 0,
+        })
+    }
+
+    pub fn new_shared(group_id: MntSharedGroupId) -> Arc<Self> {
+        Arc::new(Self {
+            prop_type: PropagationType::Shared,
+            shared_group_id: Some(group_id),
+            master: None,
+            slaves: Vec::new(),
+            peer_group_id: Some(group_id),
+            propagation_count: 0,
+        })
+    }
+
+    pub fn new_slave(master: Weak<MountFS>) -> Arc<Self> {
+        Arc::new(Self {
+            prop_type: PropagationType::Slave,
+            shared_group_id: None,
+            master: Some(master),
+            slaves: Vec::new(),
+            peer_group_id: None,
+            propagation_count: 0,
+        })
+    }
+
+    pub fn new_unbindable() -> Arc<Self> {
+        Arc::new(Self {
+            prop_type: PropagationType::Unbindable,
+            shared_group_id: None,
+            master: None,
+            slaves: Vec::new(),
+            peer_group_id: None,
+            propagation_count: 0,
+        })
+    }
+
+    /// 添加一个从属挂载
+    pub fn add_slave(&mut self, slave: Weak<MountFS>) {
+        self.slaves.push(slave);
+    }
+
+    /// 移除一个从属挂载
+    pub fn remove_slave(&mut self, slave: &Weak<MountFS>) {
+        self.slaves.retain(|s| !Weak::ptr_eq(s, slave));
+    }
+
+    /// 清理无效的从属挂载引用
+    pub fn cleanup_stale_slaves(&mut self) {
+        self.slaves.retain(|s| s.upgrade().is_some());
+    }
+
+    /// 重置传播计数器
+    pub fn reset_propagation_count(&mut self) {
+        self.propagation_count = 0;
+    }
+}
+
+impl ProcessManager {
+    /// 获取当前进程的挂载namespace
+    pub fn current_mntns() -> Arc<MntNamespace> {
+        if Self::initialized() {
+            ProcessManager::current_pcb().nsproxy.read().mnt_ns.clone()
+        } else {
+            root_mnt_namespace()
+        }
+    }
+}

+ 1 - 0
kernel/src/process/namespace/mod.rs

@@ -1,3 +1,4 @@
+pub mod mnt;
 pub mod nsproxy;
 pub mod pid_namespace;
 pub mod user_namespace;

+ 19 - 5
kernel/src/process/namespace/nsproxy.rs

@@ -1,7 +1,11 @@
 use alloc::sync::Arc;
 use system_error::SystemError;
 
-use crate::process::{fork::CloneFlags, ProcessControlBlock, ProcessManager};
+use crate::process::{
+    fork::CloneFlags,
+    namespace::mnt::{root_mnt_namespace, MntNamespace},
+    ProcessControlBlock, ProcessManager,
+};
 use core::{fmt::Debug, intrinsics::likely};
 
 use super::{pid_namespace::PidNamespace, user_namespace::UserNamespace, NamespaceType};
@@ -17,8 +21,9 @@ use super::{pid_namespace::PidNamespace, user_namespace::UserNamespace, Namespac
 pub struct NsProxy {
     /// PID namespace(用于子进程)
     pub pid_ns_for_children: Arc<PidNamespace>,
+    /// mount namespace(挂载命名空间)
+    pub mnt_ns: Arc<MntNamespace>,
     // 其他namespace(为未来扩展预留)
-    // pub mount_ns: Option<Arc<MountNamespace>>,
     // pub user_ns: Option<Arc<UserNamespace>>,
     // pub net_ns: Option<Arc<NetNamespace>>,
     // pub ipc_ns: Option<Arc<IpcNamespace>>,
@@ -37,8 +42,10 @@ impl NsProxy {
     /// 创建root namespace代理
     pub fn new_root() -> Arc<Self> {
         let root_pid_ns = super::pid_namespace::INIT_PID_NAMESPACE.clone();
+        let root_mnt_ns = root_mnt_namespace();
         Arc::new(Self {
             pid_ns_for_children: root_pid_ns,
+            mnt_ns: root_mnt_ns,
         })
     }
 
@@ -46,6 +53,11 @@ impl NsProxy {
     pub fn pid_namespace_for_children(&self) -> &Arc<PidNamespace> {
         &self.pid_ns_for_children
     }
+
+    /// 获取mount namespace
+    pub fn mnt_namespace(&self) -> &Arc<MntNamespace> {
+        &self.mnt_ns
+    }
 }
 
 impl ProcessManager {
@@ -116,13 +128,15 @@ fn create_new_namespaces(
     pcb: &Arc<ProcessControlBlock>,
     user_ns: Arc<UserNamespace>,
 ) -> Result<Arc<NsProxy>, SystemError> {
-    let pid_ns_for_children = pcb
-        .nsproxy()
+    let nsproxy = pcb.nsproxy();
+    let pid_ns_for_children = nsproxy
         .pid_ns_for_children
-        .copy_pid_ns(clone_flags, user_ns)?;
+        .copy_pid_ns(clone_flags, user_ns.clone())?;
 
+    let mnt_ns = nsproxy.mnt_ns.copy_mnt_ns(clone_flags, user_ns)?;
     let result = NsProxy {
         pid_ns_for_children,
+        mnt_ns,
     };
 
     let result = Arc::new(result);

+ 3 - 5
kernel/src/process/stdio.rs

@@ -2,10 +2,7 @@ use system_error::SystemError;
 
 use crate::{
     driver::tty::virtual_terminal::vc_manager,
-    filesystem::vfs::{
-        file::{File, FileMode},
-        ROOT_INODE,
-    },
+    filesystem::vfs::file::{File, FileMode},
     process::{ProcessManager, RawPid},
 };
 
@@ -20,7 +17,8 @@ pub fn stdio_init() -> Result<(), SystemError> {
             .current_vc_tty_name()
             .expect("Init stdio: can't get tty name")
     );
-    let tty_inode = ROOT_INODE()
+    let root_inode = ProcessManager::current_mntns().root_inode();
+    let tty_inode = root_inode
         .lookup(&tty_path)
         .unwrap_or_else(|_| panic!("Init stdio: can't find {}", tty_path));