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:
@@ -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(),
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user