Skip to main content

CgroupManager

Struct CgroupManager 

Source
pub struct CgroupManager { /* private fields */ }

Implementations§

Source§

impl CgroupManager

Source

pub fn new() -> Result<Self>

Source

pub fn at(base_path: PathBuf) -> Self

A manager rooted at base_path, with no checks. For tests and diagnostics.

Source

pub fn default_base_path() -> PathBuf

rlm’s base cgroup: user@UID.service/rlm when the user’s systemd service cgroup exists, else /sys/fs/cgroup/rlm.

Source

pub fn base_path(&self) -> &Path

Get the base path (for testing/status)

Source

pub fn prepare_cgroup(&self, name: &str, limit: &Limit) -> Result<Prepared>

Create a cgroup for a process and set limits BEFORE adding the process. If a memory or CPU limit cannot be set, a cgroup this call created is removed again; one that already existed is left alone, so a failed limit write never empties a cgroup that holds processes.

Source

pub fn placement_command(&self, cgroup_path: &Path, program: &str) -> Command

Build a Command that places the spawned child into cgroup_path before it execs the target program, so resource limits apply from the process’s very first instruction.

Without this, a process that allocates aggressively at startup could blow past the limit during the window between spawn and being added to the cgroup — exactly the freeze scenario this tool exists to prevent.

Writing “0” to cgroup.procs from the post-fork, pre-exec child moves it into the cgroup. The file is opened in the parent so the closure performs only an async-signal-safe write to an already-open fd (no allocation, no locks). Placement is best-effort: on failure the process still launches, so callers should still call add_to_cgroup after spawn as a fallback. Add command arguments to the returned Command.

Source

pub fn add_to_cgroup(&self, cgroup_path: &Path, pid: u32) -> Result<()>

Add a process to an existing cgroup

Source

pub fn find_cgroup_for_pid(&self, pid: u32) -> Option<String>

Find if a PID is already in an rlm-managed cgroup. The unlimit bucket is not a managed cgroup, so released processes can be limited again.

Source

pub fn apply_limit(&self, pid: u32, limit: &Limit) -> Result<Vec<String>>

Apply resource limits to a process (creates cgroup and adds process). Returns non-fatal warnings.

Source

pub fn apply_limit_to_multiple( &self, pids: &[u32], limit: &Limit, cgroup_name: &str, ) -> Result<Vec<String>>

Apply resource limits to multiple processes (all share the same limit pool) All processes are added to a single cgroup, so they share the resource limits. For example, if you limit 10 processes to 4GB memory, they share 4GB total, not 4GB each. Returns non-fatal warnings, including PIDs that could not be added.

Source

pub fn remove_limit(&self, pid: u32) -> Result<()>

Remove limits from a process

Source

pub fn remove_application_limit(&self, cgroup_name: &str) -> Result<()>

Remove limits from an application cgroup (removes all processes in the cgroup)

Source

pub fn cleanup_cgroup(&self, name: &str) -> Result<()>

Clean up a cgroup by name (moves processes out and deletes cgroup)

Source

pub fn is_populated(&self, name: &str) -> Option<bool>

Whether the named child cgroup (or a descendant) holds a process, from its cgroup.events. None if unreadable.

Source

pub fn oom_kills(&self, name: &str) -> Option<u64>

The oom_kill count from the named cgroup’s memory.events.

Source

pub fn memory_max(&self, name: &str) -> Option<u64>

The named cgroup’s memory.max in bytes; None for max or unreadable.

Source

pub fn remove_if_empty(&self, name: &str) -> Result<bool>

Remove the named cgroup only if it holds no process. Ok(false) when it is populated; a cgroup that is already gone counts as removed. Never moves processes.

Source

pub fn cgroup_exists(&self, name: &str) -> bool

Whether a child cgroup with this name currently exists.

Source

pub fn pids_in_cgroup(&self, name: &str) -> Vec<u32>

PIDs currently in the named child cgroup (empty if it doesn’t exist).

Source

pub fn sweep_guard_leftovers(&self) -> Result<()>

Startup recovery: thaw and clean up every leftover guard-<pid> cgroup so no process is left frozen after a prior crash.

Legacy: pre-act-in-place rlm-guard builds moved a target process into its own guard-<pid> cgroup to freeze/cap it; the guard now acts in place on the process’s existing cgroup (journal-backed, see guard/effector.rs) and never creates guard-<pid> cgroups itself. This sweep only exists to clean up leftovers from an upgrade across that change and can be removed after one release.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more