Skip to main content

CellManager

Struct CellManager 

Source
pub struct CellManager {
    cell_parent_path: PathBuf,
    inotify: Inotify,
    cells: HashMap<u64, CellInfo>,
    cell_id_to_cgid: HashMap<u32, u64>,
    free_cell_ids: Vec<u32>,
    next_cell_id: u32,
    max_cells: u32,
    all_cpus: Cpumask,
    exclude_names: HashSet<String>,
}
Expand description

Manages cells for direct child cgroups of a specified parent

Fields§

§cell_parent_path: PathBuf§inotify: Inotify§cells: HashMap<u64, CellInfo>

Maps cgroup ID to cell info

§cell_id_to_cgid: HashMap<u32, u64>

Maps cell ID to cgroup ID (for reverse lookup)

§free_cell_ids: Vec<u32>

Freed cell IDs available for reuse

§next_cell_id: u32§max_cells: u32§all_cpus: Cpumask

Cpumask of all CPUs in the system (from topology)

§exclude_names: HashSet<String>

Cgroup directory names to exclude from cell creation

Implementations§

Source§

impl CellManager

Source

pub fn new( cell_parent_path: &str, max_cells: u32, all_cpus: Cpumask, exclude: HashSet<String>, ) -> Result<Self>

Source

fn new_with_path( path: PathBuf, max_cells: u32, all_cpus: Cpumask, exclude: HashSet<String>, ) -> Result<Self>

Source

fn should_exclude(&self, path: &Path) -> bool

Source

fn scan_existing_children(&mut self) -> Result<Vec<(u64, u32)>>

Source

pub fn process_events(&mut self) -> Result<(Vec<(u64, u32)>, Vec<u32>)>

Process pending inotify events. Returns list of (cgid, cell_id) for new cells and list of cell_ids that were destroyed.

Rather than processing individual events, we simply check if any events occurred and then rescan the directory to reconcile state. This is simpler and handles edge cases like inotify queue overflow gracefully.

Source

fn reconcile_cells(&mut self) -> Result<(Vec<(u64, u32)>, Vec<u32>)>

Reconcile our tracked cells with the actual cgroup directory contents. Returns (new_cells, destroyed_cells).

Source

fn create_cell_for_cgroup( &mut self, path: &Path, cgid: u64, ) -> Result<(u64, u32)>

Source

fn read_cpuset(cgroup_path: &Path) -> Result<Option<Cpumask>>

Read cpuset.cpus from a cgroup path. Returns None if empty or unavailable.

Source

fn allocate_cell_id(&mut self) -> Result<u32>

Source

pub fn compute_cpu_assignments( &self, compute_borrowable: bool, ) -> Result<Vec<CpuAssignment>>

Compute CPU assignments for all cells.

When cpusets overlap, contested CPUs are divided proportionally among claimants. Unclaimed CPUs go to cell 0 and any unpinned cells (cells without cpusets).

If compute_borrowable is true, each assignment includes a borrowable cpumask (all system CPUs minus the cell’s own, intersected with cpuset if present). Without demand data, borrowable masks are uncapped.

Returns a Vec of CpuAssignment, or an error if any cell would receive zero CPUs (which indicates too many cells for available CPUs).

Source

pub fn compute_demand_cpu_assignments( &self, cell_demands: &HashMap<u32, f64>, compute_borrowable: bool, ) -> Result<Vec<CpuAssignment>>

Compute CPU assignments weighted by per-cell demand.

cell_demands maps cell_id -> smoothed_util_pct. All active cells must be present in the map; missing entries or negative weights are errors.

If compute_borrowable is true, each assignment includes a borrowable cpumask (all system CPUs minus the cell’s own, intersected with cpuset if present).

Source

fn compute_cpu_assignments_inner( &self, cell_demands: Option<&HashMap<u32, f64>>, compute_borrowable: bool, ) -> Result<Vec<CpuAssignment>>

Internal implementation shared by equal-weight and demand-weighted assignment.

Source

pub fn get_cell_assignments(&self) -> Vec<(u64, u32)>

Returns all cell assignments as (cgid, cell_id) pairs. Used to configure BPF with cgroup-to-cell mappings.

Source

pub fn format_cell_config(&self, cpu_assignments: &[CpuAssignment]) -> String

Format the cell configuration as a compact string for logging. Example output: “[0: 0-7] [1(container-a): 8-15] [2(container-b): 16-23]”

Source

pub fn refresh_cpusets(&mut self) -> Result<bool>

Re-read cpuset.cpus for all cells and update stored cpusets. Returns true if any cell’s cpuset changed.

Trait Implementations§

Source§

impl AsFd for CellManager

Source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more

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
§

impl<T> AsSource for T
where T: AsFd,

§

fn source(&self) -> BorrowedFd<'_>

Returns the borrowed file descriptor.
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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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.

§

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

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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