Export /proc/[pid]/task and /proc/[pid]/task/[tid]

This commit is contained in:
Fabing Li
2024-11-19 11:37:27 +08:00
committed by Tate, Hongliang Tian
parent 58cf8ea681
commit 532dac8fe3
2 changed files with 92 additions and 1 deletions

View File

@ -1,6 +1,8 @@
// SPDX-License-Identifier: MPL-2.0
use self::{cmdline::CmdlineFileOps, comm::CommFileOps, exe::ExeSymOps, fd::FdDirOps};
use self::{
cmdline::CmdlineFileOps, comm::CommFileOps, exe::ExeSymOps, fd::FdDirOps, task::TaskDirOps,
};
use super::template::{DirOps, ProcDir, ProcDirBuilder};
use crate::{
events::Observer,
@ -18,6 +20,7 @@ mod exe;
mod fd;
mod stat;
mod status;
mod task;
/// Represents the inode at `/proc/[pid]`.
pub struct PidDirOps(Arc<Process>);
@ -56,6 +59,7 @@ impl DirOps for PidDirOps {
"cmdline" => CmdlineFileOps::new_inode(self.0.clone(), this_ptr.clone()),
"status" => status::StatusFileOps::new_inode(self.0.clone(), this_ptr.clone()),
"stat" => stat::StatFileOps::new_inode(self.0.clone(), this_ptr.clone()),
"task" => TaskDirOps::new_inode(self.0.clone(), this_ptr.clone()),
_ => return_errno!(Errno::ENOENT),
};
Ok(inode)
@ -85,5 +89,8 @@ impl DirOps for PidDirOps {
cached_children.put_entry_if_not_found("stat", || {
stat::StatFileOps::new_inode(self.0.clone(), this_ptr.clone())
});
cached_children.put_entry_if_not_found("task", || {
TaskDirOps::new_inode(self.0.clone(), this_ptr.clone())
});
}
}

View File

@ -0,0 +1,84 @@
// SPDX-License-Identifier: MPL-2.0
use alloc::format;
use super::*;
use crate::{
fs::{
procfs::template::{DirOps, ProcDir, ProcDirBuilder},
utils::{DirEntryVecExt, Inode},
},
process::posix_thread::AsPosixThread,
Process,
};
/// Represents the inode at `/proc/[pid]/task`.
pub struct TaskDirOps(Arc<Process>);
impl TaskDirOps {
pub fn new_inode(process_ref: Arc<Process>, parent: Weak<dyn Inode>) -> Arc<dyn Inode> {
ProcDirBuilder::new(Self(process_ref))
.parent(parent)
.build()
.unwrap()
}
}
/// Represents the inode at `/proc/[pid]/task/[tid]`.
struct ThreadDirOps(Arc<Process>);
impl ThreadDirOps {
pub fn new_inode(process_ref: Arc<Process>, parent: Weak<dyn Inode>) -> Arc<dyn Inode> {
ProcDirBuilder::new(Self(process_ref))
.parent(parent)
.build()
.unwrap()
}
}
impl DirOps for ThreadDirOps {
fn lookup_child(&self, this_ptr: Weak<dyn Inode>, name: &str) -> Result<Arc<dyn Inode>> {
let inode = match name {
"fd" => FdDirOps::new_inode(self.0.clone(), this_ptr.clone()),
_ => return_errno!(Errno::ENOENT),
};
Ok(inode)
}
fn populate_children(&self, this_ptr: Weak<dyn Inode>) {
let this = {
let this = this_ptr.upgrade().unwrap();
this.downcast_ref::<ProcDir<ThreadDirOps>>().unwrap().this()
};
let mut cached_children = this.cached_children().write();
cached_children.put_entry_if_not_found("fd", || {
FdDirOps::new_inode(self.0.clone(), this_ptr.clone())
});
}
}
impl DirOps for TaskDirOps {
fn lookup_child(&self, this_ptr: Weak<dyn Inode>, name: &str) -> Result<Arc<dyn Inode>> {
for task in self.0.tasks().lock().iter() {
if task.as_posix_thread().unwrap().tid() != name.parse::<u32>().unwrap() {
continue;
}
return Ok(ThreadDirOps::new_inode(self.0.clone(), this_ptr));
}
return_errno_with_message!(Errno::ENOENT, "No such thread")
}
fn populate_children(&self, this_ptr: Weak<dyn Inode>) {
let this = {
let this = this_ptr.upgrade().unwrap();
this.downcast_ref::<ProcDir<TaskDirOps>>().unwrap().this()
};
let mut cached_children = this.cached_children().write();
for task in self.0.tasks().lock().iter() {
cached_children.put_entry_if_not_found(
&format!("{}", task.as_posix_thread().unwrap().tid()),
|| ThreadDirOps::new_inode(self.0.clone(), this_ptr.clone()),
);
}
}
}