Add support for '/proc/[pid]/stat'
Many field values are displayed as 0
This commit is contained in:
parent
28c0d55c88
commit
865e38258b
@ -8,6 +8,7 @@ use self::cwd::ProcCwdSymINode;
|
||||
use self::exe::ProcExeSymINode;
|
||||
use self::fd::LockedProcFdDirINode;
|
||||
use self::root::ProcRootSymINode;
|
||||
use self::stat::ProcStatINode;
|
||||
|
||||
mod cmdline;
|
||||
mod comm;
|
||||
@ -15,6 +16,7 @@ mod cwd;
|
||||
mod exe;
|
||||
mod fd;
|
||||
mod root;
|
||||
mod stat;
|
||||
|
||||
pub struct LockedPidDirINode(RwLock<PidDirINode>);
|
||||
|
||||
@ -58,6 +60,9 @@ impl LockedPidDirINode {
|
||||
// comm
|
||||
let comm_inode = ProcCommINode::new(&file.process_ref);
|
||||
file.entries.insert(String::from("comm"), comm_inode);
|
||||
// stat
|
||||
let stat_inode = ProcStatINode::new(&file.process_ref);
|
||||
file.entries.insert(String::from("stat"), stat_inode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
185
src/libos/src/fs/procfs/pid/stat.rs
Normal file
185
src/libos/src/fs/procfs/pid/stat.rs
Normal file
@ -0,0 +1,185 @@
|
||||
use super::*;
|
||||
|
||||
pub struct ProcStatINode(ProcessRef);
|
||||
|
||||
impl ProcStatINode {
|
||||
pub fn new(process_ref: &ProcessRef) -> Arc<dyn INode> {
|
||||
Arc::new(File::new(Self(Arc::clone(process_ref))))
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcINode for ProcStatINode {
|
||||
fn generate_data_in_bytes(&self) -> vfs::Result<Vec<u8>> {
|
||||
let main_thread = self.0.main_thread().ok_or(FsError::EntryNotFound)?;
|
||||
|
||||
// Get the process status information, some fields are filled with the
|
||||
// dummy value 0, while some fields are denies to access with value 0.
|
||||
// TODO: Fill in the dummy fields with meaningful values
|
||||
let pid = main_thread.tid();
|
||||
let comm = String::from_utf8(main_thread.name().as_c_str().to_bytes().to_vec()).unwrap();
|
||||
let state = match self.0.status() {
|
||||
ProcessStatus::Running => "R",
|
||||
ProcessStatus::Stopped => "T",
|
||||
ProcessStatus::Zombie => "Z",
|
||||
};
|
||||
let ppid = self.0.parent().pid();
|
||||
let pgrp = self.0.pgid();
|
||||
let session = pgrp.clone();
|
||||
let tty_nr = 0;
|
||||
let tpgid = pgrp.clone();
|
||||
let flags = 0;
|
||||
let minflt = 0;
|
||||
let cminflt = 0;
|
||||
let majflt = 0;
|
||||
let cmajflt = 0;
|
||||
let utime = 0;
|
||||
let stime = 0;
|
||||
let cutime = 0;
|
||||
let cstime = 0;
|
||||
let priority = 0;
|
||||
let nice = 0;
|
||||
let num_threads = self.0.threads().len();
|
||||
let itrealvalue = 0;
|
||||
let starttime = 0;
|
||||
let vsize = main_thread.vm().get_process_range().size();
|
||||
let rss = 0;
|
||||
let rsslim = 0;
|
||||
let startcode = 0;
|
||||
let endcode = 0;
|
||||
let startstack = 0;
|
||||
let kstkesp = 0;
|
||||
let kstkeip = 0;
|
||||
let signal = 0;
|
||||
let blocked = 0;
|
||||
let sigignore = 0;
|
||||
let sigcatch = 0;
|
||||
let wchan = 0;
|
||||
let nswap = 0;
|
||||
let cnswap = 0;
|
||||
let exit_signal = 0;
|
||||
let processor = 0;
|
||||
let rt_priority = 0;
|
||||
let policy = 0;
|
||||
let delayacct_blkio_ticks = 0;
|
||||
let guest_time = 0;
|
||||
let cguest_time = 0;
|
||||
let start_data = 0;
|
||||
let end_data = 0;
|
||||
let start_brk = 0;
|
||||
let arg_start = 0;
|
||||
let arg_end = 0;
|
||||
let env_start = 0;
|
||||
let env_end = 0;
|
||||
let exit_code = 0;
|
||||
|
||||
// Put the information together in the specific format
|
||||
let result = format!(
|
||||
"{} \
|
||||
({}) \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{} \
|
||||
{}",
|
||||
pid,
|
||||
comm,
|
||||
state,
|
||||
ppid,
|
||||
pgrp,
|
||||
session,
|
||||
tty_nr,
|
||||
tpgid,
|
||||
flags,
|
||||
minflt,
|
||||
cminflt,
|
||||
majflt,
|
||||
cmajflt,
|
||||
utime,
|
||||
stime,
|
||||
cutime,
|
||||
cstime,
|
||||
priority,
|
||||
nice,
|
||||
num_threads,
|
||||
itrealvalue,
|
||||
starttime,
|
||||
vsize,
|
||||
rss,
|
||||
rsslim,
|
||||
startcode,
|
||||
endcode,
|
||||
startstack,
|
||||
kstkesp,
|
||||
kstkeip,
|
||||
signal,
|
||||
blocked,
|
||||
sigignore,
|
||||
sigcatch,
|
||||
wchan,
|
||||
nswap,
|
||||
cnswap,
|
||||
exit_signal,
|
||||
processor,
|
||||
rt_priority,
|
||||
policy,
|
||||
delayacct_blkio_ticks,
|
||||
guest_time,
|
||||
cguest_time,
|
||||
start_data,
|
||||
end_data,
|
||||
start_brk,
|
||||
arg_start,
|
||||
arg_end,
|
||||
env_start,
|
||||
env_end,
|
||||
exit_code
|
||||
)
|
||||
.into_bytes();
|
||||
Ok(result)
|
||||
}
|
||||
}
|
@ -29,6 +29,25 @@ static int test_readlink_from_procfs(const char *proc_inode, char *buf, int buf_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_read_from_procfs(const char *proc_inode) {
|
||||
char buf[1024] = { 0 };
|
||||
int len;
|
||||
|
||||
int fd = open(proc_inode, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
THROW_ERROR("failed to open file: %s", proc_inode);
|
||||
}
|
||||
do {
|
||||
len = read(fd, buf, sizeof(buf));
|
||||
if (len < 0) {
|
||||
THROW_ERROR("failed to read: %s", proc_inode);
|
||||
}
|
||||
} while (len == sizeof(buf));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Test cases for procfs
|
||||
// ============================================================================
|
||||
@ -136,41 +155,45 @@ static int test_read_from_proc_self_comm() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_read_from_proc_self_stat() {
|
||||
const char *proc_self_stat = "/proc/self/stat";
|
||||
FILE *fp = fopen(proc_self_stat, "r");
|
||||
if (fp == NULL) {
|
||||
THROW_ERROR("failed to fopen: %s", proc_self_stat);
|
||||
}
|
||||
|
||||
int pid, ppid, pgrp;
|
||||
char comm[32] = { 0 };
|
||||
char state[32] = { 0 };
|
||||
int ret = fscanf(fp, "%d %s %s %d %d", &pid, comm, state, &ppid, &pgrp);
|
||||
if (ret != 5) {
|
||||
THROW_ERROR("failed to parse the first 5 items");
|
||||
}
|
||||
if (pid != getpid()) {
|
||||
THROW_ERROR("failed to check the result in %s", proc_self_stat);
|
||||
}
|
||||
printf("cat %s with the first 5 items:\n%d %s %s %d %d\n", proc_self_stat, pid, comm,
|
||||
state, ppid, pgrp);
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_read_from_proc_meminfo() {
|
||||
char meminfo[1024] = { 0 };
|
||||
const char *proc_meminfo = "/proc/meminfo";
|
||||
|
||||
int fd = open(proc_meminfo, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
THROW_ERROR("failed to open file: %s", proc_meminfo);
|
||||
}
|
||||
if (read(fd, meminfo, sizeof(meminfo)) < 0) {
|
||||
if (test_read_from_procfs(proc_meminfo) < 0) {
|
||||
THROW_ERROR("failed to read the meminfo");
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_read_from_proc_cpuinfo() {
|
||||
char cpuinfo[1024] = { 0 };
|
||||
const char *proc_cpuinfo = "/proc/cpuinfo";
|
||||
int len;
|
||||
|
||||
int fd = open(proc_cpuinfo, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
THROW_ERROR("failed to open file: %s", proc_cpuinfo);
|
||||
if (test_read_from_procfs(proc_cpuinfo) < 0) {
|
||||
THROW_ERROR("failed to read the cpuinfo");
|
||||
}
|
||||
do {
|
||||
len = read(fd, cpuinfo, sizeof(cpuinfo));
|
||||
if (len < 0) {
|
||||
THROW_ERROR("failed to read the cpuinfo");
|
||||
} else if (len < sizeof(cpuinfo)) {
|
||||
break;
|
||||
}
|
||||
} while (len == sizeof(cpuinfo));
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -252,6 +275,7 @@ static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_create_and_unlink_file_from_proc_self_root),
|
||||
TEST_CASE(test_read_from_proc_self_cmdline),
|
||||
TEST_CASE(test_read_from_proc_self_comm),
|
||||
TEST_CASE(test_read_from_proc_self_stat),
|
||||
TEST_CASE(test_read_from_proc_meminfo),
|
||||
TEST_CASE(test_read_from_proc_cpuinfo),
|
||||
TEST_CASE(test_statfs),
|
||||
|
Loading…
Reference in New Issue
Block a user