mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-25 02:13:24 +00:00
Export /proc/[pid]/task and /proc/[pid]/task/[tid]
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
58cf8ea681
commit
532dac8fe3
@ -1,6 +1,8 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// 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 super::template::{DirOps, ProcDir, ProcDirBuilder};
|
||||||
use crate::{
|
use crate::{
|
||||||
events::Observer,
|
events::Observer,
|
||||||
@ -18,6 +20,7 @@ mod exe;
|
|||||||
mod fd;
|
mod fd;
|
||||||
mod stat;
|
mod stat;
|
||||||
mod status;
|
mod status;
|
||||||
|
mod task;
|
||||||
|
|
||||||
/// Represents the inode at `/proc/[pid]`.
|
/// Represents the inode at `/proc/[pid]`.
|
||||||
pub struct PidDirOps(Arc<Process>);
|
pub struct PidDirOps(Arc<Process>);
|
||||||
@ -56,6 +59,7 @@ impl DirOps for PidDirOps {
|
|||||||
"cmdline" => CmdlineFileOps::new_inode(self.0.clone(), this_ptr.clone()),
|
"cmdline" => CmdlineFileOps::new_inode(self.0.clone(), this_ptr.clone()),
|
||||||
"status" => status::StatusFileOps::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()),
|
"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),
|
_ => return_errno!(Errno::ENOENT),
|
||||||
};
|
};
|
||||||
Ok(inode)
|
Ok(inode)
|
||||||
@ -85,5 +89,8 @@ impl DirOps for PidDirOps {
|
|||||||
cached_children.put_entry_if_not_found("stat", || {
|
cached_children.put_entry_if_not_found("stat", || {
|
||||||
stat::StatFileOps::new_inode(self.0.clone(), this_ptr.clone())
|
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())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
84
kernel/src/fs/procfs/pid/task.rs
Normal file
84
kernel/src/fs/procfs/pid/task.rs
Normal 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()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user