mirror of
https://github.com/uutils/procps.git
synced 2026-06-10 16:14:00 -07:00
slabtop: Add command (#42)
This commit is contained in:
Generated
+364
-25
File diff suppressed because it is too large
Load Diff
+6
-8
@@ -25,13 +25,7 @@ build = "build.rs"
|
||||
default = ["feat_common_core"]
|
||||
uudoc = []
|
||||
|
||||
feat_common_core = [
|
||||
"pwdx",
|
||||
"free",
|
||||
"w",
|
||||
"watch",
|
||||
"pmap",
|
||||
]
|
||||
feat_common_core = ["pwdx", "free", "w", "watch", "pmap", "slabtop"]
|
||||
|
||||
[workspace.dependencies]
|
||||
uucore = "0.0.25"
|
||||
@@ -51,6 +45,8 @@ bytesize = "1.3.0"
|
||||
chrono = { version = "0.4.38", default-features = false, features = [
|
||||
"clock",
|
||||
] }
|
||||
ratatui = "0.26.1"
|
||||
crossterm = "0.27.0"
|
||||
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
@@ -60,7 +56,8 @@ uucore = { workspace = true }
|
||||
phf = { workspace = true }
|
||||
textwrap = { workspace = true }
|
||||
sysinfo = { workspace = true }
|
||||
|
||||
ratatui = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
|
||||
#
|
||||
pwdx = { optional = true, version = "0.0.1", package = "uu_pwdx", path = "src/uu/pwdx" }
|
||||
@@ -68,6 +65,7 @@ free = { optional = true, version = "0.0.1", package = "uu_free", path = "src/uu
|
||||
w = { optional = true, version = "0.0.1", package = "uu_w", path = "src/uu/w" }
|
||||
watch = { optional = true, version = "0.0.1", package = "uu_watch", path = "src/uu/watch" }
|
||||
pmap = { optional = true, version = "0.0.1", package = "uu_pmap", path = "src/uu/pmap" }
|
||||
slabtop = { optional = true, version = "0.0.1", package = "uu_slabtop", path = "src/uu/slabtop" }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1"
|
||||
|
||||
@@ -17,13 +17,13 @@ Ongoing:
|
||||
* `w`: Shows who is logged on and what they are doing.
|
||||
* `watch`: Executes a program periodically, showing output fullscreen.
|
||||
* `pmap`: Displays the memory map of a process.
|
||||
* `slabtop`: Displays detailed kernel slab cache information in real time.
|
||||
|
||||
TODO:
|
||||
* `ps`: Displays information about active processes.
|
||||
* `pgrep`: Searches for processes based on name and other attributes.
|
||||
* `pidwait`: Waits for a specific process to terminate.
|
||||
* `skill`: Sends a signal to processes based on criteria like user, terminal, etc.
|
||||
* `slabtop`: Displays detailed kernel slab cache information in real time.
|
||||
* `tload`: Prints a graphical representation of system load average to the terminal.
|
||||
* `top`: Displays real-time information about system processes.
|
||||
* `vmstat`: Reports information about processes, memory, paging, block IO, traps, and CPU activity.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "uu_slabtop"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "slabtop ~ (uutils) Display kernel slab cache information in real time"
|
||||
|
||||
homepage = "https://github.com/uutils/procps"
|
||||
repository = "https://github.com/uutils/procps/tree/main/src/uu/slabtop"
|
||||
keywords = ["acl", "uutils", "cross-platform", "cli", "utility"]
|
||||
categories = ["command-line-utilities"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
uucore = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
|
||||
[lib]
|
||||
path = "src/slabtop.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "slabtop"
|
||||
path = "src/main.rs"
|
||||
@@ -0,0 +1,7 @@
|
||||
# slabtop
|
||||
|
||||
```
|
||||
slabtop [options]
|
||||
```
|
||||
|
||||
Display kernel slab cache information in real time
|
||||
@@ -0,0 +1 @@
|
||||
uucore::bin!(uu_slabtop);
|
||||
@@ -0,0 +1,295 @@
|
||||
// This file is part of the uutils procps package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (words) symdir somefakedir
|
||||
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
fs,
|
||||
io::{Error, ErrorKind},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct SlabInfo {
|
||||
pub(crate) meta: Vec<String>,
|
||||
pub(crate) data: Vec<(String, Vec<u64>)>,
|
||||
}
|
||||
|
||||
impl SlabInfo {
|
||||
// parse slabinfo from /proc/slabinfo
|
||||
// need root permission
|
||||
pub fn new() -> Result<SlabInfo, Error> {
|
||||
let content = fs::read_to_string("/proc/slabinfo")?;
|
||||
|
||||
Self::parse(content).ok_or(ErrorKind::Unsupported.into())
|
||||
}
|
||||
|
||||
pub fn parse(content: String) -> Option<SlabInfo> {
|
||||
let mut lines: Vec<&str> = content.lines().collect();
|
||||
|
||||
let _ = parse_version(lines.remove(0))?;
|
||||
let meta = parse_meta(lines.remove(0));
|
||||
let data: Vec<(String, Vec<u64>)> = lines.into_iter().filter_map(parse_data).collect();
|
||||
|
||||
Some(SlabInfo { meta, data })
|
||||
}
|
||||
|
||||
pub fn fetch(&self, name: &str, meta: &str) -> Option<u64> {
|
||||
// fetch meta's offset
|
||||
let offset = self.offset(meta)?;
|
||||
|
||||
let (_, item) = self.data.iter().find(|(key, _)| key.eq(name))?;
|
||||
|
||||
item.get(offset).copied()
|
||||
}
|
||||
|
||||
pub fn names(&self) -> Vec<&String> {
|
||||
self.data.iter().map(|(k, _)| k).collect()
|
||||
}
|
||||
|
||||
pub fn sort(mut self, by: char, ascending_order: bool) -> Self {
|
||||
let mut sort = |by_meta: &str| {
|
||||
if let Some(offset) = self.offset(by_meta) {
|
||||
self.data.sort_by(|(_, data1), (_, data2)| {
|
||||
match (data1.get(offset), data2.get(offset)) {
|
||||
(Some(v1), Some(v2)) => {
|
||||
if ascending_order {
|
||||
v1.cmp(v2)
|
||||
} else {
|
||||
v2.cmp(v1)
|
||||
}
|
||||
}
|
||||
_ => Ordering::Equal,
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
match by {
|
||||
// <active_objs>
|
||||
'a' => sort("active_objs"),
|
||||
// <objperslab>
|
||||
'b' => sort("objperslab"),
|
||||
// <objsize> Maybe cache size I guess?
|
||||
// TODO: Check is <objsize>
|
||||
'c' => sort("objsize"),
|
||||
// <num_slabs>
|
||||
'l' => sort("num_slabs"),
|
||||
// <active_slabs>
|
||||
'v' => sort("active_slabs"),
|
||||
// name, sort by lexicographical order
|
||||
'n' => self.data.sort_by(|(name1, _), (name2, _)| {
|
||||
if ascending_order {
|
||||
name1.cmp(name2)
|
||||
} else {
|
||||
name2.cmp(name1)
|
||||
}
|
||||
}),
|
||||
// <pagesperslab>
|
||||
'p' => sort("pagesperslab"),
|
||||
// <objsize>
|
||||
's' => sort("objsize"),
|
||||
// sort by cache utilization
|
||||
'u' => {
|
||||
let offset_active_objs = self.offset("active_objs");
|
||||
let offset_num_objs = self.offset("num_objs");
|
||||
|
||||
if let (Some(offset_active_objs), Some(offset_num_objs)) =
|
||||
(offset_active_objs, offset_num_objs)
|
||||
{
|
||||
self.data.sort_by(|(_, data1), (_, data2)| {
|
||||
let cu = |active_jobs: Option<&u64>, num_jobs: Option<&u64>| match (
|
||||
active_jobs,
|
||||
num_jobs,
|
||||
) {
|
||||
(Some(active_jobs), Some(num_jobs)) => {
|
||||
Some((*active_jobs as f64) / (*num_jobs as f64))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let cu1 = cu(data1.get(offset_active_objs), data1.get(offset_num_objs));
|
||||
let cu2 = cu(data2.get(offset_active_objs), data2.get(offset_num_objs));
|
||||
|
||||
if let (Some(cu1), Some(cu2)) = (cu1, cu2) {
|
||||
let result = if ascending_order {
|
||||
cu1.partial_cmp(&cu2)
|
||||
} else {
|
||||
cu2.partial_cmp(&cu1)
|
||||
};
|
||||
match result {
|
||||
Some(ord) => ord,
|
||||
None => Ordering::Equal,
|
||||
}
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// <num_objs>
|
||||
// Default branch : `o`
|
||||
_ => sort("num_objs"),
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn offset(&self, meta: &str) -> Option<usize> {
|
||||
self.meta.iter().position(|it| it.eq(meta))
|
||||
}
|
||||
|
||||
/////////////////////////////////// helpers ///////////////////////////////////
|
||||
|
||||
#[inline]
|
||||
fn total(&self, meta: &str) -> u64 {
|
||||
let Some(offset) = self.offset(meta) else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
self.data
|
||||
.iter()
|
||||
.filter_map(|(_, data)| data.get(offset))
|
||||
.sum::<u64>()
|
||||
}
|
||||
|
||||
pub fn object_minimum(&self) -> u64 {
|
||||
let Some(offset) = self.offset("objsize") else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
match self
|
||||
.data
|
||||
.iter()
|
||||
.filter_map(|(_, data)| data.get(offset))
|
||||
.min()
|
||||
{
|
||||
Some(min) => *min,
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object_maximum(&self) -> u64 {
|
||||
let Some(offset) = self.offset("objsize") else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
match self
|
||||
.data
|
||||
.iter()
|
||||
.filter_map(|(_, data)| data.get(offset))
|
||||
.max()
|
||||
{
|
||||
Some(max) => *max,
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object_avg(&self) -> u64 {
|
||||
let Some(offset) = self.offset("objsize") else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
let iter = self.data.iter().filter_map(|(_, data)| data.get(offset));
|
||||
|
||||
let count = iter.clone().count();
|
||||
let sum = iter.sum::<u64>();
|
||||
|
||||
if count == 0 {
|
||||
0
|
||||
} else {
|
||||
(sum) / (count as u64)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn total_active_objs(&self) -> u64 {
|
||||
self.total("active_objs")
|
||||
}
|
||||
|
||||
pub fn total_objs(&self) -> u64 {
|
||||
self.total("num_objs")
|
||||
}
|
||||
|
||||
pub fn total_active_slabs(&self) -> u64 {
|
||||
self.total("active_slabs")
|
||||
}
|
||||
|
||||
pub fn total_slabs(&self) -> u64 {
|
||||
self.total("num_slabs")
|
||||
}
|
||||
|
||||
pub fn total_active_size(&self) -> u64 {
|
||||
self.names()
|
||||
.iter()
|
||||
.map(|name| {
|
||||
self.fetch(name, "active_objs").unwrap_or_default()
|
||||
* self.fetch(name, "objsize").unwrap_or_default()
|
||||
})
|
||||
.sum::<u64>()
|
||||
}
|
||||
|
||||
pub fn total_size(&self) -> u64 {
|
||||
self.names()
|
||||
.iter()
|
||||
.map(|name| {
|
||||
self.fetch(name, "num_objs").unwrap_or_default()
|
||||
* self.fetch(name, "objsize").unwrap_or_default()
|
||||
})
|
||||
.sum::<u64>()
|
||||
}
|
||||
|
||||
pub fn total_active_cache(&self) -> u64 {
|
||||
self.names()
|
||||
.iter()
|
||||
.map(|name| {
|
||||
self.fetch(name, "objsize").unwrap_or_default()
|
||||
* self.fetch(name, "active_objs").unwrap_or_default()
|
||||
})
|
||||
.sum::<u64>()
|
||||
}
|
||||
|
||||
pub fn total_cache(&self) -> u64 {
|
||||
self.names()
|
||||
.iter()
|
||||
.map(|name| {
|
||||
self.fetch(name, "objsize").unwrap_or_default()
|
||||
* self.fetch(name, "num_objs").unwrap_or_default()
|
||||
})
|
||||
.sum::<u64>()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_version(line: &str) -> Option<String> {
|
||||
line.replace(':', " ")
|
||||
.split_whitespace()
|
||||
.last()
|
||||
.map(String::from)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_meta(line: &str) -> Vec<String> {
|
||||
line.replace(['#', ':'], " ")
|
||||
.split_whitespace()
|
||||
.filter(|it| it.starts_with('<') && it.ends_with('>'))
|
||||
.map(|it| it.replace(['<', '>'], ""))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn parse_data(line: &str) -> Option<(String, Vec<u64>)> {
|
||||
let split: Vec<String> = line
|
||||
.replace(':', " ")
|
||||
.split_whitespace()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
|
||||
split.first().map(|name| {
|
||||
(
|
||||
name.to_string(),
|
||||
split
|
||||
.clone()
|
||||
.into_iter()
|
||||
.flat_map(|it| it.parse::<u64>())
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// This file is part of the uutils procps package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::parse::SlabInfo;
|
||||
use clap::{arg, crate_version, ArgAction, Command};
|
||||
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||
|
||||
const ABOUT: &str = help_about!("slabtop.md");
|
||||
const USAGE: &str = help_usage!("slabtop.md");
|
||||
|
||||
mod parse;
|
||||
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uu_app().try_get_matches_from(args)?;
|
||||
|
||||
let sort_flag = matches
|
||||
.try_get_one::<char>("sort")
|
||||
.ok()
|
||||
.unwrap_or(Some(&'o'))
|
||||
.unwrap_or(&'o');
|
||||
|
||||
let slabinfo = SlabInfo::new()?.sort(*sort_flag, false);
|
||||
|
||||
println!(
|
||||
r" Active / Total Objects (% used) : {} / {} ({:.1}%)",
|
||||
slabinfo.total_active_objs(),
|
||||
slabinfo.total_objs(),
|
||||
percentage(slabinfo.total_active_objs(), slabinfo.total_objs())
|
||||
);
|
||||
println!(
|
||||
r" Active / Total Slabs (% used) : {} / {} ({:.1}%)",
|
||||
slabinfo.total_active_slabs(),
|
||||
slabinfo.total_slabs(),
|
||||
percentage(slabinfo.total_active_slabs(), slabinfo.total_slabs(),)
|
||||
);
|
||||
|
||||
// TODO: I don't know the 'cache' meaning.
|
||||
println!(
|
||||
r" Active / Total Caches (% used) : {} / {} ({:.1}%)",
|
||||
slabinfo.total_active_cache(),
|
||||
slabinfo.total_cache(),
|
||||
percentage(slabinfo.total_active_cache(), slabinfo.total_cache())
|
||||
);
|
||||
|
||||
println!(
|
||||
r" Active / Total Size (% used) : {:.2}K / {:.2}K ({:.1}%)",
|
||||
to_kb(slabinfo.total_active_size()),
|
||||
to_kb(slabinfo.total_size()),
|
||||
percentage(slabinfo.total_active_size(), slabinfo.total_size())
|
||||
);
|
||||
|
||||
println!(
|
||||
r" Minimum / Average / Maximum Object : {:.2}K / {:.2}K / {:.2}K",
|
||||
to_kb(slabinfo.object_minimum()),
|
||||
to_kb(slabinfo.object_avg()),
|
||||
to_kb(slabinfo.object_maximum())
|
||||
);
|
||||
|
||||
// TODO: TUI Implementation
|
||||
let title = format!(
|
||||
"{:>6} {:>6} {:>4} {:>8} {:>6} {:>8} {:>10} {:<}",
|
||||
"OBJS", "ACTIVE", "USE", "OBJ SIZE", "SLABS", "OBJ/SLAB", "CACHE SIZE", "NAME"
|
||||
);
|
||||
println!("{}", title);
|
||||
|
||||
output(&slabinfo);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn to_kb(byte: u64) -> f64 {
|
||||
byte as f64 / 1024.0
|
||||
}
|
||||
|
||||
fn percentage(numerator: u64, denominator: u64) -> f64 {
|
||||
if denominator == 0 {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
let numerator = numerator as f64;
|
||||
let denominator = denominator as f64;
|
||||
|
||||
(numerator / denominator) * 100.0
|
||||
}
|
||||
|
||||
fn output(info: &SlabInfo) {
|
||||
for name in info.names() {
|
||||
let objs = info.fetch(name, "num_objs").unwrap_or_default();
|
||||
let active = info.fetch(name, "active_objs").unwrap_or_default();
|
||||
let used = format!("{:.0}%", percentage(active, objs));
|
||||
let objsize = {
|
||||
let size = info.fetch(name, "objsize").unwrap_or_default(); // Byte to KB :1024
|
||||
size as f64 / 1024.0
|
||||
};
|
||||
let slabs = info.fetch(name, "num_slabs").unwrap_or_default();
|
||||
let obj_per_slab = info.fetch(name, "objperslab").unwrap_or_default();
|
||||
|
||||
let cache_size = (objsize * (objs as f64)) as u64;
|
||||
let objsize = format!("{:.2}", objsize);
|
||||
|
||||
let content = format!(
|
||||
"{:>6} {:>6} {:>4} {:>7}K {:>6} {:>8} {:>10} {:<}",
|
||||
objs, active, used, objsize, slabs, obj_per_slab, cache_size, name
|
||||
);
|
||||
|
||||
println!("{}", content);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.disable_help_flag(true)
|
||||
.args([
|
||||
// arg!(-d --delay <secs> "delay updates"),
|
||||
// arg!(-o --once "only display once, then exit"),
|
||||
arg!(-s --sort <char> "specify sort criteria by character (see below)"),
|
||||
arg!(-h --help "display this help and exit").action(ArgAction::Help),
|
||||
])
|
||||
.after_help(
|
||||
r"The following are valid sort criteria:
|
||||
a: sort by number of active objects
|
||||
b: sort by objects per slab
|
||||
c: sort by cache size
|
||||
l: sort by number of slabs
|
||||
v: sort by (non display) number of active slabs
|
||||
n: sort by name
|
||||
o: sort by number of objects (the default)
|
||||
p: sort by (non display) pages per slab
|
||||
s: sort by object size
|
||||
u: sort by cache utilization",
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
use crate::common::util::TestScenario;
|
||||
use crate::test_slabtop::parse::parse_data;
|
||||
use crate::test_slabtop::parse::parse_meta;
|
||||
use crate::test_slabtop::parse::parse_version;
|
||||
use crate::test_slabtop::parse::SlabInfo;
|
||||
|
||||
#[path = "../../src/uu/slabtop/src/parse.rs"]
|
||||
mod parse;
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slabtop() {
|
||||
new_ucmd!().arg("--help").succeeds().code_is(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_version() {
|
||||
let test = "slabinfo - version: 2.1";
|
||||
assert_eq!("2.1", parse_version(test).unwrap())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_meta() {
|
||||
let test="# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>";
|
||||
|
||||
let result = parse_meta(test);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
[
|
||||
"active_objs",
|
||||
"num_objs",
|
||||
"objsize",
|
||||
"objperslab",
|
||||
"pagesperslab",
|
||||
"limit",
|
||||
"batchcount",
|
||||
"sharedfactor",
|
||||
"active_slabs",
|
||||
"num_slabs",
|
||||
"sharedavail"
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_data() {
|
||||
// Success case
|
||||
|
||||
let test = "nf_conntrack_expect 0 0 208 39 2 : tunables 0 0 0 : slabdata 0 0 0";
|
||||
let (name, value) = parse_data(test).unwrap();
|
||||
|
||||
assert_eq!(name, "nf_conntrack_expect");
|
||||
assert_eq!(value, [0, 0, 208, 39, 2, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// Fail case
|
||||
let test =
|
||||
"0 0 208 39 2 : tunables 0 0 0 : slabdata 0 0 0";
|
||||
let (name, _value) = parse_data(test).unwrap();
|
||||
|
||||
assert_ne!(name, "nf_conntrack_expect");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let test = include_str!("../fixtures/slabtop/data.txt");
|
||||
let result = SlabInfo::parse(test.into()).unwrap();
|
||||
|
||||
assert_eq!(result.fetch("nf_conntrack_expect", "objsize").unwrap(), 208);
|
||||
assert_eq!(
|
||||
result.fetch("dmaengine-unmap-2", "active_slabs").unwrap(),
|
||||
16389
|
||||
);
|
||||
}
|
||||
@@ -29,13 +29,13 @@ fn test_output_format() {
|
||||
let output_lines = cmd.stdout_str().lines();
|
||||
|
||||
for line in output_lines {
|
||||
let line_vec: Vec<String> = line.split_whitespace().map(String::from).collect();
|
||||
let line_vec: Vec<String> = line.split_whitespace().map(|s| String::from(s)).collect();
|
||||
// Check the time formatting, this should be the third entry in list
|
||||
// For now, we are just going to check that that length of time is 5 and it has a colon, else
|
||||
// it is possible that a time can look like Fri13, so it can start with a letter and end
|
||||
// with a number
|
||||
assert!(
|
||||
(line_vec[2].contains(':') && line_vec[2].chars().count() == 5)
|
||||
(line_vec[2].contains(":") && line_vec[2].chars().count() == 5)
|
||||
|| (line_vec[2].starts_with(char::is_alphabetic)
|
||||
&& line_vec[2].ends_with(char::is_numeric)
|
||||
&& line_vec[2].chars().count() == 5)
|
||||
|
||||
Vendored
+176
@@ -0,0 +1,176 @@
|
||||
slabinfo - version: 2.1
|
||||
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
|
||||
nf_conntrack_expect 0 0 208 39 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
nf_conntrack 1428 1536 256 32 2 : tunables 0 0 0 : slabdata 48 48 0
|
||||
QIPCRTR 2 78 832 39 8 : tunables 0 0 0 : slabdata 2 2 0
|
||||
ovl_inode 264 540 720 45 8 : tunables 0 0 0 : slabdata 12 12 0
|
||||
kvm_vcpu 0 0 7288 4 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
x86_emulator 0 0 2656 12 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
fat_inode_cache 12 246 792 41 8 : tunables 0 0 0 : slabdata 6 6 0
|
||||
fat_cache 0 102 40 102 1 : tunables 0 0 0 : slabdata 1 1 0
|
||||
kcopyd_job 0 0 3240 10 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dm_uevent 0 0 2888 11 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
btrfs_delayed_ref_head 1140 1140 136 30 1 : tunables 0 0 0 : slabdata 38 38 0
|
||||
btrfs_ordered_extent 1178 1178 424 38 4 : tunables 0 0 0 : slabdata 31 31 0
|
||||
btrfs_extent_map 78368 78512 144 28 1 : tunables 0 0 0 : slabdata 2804 2804 0
|
||||
bio-304 2 25 320 25 2 : tunables 0 0 0 : slabdata 1 1 0
|
||||
bio-368 1344 1554 384 42 4 : tunables 0 0 0 : slabdata 37 37 0
|
||||
btrfs_extent_buffer 7805 13906 240 34 2 : tunables 0 0 0 : slabdata 409 409 0
|
||||
btrfs_free_space 8100 8541 104 39 1 : tunables 0 0 0 : slabdata 219 219 0
|
||||
btrfs_path 1440 1440 112 36 1 : tunables 0 0 0 : slabdata 40 40 0
|
||||
bio-384 2 36 448 36 4 : tunables 0 0 0 : slabdata 1 1 0
|
||||
btrfs_inode 81157 81172 1136 28 8 : tunables 0 0 0 : slabdata 2899 2899 0
|
||||
bio-440 2 36 448 36 4 : tunables 0 0 0 : slabdata 1 1 0
|
||||
bio-128 1260 1260 192 42 2 : tunables 0 0 0 : slabdata 30 30 0
|
||||
scsi_sense_cache 160 160 128 32 1 : tunables 0 0 0 : slabdata 5 5 0
|
||||
fsverity_info 0 0 272 30 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
fscrypt_info 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
MPTCPv6 0 0 2112 15 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
ip6-frags 0 0 184 44 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
PINGv6 0 0 1216 26 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
RAWv6 234 234 1216 26 8 : tunables 0 0 0 : slabdata 9 9 0
|
||||
UDPv6 480 480 1344 24 8 : tunables 0 0 0 : slabdata 20 20 0
|
||||
tw_sock_TCPv6 150 180 272 30 2 : tunables 0 0 0 : slabdata 6 6 0
|
||||
request_sock_TCPv6 0 0 312 26 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
TCPv6 286 286 2432 13 8 : tunables 0 0 0 : slabdata 22 22 0
|
||||
io_kiocb 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
mqueue_inode_cache 38 204 960 34 8 : tunables 0 0 0 : slabdata 6 6 0
|
||||
fuse_request 234 234 152 26 1 : tunables 0 0 0 : slabdata 9 9 0
|
||||
fuse_inode 112 468 896 36 8 : tunables 0 0 0 : slabdata 13 13 0
|
||||
kioctx 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0
|
||||
userfaultfd_ctx_cache 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dnotify_struct 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
UNIX 1495 1590 1088 30 8 : tunables 0 0 0 : slabdata 53 53 0
|
||||
ip4-frags 0 0 200 40 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
MPTCP 0 0 1984 16 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
request_sock_subflow_v6 0 0 384 42 4 : tunables 0 0 0 : slabdata 0 0 0
|
||||
request_sock_subflow_v4 0 0 384 42 4 : tunables 0 0 0 : slabdata 0 0 0
|
||||
xfrm_dst_cache 25668 25675 320 25 2 : tunables 0 0 0 : slabdata 1027 1027 0
|
||||
xfrm_state 0 0 768 42 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
ip_fib_trie 680 680 48 85 1 : tunables 0 0 0 : slabdata 8 8 0
|
||||
ip_fib_alias 584 584 56 73 1 : tunables 0 0 0 : slabdata 8 8 0
|
||||
PING 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
RAW 32 32 1024 32 8 : tunables 0 0 0 : slabdata 1 1 0
|
||||
tw_sock_TCP 690 690 272 30 2 : tunables 0 0 0 : slabdata 23 23 0
|
||||
request_sock_TCP 494 494 312 26 2 : tunables 0 0 0 : slabdata 19 19 0
|
||||
TCP 658 658 2304 14 8 : tunables 0 0 0 : slabdata 47 47 0
|
||||
hugetlbfs_inode_cache 25 72 664 24 4 : tunables 0 0 0 : slabdata 3 3 0
|
||||
dquot 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
bio-256 50 50 320 25 2 : tunables 0 0 0 : slabdata 2 2 0
|
||||
ep_head 5888 5888 16 256 1 : tunables 0 0 0 : slabdata 23 23 0
|
||||
dax_cache 39 39 832 39 8 : tunables 0 0 0 : slabdata 1 1 0
|
||||
request_queue 47 175 936 35 8 : tunables 0 0 0 : slabdata 5 5 0
|
||||
blkdev_ioc 184 184 88 46 1 : tunables 0 0 0 : slabdata 4 4 0
|
||||
bio-192 896 1024 256 32 2 : tunables 0 0 0 : slabdata 32 32 0
|
||||
biovec-max 429 440 4096 8 8 : tunables 0 0 0 : slabdata 55 55 0
|
||||
biovec-128 16 64 2048 16 8 : tunables 0 0 0 : slabdata 4 4 0
|
||||
biovec-64 32 192 1024 32 8 : tunables 0 0 0 : slabdata 6 6 0
|
||||
khugepaged_mm_slot 2652 2652 40 102 1 : tunables 0 0 0 : slabdata 26 26 0
|
||||
user_namespace 135 234 624 26 4 : tunables 0 0 0 : slabdata 9 9 0
|
||||
dmaengine-unmap-256 15 15 2112 15 8 : tunables 0 0 0 : slabdata 1 1 0
|
||||
dmaengine-unmap-128 30 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0
|
||||
dmaengine-unmap-2 1048896 1048896 64 64 1 : tunables 0 0 0 : slabdata 16389 16389 0
|
||||
audit_buffer 170 1020 24 170 1 : tunables 0 0 0 : slabdata 6 6 0
|
||||
sock_inode_cache 2428 3042 832 39 8 : tunables 0 0 0 : slabdata 78 78 0
|
||||
skbuff_ext_cache 3815 4872 192 42 2 : tunables 0 0 0 : slabdata 116 116 0
|
||||
skbuff_small_head 950 950 640 25 4 : tunables 0 0 0 : slabdata 38 38 0
|
||||
skbuff_head_cache 1440 1440 256 32 2 : tunables 0 0 0 : slabdata 45 45 0
|
||||
tracefs_inode_cache 236 240 656 24 4 : tunables 0 0 0 : slabdata 10 10 0
|
||||
file_lock_cache 1036 1036 216 37 2 : tunables 0 0 0 : slabdata 28 28 0
|
||||
buffer_head 1587 1755 104 39 1 : tunables 0 0 0 : slabdata 45 45 0
|
||||
task_delay_info 38 252 144 28 1 : tunables 0 0 0 : slabdata 9 9 0
|
||||
taskstats 925 925 432 37 4 : tunables 0 0 0 : slabdata 25 25 0
|
||||
proc_dir_entry 2016 2016 192 42 2 : tunables 0 0 0 : slabdata 48 48 0
|
||||
proc_inode_cache 15645 19550 712 46 8 : tunables 0 0 0 : slabdata 425 425 0
|
||||
seq_file 1122 1122 120 34 1 : tunables 0 0 0 : slabdata 33 33 0
|
||||
sigqueue 2156 2295 80 51 1 : tunables 0 0 0 : slabdata 45 45 0
|
||||
bdev_cache 39 100 1600 20 8 : tunables 0 0 0 : slabdata 5 5 0
|
||||
shmem_inode_cache 5690 5840 800 40 8 : tunables 0 0 0 : slabdata 146 146 0
|
||||
kernfs_node_cache 56421 56480 128 32 1 : tunables 0 0 0 : slabdata 1765 1765 0
|
||||
mnt_cache 1925 1925 320 25 2 : tunables 0 0 0 : slabdata 77 77 0
|
||||
filp 23221 24768 256 32 2 : tunables 0 0 0 : slabdata 774 774 0
|
||||
inode_cache 11014 12325 640 25 4 : tunables 0 0 0 : slabdata 493 493 0
|
||||
dentry 206491 207690 192 42 2 : tunables 0 0 0 : slabdata 4945 4945 0
|
||||
names_cache 160 160 4096 8 8 : tunables 0 0 0 : slabdata 20 20 0
|
||||
net_namespace 44 63 4480 7 8 : tunables 0 0 0 : slabdata 9 9 0
|
||||
iint_cache 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
lsm_file_cache 137599 139392 32 128 1 : tunables 0 0 0 : slabdata 1089 1089 0
|
||||
uts_namespace 296 296 432 37 4 : tunables 0 0 0 : slabdata 8 8 0
|
||||
nsproxy 896 896 72 56 1 : tunables 0 0 0 : slabdata 16 16 0
|
||||
vma_lock 121072 124746 40 102 1 : tunables 0 0 0 : slabdata 1223 1223 0
|
||||
vm_area_struct 120603 123816 184 44 2 : tunables 0 0 0 : slabdata 2814 2814 0
|
||||
files_cache 1196 1196 704 46 8 : tunables 0 0 0 : slabdata 26 26 0
|
||||
signal_cache 1074 1148 1152 28 8 : tunables 0 0 0 : slabdata 41 41 0
|
||||
sighand_cache 844 885 2112 15 8 : tunables 0 0 0 : slabdata 59 59 0
|
||||
task_struct 2645 2670 6528 5 8 : tunables 0 0 0 : slabdata 534 534 0
|
||||
cred_jar 2310 2310 192 42 2 : tunables 0 0 0 : slabdata 55 55 0
|
||||
anon_vma_chain 60015 65280 64 64 1 : tunables 0 0 0 : slabdata 1020 1020 0
|
||||
anon_vma 38443 40443 104 39 1 : tunables 0 0 0 : slabdata 1037 1037 0
|
||||
pid 4045 4224 128 32 1 : tunables 0 0 0 : slabdata 132 132 0
|
||||
irq_remap_cache 27 48 8192 4 8 : tunables 0 0 0 : slabdata 12 12 0
|
||||
Acpi-State 3430 3519 80 51 1 : tunables 0 0 0 : slabdata 69 69 0
|
||||
shared_policy_node 3315 3315 48 85 1 : tunables 0 0 0 : slabdata 39 39 0
|
||||
numa_policy 30 30 272 30 2 : tunables 0 0 0 : slabdata 1 1 0
|
||||
perf_event 550 550 1264 25 8 : tunables 0 0 0 : slabdata 22 22 0
|
||||
trace_event_file 2191 2562 96 42 1 : tunables 0 0 0 : slabdata 61 61 0
|
||||
ftrace_event_field 8395 8395 56 73 1 : tunables 0 0 0 : slabdata 115 115 0
|
||||
pool_workqueue 1792 1792 512 32 4 : tunables 0 0 0 : slabdata 56 56 0
|
||||
maple_node 12054 13728 256 32 2 : tunables 0 0 0 : slabdata 429 429 0
|
||||
radix_tree_node 208307 208628 584 28 4 : tunables 0 0 0 : slabdata 7451 7451 0
|
||||
task_group 700 700 640 25 4 : tunables 0 0 0 : slabdata 28 28 0
|
||||
mm_struct 667 667 1408 23 8 : tunables 0 0 0 : slabdata 29 29 0
|
||||
vmap_area 16392 19432 72 56 1 : tunables 0 0 0 : slabdata 347 347 0
|
||||
kmalloc-cg-8k 88 88 8192 4 8 : tunables 0 0 0 : slabdata 22 22 0
|
||||
kmalloc-cg-4k 400 400 4096 8 8 : tunables 0 0 0 : slabdata 50 50 0
|
||||
kmalloc-cg-2k 864 912 2048 16 8 : tunables 0 0 0 : slabdata 57 57 0
|
||||
kmalloc-cg-1k 1132 1280 1024 32 8 : tunables 0 0 0 : slabdata 40 40 0
|
||||
kmalloc-cg-512 1462 1504 512 32 4 : tunables 0 0 0 : slabdata 47 47 0
|
||||
kmalloc-cg-256 704 704 256 32 2 : tunables 0 0 0 : slabdata 22 22 0
|
||||
kmalloc-cg-192 1638 1638 192 42 2 : tunables 0 0 0 : slabdata 39 39 0
|
||||
kmalloc-cg-128 1024 1024 128 32 1 : tunables 0 0 0 : slabdata 32 32 0
|
||||
kmalloc-cg-96 1386 1386 96 42 1 : tunables 0 0 0 : slabdata 33 33 0
|
||||
kmalloc-cg-64 2509 2752 64 64 1 : tunables 0 0 0 : slabdata 43 43 0
|
||||
kmalloc-cg-32 3584 3584 32 128 1 : tunables 0 0 0 : slabdata 28 28 0
|
||||
kmalloc-cg-16 6400 6400 16 256 1 : tunables 0 0 0 : slabdata 25 25 0
|
||||
kmalloc-cg-8 6772 7680 8 512 1 : tunables 0 0 0 : slabdata 15 15 0
|
||||
dma-kmalloc-8k 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-4k 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-2k 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-1k 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-512 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-256 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-192 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-128 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-96 0 0 96 42 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-64 0 0 64 64 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
dma-kmalloc-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-8k 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-4k 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-2k 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-1k 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-512 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-256 32 32 256 32 2 : tunables 0 0 0 : slabdata 1 1 0
|
||||
kmalloc-rcl-192 256 336 192 42 2 : tunables 0 0 0 : slabdata 8 8 0
|
||||
kmalloc-rcl-128 1408 1408 128 32 1 : tunables 0 0 0 : slabdata 44 44 0
|
||||
kmalloc-rcl-96 3926 3948 96 42 1 : tunables 0 0 0 : slabdata 94 94 0
|
||||
kmalloc-rcl-64 39865 39872 64 64 1 : tunables 0 0 0 : slabdata 623 623 0
|
||||
kmalloc-rcl-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-rcl-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0
|
||||
kmalloc-8k 543 580 8192 4 8 : tunables 0 0 0 : slabdata 145 145 0
|
||||
kmalloc-4k 1201 1240 4096 8 8 : tunables 0 0 0 : slabdata 155 155 0
|
||||
kmalloc-2k 1655 1808 2048 16 8 : tunables 0 0 0 : slabdata 113 113 0
|
||||
kmalloc-1k 10620 11488 1024 32 8 : tunables 0 0 0 : slabdata 359 359 0
|
||||
kmalloc-512 18788 18880 512 32 4 : tunables 0 0 0 : slabdata 590 590 0
|
||||
kmalloc-256 16020 16192 256 32 2 : tunables 0 0 0 : slabdata 506 506 0
|
||||
kmalloc-192 3353 3444 192 42 2 : tunables 0 0 0 : slabdata 82 82 0
|
||||
kmalloc-128 19951 20160 128 32 1 : tunables 0 0 0 : slabdata 630 630 0
|
||||
kmalloc-96 5736 6258 96 42 1 : tunables 0 0 0 : slabdata 149 149 0
|
||||
kmalloc-64 22592 24256 64 64 1 : tunables 0 0 0 : slabdata 379 379 0
|
||||
kmalloc-32 20258 20480 32 128 1 : tunables 0 0 0 : slabdata 160 160 0
|
||||
kmalloc-16 25920 26112 16 256 1 : tunables 0 0 0 : slabdata 102 102 0
|
||||
kmalloc-8 30083 30208 8 512 1 : tunables 0 0 0 : slabdata 59 59 0
|
||||
kmem_cache_node 219 576 64 64 1 : tunables 0 0 0 : slabdata 9 9 0
|
||||
kmem_cache 187 352 256 32 2 : tunables 0 0 0 : slabdata 11 11 0
|
||||
@@ -24,3 +24,7 @@ mod test_watch;
|
||||
#[cfg(feature = "pmap")]
|
||||
#[path = "by-util/test_pmap.rs"]
|
||||
mod test_pmap;
|
||||
|
||||
#[cfg(feature = "slabtop")]
|
||||
#[path = "by-util/test_slabtop.rs"]
|
||||
mod test_slabtop;
|
||||
|
||||
Reference in New Issue
Block a user