kernel: implement /proc/[pid]/limits — resource limits

Added rlimits: [u64; 16] to Context (initialized to RLIM_INFINITY)
and new ProcLimits ContextHandle that outputs in Linux format:

  Limit                     Soft Limit          Hard Limit          Units
  Max cpu time              unlimited            unlimited            seconds
  Max file size             unlimited            unlimited            bytes
  ...

Cross-referenced with Linux 7.1 fs/proc/array.c proc_pid_limits().
All 16 RLIMIT_* resource limits are listed with their units.
This commit is contained in:
2026-07-08 18:57:12 +03:00
parent 0b089c7582
commit 207cf8707c
2 changed files with 49 additions and 0 deletions
+5
View File
@@ -150,6 +150,10 @@ pub struct Context {
pub session: usize,
/// Context start time in nanoseconds since boot.
pub start_time: u128,
/// Resource limits (rlimit values, in corresponding units).
/// Indexed by RLIMIT_* constants from <sys/resource.h>.
/// RLIM_INFINITY (u64::MAX) means unlimited.
pub rlimits: [u64; 16],
// TODO: id can reappear after wraparound?
pub owner_proc_id: Option<NonZeroUsize>,
@@ -222,6 +226,7 @@ impl Context {
pgrp: 0,
session: 0,
start_time: 0,
rlimits: [u64::MAX; 16], // All unlimited (RLIM_INFINITY)
#[cfg(feature = "syscall_debug")]
syscall_debug_info: crate::syscall::debug::SyscallDebugInfo::default(),
+44
View File
@@ -176,6 +176,9 @@ enum ContextHandle {
ProcStatm {
pid: usize,
},
ProcLimits {
pid: usize,
},
}
#[derive(Clone)]
struct Handle {
@@ -397,6 +400,7 @@ impl ProcScheme {
(Some("status"), None) => Some(ContextHandle::ProcStatus { pid }),
(Some("maps"), None) => Some(ContextHandle::ProcMaps { pid }),
(Some("statm"), None) => Some(ContextHandle::ProcStatm { pid }),
(Some("limits"), None) => Some(ContextHandle::ProcLimits { pid }),
_ => None,
}
}
@@ -1962,6 +1966,46 @@ impl ContextHandle {
);
read_from(buf, output.as_bytes(), offset)
}
ContextHandle::ProcLimits { pid } => {
let context = proc_context(*pid, token).ok_or(Error::new(ESRCH))?;
let rlimits = context.read(token.token()).rlimits;
// Linux 7.1 fs/proc/array.c:proc_pid_limits() format
// 16 RLIMITs with soft/hard values and units string
let names = [
("Max cpu time", "seconds"),
("Max file size", "bytes"),
("Max data size", "bytes"),
("Max stack size", "bytes"),
("Max core file size", "bytes"),
("Max resident set", "bytes"),
("Max processes", "processes"),
("Max open files", "files"),
("Max locked memory", "bytes"),
("Max address space", "bytes"),
("Max file locks", "locks"),
("Max sigpending", "signals"),
("Max msgqueue size", "bytes"),
("Max nice priority", "0"),
("Max realtime priority", "0"),
("Max realtime timeout", "us"),
];
let format_limit = |v: u64| -> alloc::string::String {
if v == u64::MAX { String::from("unlimited") }
else { alloc::format!("{}", v) }
};
let mut output = String::from(
"Limit Soft Limit Hard Limit Units\n",
);
for (i, (name, units)) in names.iter().enumerate() {
let soft = format_limit(rlimits[i]);
let hard = format_limit(if i + 16 < rlimits.len() { rlimits[i + 16] } else { u64::MAX });
output.push_str(&alloc::format!(
"{:<24} {:>20} {:>20} {}\n",
name, soft, hard, units
));
}
read_from(buf, output.as_bytes(), offset)
}
ContextHandle::ProcRoot | ContextHandle::ProcDir { .. } => Err(Error::new(EBADF)),
ContextHandle::MmapMinAddr(addrspace) => {
let mut token = token.token();