use alloc::{borrow::Cow, sync::Arc};
use ax_fs_ng::MountNamespace as FsMountNamespace;
use axpoll::{IoEvents, Pollable};
use linux_raw_sys::general::{
CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUSER,
CLONE_NEWUTS,
};
use super::FileLike;
use crate::{
StarryResult,
namespace::{
CgroupNamespace, IpcNamespace, MntNamespace as ProxyMntNamespace, NetNamespace,
UserNamespace, UtNamespace,
},
sync::IrqMutex,
};
pub enum NsFd {
Uts(Arc<IrqMutex<UtNamespace>>),
Ipc(Arc<IrqMutex<IpcNamespace>>),
Mnt {
ns: Arc<IrqMutex<ProxyMntNamespace>>,
fs_ns: Arc<FsMountNamespace>,
},
Pid(crate::namespace::PidNamespaceRef),
Net(Arc<IrqMutex<NetNamespace>>),
User(Arc<IrqMutex<UserNamespace>>),
Cgroup(Arc<IrqMutex<CgroupNamespace>>),
}
impl NsFd {
pub fn ns_type(&self) -> u32 {
match self {
NsFd::Uts(_) => CLONE_NEWUTS,
NsFd::Ipc(_) => CLONE_NEWIPC,
NsFd::Mnt { .. } => CLONE_NEWNS,
NsFd::Pid(_) => CLONE_NEWPID,
NsFd::Net(_) => CLONE_NEWNET,
NsFd::User(_) => CLONE_NEWUSER,
NsFd::Cgroup(_) => CLONE_NEWCGROUP,
}
}
}
impl FileLike for NsFd {
fn path(&self) -> Cow<'_, str> {
match self {
NsFd::Uts(_) => "anon_inode:[uts_ns]".into(),
NsFd::Ipc(_) => "anon_inode:[ipc_ns]".into(),
NsFd::Mnt { .. } => "anon_inode:[mnt_ns]".into(),
NsFd::Pid(_) => "anon_inode:[pid_ns]".into(),
NsFd::Net(_) => "anon_inode:[net_ns]".into(),
NsFd::User(_) => "anon_inode:[user_ns]".into(),
NsFd::Cgroup(_) => "anon_inode:[cgroup_ns]".into(),
}
}
fn stat(&self) -> StarryResult<super::Kstat> {
let ino = match self {
NsFd::Uts(ns) => ns.lock().id,
NsFd::Ipc(ns) => ns.lock().ns_id,
NsFd::Mnt { ns, .. } => ns.lock().id(),
NsFd::Pid(ns) => ns.id().get(),
NsFd::Net(ns) => ns.lock().ns_id,
NsFd::User(ns) => ns.lock().id,
NsFd::Cgroup(ns) => ns.lock().id(),
};
Ok(super::Kstat {
ino,
mode: 0o100_444, nlink: 1,
blksize: 4096,
..super::Kstat::default()
})
}
}
impl Pollable for NsFd {
fn poll(&self) -> IoEvents {
IoEvents::empty()
}
unsafe fn register_shared(
&self,
_sink: &mut dyn axpoll::SharedRegistrationSink,
_events: IoEvents,
) {
}
}