Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(namespace) feat some namespace bugs #1033

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kernel/src/init/initial_kthread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ fn run_init_process(
trap_frame: &mut TrapFrame,
) -> Result<(), SystemError> {
compiler_fence(Ordering::SeqCst);
ProcessManager::current_pcb().set_nsproxy(NsProxy::new()); // 初始化init进程的namespace
ProcessManager::current_pcb().set_nsproxy(NsProxy::default()); // 初始化init进程的namespace
let path = proc_init_info.proc_name.to_str().unwrap();

Syscall::do_execve(
Expand Down
113 changes: 40 additions & 73 deletions kernel/src/namespaces/mnt_namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ use alloc::sync::Arc;
use system_error::SystemError;

use super::namespace::Namespace;
use super::namespace::NsOperations;
use super::ucount::Ucount::MntNamespaces;
use super::{namespace::NsCommon, ucount::UCounts, user_namespace::UserNamespace};
use crate::container_of;
use super::{ucount::UCounts, user_namespace::UserNamespace};
use crate::filesystem::vfs::mount::MountFSInode;
use crate::filesystem::vfs::IndexNode;
use crate::filesystem::vfs::InodeId;
Expand All @@ -26,22 +24,20 @@ use crate::process::fork::CloneFlags;
use crate::process::ProcessManager;
use crate::syscall::Syscall;
#[allow(dead_code)]
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct MntNamespace {
/// namespace 共有的部分
ns_common: Arc<NsCommon>,
/// 关联的用户名字空间
user_ns: Arc<UserNamespace>,
/// 资源计数器
ucounts: Arc<UCounts>,
/// 根文件系统
root: Option<Arc<MountFS>>,
/// 红黑树用于挂载所有挂载点
mounts: RBTree<InodeId, MountFSInode>,
mounts: Arc<RBTree<InodeId, MountFSInode>>,
/// 等待队列
poll: WaitQueue,
poll: Arc<WaitQueue>,
/// 挂载序列号
seq: AtomicU64,
seq: Arc<AtomicU64>,
/// 挂载点的数量
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么每个成员变量都是Arc<>?这个访存效率低并且浪费内存。直接一个Arc<MntNamespace>会不会好些。
并且,mounts字段还有poll字段,你确定你测试过能用????这个一眼看过去就知道跑不了。

nr_mounts: u32,
/// 待处理的挂载点
Expand All @@ -50,7 +46,16 @@ pub struct MntNamespace {

impl Default for MntNamespace {
fn default() -> Self {
Self::new()
Self {
user_ns: Arc::new(UserNamespace::default()),
ucounts: Arc::new(UCounts::default()),
root: None,
mounts: Arc::new(RBTree::new()),
poll: Arc::new(WaitQueue::default()),
seq: Arc::new(AtomicU64::new(0)),
nr_mounts: 0,
pending_mounts: 0,
}
}
}

Expand All @@ -69,18 +74,15 @@ pub struct FsStruct {
}
impl Default for FsStruct {
fn default() -> Self {
Self::new()
}
}

impl FsStruct {
pub fn new() -> Self {
Self {
umask: 0o22,
root: ROOT_INODE(),
pwd: ROOT_INODE(),
}
}
}

impl FsStruct {
pub fn set_root(&mut self, inode: Arc<dyn IndexNode>) {
self.root = inode;
}
Expand All @@ -90,72 +92,41 @@ impl FsStruct {
}

impl Namespace for MntNamespace {
fn ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self> {
let ns_common_ptr = Arc::as_ptr(&ns_common);
container_of!(ns_common_ptr, MntNamespace, ns_common)
fn name(&self) -> String {
"mnt".to_string()
}
}

impl MntNsOperations {
pub fn new(name: String) -> Self {
Self {
name,
clone_flags: CloneFlags::CLONE_NEWNS,
}
fn get(&self, pid: crate::process::Pid) -> Option<Arc<dyn Namespace>> {
ProcessManager::find(pid)
.map(|pcb| pcb.get_nsproxy().read().mnt_namespace.clone() as Arc<dyn Namespace>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_nsproxy方法改名为nsproxy。这样比较符合rust的命名规范。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot from 2024-11-18 09-45-30

我是这两个一起设计的 get set

}
}

impl NsOperations for MntNsOperations {
fn get(&self, pid: crate::process::Pid) -> Option<Arc<NsCommon>> {
let pcb = ProcessManager::find(pid);
pcb.map(|pcb| pcb.get_nsproxy().read().mnt_namespace.ns_common.clone())
fn clone_flags(&self) -> CloneFlags {
CloneFlags::CLONE_NEWNS
}
// 不存在这个方法
fn get_parent(&self, _ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError> {
unreachable!()
}
fn install(
&self,
nsset: &mut super::NsSet,
ns_common: Arc<NsCommon>,
) -> Result<(), SystemError> {

fn put(&self) {}

fn install(&self, nsset: &mut super::NsSet) -> Result<(), SystemError> {
let nsproxy = &mut nsset.nsproxy;
let mnt_ns = MntNamespace::ns_common_to_ns(ns_common);
if mnt_ns.is_anon_ns() {
if self.is_anon_ns() {
return Err(SystemError::EINVAL);
}
nsproxy.mnt_namespace = mnt_ns;
nsproxy.mnt_namespace = Arc::new(self.clone());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里指向的根本就不是当前的namespace了啊。
你可能需要搜下我们代码里面的self_ref. 并且你还需要了解Arc指针跟Weak指针。因为类似这种写法就是错误的:
q9MHRqX0XQ

怎么能child存储指向父级的Arc呢?这显然是不正确的。


nsset.fs.lock().set_pwd(ROOT_INODE());
nsset.fs.lock().set_root(ROOT_INODE());
Ok(())
}
fn owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace> {
let mnt_ns = MntNamespace::ns_common_to_ns(ns_common);
mnt_ns.user_ns.clone()

fn owner(&self) -> Arc<UserNamespace> {
self.user_ns.clone()
}
fn put(&self, ns_common: Arc<NsCommon>) {
let pid_ns = MntNamespace::ns_common_to_ns(ns_common);
// 不存在这个方法
fn get_parent(&self) -> Result<Arc<dyn Namespace>, SystemError> {
unreachable!()
}
}
impl MntNamespace {
pub fn new() -> Self {
let ns_common = Arc::new(NsCommon::new(Box::new(MntNsOperations::new(
"mnt".to_string(),
))));

Self {
ns_common,
user_ns: Arc::new(UserNamespace::new()),
ucounts: Arc::new(UCounts::new()),
root: None,
mounts: RBTree::new(),
poll: WaitQueue::default(),
seq: AtomicU64::new(0),
nr_mounts: 0,
pending_mounts: 0,
}
}
/// anon 用来判断是否是匿名的.匿名函数的问题还需要考虑
pub fn create_mnt_namespace(
&self,
Expand All @@ -167,20 +138,16 @@ impl MntNamespace {
return Err(SystemError::ENOSPC);
}
let ucounts = ucounts.unwrap();
let ns_common = Arc::new(NsCommon::new(Box::new(MntNsOperations::new(
"mnt".to_string(),
))));
let seq = AtomicU64::new(0);
let seq = Arc::new(AtomicU64::new(0));
if !anon {
seq.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
}
Ok(Self {
ns_common,
user_ns,
ucounts,
root: None,
mounts: RBTree::new(),
poll: WaitQueue::default(),
mounts: Arc::new(RBTree::new()),
poll: Arc::new(WaitQueue::default()),
seq,
nr_mounts: 0,
pending_mounts: 0,
Expand Down
30 changes: 7 additions & 23 deletions kernel/src/namespaces/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,14 @@ pub struct NsProxy {
}
impl Default for NsProxy {
fn default() -> Self {
Self::new()
Self {
pid_namespace: Arc::new(PidNamespace::default()),
mnt_namespace: Arc::new(MntNamespace::default()),
}
}
}

impl NsProxy {
pub fn new() -> Self {
Self {
pid_namespace: Arc::new(PidNamespace::new()),
mnt_namespace: Arc::new(MntNamespace::new()),
}
}
pub fn set_pid_namespace(&mut self, new_pid_ns: Arc<PidNamespace>) {
self.pid_namespace = new_pid_ns;
}
Expand All @@ -55,10 +52,10 @@ pub fn create_new_namespaces(
pcb: &Arc<ProcessControlBlock>,
user_ns: Arc<UserNamespace>,
) -> Result<NsProxy, SystemError> {
let mut nsproxy = NsProxy::new();
let mut nsproxy = NsProxy::default();
// pid_namespace
let new_pid_ns = if (clone_flags & CloneFlags::CLONE_NEWPID.bits()) != 0 {
Arc::new(PidNamespace::new().create_pid_namespace(
Arc::new(PidNamespace::default().create_pid_namespace(
pcb.get_nsproxy().read().pid_namespace.clone(),
user_ns.clone(),
)?)
Expand All @@ -69,24 +66,11 @@ pub fn create_new_namespaces(

// mnt_namespace
let new_mnt_ns = if clone_flags & CloneFlags::CLONE_NEWNS.bits() != 0 {
Arc::new(MntNamespace::new().create_mnt_namespace(user_ns.clone(), false)?)
Arc::new(MntNamespace::default().create_mnt_namespace(user_ns.clone(), false)?)
} else {
pcb.get_nsproxy().read().mnt_namespace.clone()
};
nsproxy.set_mnt_namespace(new_mnt_ns);

Ok(nsproxy)
}

#[macro_export]
macro_rules! container_of {
($ptr:expr, $struct:path, $field:ident) => {
unsafe {
let dummy = core::mem::MaybeUninit::<$struct>::uninit();
let dummy_ptr = dummy.as_ptr();
let field_ptr = &(*dummy_ptr).$field as *const _ as usize;
let offset = field_ptr - dummy_ptr as usize;
Arc::from_raw(($ptr as *const u8).wrapping_sub(offset) as *mut $struct)
}
};
}
36 changes: 10 additions & 26 deletions kernel/src/namespaces/namespace.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(dead_code, unused_variables, unused_imports)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删掉全局的这种lint

use alloc::string::String;
use core::fmt::Debug;

use crate::filesystem::procfs::ProcFSInode;
Expand All @@ -12,30 +13,17 @@ use system_error::SystemError;

// 目前无credit功能,采用全局静态的user_namespace
lazy_static! {
pub static ref USER_NS: Arc<UserNamespace> = Arc::new(UserNamespace::new());
pub static ref USER_NS: Arc<UserNamespace> = Arc::new(UserNamespace::default());
}
use super::{create_new_namespaces, NsProxy, NsSet};
pub trait NsOperations: Send + Sync + Debug {
fn get(&self, pid: Pid) -> Option<Arc<NsCommon>>;
fn put(&self, ns_common: Arc<NsCommon>);
fn install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError>;
fn owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace>;
fn get_parent(&self, ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError>;
}
#[derive(Debug)]
pub struct NsCommon {
ops: Box<dyn NsOperations>,
stashed: Arc<dyn IndexNode>,
}

impl NsCommon {
pub fn new(ops: Box<dyn NsOperations>) -> Self {
let inode = ROOT_INODE().find("proc").unwrap_or_else(|_| ROOT_INODE());
Self {
ops,
stashed: inode,
}
}
pub trait Namespace: Send + Sync + Debug {
fn name(&self) -> String;
fn clone_flags(&self) -> CloneFlags;
fn get(&self, pid: Pid) -> Option<Arc<dyn Namespace>>;
fn put(&self);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不需要put方法吧

fn install(&self, nsset: &mut NsSet) -> Result<(), SystemError>;
fn owner(&self) -> Arc<UserNamespace>;
fn get_parent(&self) -> Result<Arc<dyn Namespace>, SystemError>;
}

pub enum NsType {
Expand All @@ -49,10 +37,6 @@ pub enum NsType {
Time,
}

pub trait Namespace {
fn ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self>;
}

pub fn check_unshare_flags(unshare_flags: u64) -> Result<usize, SystemError> {
let valid_flags = CloneFlags::CLONE_THREAD
| CloneFlags::CLONE_FS
Expand Down
Loading
Loading