From 6faaeef9d4ef3ffd62b7e8eff43dd42b030aeff8 Mon Sep 17 00:00:00 2001 From: Jon Doron Date: Sun, 17 Jul 2022 14:43:25 +0300 Subject: [PATCH] Process: namespaces: Change from Vec to HashMap This change breaks the API for process namespaces, but it provides a more efficent way of working with the namespaces of a process. Signed-off-by: Jon Doron --- src/process/namespaces.rs | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/process/namespaces.rs b/src/process/namespaces.rs index 12075035..31e57a83 100644 --- a/src/process/namespaces.rs +++ b/src/process/namespaces.rs @@ -1,5 +1,6 @@ use rustix::fs::AtFlags; use std::{ + collections::HashMap, ffi::OsString, fs::{self}, path::PathBuf, @@ -12,9 +13,10 @@ use super::Process; impl Process { /// Describes namespaces to which the process with the corresponding PID belongs. /// Doc reference: https://man7.org/linux/man-pages/man7/namespaces.7.html - pub fn namespaces(&self) -> ProcResult> { + /// The namespace type is the key for the HashMap, i.e 'net', 'user', etc. + pub fn namespaces(&self) -> ProcResult> { let ns = self.root.join("ns"); - let mut namespaces = Vec::new(); + let mut namespaces = HashMap::new(); for entry in fs::read_dir(ns)? { let entry = entry?; let path = entry.path(); @@ -22,12 +24,25 @@ impl Process { let stat = rustix::fs::statat(&rustix::fs::cwd(), &path, AtFlags::empty()) .map_err(|_| build_internal_error!(format!("Unable to stat {:?}", path)))?; - namespaces.push(Namespace { - ns_type, - path, - identifier: stat.st_ino, - device_id: stat.st_dev, - }) + namespaces + .insert( + ns_type.clone(), + Namespace { + ns_type, + path, + identifier: stat.st_ino, + device_id: stat.st_dev, + }, + ) + .map_or_else( + || Ok(()), + |n| { + Err(build_internal_error!(format!( + "NsType appears more than once {:?}", + n.ns_type + ))) + }, + )?; } Ok(namespaces)