74 lines
3.2 KiB
Rust
74 lines
3.2 KiB
Rust
use log::{debug, error, trace, warn};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::fs;
|
|
use std::io;
|
|
use std::path::Path;
|
|
|
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
|
pub(crate) struct Ptypes {
|
|
pub(crate) running: u32, // R => Running
|
|
pub(crate) sleeping: u32, // S => Sleeping in an interruptible wait
|
|
pub(crate) waiting: u32, // D => Waiting in uninterruptible disk sleep
|
|
pub(crate) zombie: u32, // Z => Zombie
|
|
pub(crate) stopped: u32, // T => Stopped (on a signal) or (before Linux 2.6.33) trace stopped
|
|
pub(crate) stop: u32, // t => tracing stop (Linux 2.6.33 onward)
|
|
//pub(crate) paging: u64, // W => Paging (only before Linux 2.6.0)
|
|
pub(crate) dead: u32, // X => Dead (from Linux 2.6.0 onward) or x => Dead (Linux 2.6.33 to 3.13 only)
|
|
pub(crate) wakekill: u32, // K => Wakekill (Linux 2.6.33 to 3.13 only)
|
|
pub(crate) waking: u32, // W => Waking (Linux 2.6.33 to 3.13 only)
|
|
pub(crate) idle: u32, // I => Idle (Linux 4.14 onward)
|
|
}
|
|
|
|
pub(crate) fn count_processes(proc_path: &Path) -> io::Result<Ptypes> {
|
|
let mut counts = Ptypes::default();
|
|
|
|
debug!("Staring count_processes, iterating over {:?}", proc_path);
|
|
for entry_result in fs::read_dir(proc_path)? {
|
|
let entry = entry_result?;
|
|
let path = entry.path();
|
|
|
|
// Check if the directory name is a number (a PID)
|
|
if path.is_dir()
|
|
&& path
|
|
.file_name()
|
|
.and_then(|s| s.to_str())
|
|
.unwrap_or("")
|
|
.parse::<u32>()
|
|
.is_ok()
|
|
{
|
|
let stat_path = path.join("stat");
|
|
|
|
trace!("now reading contents of {:?}", stat_path);
|
|
if let Ok(stat_contents) = fs::read_to_string(&stat_path) {
|
|
// Read whole file, we read from memory, so we can search ")" from behind.
|
|
if let Some(pos) = stat_contents.rfind(")") {
|
|
match stat_contents.as_bytes().get(pos + 2) {
|
|
Some(&byteval) => {
|
|
match byteval {
|
|
82 => counts.running += 1, // R
|
|
83 => counts.sleeping += 1, // S
|
|
68 => counts.waiting += 1, // D
|
|
84 => counts.stopped += 1, // T
|
|
116 => counts.stop += 1, // t
|
|
//87 => counts.paging += 1, // W --> only before 2.6 !!
|
|
88 => counts.dead += 1, // X
|
|
120 => counts.dead += 1, // x
|
|
75 => counts.wakekill += 1, // K
|
|
87 => counts.waking += 1, // W
|
|
73 => counts.idle += 1, // I
|
|
_ => warn!("unknown proc status value {}", byteval),
|
|
}
|
|
}
|
|
None => {
|
|
error!("Problem parsing stat data {}", stat_contents);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
error!("read_to_string failed for {:?}", stat_path);
|
|
}
|
|
}
|
|
}
|
|
Ok(counts)
|
|
}
|