Skip to content

Commit c79514d

Browse files
authored
Merge pull request #567 from Krysztal112233/chore/pgrep_optimize_namespace
pgrep: optimize get `Namespace` via `statx` syscall
2 parents f40f588 + 7d94174 commit c79514d

File tree

4 files changed

+68
-38
lines changed

4 files changed

+68
-38
lines changed

Cargo.lock

Lines changed: 13 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ prettytable-rs = "0.10.0"
6969
rand = { version = "0.9.0", features = ["small_rng"] }
7070
ratatui = "0.29.0"
7171
regex = "1.10.4"
72+
rustix = { version = "1.1.2", features = ["fs"] }
7273
sysinfo = "0.37.0"
7374
tempfile = "3.10.1"
7475
terminal_size = "0.4.2"

src/uu/pgrep/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ version.workspace = true
1414
workspace = true
1515

1616
[dependencies]
17-
uucore = { workspace = true, features = ["entries", "signals", "process"] }
1817
clap = { workspace = true }
19-
walkdir = { workspace = true }
2018
regex = { workspace = true }
19+
rustix = { workspace = true }
20+
uucore = { workspace = true, features = ["entries", "signals", "process"] }
21+
walkdir = { workspace = true }
2122

2223
[lib]
2324
path = "src/pgrep.rs"

src/uu/pgrep/src/process.rs

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,19 @@ impl TryFrom<&str> for CgroupMembership {
218218
}
219219
}
220220

221-
// See https://www.man7.org/linux/man-pages/man7/namespaces.7.html
221+
/// See https://www.man7.org/linux/man-pages/man7/namespaces.7.html
222+
///
223+
/// # Support status
224+
///
225+
/// **_Linux only._**
222226
#[derive(Default)]
223227
pub struct Namespace {
224-
pub ipc: Option<String>,
225-
pub mnt: Option<String>,
226-
pub net: Option<String>,
227-
pub pid: Option<String>,
228-
pub user: Option<String>,
229-
pub uts: Option<String>,
228+
pub ipc: Option<u64>,
229+
pub mnt: Option<u64>,
230+
pub net: Option<u64>,
231+
pub pid: Option<u64>,
232+
pub user: Option<u64>,
233+
pub uts: Option<u64>,
230234
}
231235

232236
impl Namespace {
@@ -241,28 +245,51 @@ impl Namespace {
241245
}
242246
}
243247

244-
pub fn from_pid(pid: usize) -> Result<Self, io::Error> {
245-
let mut ns = Namespace::new();
246-
let path = PathBuf::from(format!("/proc/{pid}/ns"));
247-
for entry in fs::read_dir(path)? {
248-
let entry = entry?;
249-
if let Some(name) = entry.file_name().to_str() {
250-
if let Ok(value) = read_link(entry.path()) {
251-
match name {
252-
"ipc" => ns.ipc = Some(value.to_str().unwrap_or_default().to_string()),
253-
"mnt" => ns.mnt = Some(value.to_str().unwrap_or_default().to_string()),
254-
"net" => ns.net = Some(value.to_str().unwrap_or_default().to_string()),
255-
"pid" => ns.pid = Some(value.to_str().unwrap_or_default().to_string()),
256-
"user" => ns.user = Some(value.to_str().unwrap_or_default().to_string()),
257-
"uts" => ns.uts = Some(value.to_str().unwrap_or_default().to_string()),
258-
_ => {}
259-
}
260-
}
248+
#[cfg(target_os = "linux")]
249+
pub fn from_pid(pid: usize) -> io::Result<Self> {
250+
use std::os::fd::OwnedFd;
251+
252+
use rustix::fs::{openat, statx, AtFlags, Mode, OFlags, StatxFlags, CWD};
253+
254+
let f = |name: &str, fd: &OwnedFd| {
255+
statx(
256+
fd,
257+
name,
258+
AtFlags::empty(), // NO FOLLOW LINKS
259+
StatxFlags::INO, // INNODE ONLY
260+
)
261+
};
262+
263+
let ns_dir = openat(
264+
CWD,
265+
PathBuf::from(format!("/proc/{}/ns", pid)),
266+
OFlags::RDONLY | OFlags::CLOEXEC,
267+
Mode::empty(),
268+
)?;
269+
let mut ns = Namespace::default();
270+
271+
for (name, slot) in [
272+
("ipc", &mut ns.ipc),
273+
("mnt", &mut ns.mnt),
274+
("net", &mut ns.net),
275+
("pid", &mut ns.pid),
276+
("user", &mut ns.user),
277+
("uts", &mut ns.uts),
278+
] {
279+
match f(name, &ns_dir) {
280+
Ok(st) => *slot = Some(st.stx_ino),
281+
Err(e) => return Err(e.into()),
261282
}
262283
}
263284
Ok(ns)
264285
}
265286

287+
/// TODO: implementation for other system
288+
#[cfg(not(target_os = "linux"))]
289+
pub fn from_pid(_pid: usize) -> Result<Self, io::Error> {
290+
Ok(Namespace::new())
291+
}
292+
266293
pub fn filter(&mut self, filters: &[&str]) {
267294
if !filters.contains(&"ipc") {
268295
self.ipc = None;

0 commit comments

Comments
 (0)