agent: Avoid container stats panic caused by cgroup controller non-exist

Return SingularPtrField::none() instead of panic when getting stats
from cgroup failed caused by cgroup controller missing.

Signed-off-by: Tim Zhang <tim@hyper.sh>
This commit is contained in:
Tim Zhang 2020-12-28 17:57:37 +08:00
parent 157e055fdd
commit d4cd255485

View File

@ -44,6 +44,15 @@ macro_rules! sl {
};
}
macro_rules! get_controller_or_return_singular_none {
($cg:ident) => {
match $cg.controller_of() {
Some(c) => c,
None => return SingularPtrField::none(),
}
};
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Manager {
pub paths: HashMap<String, String>,
@ -561,10 +570,8 @@ lazy_static! {
}
fn get_cpu_stats(cg: &cgroups::Cgroup) -> SingularPtrField<ThrottlingData> {
let cpu_controller: &CpuController = cg.controller_of().unwrap();
let cpu_controller: &CpuController = get_controller_or_return_singular_none!(cg);
let stat = cpu_controller.cpu().stat;
let h = lines_to_map(&stat);
SingularPtrField::some(ThrottlingData {
@ -577,27 +584,18 @@ fn get_cpu_stats(cg: &cgroups::Cgroup) -> SingularPtrField<ThrottlingData> {
}
fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> SingularPtrField<CpuUsage> {
let cpuacct_controller: Option<&CpuAcctController> = cg.controller_of();
if cpuacct_controller.is_none() {
if cg.v2() {
return SingularPtrField::some(CpuUsage {
total_usage: 0,
percpu_usage: vec![],
usage_in_kernelmode: 0,
usage_in_usermode: 0,
unknown_fields: UnknownFields::default(),
cached_size: CachedSize::default(),
});
}
if let Some(cpuacct_controller) = cg.controller_of::<CpuAcctController>() {
let cpuacct = cpuacct_controller.cpuacct();
// try to get from cpu controller
let cpu_controller: &CpuController = cg.controller_of().unwrap();
let stat = cpu_controller.cpu().stat;
let h = lines_to_map(&stat);
let usage_in_usermode = *h.get("user_usec").unwrap();
let usage_in_kernelmode = *h.get("system_usec").unwrap();
let total_usage = *h.get("usage_usec").unwrap();
let percpu_usage = vec![];
let h = lines_to_map(&cpuacct.stat);
let usage_in_usermode =
(((*h.get("user").unwrap() * NANO_PER_SECOND) as f64) / *CLOCK_TICKS) as u64;
let usage_in_kernelmode =
(((*h.get("system").unwrap() * NANO_PER_SECOND) as f64) / *CLOCK_TICKS) as u64;
let total_usage = cpuacct.usage;
let percpu_usage = line_to_vec(&cpuacct.usage_percpu);
return SingularPtrField::some(CpuUsage {
total_usage,
@ -609,18 +607,25 @@ fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> SingularPtrField<CpuUsage> {
});
}
let cpuacct_controller = cpuacct_controller.unwrap();
let cpuacct = cpuacct_controller.cpuacct();
if cg.v2() {
return SingularPtrField::some(CpuUsage {
total_usage: 0,
percpu_usage: vec![],
usage_in_kernelmode: 0,
usage_in_usermode: 0,
unknown_fields: UnknownFields::default(),
cached_size: CachedSize::default(),
});
}
let h = lines_to_map(&cpuacct.stat);
let usage_in_usermode =
(((*h.get("user").unwrap() * NANO_PER_SECOND) as f64) / *CLOCK_TICKS) as u64;
let usage_in_kernelmode =
(((*h.get("system").unwrap() * NANO_PER_SECOND) as f64) / *CLOCK_TICKS) as u64;
let total_usage = cpuacct.usage;
let percpu_usage = line_to_vec(&cpuacct.usage_percpu);
// try to get from cpu controller
let cpu_controller: &CpuController = get_controller_or_return_singular_none!(cg);
let stat = cpu_controller.cpu().stat;
let h = lines_to_map(&stat);
let usage_in_usermode = *h.get("user_usec").unwrap();
let usage_in_kernelmode = *h.get("system_usec").unwrap();
let total_usage = *h.get("usage_usec").unwrap();
let percpu_usage = vec![];
SingularPtrField::some(CpuUsage {
total_usage,
@ -633,7 +638,7 @@ fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> SingularPtrField<CpuUsage> {
}
fn get_memory_stats(cg: &cgroups::Cgroup) -> SingularPtrField<MemoryStats> {
let memory_controller: &MemController = cg.controller_of().unwrap();
let memory_controller: &MemController = get_controller_or_return_singular_none!(cg);
// cache from memory stat
let memory = memory_controller.memory_stat();
@ -690,7 +695,7 @@ fn get_memory_stats(cg: &cgroups::Cgroup) -> SingularPtrField<MemoryStats> {
}
fn get_pids_stats(cg: &cgroups::Cgroup) -> SingularPtrField<PidsStats> {
let pid_controller: &PidController = cg.controller_of().unwrap();
let pid_controller: &PidController = get_controller_or_return_singular_none!(cg);
let current = pid_controller.get_pid_current().unwrap_or(0);
let max = pid_controller.get_pid_max();
@ -796,7 +801,7 @@ fn build_blkio_stats_entry(major: i16, minor: i16, op: &str, value: u64) -> Blki
}
fn get_blkio_stats_v2(cg: &cgroups::Cgroup) -> SingularPtrField<BlkioStats> {
let blkio_controller: &BlkIoController = cg.controller_of().unwrap();
let blkio_controller: &BlkIoController = get_controller_or_return_singular_none!(cg);
let blkio = blkio_controller.blkio();
let mut resp = BlkioStats::new();
@ -824,7 +829,7 @@ fn get_blkio_stats(cg: &cgroups::Cgroup) -> SingularPtrField<BlkioStats> {
return get_blkio_stats_v2(&cg);
}
let blkio_controller: &BlkIoController = cg.controller_of().unwrap();
let blkio_controller: &BlkIoController = get_controller_or_return_singular_none!(cg);
let blkio = blkio_controller.blkio();
let mut m = BlkioStats::new();