From c8febbc67d5feadccaa63806110cc276ff5b1208 Mon Sep 17 00:00:00 2001 From: Xuewei Niu Date: Tue, 8 Jul 2025 17:07:52 +0800 Subject: [PATCH 1/3] .github: Bump Rust version to 1.85.1 Rust 1.69.0, released in 2023, lags significantly behind the version used by Kata Containers. Therefore, we bump it to 1.85.1. Signed-off-by: Xuewei Niu --- .github/workflows/bvt.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bvt.yaml b/.github/workflows/bvt.yaml index f04c5c5..3b97767 100644 --- a/.github/workflows/bvt.yaml +++ b/.github/workflows/bvt.yaml @@ -1,7 +1,7 @@ name: BVT on: [pull_request] env: - RUST_VERSION: 1.69.0 + RUST_VERSION: 1.85.1 jobs: build: name: Build From f5a67c632ec5715f8652775b55170dfdc4632332 Mon Sep 17 00:00:00 2001 From: Xuewei Niu Date: Tue, 8 Jul 2025 23:42:30 +0800 Subject: [PATCH 2/3] Fix the issues that makes cargo clippy unhappy Most of the issues are small, but `fold()`. The usage of `fold()` in these cases confuses me a lot, so that I don't follow the sugguestions from clippy to replace `fold()` with `try_fold()`. Instead, I replace them with `map() + collect()`. Signed-off-by: Xuewei Niu --- src/blkio.rs | 11 ++++---- src/cpuset.rs | 2 +- src/devices.rs | 75 ++++++++++++++++++++++++++----------------------- src/lib.rs | 2 +- src/memory.rs | 32 ++++++--------------- src/net_prio.rs | 40 ++++++++++---------------- 6 files changed, 71 insertions(+), 91 deletions(-) diff --git a/src/blkio.rs b/src/blkio.rs index 8363d13..452482b 100644 --- a/src/blkio.rs +++ b/src/blkio.rs @@ -181,13 +181,14 @@ fn parse_io_stat(s: String) -> Vec { fn parse_io_service_total(s: String) -> Result { s.lines() - .filter(|x| x.split_whitespace().count() == 2) - .fold(Err(Error::new(ParseError)), |_, x| { - match x.split_whitespace().collect::>().as_slice() { - ["Total", val] => val.parse::().map_err(|_| Error::new(ParseError)), - _ => Err(Error::new(ParseError)), + .find_map(|line| { + let mut parts = line.split_whitespace(); + match (parts.next(), parts.next(), parts.next()) { + (Some("Total"), Some(val), None) => val.parse::().ok(), + _ => None, } }) + .ok_or_else(|| Error::new(ParseError)) } fn parse_blkio_data(s: String) -> Result> { diff --git a/src/cpuset.rs b/src/cpuset.rs index bcf0a99..5a9e7dc 100644 --- a/src/cpuset.rs +++ b/src/cpuset.rs @@ -602,7 +602,7 @@ mod tests { "1,2,3,4".to_string(), "1-5,6-7,8-9".to_string(), ]; - let expecteds = vec![ + let expecteds = [ vec![(1, 1), (2, 2), (4, 6), (9, 9)], vec![], vec![(1, 1)], diff --git a/src/devices.rs b/src/devices.rs index a842250..56c11c5 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -295,43 +295,48 @@ impl DevicesController { let mut s = String::new(); let res = file.read_to_string(&mut s); match res { - Ok(_) => { - s.lines().fold(Ok(Vec::new()), |acc, line| { - let ls = line.split(|c| c == ' ' || c == ':').map(|x| x.to_string()).collect::>(); - if acc.is_err() || ls.len() != 4 { - error!("allowed_devices: acc: {:?}, ls: {:?}", acc, ls); - Err(Error::new(ParseError)) - } else { - let devtype = DeviceType::from_char(ls[0].chars().next()); - let mut major = ls[1].parse::(); - let mut minor = ls[2].parse::(); - if major.is_err() && ls[1] == "*" { - major = Ok(-1); - } - if minor.is_err() && ls[2] == "*" { - minor = Ok(-1); - } - if devtype.is_none() || major.is_err() || minor.is_err() || !DevicePermissions::is_valid(&ls[3]) { - error!("allowed_devices: acc: {:?}, ls: {:?}, devtype: {:?}, major {:?} minor {:?} ls3 {:?}", - acc, ls, devtype, major, minor, &ls[3]); - Err(Error::new(ParseError)) - } else { - let access = DevicePermissions::from_str(&ls[3])?; - let mut acc = acc.unwrap(); - acc.push(DeviceResource { - allow: true, - devtype: devtype.unwrap(), - major: major.unwrap(), - minor: minor.unwrap(), - access, - }); - Ok(acc) - } - } - }) - }, + Ok(_) => s + .lines() + .map(|line| parse_device_line(line, true)) + .collect(), Err(e) => Err(Error::with_cause(ReadFailed("devices.list".to_string()), e)), } }) } } + +fn parse_device_number(s: &str) -> Result { + if s == "*" { + Ok(-1) + } else { + s.parse::().map_err(|_| Error::new(ParseError)) + } +} + +fn parse_device_line(line: &str, allow: bool) -> Result { + let parts: Vec<&str> = line.split([' ', ':']).collect(); + if parts.len() != 4 { + error!("allowed_devices: invalid line format: {:?}", line); + return Err(Error::new(ParseError)); + } + + let devtype = DeviceType::from_char(parts[0].chars().next()).ok_or_else(|| { + error!("allowed_devices: invalid device type: {:?}", parts[0]); + Error::new(ParseError) + })?; + let major = parse_device_number(parts[1]).inspect_err(|_| { + error!("allowed_devices: invalid major number: {:?}", parts[1]); + })?; + let minor = parse_device_number(parts[2]).inspect_err(|_| { + error!("allowed_devices: invalid minor number: {:?}", parts[2]); + })?; + let access = DevicePermissions::from_str(parts[3])?; + + Ok(DeviceResource { + allow, + devtype, + major, + minor, + access, + }) +} diff --git a/src/lib.rs b/src/lib.rs index 61d1f65..54e940b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -785,7 +785,7 @@ impl From for CgroupPid { } } -impl<'a> From<&'a std::process::Child> for CgroupPid { +impl From<&std::process::Child> for CgroupPid { fn from(u: &std::process::Child) -> CgroupPid { CgroupPid { pid: u.id() as u64 } } diff --git a/src/memory.rs b/src/memory.rs index c5382cc..653006d 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -142,9 +142,7 @@ fn parse_numa_stat(s: String) -> Result { let hier_unevict_line = ls.next().unwrap_or_default(); Ok(NumaStat { - total_pages: total_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + total_pages: total_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0), total_pages_per_node: { @@ -157,9 +155,7 @@ fn parse_numa_stat(s: String) -> Result { }) .collect() }, - file_pages: file_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + file_pages: file_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0), file_pages_per_node: { @@ -172,9 +168,7 @@ fn parse_numa_stat(s: String) -> Result { }) .collect() }, - anon_pages: anon_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + anon_pages: anon_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0), anon_pages_per_node: { @@ -187,9 +181,7 @@ fn parse_numa_stat(s: String) -> Result { }) .collect() }, - unevictable_pages: unevict_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + unevictable_pages: unevict_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0), unevictable_pages_per_node: { @@ -204,9 +196,7 @@ fn parse_numa_stat(s: String) -> Result { }, hierarchical_total_pages: { if !hier_total_line.is_empty() { - hier_total_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + hier_total_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0) } else { @@ -229,9 +219,7 @@ fn parse_numa_stat(s: String) -> Result { }, hierarchical_file_pages: { if !hier_file_line.is_empty() { - hier_file_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + hier_file_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0) } else { @@ -254,9 +242,7 @@ fn parse_numa_stat(s: String) -> Result { }, hierarchical_anon_pages: { if !hier_anon_line.is_empty() { - hier_anon_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + hier_anon_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0) } else { @@ -279,9 +265,7 @@ fn parse_numa_stat(s: String) -> Result { }, hierarchical_unevictable_pages: { if !hier_unevict_line.is_empty() { - hier_unevict_line - .split(|x| x == ' ' || x == '=') - .collect::>()[1] + hier_unevict_line.split([' ', '=']).collect::>()[1] .parse::() .unwrap_or(0) } else { diff --git a/src/net_prio.rs b/src/net_prio.rs index 170633d..51fede4 100644 --- a/src/net_prio.rs +++ b/src/net_prio.rs @@ -94,36 +94,26 @@ impl NetPrioController { } /// A map of priorities for each network interface. - #[allow(clippy::iter_nth_zero, clippy::unnecessary_unwrap)] pub fn ifpriomap(&self) -> Result> { self.open_path("net_prio.ifpriomap", false) .and_then(|file| { let bf = BufReader::new(file); - bf.lines().fold(Ok(HashMap::new()), |acc, line| { - if acc.is_err() { - acc - } else { - let mut acc = acc.unwrap(); - let l = line.unwrap(); - let mut sp = l.split_whitespace(); + bf.lines() + .map(|line| { + let line = line.map_err(|_| Error::new(ParseError))?; + let mut parts = line.split_whitespace(); - let ifname = sp.nth(0); - let ifprio = sp.nth(1); - if ifname.is_none() || ifprio.is_none() { - Err(Error::new(ParseError)) - } else { - let ifname = ifname.unwrap(); - let ifprio = ifprio.unwrap().trim().parse(); - match ifprio { - Err(e) => Err(Error::with_cause(ParseError, e)), - Ok(_) => { - acc.insert(ifname.to_string(), ifprio.unwrap()); - Ok(acc) - } - } - } - } - }) + let ifname = parts.next().ok_or(Error::new(ParseError))?; + let ifprio_str = parts.next().ok_or(Error::new(ParseError))?; + + let ifprio = ifprio_str + .trim() + .parse() + .map_err(|e| Error::with_cause(ParseError, e))?; + + Ok((ifname.to_string(), ifprio)) + }) + .collect::>>() }) } From bce4b0bb3bf052378a2a3848356b8a55e32deef3 Mon Sep 17 00:00:00 2001 From: Xuewei Niu Date: Tue, 8 Jul 2025 23:45:08 +0800 Subject: [PATCH 3/3] Fix the warning about config file The cargo complaints that ".cargo/config" is deprecated in favor of ".cargo/config.toml". Therefore, the file is renamed to it to make cargo happy. Signed-off-by: Xuewei Niu --- .cargo/{config => config.toml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .cargo/{config => config.toml} (100%) diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml