summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeon Yang (Containers) <lnyng@meta.com>2024-01-25 19:36:06 -0800
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>2024-01-25 19:36:06 -0800
commita1395ebb09e3f647a7c7eedc6f2296b1e22c75a1 (patch)
treeb2fcc3e2860e84a5cc71af7ae9dabd31625c6e7d
parent5ff74b43a51c737bd9acb603a830f0313296ba92 (diff)
add read_slabinfo
Summary: Add function to read /proc/slabinfo Reviewed By: brianc118 Differential Revision: D53074161 fbshipit-source-id: c8831237b4709a79d40abebf2f69faee5cdbe017
-rw-r--r--below/procfs/src/lib.rs29
-rw-r--r--below/procfs/src/test.rs115
-rw-r--r--below/procfs/src/types.rs13
3 files changed, 157 insertions, 0 deletions
diff --git a/below/procfs/src/lib.rs b/below/procfs/src/lib.rs
index c3f0afaa..bc614ab4 100644
--- a/below/procfs/src/lib.rs
+++ b/below/procfs/src/lib.rs
@@ -393,6 +393,35 @@ impl ProcReader {
}
}
+ pub fn read_slabinfo(&self) -> Result<SlabInfoMap> {
+ let path = self.path.join("slabinfo");
+ let file = File::open(&path).map_err(|e| Error::IoError(path.clone(), e))?;
+ let buf_reader = BufReader::new(file);
+ let mut slab_info_map: SlabInfoMap = Default::default();
+
+ // The first line is version, second line is headers:
+ //
+ // slabinfo - version: 2.1
+ // # name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
+ //
+ for line in buf_reader.lines().skip(2) {
+ let line = line.map_err(|e| Error::IoError(path.clone(), e))?;
+ let mut items = line.split_whitespace();
+ let mut slab_info: SlabInfo = Default::default();
+ let name = items.next().unwrap().to_owned();
+ slab_info.name = Some(name.clone());
+ slab_info.active_objs = parse_item!(path, items.next(), u64, line)?;
+ slab_info.num_objs = parse_item!(path, items.next(), u64, line)?;
+ slab_info.obj_size = parse_item!(path, items.next(), u64, line)?;
+ slab_info.obj_per_slab = parse_item!(path, items.next(), u64, line)?;
+ slab_info.pages_per_slab = parse_item!(path, items.next(), u64, line)?;
+ slab_info.active_slabs = parse_item!(path, items.nth(7), u64, line)?;
+ slab_info.num_slabs = parse_item!(path, items.next(), u64, line)?;
+ slab_info_map.insert(name, slab_info);
+ }
+ Ok(slab_info_map)
+ }
+
fn read_disk_fsinfo(&self, mount_info: &MountInfo) -> Option<(f32, u64)> {
if let Some(mount_point) = &mount_info.mount_point {
if let Ok(stat) = sys::statvfs::statvfs(Path::new(&mount_point)) {
diff --git a/below/procfs/src/test.rs b/below/procfs/src/test.rs
index eac2e2c7..301084db 100644
--- a/below/procfs/src/test.rs
+++ b/below/procfs/src/test.rs
@@ -464,6 +464,121 @@ swap_ra_hit 139012
}
#[test]
+fn test_read_slabinfo() {
+ let slabinfo = b"slabinfo - version: 2.1
+ # name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
+ zs_handle 3860100 6265344 8 512 1 : tunables 0 0 0 : slabdata 12237 12237 0
+ kvm_async_pf 0 0 136 30 1 : tunables 0 0 0 : slabdata 0 0 0
+ kvm_vcpu 0 0 9792 3 8 : tunables 0 0 0 : slabdata 0 0 0
+ kvm_mmu_page_header 0 0 184 44 2 : tunables 0 0 0 : slabdata 0 0 0
+ x86_emulator 0 0 2672 12 8 : tunables 0 0 0 : slabdata 0 0 0
+ x86_fpu 0 0 4160 7 8 : tunables 0 0 0 : slabdata 0 0 0
+ ext4_groupinfo_1k 90 90 136 30 1 : tunables 0 0 0 : slabdata 3 3 0
+";
+ let procfs = TestProcfs::new();
+ procfs.create_file_with_content("slabinfo", slabinfo);
+ let reader = procfs.get_reader();
+ let slabinfo = reader
+ .read_slabinfo()
+ .expect("Failed to read slabinfo file");
+ let expected_slabinfo = std::collections::BTreeMap::from([
+ (
+ "zs_handle".to_string(),
+ SlabInfo {
+ name: Some("zs_handle".to_string()),
+ active_objs: Some(3860100),
+ num_objs: Some(6265344),
+ obj_size: Some(8),
+ obj_per_slab: Some(512),
+ pages_per_slab: Some(1),
+ active_slabs: Some(12237),
+ num_slabs: Some(12237),
+ },
+ ),
+ (
+ "kvm_async_pf".to_string(),
+ SlabInfo {
+ name: Some("kvm_async_pf".to_string()),
+ active_objs: Some(0),
+ num_objs: Some(0),
+ obj_size: Some(136),
+ obj_per_slab: Some(30),
+ pages_per_slab: Some(1),
+ active_slabs: Some(0),
+ num_slabs: Some(0),
+ },
+ ),
+ (
+ "kvm_vcpu".to_string(),
+ SlabInfo {
+ name: Some("kvm_vcpu".to_string()),
+ active_objs: Some(0),
+ num_objs: Some(0),
+ obj_size: Some(9792),
+ obj_per_slab: Some(3),
+ pages_per_slab: Some(8),
+ active_slabs: Some(0),
+ num_slabs: Some(0),
+ },
+ ),
+ (
+ "kvm_mmu_page_header".to_string(),
+ SlabInfo {
+ name: Some("kvm_mmu_page_header".to_string()),
+ active_objs: Some(0),
+ num_objs: Some(0),
+ obj_size: Some(184),
+ obj_per_slab: Some(44),
+
+ pages_per_slab: Some(2),
+ active_slabs: Some(0),
+ num_slabs: Some(0),
+ },
+ ),
+ (
+ "x86_emulator".to_string(),
+ SlabInfo {
+ name: Some("x86_emulator".to_string()),
+ active_objs: Some(0),
+ num_objs: Some(0),
+ obj_size: Some(2672),
+ obj_per_slab: Some(12),
+ pages_per_slab: Some(8),
+ active_slabs: Some(0),
+ num_slabs: Some(0),
+ },
+ ),
+ (
+ "x86_fpu".to_string(),
+ SlabInfo {
+ name: Some("x86_fpu".to_string()),
+ active_objs: Some(0),
+ num_objs: Some(0),
+ obj_size: Some(4160),
+ obj_per_slab: Some(7),
+ pages_per_slab: Some(8),
+ active_slabs: Some(0),
+ num_slabs: Some(0),
+ },
+ ),
+ (
+ "ext4_groupinfo_1k".to_string(),
+ SlabInfo {
+ name: Some("ext4_groupinfo_1k".to_string()),
+ active_objs: Some(90),
+ num_objs: Some(90),
+ obj_size: Some(136),
+ obj_per_slab: Some(30),
+ pages_per_slab: Some(1),
+ active_slabs: Some(3),
+ num_slabs: Some(3),
+ },
+ ),
+ ]);
+ assert_eq!(slabinfo, expected_slabinfo);
+}
+
+#[test]
fn test_disk_stat() {
let diskstats = b" 1 0 ram0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/below/procfs/src/types.rs b/below/procfs/src/types.rs
index 967769a4..ea326b96 100644
--- a/below/procfs/src/types.rs
+++ b/below/procfs/src/types.rs
@@ -273,6 +273,18 @@ pub struct VmStat {
}
#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
+pub struct SlabInfo {
+ pub name: Option<String>,
+ pub active_objs: Option<u64>,
+ pub num_objs: Option<u64>,
+ pub obj_size: Option<u64>,
+ pub obj_per_slab: Option<u64>,
+ pub pages_per_slab: Option<u64>,
+ pub active_slabs: Option<u64>,
+ pub num_slabs: Option<u64>,
+}
+
+#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct MountInfo {
pub mnt_id: Option<i32>,
pub parent_mnt_id: Option<i32>,
@@ -374,6 +386,7 @@ pub struct PidInfo {
pub type PidMap = BTreeMap<i32, PidInfo>;
pub type NetMap = BTreeMap<String, InterfaceStat>;
pub type DiskMap = BTreeMap<String, DiskStat>;
+pub type SlabInfoMap = BTreeMap<String, SlabInfo>;
#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct NetStat {