From afe1519ed2c8b5c55a87e5a96fa01f39c16d19c6 Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Thu, 27 Sep 2018 10:19:19 -0400 Subject: [PATCH] blkio: parse time/time_recursive Signed-off-by: Levente Kurusa --- src/blkio.rs | 123 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 31 deletions(-) diff --git a/src/blkio.rs b/src/blkio.rs index 0713d0c..c7435aa 100644 --- a/src/blkio.rs +++ b/src/blkio.rs @@ -19,6 +19,17 @@ pub struct BlkIoController { path: PathBuf, } +#[derive(Eq, PartialEq, Debug)] +/// Per-device time used in milliseconds. +pub struct BlkIoTime { + /// The major number of the device. + pub major: i16, + /// The minor number of the device. + pub minor: i16, + /// The disk time allocated to the device. + pub time: u64, +} + #[derive(Eq, PartialEq, Debug)] /// Per-device activity from the control group. pub struct IoService { @@ -38,29 +49,6 @@ pub struct IoService { pub total: u64, } -/* - * 8:32 Read 4280320 - * 8:32 Write 0 - * 8:32 Sync 4280320 - * 8:32 Async 0 - * 8:32 Total 4280320 - * 8:48 Read 5705479168 - * 8:48 Write 56096055296 - * 8:48 Sync 11213923328 - * 8:48 Async 50587611136 - * 8:48 Total 61801534464 - * 8:16 Read 10059776 - * 8:16 Write 0 - * 8:16 Sync 10059776 - * 8:16 Async 0 - * 8:16 Total 10059776 - * 8:0 Read 7192576 - * 8:0 Write 0 - * 8:0 Sync 7192576 - * 8:0 Async 0 - * 8:0 Total 7192576 - * Total 61823067136 - */ fn parse_io_service(s: String) -> Result, CgroupError> { s.lines() .filter(|x| x.split_whitespace().collect::>().len() == 3) @@ -113,6 +101,44 @@ fn parse_io_service_total(s: String) -> Result { }) } +fn parse_blkio_time(s: String) -> Result, CgroupError> { + let r = s.chars() + .map(|x| if x == ':' { ' ' } else { x }) + .collect::(); + + let r = r.lines() + .flat_map(|x| x.split_whitespace()) + .collect::>(); + + let r = r.chunks(3) + .collect::>(); + + let mut res = Vec::new(); + + let err = r.iter() + .try_for_each(|x| + match x { + [major, minor, time] => { + res.push(BlkIoTime { + major: major.parse::().unwrap(), + minor: minor.parse::().unwrap(), + time: time.parse::().unwrap(), + }); + Ok(()) + }, + _ => { + Err(CgroupError::ParseError) + } + } + ); + + if err.is_err() { + return Err(CgroupError::ParseError); + } else { + return Ok(res); + } +} + /// Current state and statistics about how throttled are the block devices when accessed from the /// controller's control group. #[derive(Debug)] @@ -220,9 +246,9 @@ pub struct BlkIo { /// Similar statistics, but as seen by the throttle policy. pub throttle: BlkIoThrottle, /// The time the control group had access to the I/O devices. - pub time: String, + pub time: Vec, /// Same as `time`, but contains all descendant control groups. - pub time_recursive: String, + pub time_recursive: Vec, /// The weight of this control group. pub weight: u64, /// Same as `weight`, but per-block-device. @@ -473,12 +499,14 @@ impl BlkIoController { read_string_from(file) }).unwrap_or("".to_string()), }, - time: self.open_path("blkio.time", false).and_then(|file| { - read_string_from(file) - }).unwrap_or("".to_string()), - time_recursive: self.open_path("blkio.time_recursive", false).and_then(|file| { - read_string_from(file) - }).unwrap_or("".to_string()), + time: self.open_path("blkio.time", false) + .and_then(read_string_from) + .and_then(parse_blkio_time) + .unwrap_or(Vec::new()), + time_recursive: self.open_path("blkio.time_recursive", false) + .and_then(read_string_from) + .and_then(parse_blkio_time) + .unwrap_or(Vec::new()), weight: self.open_path("blkio.weight", false).and_then(|file| { read_u64_from(file) }).unwrap_or(0u64), @@ -560,6 +588,7 @@ impl BlkIoController { #[cfg(test)] mod test { use blkio::{IoService, parse_io_service, parse_io_service_total}; + use blkio::{BlkIoTime, parse_blkio_time}; use ::CgroupError; const test_value: &str = "\ @@ -605,6 +634,12 @@ Total 61823067136 8:0 Async 0 8:0 Total 7192576 Total 61823067136 + "; + const test_blkio_time: &str = "\ +8:48 454480833999 +8:32 228392923193 +8:16 772456885 +8:0 559583764 "; #[test] @@ -654,4 +689,30 @@ Total 61823067136 ])); assert_eq!(parse_io_service(test_wrong_value.to_string()), Err(CgroupError::ParseError)); } + + #[test] + fn test_parse_blkio_time() { + assert_eq!(parse_blkio_time(test_blkio_time.to_string()), Ok(vec![ + BlkIoTime { + major: 8, + minor: 48, + time: 454480833999, + }, + BlkIoTime { + major: 8, + minor: 32, + time: 228392923193, + }, + BlkIoTime { + major: 8, + minor: 16, + time: 772456885, + }, + BlkIoTime { + major: 8, + minor: 0, + time: 559583764, + } + ])); + } }