1
0
mirror of https://github.com/containers/youki synced 2024-11-23 01:11:58 +01:00

fix(libcgroup): parse CPU stats with 'parse_flat_keyed_data()'

Signed-off-by: Xiaoyang Liu <siujoeng.lau@gmail.com>
This commit is contained in:
Xiaoyang Liu 2023-11-14 11:51:30 -08:00
parent eeee7ca815
commit c857857ce3
No known key found for this signature in database
GPG Key ID: B9BA62A6A30D7995

@ -1,12 +1,11 @@
use std::{
borrow::Cow,
num::ParseIntError,
path::{Path, PathBuf},
};
use crate::{
common::{self, ControllerOpt, WrappedIoError},
stats::{self, CpuStats, StatsProvider},
stats::{self, CpuStats, ParseFlatKeyedDataError, StatsProvider},
};
use oci_spec::runtime::LinuxCpu;
@ -49,13 +48,10 @@ impl Controller for Cpu {
pub enum V2CpuStatsError {
#[error("io error: {0}")]
WrappedIo(#[from] WrappedIoError),
#[error("failed parsing value {value} for field {field} in {path}: {err}")]
ParseField {
value: String,
field: String,
path: PathBuf,
err: ParseIntError,
},
#[error("while parsing stat table: {0}")]
ParseNestedKeyedData(#[from] ParseFlatKeyedDataError),
#[error("missing field {field} from {path}")]
MissingField { field: &'static str, path: PathBuf },
}
impl StatsProvider for Cpu {
@ -66,32 +62,27 @@ impl StatsProvider for Cpu {
let mut stats = CpuStats::default();
let stats_path = cgroup_path.join(CPU_STAT);
let stat_content = common::read_cgroup_file(&stats_path)?;
for entry in stat_content.lines() {
let parts: Vec<&str> = entry.split_ascii_whitespace().collect();
if parts.len() != 2 {
continue;
}
let stats_table = stats::parse_flat_keyed_data(&stats_path)?;
let value = parts[1]
.parse()
.map_err(|err| V2CpuStatsError::ParseField {
value: parts[1].into(),
field: parts[0].into(),
path: stats_path.clone(),
err,
})?;
match parts[0] {
"usage_usec" => stats.usage.usage_total = value,
"user_usec" => stats.usage.usage_user = value,
"system_usec" => stats.usage.usage_kernel = value,
"nr_periods" => stats.throttling.periods = value,
"nr_throttled" => stats.throttling.throttled_periods = value,
"throttled_usec" => stats.throttling.throttled_time = value,
_ => continue,
}
macro_rules! get {
($name: expr => $field1:ident.$field2:ident) => {
stats.$field1.$field2 =
*stats_table
.get($name)
.ok_or_else(|| V2CpuStatsError::MissingField {
field: $name,
path: stats_path.clone(),
})?;
};
}
get!("usage_usec" => usage.usage_total);
get!("user_usec" => usage.usage_user);
get!("system_usec" => usage.usage_kernel);
get!("nr_periods" => throttling.periods);
get!("nr_throttled" => throttling.throttled_periods);
get!("throttled_usec" => throttling.throttled_time);
stats.psi = stats::psi_stats(&cgroup_path.join(CPU_PSI))?;
Ok(stats)
}