support stat in procfs

This commit is contained in:
Ashwin Naren
2025-12-31 11:53:44 -08:00
parent e8b0eda15c
commit 2383bf99bb
3 changed files with 84 additions and 7 deletions

View File

@@ -8,6 +8,7 @@ use crate::{
drivers::{Driver, FilesystemDriver},
process::TASK_LIST,
};
use alloc::string::String;
use alloc::{boxed::Box, format, string::ToString, sync::Arc, vec::Vec};
use async_trait::async_trait;
use core::sync::atomic::{AtomicU64, Ordering};
@@ -225,6 +226,12 @@ impl Inode for ProcTaskInode {
FileType::Symlink,
4,
));
entries.push(Dirent::new(
"stat".to_string(),
InodeId::from_fsid_and_inodeid(PROCFS_ID, inode_offset + 5),
FileType::File,
5,
));
// honour start_offset
let entries = entries.into_iter().skip(start_offset as usize).collect();
@@ -238,6 +245,7 @@ enum TaskFileType {
Comm,
Cwd,
State,
Stat,
}
impl TryFrom<&str> for TaskFileType {
@@ -248,6 +256,7 @@ impl TryFrom<&str> for TaskFileType {
"status" => Ok(TaskFileType::Status),
"comm" => Ok(TaskFileType::Comm),
"state" => Ok(TaskFileType::State),
"stat" => Ok(TaskFileType::Stat),
"cwd" => Ok(TaskFileType::Cwd),
_ => Err(()),
}
@@ -267,9 +276,10 @@ impl ProcTaskFileInode {
id: inode_id,
attr: FileAttr {
file_type: match file_type {
TaskFileType::Status | TaskFileType::Comm | TaskFileType::State => {
FileType::File
}
TaskFileType::Status
| TaskFileType::Comm
| TaskFileType::State
| TaskFileType::Stat => FileType::File,
TaskFileType::Cwd => FileType::Symlink,
},
mode: FilePermissions::from_bits_retain(0o444),
@@ -301,10 +311,15 @@ impl Inode for ProcTaskFileInode {
async fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<usize> {
let pid = self.pid;
// TODO: task needs to be the main thread of the process
let task_list = TASK_LIST.lock_save_irq();
let id = task_list.iter().find(|(desc, _)| desc.tgid() == pid);
let task_details = if let Some((desc, _)) = id {
find_task_by_descriptor(desc)
let id = task_list
.iter()
.find(|(desc, _)| desc.tgid() == pid)
.map(|(desc, _)| *desc);
drop(task_list);
let task_details = if let Some(desc) = id {
find_task_by_descriptor(&desc)
} else {
None
};
@@ -327,6 +342,63 @@ Threads:\t{tasks}\n",
),
TaskFileType::Comm => format!("{name}\n", name = name.as_str()),
TaskFileType::State => format!("{state}\n"),
TaskFileType::Stat => {
let mut output = String::new();
output.push_str(&format!("{} ", task.process.tgid.0)); // pid
output.push_str(&format!("({}) ", name.as_str())); // comm
output.push_str(&format!("{} ", state)); // state
output.push_str(&format!("{} ", 0)); // ppid
output.push_str(&format!("{} ", 0)); // pgrp
output.push_str(&format!("{} ", task.process.sid.lock_save_irq().value())); // session
output.push_str(&format!("{} ", 0)); // tty_nr
output.push_str(&format!("{} ", 0)); // tpgid
output.push_str(&format!("{} ", 0)); // flags
output.push_str(&format!("{} ", 0)); // minflt
output.push_str(&format!("{} ", 0)); // cminflt
output.push_str(&format!("{} ", 0)); // majflt
output.push_str(&format!("{} ", 0)); // cmajflt
output.push_str(&format!("{} ", task.process.utime.load(Ordering::Relaxed))); // utime
output.push_str(&format!("{} ", task.process.stime.load(Ordering::Relaxed))); // stime
output.push_str(&format!("{} ", 0)); // cutime
output.push_str(&format!("{} ", 0)); // cstime
output.push_str(&format!("{} ", task.priority)); // priority
output.push_str(&format!("{} ", 0)); // nice
output.push_str(&format!("{} ", 0)); // num_threads
output.push_str(&format!("{} ", 0)); // itrealvalue
output.push_str(&format!("{} ", 0)); // starttime
output.push_str(&format!("{} ", 0)); // vsize
output.push_str(&format!("{} ", 0)); // rss
output.push_str(&format!("{} ", 0)); // rsslim
output.push_str(&format!("{} ", 0)); // startcode
output.push_str(&format!("{} ", 0)); // endcode
output.push_str(&format!("{} ", 0)); // startstack
output.push_str(&format!("{} ", 0)); // kstkesp
output.push_str(&format!("{} ", 0)); // kstkeip
output.push_str(&format!("{} ", 0)); // signal
output.push_str(&format!("{} ", 0)); // blocked
output.push_str(&format!("{} ", 0)); // sigignore
output.push_str(&format!("{} ", 0)); // sigcatch
output.push_str(&format!("{} ", 0)); // wchan
output.push_str(&format!("{} ", 0)); // nswap
output.push_str(&format!("{} ", 0)); // cnswap
output.push_str(&format!("{} ", 0)); // exit_signal
output.push_str(&format!("{} ", 0)); // processor
output.push_str(&format!("{} ", 0)); // rt_priority
output.push_str(&format!("{} ", 0)); // policy
output.push_str(&format!("{} ", 0)); // delayacct_blkio_ticks
output.push_str(&format!("{} ", 0)); // guest_time
output.push_str(&format!("{} ", 0)); // cguest_time
output.push_str(&format!("{} ", 0)); // start_data
output.push_str(&format!("{} ", 0)); // end_data
output.push_str(&format!("{} ", 0)); // start_brk
output.push_str(&format!("{} ", 0)); // arg_start
output.push_str(&format!("{} ", 0)); // arg_end
output.push_str(&format!("{} ", 0)); // env_start
output.push_str(&format!("{} ", 0)); // env_end
output.push_str(&format!("{} ", 0)); // exit_code
output.push('\n');
output
}
TaskFileType::Cwd => task.cwd.lock_save_irq().clone().1.as_str().to_string(),
}
} else {

View File

@@ -5,6 +5,7 @@ use alloc::{
sync::{Arc, Weak},
};
use builder::ThreadGroupBuilder;
use core::sync::atomic::AtomicU64;
use core::{
fmt::Display,
sync::atomic::{AtomicU32, Ordering},
@@ -99,6 +100,8 @@ pub struct ThreadGroup {
pub rsrc_lim: Arc<SpinLock<ResourceLimits>>,
pub pending_signals: SpinLock<SigSet>,
pub child_notifiers: ChildNotifiers,
pub utime: AtomicU64,
pub stime: AtomicU64,
next_tid: AtomicU32,
}

View File

@@ -1,4 +1,4 @@
use core::sync::atomic::AtomicU32;
use core::sync::atomic::{AtomicU32, AtomicU64};
use alloc::{collections::btree_map::BTreeMap, sync::Arc};
@@ -68,6 +68,8 @@ impl ThreadGroupBuilder {
.unwrap_or_else(|| Arc::new(SpinLock::new(ResourceLimits::default()))),
pending_signals: SpinLock::new(SigSet::empty()),
child_notifiers: ChildNotifiers::new(),
utime: AtomicU64::new(0),
stime: AtomicU64::new(0),
// Don't start from '0'. Since clone expects the parent to return
// the tid and the child to return '0', if we started from '0' we
// couldn't then differentiate between a child and a parent.