|
@@ -14,7 +14,7 @@ use system_error::SystemError;
|
|
use crate::{
|
|
use crate::{
|
|
arch::mm::LockedFrameAllocator,
|
|
arch::mm::LockedFrameAllocator,
|
|
driver::base::device::device_number::DeviceNumber,
|
|
driver::base::device::device_number::DeviceNumber,
|
|
- filesystem::vfs::{vcore::generate_inode_id, FileType},
|
|
|
|
|
|
+ filesystem::vfs::{mount::MountFlags, vcore::generate_inode_id, FileType},
|
|
libs::{
|
|
libs::{
|
|
once::Once,
|
|
once::Once,
|
|
rwlock::RwLock,
|
|
rwlock::RwLock,
|
|
@@ -34,11 +34,12 @@ use super::vfs::{
|
|
|
|
|
|
pub mod kmsg;
|
|
pub mod kmsg;
|
|
pub mod log;
|
|
pub mod log;
|
|
|
|
+mod proc_mounts;
|
|
mod syscall;
|
|
mod syscall;
|
|
|
|
|
|
/// @brief 进程文件类型
|
|
/// @brief 进程文件类型
|
|
/// @usage 用于定义进程文件夹下的各类文件类型
|
|
/// @usage 用于定义进程文件夹下的各类文件类型
|
|
-#[derive(Debug)]
|
|
|
|
|
|
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
#[repr(u8)]
|
|
#[repr(u8)]
|
|
pub enum ProcFileType {
|
|
pub enum ProcFileType {
|
|
///展示进程状态信息
|
|
///展示进程状态信息
|
|
@@ -49,6 +50,11 @@ pub enum ProcFileType {
|
|
ProcKmsg = 2,
|
|
ProcKmsg = 2,
|
|
/// 可执行路径
|
|
/// 可执行路径
|
|
ProcExe = 3,
|
|
ProcExe = 3,
|
|
|
|
+ /// /proc/mounts
|
|
|
|
+ ProcSelf = 4,
|
|
|
|
+ ProcFdDir = 5,
|
|
|
|
+ ProcFdFile = 6,
|
|
|
|
+ ProcMounts = 7,
|
|
//todo: 其他文件类型
|
|
//todo: 其他文件类型
|
|
///默认文件类型
|
|
///默认文件类型
|
|
Default,
|
|
Default,
|
|
@@ -61,19 +67,105 @@ impl From<u8> for ProcFileType {
|
|
1 => ProcFileType::ProcMeminfo,
|
|
1 => ProcFileType::ProcMeminfo,
|
|
2 => ProcFileType::ProcKmsg,
|
|
2 => ProcFileType::ProcKmsg,
|
|
3 => ProcFileType::ProcExe,
|
|
3 => ProcFileType::ProcExe,
|
|
|
|
+ 4 => ProcFileType::ProcSelf,
|
|
|
|
+ 5 => ProcFileType::ProcFdDir,
|
|
|
|
+ 6 => ProcFileType::ProcFdFile,
|
|
|
|
+ 7 => ProcFileType::ProcMounts,
|
|
_ => ProcFileType::Default,
|
|
_ => ProcFileType::Default,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+/// @brief 创建 ProcFS 文件的参数结构体
|
|
|
|
+#[derive(Debug, Clone)]
|
|
|
|
+pub struct ProcFileCreationParams<'a> {
|
|
|
|
+ pub parent: Arc<dyn IndexNode>,
|
|
|
|
+ pub name: &'a str,
|
|
|
|
+ pub file_type: FileType,
|
|
|
|
+ pub mode: ModeType,
|
|
|
|
+ pub pid: Option<RawPid>,
|
|
|
|
+ pub ftype: ProcFileType,
|
|
|
|
+ pub data: Option<&'a str>,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl<'a> ProcFileCreationParams<'a> {
|
|
|
|
+ pub fn builder() -> ProcFileCreationParamsBuilder<'a> {
|
|
|
|
+ ProcFileCreationParamsBuilder::default()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/// @brief ProcFileCreationParams 的 Builder 模式实现
|
|
|
|
+#[derive(Debug, Clone, Default)]
|
|
|
|
+pub struct ProcFileCreationParamsBuilder<'a> {
|
|
|
|
+ parent: Option<Arc<dyn IndexNode>>,
|
|
|
|
+ name: Option<&'a str>,
|
|
|
|
+ file_type: Option<FileType>,
|
|
|
|
+ mode: Option<ModeType>,
|
|
|
|
+ pid: Option<RawPid>,
|
|
|
|
+ ftype: Option<ProcFileType>,
|
|
|
|
+ data: Option<&'a str>,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[allow(dead_code)]
|
|
|
|
+impl<'a> ProcFileCreationParamsBuilder<'a> {
|
|
|
|
+ pub fn parent(mut self, parent: Arc<dyn IndexNode>) -> Self {
|
|
|
|
+ self.parent = Some(parent);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn name(mut self, name: &'a str) -> Self {
|
|
|
|
+ self.name = Some(name);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn file_type(mut self, file_type: FileType) -> Self {
|
|
|
|
+ self.file_type = Some(file_type);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn mode(mut self, mode: ModeType) -> Self {
|
|
|
|
+ self.mode = Some(mode);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn pid(mut self, pid: RawPid) -> Self {
|
|
|
|
+ self.pid = Some(pid);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn ftype(mut self, ftype: ProcFileType) -> Self {
|
|
|
|
+ self.ftype = Some(ftype);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn data(mut self, data: &'a str) -> Self {
|
|
|
|
+ self.data = Some(data);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn build(self) -> Result<ProcFileCreationParams<'a>, SystemError> {
|
|
|
|
+ Ok(ProcFileCreationParams {
|
|
|
|
+ parent: self.parent.ok_or(SystemError::EINVAL)?,
|
|
|
|
+ name: self.name.ok_or(SystemError::EINVAL)?,
|
|
|
|
+ file_type: self.file_type.ok_or(SystemError::EINVAL)?,
|
|
|
|
+ mode: self.mode.unwrap_or(ModeType::S_IRUGO),
|
|
|
|
+ pid: self.pid,
|
|
|
|
+ ftype: self.ftype.ok_or(SystemError::EINVAL)?,
|
|
|
|
+ data: self.data,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/// @brief 节点私有信息结构体
|
|
/// @brief 节点私有信息结构体
|
|
/// @usage 用于传入各类文件所需的信息
|
|
/// @usage 用于传入各类文件所需的信息
|
|
#[derive(Debug)]
|
|
#[derive(Debug)]
|
|
pub struct InodeInfo {
|
|
pub struct InodeInfo {
|
|
///进程的pid
|
|
///进程的pid
|
|
- pid: RawPid,
|
|
|
|
|
|
+ pid: Option<RawPid>,
|
|
///文件类型
|
|
///文件类型
|
|
ftype: ProcFileType,
|
|
ftype: ProcFileType,
|
|
- //其他需要传入的信息在此定义
|
|
|
|
|
|
+ /// 文件描述符
|
|
|
|
+ fd: i32,
|
|
|
|
+ // 其他需要传入的信息在此定义
|
|
}
|
|
}
|
|
|
|
|
|
/// @brief procfs的inode名称的最大长度
|
|
/// @brief procfs的inode名称的最大长度
|
|
@@ -144,7 +236,10 @@ impl ProcFSInode {
|
|
///
|
|
///
|
|
fn open_status(&self, pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
|
|
fn open_status(&self, pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
|
|
// 获取该pid对应的pcb结构体
|
|
// 获取该pid对应的pcb结构体
|
|
- let pid = self.fdata.pid;
|
|
|
|
|
|
+ let pid = self
|
|
|
|
+ .fdata
|
|
|
|
+ .pid
|
|
|
|
+ .expect("ProcFS: pid is None when opening 'status' file.");
|
|
let pcb = ProcessManager::find_task_by_vpid(pid);
|
|
let pcb = ProcessManager::find_task_by_vpid(pid);
|
|
let pcb = if let Some(pcb) = pcb {
|
|
let pcb = if let Some(pcb) = pcb {
|
|
pcb
|
|
pcb
|
|
@@ -179,7 +274,8 @@ impl ProcFSInode {
|
|
|
|
|
|
let priority = sched_info_guard.policy();
|
|
let priority = sched_info_guard.policy();
|
|
let vrtime = sched_info_guard.sched_entity.vruntime;
|
|
let vrtime = sched_info_guard.sched_entity.vruntime;
|
|
-
|
|
|
|
|
|
+ let time = sched_info_guard.sched_entity.sum_exec_runtime;
|
|
|
|
+ let start_time = sched_info_guard.sched_entity.exec_start;
|
|
// State
|
|
// State
|
|
pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
|
|
pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
|
|
|
|
|
|
@@ -229,9 +325,12 @@ impl ProcFSInode {
|
|
};
|
|
};
|
|
pdata.append(&mut format!("\nTty:\t{}", name).as_bytes().to_owned());
|
|
pdata.append(&mut format!("\nTty:\t{}", name).as_bytes().to_owned());
|
|
|
|
|
|
|
|
+ // 进程在cpu上的运行时间
|
|
|
|
+ pdata.append(&mut format!("\nTime:\t{}", time).as_bytes().to_owned());
|
|
|
|
+ // 进程开始运行的时间
|
|
|
|
+ pdata.append(&mut format!("\nStime:\t{}", start_time).as_bytes().to_owned());
|
|
// kthread
|
|
// kthread
|
|
pdata.append(&mut format!("\nKthread:\t{}", pcb.is_kthread() as usize).into());
|
|
pdata.append(&mut format!("\nKthread:\t{}", pcb.is_kthread() as usize).into());
|
|
-
|
|
|
|
pdata.append(&mut format!("\ncpu_id:\t{}", cpu_id).as_bytes().to_owned());
|
|
pdata.append(&mut format!("\ncpu_id:\t{}", cpu_id).as_bytes().to_owned());
|
|
pdata.append(&mut format!("\npriority:\t{:?}", priority).as_bytes().to_owned());
|
|
pdata.append(&mut format!("\npriority:\t{:?}", priority).as_bytes().to_owned());
|
|
pdata.append(
|
|
pdata.append(
|
|
@@ -304,15 +403,21 @@ impl ProcFSInode {
|
|
return Ok(0);
|
|
return Ok(0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ fn open_self(&self, _pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
|
|
|
|
+ let pid = ProcessManager::current_pid().data();
|
|
|
|
+ return Ok(pid.to_string().as_bytes().len() as _);
|
|
|
|
+ }
|
|
|
|
+
|
|
// 读取exe文件
|
|
// 读取exe文件
|
|
- fn read_link(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
|
|
|
|
|
+ fn read_exe_link(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
|
// 判断是否有记录pid信息,有的话就是当前进程的exe文件,没有则是当前进程的exe文件
|
|
// 判断是否有记录pid信息,有的话就是当前进程的exe文件,没有则是当前进程的exe文件
|
|
- let pid = self.fdata.pid;
|
|
|
|
- let pcb = if pid == RawPid::from(0) {
|
|
|
|
- ProcessManager::current_pcb()
|
|
|
|
- } else {
|
|
|
|
|
|
+ let pcb = if let Some(pid) = self.fdata.pid {
|
|
ProcessManager::find_task_by_vpid(pid).ok_or(SystemError::ESRCH)?
|
|
ProcessManager::find_task_by_vpid(pid).ok_or(SystemError::ESRCH)?
|
|
|
|
+ } else {
|
|
|
|
+ // 如果没有pid信息,则读取当前进程的exe文件
|
|
|
|
+ ProcessManager::current_pcb()
|
|
};
|
|
};
|
|
|
|
+
|
|
let exe = pcb.execute_path();
|
|
let exe = pcb.execute_path();
|
|
let exe_bytes = exe.as_bytes();
|
|
let exe_bytes = exe.as_bytes();
|
|
let len = exe_bytes.len().min(buf.len());
|
|
let len = exe_bytes.len().min(buf.len());
|
|
@@ -320,6 +425,31 @@ impl ProcFSInode {
|
|
Ok(len)
|
|
Ok(len)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// read current task pid dynamically
|
|
|
|
+ fn read_self_link(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
|
|
|
+ let pid = ProcessManager::current_pid().data();
|
|
|
|
+ let pid_bytes = pid.to_string();
|
|
|
|
+ let len = pid_bytes.len().min(buf.len());
|
|
|
|
+ buf[..len].copy_from_slice(&pid_bytes.as_bytes()[..len]);
|
|
|
|
+ Ok(len)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn read_fd_link(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
|
|
|
+ let fd = self.fdata.fd;
|
|
|
|
+ let fd_table = ProcessManager::current_pcb().fd_table();
|
|
|
|
+ let fd_table = fd_table.read();
|
|
|
|
+ let file = fd_table.get_file_by_fd(fd);
|
|
|
|
+ if let Some(file) = file {
|
|
|
|
+ let inode = file.inode();
|
|
|
|
+ let path = inode.absolute_path().unwrap();
|
|
|
|
+ let len = path.len().min(buf.len());
|
|
|
|
+ buf[..len].copy_from_slice(&path.as_bytes()[..len]);
|
|
|
|
+ Ok(len)
|
|
|
|
+ } else {
|
|
|
|
+ return Err(SystemError::EBADF);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/// proc文件系统读取函数
|
|
/// proc文件系统读取函数
|
|
fn proc_read(
|
|
fn proc_read(
|
|
&self,
|
|
&self,
|
|
@@ -368,6 +498,26 @@ impl FileSystem for ProcFS {
|
|
}
|
|
}
|
|
|
|
|
|
impl ProcFS {
|
|
impl ProcFS {
|
|
|
|
+ #[inline(never)]
|
|
|
|
+ fn create_proc_file(&self, params: ProcFileCreationParams) -> Result<(), SystemError> {
|
|
|
|
+ let binding = params
|
|
|
|
+ .parent
|
|
|
|
+ .create(params.name, params.file_type, params.mode)?;
|
|
|
|
+ let proc_file = binding
|
|
|
|
+ .as_any_ref()
|
|
|
|
+ .downcast_ref::<LockedProcFSInode>()
|
|
|
|
+ .unwrap();
|
|
|
|
+ let mut proc_file_guard = proc_file.0.lock();
|
|
|
|
+ proc_file_guard.fdata.pid = params.pid;
|
|
|
|
+ proc_file_guard.fdata.ftype = params.ftype;
|
|
|
|
+ if let Some(data_content) = params.data {
|
|
|
|
+ proc_file_guard.data = data_content.to_string().as_bytes().to_vec();
|
|
|
|
+ }
|
|
|
|
+ drop(proc_file_guard);
|
|
|
|
+ Ok(())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[inline(never)]
|
|
pub fn new() -> Arc<Self> {
|
|
pub fn new() -> Arc<Self> {
|
|
let super_block = SuperBlock::new(
|
|
let super_block = SuperBlock::new(
|
|
Magic::PROC_MAGIC,
|
|
Magic::PROC_MAGIC,
|
|
@@ -400,8 +550,9 @@ impl ProcFS {
|
|
},
|
|
},
|
|
fs: Weak::default(),
|
|
fs: Weak::default(),
|
|
fdata: InodeInfo {
|
|
fdata: InodeInfo {
|
|
- pid: RawPid::new(0),
|
|
|
|
|
|
+ pid: None,
|
|
ftype: ProcFileType::Default,
|
|
ftype: ProcFileType::Default,
|
|
|
|
+ fd: -1,
|
|
},
|
|
},
|
|
dname: DName::default(),
|
|
dname: DName::default(),
|
|
})));
|
|
})));
|
|
@@ -420,35 +571,30 @@ impl ProcFS {
|
|
drop(root_guard);
|
|
drop(root_guard);
|
|
|
|
|
|
// 创建meminfo文件
|
|
// 创建meminfo文件
|
|
- let inode = result.root_inode();
|
|
|
|
- let binding = inode.create(
|
|
|
|
- "meminfo",
|
|
|
|
- FileType::File,
|
|
|
|
- ModeType::from_bits_truncate(0o444),
|
|
|
|
- );
|
|
|
|
- if let Ok(meminfo) = binding {
|
|
|
|
- let meminfo_file = meminfo
|
|
|
|
- .as_any_ref()
|
|
|
|
- .downcast_ref::<LockedProcFSInode>()
|
|
|
|
- .unwrap();
|
|
|
|
- meminfo_file.0.lock().fdata.pid = RawPid::new(0);
|
|
|
|
- meminfo_file.0.lock().fdata.ftype = ProcFileType::ProcMeminfo;
|
|
|
|
- } else {
|
|
|
|
- panic!("create meminfo error");
|
|
|
|
- }
|
|
|
|
|
|
+ let meminfo_params = ProcFileCreationParams::builder()
|
|
|
|
+ .parent(result.root_inode())
|
|
|
|
+ .name("meminfo")
|
|
|
|
+ .file_type(FileType::File)
|
|
|
|
+ .mode(ModeType::from_bits_truncate(0o444))
|
|
|
|
+ .ftype(ProcFileType::ProcMeminfo)
|
|
|
|
+ .build()
|
|
|
|
+ .unwrap();
|
|
|
|
+ result
|
|
|
|
+ .create_proc_file(meminfo_params)
|
|
|
|
+ .unwrap_or_else(|_| panic!("create meminfo error"));
|
|
|
|
|
|
// 创建kmsg文件
|
|
// 创建kmsg文件
|
|
- let binding = inode.create("kmsg", FileType::File, ModeType::from_bits_truncate(0o444));
|
|
|
|
- if let Ok(kmsg) = binding {
|
|
|
|
- let kmsg_file = kmsg
|
|
|
|
- .as_any_ref()
|
|
|
|
- .downcast_ref::<LockedProcFSInode>()
|
|
|
|
- .unwrap();
|
|
|
|
- kmsg_file.0.lock().fdata.pid = RawPid::new(1);
|
|
|
|
- kmsg_file.0.lock().fdata.ftype = ProcFileType::ProcKmsg;
|
|
|
|
- } else {
|
|
|
|
- panic!("create ksmg error");
|
|
|
|
- }
|
|
|
|
|
|
+ let kmsg_params = ProcFileCreationParams::builder()
|
|
|
|
+ .parent(result.root_inode())
|
|
|
|
+ .name("kmsg")
|
|
|
|
+ .file_type(FileType::File)
|
|
|
|
+ .mode(ModeType::from_bits_truncate(0o444))
|
|
|
|
+ .ftype(ProcFileType::ProcKmsg)
|
|
|
|
+ .build()
|
|
|
|
+ .unwrap();
|
|
|
|
+ result
|
|
|
|
+ .create_proc_file(kmsg_params)
|
|
|
|
+ .unwrap_or_else(|_| panic!("create kmsg error"));
|
|
// 这个文件是用来欺骗Aya框架识别内核版本
|
|
// 这个文件是用来欺骗Aya框架识别内核版本
|
|
/* On Ubuntu LINUX_VERSION_CODE doesn't correspond to info.release,
|
|
/* On Ubuntu LINUX_VERSION_CODE doesn't correspond to info.release,
|
|
* but Ubuntu provides /proc/version_signature file, as described at
|
|
* but Ubuntu provides /proc/version_signature file, as described at
|
|
@@ -460,36 +606,44 @@ impl ProcFS {
|
|
* In the above, 5.4.8 is what kernel is actually expecting, while
|
|
* In the above, 5.4.8 is what kernel is actually expecting, while
|
|
* uname() call will return 5.4.0 in info.release.
|
|
* uname() call will return 5.4.0 in info.release.
|
|
*/
|
|
*/
|
|
- let binding = inode.create("version_signature", FileType::File, ModeType::S_IRUGO);
|
|
|
|
- if let Ok(version_signature) = binding {
|
|
|
|
- let version_signature = version_signature
|
|
|
|
- .as_any_ref()
|
|
|
|
- .downcast_ref::<LockedProcFSInode>()
|
|
|
|
- .unwrap();
|
|
|
|
- version_signature.0.lock().fdata.ftype = ProcFileType::Default;
|
|
|
|
- version_signature.0.lock().data = "DragonOS 6.0.0-generic 6.0.0\n"
|
|
|
|
- .to_string()
|
|
|
|
- .as_bytes()
|
|
|
|
- .to_vec();
|
|
|
|
- } else {
|
|
|
|
- panic!("create version_signature error");
|
|
|
|
- }
|
|
|
|
|
|
+ let version_signature_params = ProcFileCreationParams::builder()
|
|
|
|
+ .parent(result.root_inode())
|
|
|
|
+ .name("version_signature")
|
|
|
|
+ .file_type(FileType::File)
|
|
|
|
+ .ftype(ProcFileType::Default)
|
|
|
|
+ .data("DragonOS 6.0.0-generic 6.0.0\n")
|
|
|
|
+ .build()
|
|
|
|
+ .unwrap();
|
|
|
|
+ result
|
|
|
|
+ .create_proc_file(version_signature_params)
|
|
|
|
+ .unwrap_or_else(|_| panic!("create version_signature error"));
|
|
|
|
+
|
|
|
|
+ let mounts_params = ProcFileCreationParams::builder()
|
|
|
|
+ .parent(result.root_inode())
|
|
|
|
+ .name("mounts")
|
|
|
|
+ .file_type(FileType::File)
|
|
|
|
+ .ftype(ProcFileType::ProcMounts)
|
|
|
|
+ .build()
|
|
|
|
+ .unwrap();
|
|
|
|
+ result
|
|
|
|
+ .create_proc_file(mounts_params)
|
|
|
|
+ .unwrap_or_else(|_| panic!("create mounts error"));
|
|
|
|
|
|
- let self_dir = inode
|
|
|
|
|
|
+ let self_dir = result
|
|
|
|
+ .root_inode()
|
|
.create("self", FileType::Dir, ModeType::from_bits_truncate(0o555))
|
|
.create("self", FileType::Dir, ModeType::from_bits_truncate(0o555))
|
|
.unwrap();
|
|
.unwrap();
|
|
|
|
|
|
- let binding = self_dir.create("exe", FileType::SymLink, ModeType::S_IRUGO);
|
|
|
|
- if let Ok(exe) = binding {
|
|
|
|
- let exe_file = exe
|
|
|
|
- .as_any_ref()
|
|
|
|
- .downcast_ref::<LockedProcFSInode>()
|
|
|
|
- .unwrap();
|
|
|
|
- exe_file.0.lock().fdata.pid = RawPid::new(0);
|
|
|
|
- exe_file.0.lock().fdata.ftype = ProcFileType::ProcExe;
|
|
|
|
- } else {
|
|
|
|
- panic!("create exe error");
|
|
|
|
- }
|
|
|
|
|
|
+ let exe_params = ProcFileCreationParams::builder()
|
|
|
|
+ .parent(self_dir)
|
|
|
|
+ .name("exe")
|
|
|
|
+ .file_type(FileType::SymLink)
|
|
|
|
+ .ftype(ProcFileType::ProcExe)
|
|
|
|
+ .build()
|
|
|
|
+ .unwrap();
|
|
|
|
+ result
|
|
|
|
+ .create_proc_file(exe_params)
|
|
|
|
+ .unwrap_or_else(|_| panic!("create exe error"));
|
|
|
|
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
@@ -498,16 +652,16 @@ impl ProcFS {
|
|
/// @usage 在进程中调用并创建进程对应文件
|
|
/// @usage 在进程中调用并创建进程对应文件
|
|
pub fn register_pid(&self, pid: RawPid) -> Result<(), SystemError> {
|
|
pub fn register_pid(&self, pid: RawPid) -> Result<(), SystemError> {
|
|
// 获取当前inode
|
|
// 获取当前inode
|
|
- let inode: Arc<dyn IndexNode> = self.root_inode();
|
|
|
|
|
|
+ let inode = self.root_inode();
|
|
// 创建对应进程文件夹
|
|
// 创建对应进程文件夹
|
|
- let pid_dir: Arc<dyn IndexNode> = inode.create(
|
|
|
|
|
|
+ let pid_dir = inode.create(
|
|
&pid.to_string(),
|
|
&pid.to_string(),
|
|
FileType::Dir,
|
|
FileType::Dir,
|
|
ModeType::from_bits_truncate(0o555),
|
|
ModeType::from_bits_truncate(0o555),
|
|
)?;
|
|
)?;
|
|
// 创建相关文件
|
|
// 创建相关文件
|
|
// status文件
|
|
// status文件
|
|
- let status_binding: Arc<dyn IndexNode> = pid_dir.create(
|
|
|
|
|
|
+ let status_binding = pid_dir.create(
|
|
"status",
|
|
"status",
|
|
FileType::File,
|
|
FileType::File,
|
|
ModeType::from_bits_truncate(0o444),
|
|
ModeType::from_bits_truncate(0o444),
|
|
@@ -516,11 +670,11 @@ impl ProcFS {
|
|
.as_any_ref()
|
|
.as_any_ref()
|
|
.downcast_ref::<LockedProcFSInode>()
|
|
.downcast_ref::<LockedProcFSInode>()
|
|
.unwrap();
|
|
.unwrap();
|
|
- status_file.0.lock().fdata.pid = pid;
|
|
|
|
|
|
+ status_file.0.lock().fdata.pid = Some(pid);
|
|
status_file.0.lock().fdata.ftype = ProcFileType::ProcStatus;
|
|
status_file.0.lock().fdata.ftype = ProcFileType::ProcStatus;
|
|
|
|
|
|
// exe文件
|
|
// exe文件
|
|
- let exe_binding: Arc<dyn IndexNode> = pid_dir.create_with_data(
|
|
|
|
|
|
+ let exe_binding = pid_dir.create_with_data(
|
|
"exe",
|
|
"exe",
|
|
FileType::SymLink,
|
|
FileType::SymLink,
|
|
ModeType::from_bits_truncate(0o444),
|
|
ModeType::from_bits_truncate(0o444),
|
|
@@ -530,9 +684,13 @@ impl ProcFS {
|
|
.as_any_ref()
|
|
.as_any_ref()
|
|
.downcast_ref::<LockedProcFSInode>()
|
|
.downcast_ref::<LockedProcFSInode>()
|
|
.unwrap();
|
|
.unwrap();
|
|
- exe_file.0.lock().fdata.pid = pid;
|
|
|
|
|
|
+ exe_file.0.lock().fdata.pid = Some(pid);
|
|
exe_file.0.lock().fdata.ftype = ProcFileType::ProcExe;
|
|
exe_file.0.lock().fdata.ftype = ProcFileType::ProcExe;
|
|
|
|
|
|
|
|
+ // fd dir
|
|
|
|
+ let fd = pid_dir.create("fd", FileType::Dir, ModeType::from_bits_truncate(0o555))?;
|
|
|
|
+ let fd = fd.as_any_ref().downcast_ref::<LockedProcFSInode>().unwrap();
|
|
|
|
+ fd.0.lock().fdata.ftype = ProcFileType::ProcFdDir;
|
|
//todo: 创建其他文件
|
|
//todo: 创建其他文件
|
|
|
|
|
|
return Ok(());
|
|
return Ok(());
|
|
@@ -548,6 +706,7 @@ impl ProcFS {
|
|
// 删除进程文件夹下文件
|
|
// 删除进程文件夹下文件
|
|
pid_dir.unlink("status")?;
|
|
pid_dir.unlink("status")?;
|
|
pid_dir.unlink("exe")?;
|
|
pid_dir.unlink("exe")?;
|
|
|
|
+ pid_dir.rmdir("fd")?;
|
|
|
|
|
|
// 查看进程文件是否还存在
|
|
// 查看进程文件是否还存在
|
|
// let pf= pid_dir.find("status").expect("Cannot find status");
|
|
// let pf= pid_dir.find("status").expect("Cannot find status");
|
|
@@ -559,6 +718,43 @@ impl ProcFS {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+impl LockedProcFSInode {
|
|
|
|
+ fn dynamical_find_fd(&self, fd: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
|
|
+ // ::log::info!("ProcFS: Dynamically opening fd files for current process.");
|
|
|
|
+ let fd = fd.parse::<i32>().map_err(|_| SystemError::EINVAL)?;
|
|
|
|
+ let pcb = ProcessManager::current_pcb();
|
|
|
|
+ let fd_table = pcb.fd_table();
|
|
|
|
+ let fd_table = fd_table.read();
|
|
|
|
+ let file = fd_table.get_file_by_fd(fd);
|
|
|
|
+ if file.is_some() {
|
|
|
|
+ let _ = self.unlink(&fd.to_string());
|
|
|
|
+ let fd_file = self.create(
|
|
|
|
+ &fd.to_string(),
|
|
|
|
+ FileType::SymLink,
|
|
|
|
+ ModeType::from_bits_truncate(0o444),
|
|
|
|
+ )?;
|
|
|
|
+ let fd_file_proc = fd_file
|
|
|
|
+ .as_any_ref()
|
|
|
|
+ .downcast_ref::<LockedProcFSInode>()
|
|
|
|
+ .unwrap();
|
|
|
|
+ fd_file_proc.0.lock().fdata.fd = fd;
|
|
|
|
+ fd_file_proc.0.lock().fdata.ftype = ProcFileType::ProcFdFile;
|
|
|
|
+ return Ok(fd_file);
|
|
|
|
+ } else {
|
|
|
|
+ return Err(SystemError::ENOENT);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn dynamical_list_fd(&self) -> Result<Vec<String>, SystemError> {
|
|
|
|
+ // ::log::info!("ProcFS: Dynamically listing fd files for current process");
|
|
|
|
+ let pcb = ProcessManager::current_pcb();
|
|
|
|
+ let fd_table = pcb.fd_table();
|
|
|
|
+ let fd_table = fd_table.read();
|
|
|
|
+ let res = fd_table.iter().map(|(fd, _)| fd.to_string()).collect();
|
|
|
|
+ return Ok(res);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
impl IndexNode for LockedProcFSInode {
|
|
impl IndexNode for LockedProcFSInode {
|
|
fn open(
|
|
fn open(
|
|
&self,
|
|
&self,
|
|
@@ -567,6 +763,7 @@ impl IndexNode for LockedProcFSInode {
|
|
) -> Result<(), SystemError> {
|
|
) -> Result<(), SystemError> {
|
|
// 加锁
|
|
// 加锁
|
|
let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
|
|
let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
|
|
|
|
+ let proc_ty = inode.fdata.ftype;
|
|
|
|
|
|
// 如果inode类型为文件夹,则直接返回成功
|
|
// 如果inode类型为文件夹,则直接返回成功
|
|
if let FileType::Dir = inode.metadata.file_type {
|
|
if let FileType::Dir = inode.metadata.file_type {
|
|
@@ -574,22 +771,37 @@ impl IndexNode for LockedProcFSInode {
|
|
}
|
|
}
|
|
let mut private_data = ProcfsFilePrivateData::new();
|
|
let mut private_data = ProcfsFilePrivateData::new();
|
|
// 根据文件类型获取相应数据
|
|
// 根据文件类型获取相应数据
|
|
- let file_size = match inode.fdata.ftype {
|
|
|
|
|
|
+ let file_size = match proc_ty {
|
|
ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
|
|
ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
|
|
ProcFileType::ProcMeminfo => inode.open_meminfo(&mut private_data)?,
|
|
ProcFileType::ProcMeminfo => inode.open_meminfo(&mut private_data)?,
|
|
ProcFileType::ProcExe => inode.open_exe(&mut private_data)?,
|
|
ProcFileType::ProcExe => inode.open_exe(&mut private_data)?,
|
|
|
|
+ ProcFileType::ProcMounts => inode.open_mounts(&mut private_data)?,
|
|
ProcFileType::Default => inode.data.len() as i64,
|
|
ProcFileType::Default => inode.data.len() as i64,
|
|
- _ => {
|
|
|
|
- todo!()
|
|
|
|
- }
|
|
|
|
|
|
+ ProcFileType::ProcSelf => inode.open_self(&mut private_data)?,
|
|
|
|
+ _ => 0,
|
|
};
|
|
};
|
|
*data = FilePrivateData::Procfs(private_data);
|
|
*data = FilePrivateData::Procfs(private_data);
|
|
// 更新metadata里面的文件大小数值
|
|
// 更新metadata里面的文件大小数值
|
|
inode.metadata.size = file_size;
|
|
inode.metadata.size = file_size;
|
|
|
|
+ drop(inode);
|
|
|
|
+ return Ok(());
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ fn rmdir(&self, name: &str) -> Result<(), SystemError> {
|
|
|
|
+ let mut guard = self.0.lock();
|
|
|
|
+ if guard.metadata.file_type != FileType::Dir {
|
|
|
|
+ return Err(SystemError::ENOTDIR);
|
|
|
|
+ }
|
|
|
|
+ let name = DName::from(name);
|
|
|
|
+ guard.children.remove(&name);
|
|
return Ok(());
|
|
return Ok(());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
|
|
+ let parent = self.0.lock().parent.upgrade().ok_or(SystemError::ENOENT)?;
|
|
|
|
+ return Ok(parent as Arc<dyn IndexNode>);
|
|
|
|
+ }
|
|
|
|
+
|
|
fn close(&self, mut data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
|
|
fn close(&self, mut data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
|
|
let guard: SpinLockGuard<ProcFSInode> = self.0.lock();
|
|
let guard: SpinLockGuard<ProcFSInode> = self.0.lock();
|
|
// 如果inode类型为文件夹,则直接返回成功
|
|
// 如果inode类型为文件夹,则直接返回成功
|
|
@@ -613,32 +825,30 @@ impl IndexNode for LockedProcFSInode {
|
|
return Err(SystemError::EINVAL);
|
|
return Err(SystemError::EINVAL);
|
|
}
|
|
}
|
|
// 加锁
|
|
// 加锁
|
|
- let inode: SpinLockGuard<ProcFSInode> = self.0.lock();
|
|
|
|
|
|
+ let inode = self.0.lock();
|
|
|
|
|
|
// 检查当前inode是否为一个文件夹,如果是的话,就返回错误
|
|
// 检查当前inode是否为一个文件夹,如果是的话,就返回错误
|
|
if inode.metadata.file_type == FileType::Dir {
|
|
if inode.metadata.file_type == FileType::Dir {
|
|
return Err(SystemError::EISDIR);
|
|
return Err(SystemError::EISDIR);
|
|
}
|
|
}
|
|
|
|
|
|
- // 获取数据信息
|
|
|
|
- let mut private_data = match &*data {
|
|
|
|
- FilePrivateData::Procfs(p) => p.clone(),
|
|
|
|
- _ => {
|
|
|
|
- panic!("ProcFS: FilePrivateData mismatch!");
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
// 根据文件类型读取相应数据
|
|
// 根据文件类型读取相应数据
|
|
match inode.fdata.ftype {
|
|
match inode.fdata.ftype {
|
|
- ProcFileType::ProcStatus => {
|
|
|
|
- return inode.proc_read(offset, len, buf, &mut private_data)
|
|
|
|
- }
|
|
|
|
- ProcFileType::ProcMeminfo => {
|
|
|
|
- return inode.proc_read(offset, len, buf, &mut private_data)
|
|
|
|
|
|
+ ProcFileType::ProcStatus | ProcFileType::ProcMeminfo | ProcFileType::ProcMounts => {
|
|
|
|
+ // 获取数据信息
|
|
|
|
+ let mut private_data = match &*data {
|
|
|
|
+ FilePrivateData::Procfs(p) => p.clone(),
|
|
|
|
+ _ => {
|
|
|
|
+ panic!("ProcFS: FilePrivateData mismatch!");
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ return inode.proc_read(offset, len, buf, &mut private_data);
|
|
}
|
|
}
|
|
- ProcFileType::ProcExe => return inode.read_link(buf),
|
|
|
|
- ProcFileType::ProcKmsg => (),
|
|
|
|
- ProcFileType::Default => (),
|
|
|
|
|
|
+ ProcFileType::ProcExe => return inode.read_exe_link(buf),
|
|
|
|
+ ProcFileType::ProcSelf => return inode.read_self_link(buf),
|
|
|
|
+ ProcFileType::ProcFdFile => return inode.read_fd_link(buf),
|
|
|
|
+
|
|
|
|
+ _ => (),
|
|
};
|
|
};
|
|
|
|
|
|
// 默认读取
|
|
// 默认读取
|
|
@@ -677,7 +887,6 @@ impl IndexNode for LockedProcFSInode {
|
|
fn metadata(&self) -> Result<Metadata, SystemError> {
|
|
fn metadata(&self) -> Result<Metadata, SystemError> {
|
|
let inode = self.0.lock();
|
|
let inode = self.0.lock();
|
|
let metadata = inode.metadata.clone();
|
|
let metadata = inode.metadata.clone();
|
|
-
|
|
|
|
return Ok(metadata);
|
|
return Ok(metadata);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -749,8 +958,9 @@ impl IndexNode for LockedProcFSInode {
|
|
},
|
|
},
|
|
fs: inode.fs.clone(),
|
|
fs: inode.fs.clone(),
|
|
fdata: InodeInfo {
|
|
fdata: InodeInfo {
|
|
- pid: RawPid::new(0),
|
|
|
|
|
|
+ pid: None,
|
|
ftype: ProcFileType::Default,
|
|
ftype: ProcFileType::Default,
|
|
|
|
+ fd: -1,
|
|
},
|
|
},
|
|
dname: name.clone(),
|
|
dname: name.clone(),
|
|
})));
|
|
})));
|
|
@@ -829,23 +1039,32 @@ impl IndexNode for LockedProcFSInode {
|
|
}
|
|
}
|
|
|
|
|
|
fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
- let inode = self.0.lock();
|
|
|
|
-
|
|
|
|
- if inode.metadata.file_type != FileType::Dir {
|
|
|
|
|
|
+ if self.0.lock().metadata.file_type != FileType::Dir {
|
|
return Err(SystemError::ENOTDIR);
|
|
return Err(SystemError::ENOTDIR);
|
|
}
|
|
}
|
|
|
|
|
|
match name {
|
|
match name {
|
|
"" | "." => {
|
|
"" | "." => {
|
|
- return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
|
|
|
|
|
|
+ return Ok(self
|
|
|
|
+ .0
|
|
|
|
+ .lock()
|
|
|
|
+ .self_ref
|
|
|
|
+ .upgrade()
|
|
|
|
+ .ok_or(SystemError::ENOENT)?);
|
|
}
|
|
}
|
|
|
|
|
|
".." => {
|
|
".." => {
|
|
- return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?);
|
|
|
|
|
|
+ return Ok(self.0.lock().parent.upgrade().ok_or(SystemError::ENOENT)?);
|
|
}
|
|
}
|
|
|
|
+
|
|
name => {
|
|
name => {
|
|
|
|
+ if self.0.lock().fdata.ftype == ProcFileType::ProcFdDir {
|
|
|
|
+ return self.dynamical_find_fd(name);
|
|
|
|
+ }
|
|
// 在子目录项中查找
|
|
// 在子目录项中查找
|
|
- return Ok(inode
|
|
|
|
|
|
+ return Ok(self
|
|
|
|
+ .0
|
|
|
|
+ .lock()
|
|
.children
|
|
.children
|
|
.get(&DName::from(name))
|
|
.get(&DName::from(name))
|
|
.ok_or(SystemError::ENOENT)?
|
|
.ok_or(SystemError::ENOENT)?
|
|
@@ -897,9 +1116,14 @@ impl IndexNode for LockedProcFSInode {
|
|
return Err(SystemError::ENOTDIR);
|
|
return Err(SystemError::ENOTDIR);
|
|
}
|
|
}
|
|
|
|
|
|
- let mut keys: Vec<String> = Vec::new();
|
|
|
|
|
|
+ let mut keys = Vec::new();
|
|
keys.push(String::from("."));
|
|
keys.push(String::from("."));
|
|
keys.push(String::from(".."));
|
|
keys.push(String::from(".."));
|
|
|
|
+
|
|
|
|
+ if self.0.lock().fdata.ftype == ProcFileType::ProcFdDir {
|
|
|
|
+ return self.dynamical_list_fd();
|
|
|
|
+ }
|
|
|
|
+
|
|
keys.append(
|
|
keys.append(
|
|
&mut self
|
|
&mut self
|
|
.0
|
|
.0
|
|
@@ -919,6 +1143,7 @@ impl IndexNode for LockedProcFSInode {
|
|
}
|
|
}
|
|
|
|
|
|
/// @brief 向procfs注册进程
|
|
/// @brief 向procfs注册进程
|
|
|
|
+#[inline(never)]
|
|
pub fn procfs_register_pid(pid: RawPid) -> Result<(), SystemError> {
|
|
pub fn procfs_register_pid(pid: RawPid) -> Result<(), SystemError> {
|
|
let root_inode = ProcessManager::current_mntns().root_inode();
|
|
let root_inode = ProcessManager::current_mntns().root_inode();
|
|
let procfs_inode = root_inode.find("proc")?;
|
|
let procfs_inode = root_inode.find("proc")?;
|
|
@@ -936,6 +1161,7 @@ pub fn procfs_register_pid(pid: RawPid) -> Result<(), SystemError> {
|
|
}
|
|
}
|
|
|
|
|
|
/// @brief 在ProcFS中,解除进程的注册
|
|
/// @brief 在ProcFS中,解除进程的注册
|
|
|
|
+#[inline(never)]
|
|
pub fn procfs_unregister_pid(pid: RawPid) -> Result<(), SystemError> {
|
|
pub fn procfs_unregister_pid(pid: RawPid) -> Result<(), SystemError> {
|
|
let root_inode = ProcessManager::current_mntns().root_inode();
|
|
let root_inode = ProcessManager::current_mntns().root_inode();
|
|
// 获取procfs实例
|
|
// 获取procfs实例
|
|
@@ -963,7 +1189,7 @@ pub fn procfs_init() -> Result<(), SystemError> {
|
|
root_inode
|
|
root_inode
|
|
.mkdir("proc", ModeType::from_bits_truncate(0o755))
|
|
.mkdir("proc", ModeType::from_bits_truncate(0o755))
|
|
.expect("Unabled to find /proc")
|
|
.expect("Unabled to find /proc")
|
|
- .mount(procfs)
|
|
|
|
|
|
+ .mount(procfs, MountFlags::empty())
|
|
.expect("Failed to mount at /proc");
|
|
.expect("Failed to mount at /proc");
|
|
info!("ProcFS mounted.");
|
|
info!("ProcFS mounted.");
|
|
result = Some(Ok(()));
|
|
result = Some(Ok(()));
|