summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Chen <brianc118@meta.com>2023-06-22 14:13:01 -0700
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>2023-06-22 14:13:01 -0700
commite7aded45b387614aa97d695ef0a61f1934a31595 (patch)
tree3674f805e99b52161e31da7f169ba4e4b838cf76
parente96c4280b872b03fc5c159d2acf885023989af61 (diff)
Support for offlined CPUs in /proc/stat (#8193)
Summary: Pull Request resolved: https://github.com/facebookincubator/below/pull/8193 Currently procfs assumes that no CPUs are offlined. That is not always the case. Addresses #8190. Reviewed By: antonis-m Differential Revision: D46937378 fbshipit-source-id: 3f21fbd283fb43e4f6c64c4a28e6e756ca23a93e
-rw-r--r--below/procfs/src/lib.rs20
-rw-r--r--below/procfs/src/test.rs8
-rw-r--r--below/procfs/src/types.rs2
3 files changed, 21 insertions, 9 deletions
diff --git a/below/procfs/src/lib.rs b/below/procfs/src/lib.rs
index bee9d294..667d04af 100644
--- a/below/procfs/src/lib.rs
+++ b/below/procfs/src/lib.rs
@@ -181,7 +181,7 @@ impl ProcReader {
}
fn process_cpu_stat(path: &PathBuf, line: &String) -> Result<CpuStat> {
- //Format is like "cpu9 6124418 452468 3062529 230073290 216237 0 45647 0 0 0"
+ // Format is like "cpu9 6124418 452468 3062529 230073290 216237 0 45647 0 0 0"
let mut items = line.split_whitespace();
let mut cpu: CpuStat = Default::default();
@@ -215,7 +215,7 @@ impl ProcReader {
let file = File::open(&path).map_err(|e| Error::IoError(path.clone(), e))?;
let buf_reader = BufReader::new(file);
let mut stat: Stat = Default::default();
- let mut cpus = Vec::new();
+ let mut cpus_map = BTreeMap::new();
for line in buf_reader.lines() {
let line = line.map_err(|e| Error::IoError(path.clone(), e))?;
@@ -241,15 +241,23 @@ impl ProcReader {
x => {
if x == "cpu" {
stat.total_cpu = Some(Self::process_cpu_stat(&path, &line)?);
- } else if x.starts_with("cpu") {
- cpus.push(Self::process_cpu_stat(&path, &line)?);
+ } else if let Some(cpu_suffix) = x.strip_prefix("cpu") {
+ let cpu_id =
+ parse_item!(&path, Some(cpu_suffix.to_owned()), u32, line)?
+ .unwrap();
+ let existing =
+ cpus_map.insert(cpu_id, Self::process_cpu_stat(&path, &line)?);
+ if existing.is_some() {
+ return Err(Error::UnexpectedLine(path, line));
+ }
}
}
}
}
}
- if !cpus.is_empty() {
- stat.cpus = Some(cpus);
+ if !cpus_map.is_empty() {
+ stat.cpus = Some(cpus_map.values().cloned().collect());
+ stat.cpus_map = Some(cpus_map);
}
if stat == Default::default() {
diff --git a/below/procfs/src/test.rs b/below/procfs/src/test.rs
index 94e2c703..3d554cd4 100644
--- a/below/procfs/src/test.rs
+++ b/below/procfs/src/test.rs
@@ -160,7 +160,6 @@ cpu18 5917745 448756 3050060 230279037 215704 0 45064 0 0 0
cpu19 6042834 433710 3058862 230151162 214883 0 45179 0 0 0
cpu20 5804757 444950 3057184 230372774 224962 0 46132 0 0 0
cpu21 5935027 455253 3052007 230250433 209736 0 45325 0 0 0
-cpu22 5874699 446579 3061270 230279298 235842 0 45808 0 0 0
cpu23 5937943 460201 3057286 230166670 230819 0 42628 0 0 0
intr 29638874355 54 9 0 0 14325 0 0 0 1 0 19 0 5 0 0 0 0 0 0 0 0 0 0 0 0 14 0 109094370 0 464199486 9840 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 48203489122
@@ -189,8 +188,11 @@ softirq 15518280031 0 3506477306 138437 1090758178 117192437 0 24543 800441241 9
assert_eq!(total_cpu.guest_nice_usec, Some(0));
- let cpu23 = &stat.cpus.expect("Failed to read cpus")[23];
- assert_eq!(cpu23.user_usec, Some(59379430000));
+ let cpu23_from_vec = &stat.cpus.expect("Failed to read cpus")[22];
+ assert_eq!(cpu23_from_vec.user_usec, Some(59379430000));
+
+ let cpu23_from_map = &stat.cpus_map.expect("Failed to read cpus_map")[&23];
+ assert_eq!(cpu23_from_map.user_usec, Some(59379430000));
assert_eq!(stat.total_interrupt_count, Some(29638874355));
assert_eq!(stat.context_switches, Some(48203489122));
diff --git a/below/procfs/src/types.rs b/below/procfs/src/types.rs
index 665b4c19..ae97e267 100644
--- a/below/procfs/src/types.rs
+++ b/below/procfs/src/types.rs
@@ -35,7 +35,9 @@ pub struct CpuStat {
#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Stat {
pub total_cpu: Option<CpuStat>,
+ // TODO: deprecate in favor of cpus_map
pub cpus: Option<Vec<CpuStat>>,
+ pub cpus_map: Option<BTreeMap<u32, CpuStat>>,
pub total_interrupt_count: Option<u64>,
pub context_switches: Option<u64>,
pub boot_time_epoch_secs: Option<u64>,