pub trait Cgroup: Sized
{
fn to_path<'b>(&self, mount_point: &'b CgroupMountPoint) -> Cow<'b, Path>;
fn child(self: Rc<Self>, name: CgroupName) -> Rc<NonRootCgroup>;
#[inline(always)]
fn open(&self, mount_point: &CgroupMountPoint) -> io::Result<CgroupFileDescriptor>
{
CgroupFileDescriptor::new(mount_point, self)
}
#[inline(always)]
fn change_subtree_controllers_taking_account_of_those_available(&self, mount_point: &CgroupMountPoint, desired_controllers: &Controllers) -> io::Result<Controllers>
{
let available_controllers = self.read_available_controllers(mount_point)?;
let (enable, disable) = desired_controllers.to_enable_and_disable(&available_controllers);
self.change_subtree_controllers(mount_point, &enable, &disable)?;
Ok(available_controllers)
}
#[inline(always)]
fn read_available_controllers(&self, mount_point: &CgroupMountPoint) -> io::Result<Controllers>
{
self.cgroup_controllers_file_path(mount_point).read_value()
}
#[inline(always)]
fn read_maximum_depth(&self, mount_point: &CgroupMountPoint) -> io::Result<MaximumNumber<usize>>
{
self.cgroup_max_depth_file_path(mount_point).read_value()
}
#[inline(always)]
fn write_maximum_depth(&self, mount_point: &CgroupMountPoint, maximum_number: MaximumNumber<usize>) -> io::Result<()>
{
self.cgroup_max_depth_file_path(mount_point).write_value(maximum_number)
}
#[inline(always)]
fn read_maximum_descendants(&self, mount_point: &CgroupMountPoint) -> io::Result<MaximumNumber<usize>>
{
self.cgroup_max_descendants_file_path(mount_point).read_value()
}
#[inline(always)]
fn write_maximum_descendants(&self, mount_point: &CgroupMountPoint, maximum_number: MaximumNumber<usize>) -> io::Result<()>
{
self.cgroup_max_descendants_file_path(mount_point).write_value(maximum_number)
}
#[inline(always)]
fn get_process_identifiers(&self, mount_point: &CgroupMountPoint) -> io::Result<Vec<ProcessIdentifier>>
{
read_process_or_thread_identifiers(self.cgroup_procs_file_path(mount_point))
}
#[inline(always)]
fn migrate_process_to_this_cgroup(&self, mount_point: &CgroupMountPoint, process_identifier: ProcessIdentifierChoice) -> io::Result<()>
{
self.cgroup_procs_file_path(mount_point).write_value(process_identifier)
}
#[inline(always)]
fn read_statistics(&self, mount_point: &CgroupMountPoint) -> Result<Statistics, StatisticsParseError>
{
let path = self.cgroup_stat_file_path(mount_point);
Statistics::from_file(&path)
}
#[inline(always)]
fn read_cpu_pressure_stall_information(&self, mount_point: &CgroupMountPoint) -> io::Result<CpuTimeStalled>
{
let path = self.cpu_pressure_file_path(mount_point);
CpuTimeStalled::from_file(&path)
}
#[inline(always)]
fn monitor_some_cpu_pressure_stall_information(&self, mount_point: &CgroupMountPoint, maximum_total_stall_time_in_window: U64Microseconds, window: U64Microseconds) -> io::Result<File>
{
let path = self.cpu_pressure_file_path(mount_point);
CpuTimeStalled::monitor_some(&path, maximum_total_stall_time_in_window, window)
}
#[inline(always)]
fn read_cpu_statistics(&self, mount_point: &CgroupMountPoint) -> Result<CpuStatistics, StatisticsParseError>
{
let path = self.cpu_stat_file_path(mount_point);
CpuStatistics::from_file(&path)
}
#[inline(always)]
fn read_input_output_pressure_stall_information(&self, mount_point: &CgroupMountPoint) -> io::Result<MemoryOrInputOutputTimeStalled>
{
let path = self.io_pressure_file_path(mount_point);
MemoryOrInputOutputTimeStalled::from_file(&path)
}
#[inline(always)]
fn monitor_some_input_output_pressure_stall_information(&self, mount_point: &CgroupMountPoint, maximum_total_stall_time_in_window: U64Microseconds, window: U64Microseconds) -> io::Result<File>
{
let path = self.io_pressure_file_path(mount_point);
MemoryOrInputOutputTimeStalled::monitor_some(&path, maximum_total_stall_time_in_window, window)
}
#[inline(always)]
fn monitor_all_input_output_pressure_stall_information(&self, mount_point: &CgroupMountPoint, maximum_total_stall_time_in_window: U64Microseconds, window: U64Microseconds) -> io::Result<File>
{
let path = self.io_pressure_file_path(mount_point);
MemoryOrInputOutputTimeStalled::monitor_all(&path, maximum_total_stall_time_in_window, window)
}
#[inline(always)]
fn read_memory_pressure_stall_information(&self, mount_point: &CgroupMountPoint) -> io::Result<MemoryOrInputOutputTimeStalled>
{
let path = self.memory_pressure_file_path(mount_point);
MemoryOrInputOutputTimeStalled::from_file(&path)
}
#[inline(always)]
fn monitor_some_memory_pressure_stall_information(&self, mount_point: &CgroupMountPoint, maximum_total_stall_time_in_window: U64Microseconds, window: U64Microseconds) -> io::Result<File>
{
let path = self.memory_pressure_file_path(mount_point);
MemoryOrInputOutputTimeStalled::monitor_some(&path, maximum_total_stall_time_in_window, window)
}
#[inline(always)]
fn monitor_all_memory_pressure_stall_information(&self, mount_point: &CgroupMountPoint, maximum_total_stall_time_in_window: U64Microseconds, window: U64Microseconds) -> io::Result<File>
{
let path = self.memory_pressure_file_path(mount_point);
MemoryOrInputOutputTimeStalled::monitor_all(&path, maximum_total_stall_time_in_window, window)
}
#[inline(always)]
fn read_subtree_controllers(&self, mount_point: &CgroupMountPoint) -> io::Result<Controllers>
{
self.cgroup_subtree_control_file_path(mount_point).read_value()
}
#[inline(always)]
fn change_subtree_controllers(&self, mount_point: &CgroupMountPoint, enable: &Controllers, disable: &Controllers) -> io::Result<()>
{
debug_assert_eq!(enable.intersection(disable).count(), 0, "There are controllers in both the `enable` and `disable` sets");
let line = Controllers::create_change_line(enable, disable);
self.cgroup_subtree_control_file_path(mount_point).write_value(line)
}
#[inline(always)]
fn get_thread_identifiers(&self, mount_point: &CgroupMountPoint) -> io::Result<Vec<ThreadIdentifier>>
{
read_process_or_thread_identifiers(self.cgroup_threads_file_path(mount_point))
}
#[inline(always)]
fn migrate_thread_to_this_cgroup(&self, mount_point: &CgroupMountPoint, thread_identifier: ThreadIdentifierChoice) -> io::Result<()>
{
self.cgroup_threads_file_path(mount_point).write_value(thread_identifier)
}
#[inline(always)]
fn cpuset_hyper_threads_effective(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<HyperThreads>>
{
self.cpuset_cpus_effective_file_path(mount_point).read_hyper_thread_or_numa_node_list_if_exists().map(|option| option.map(HyperThreads))
}
#[inline(always)]
fn cpuset_numa_nodes_effective(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<NumaNodes>>
{
self.cpuset_mems_effective_file_path(mount_point).read_hyper_thread_or_numa_node_list_if_exists().map(|option| option.map(NumaNodes))
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_controllers_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.controllers")
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_max_depth_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.max.depth")
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_max_descendants_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.max.descendants")
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_procs_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.procs")
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_subtree_control_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.subtree_control")
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_stat_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.stat")
}
#[doc(hidden)]
#[inline(always)]
fn cgroup_threads_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.threads")
}
#[doc(hidden)]
#[inline(always)]
fn cpu_pressure_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpu.pressure")
}
#[doc(hidden)]
#[inline(always)]
fn cpu_stat_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpu.stat")
}
#[doc(hidden)]
#[inline(always)]
fn cpuset_cpus_effective_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpuset.cpus.effective")
}
#[doc(hidden)]
#[inline(always)]
fn cpuset_mems_effective_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpuset.mems.effective")
}
#[doc(hidden)]
#[inline(always)]
fn io_pressure_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "io.pressure")
}
#[doc(hidden)]
#[inline(always)]
fn memory_pressure_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.pressure")
}
#[doc(hidden)]
#[inline(always)]
fn file_path(&self, mount_point: &CgroupMountPoint, file_name: impl AsRef<Path>) -> PathBuf
{
self.to_owned_path(mount_point).append(file_name)
}
#[doc(hidden)]
#[inline(always)]
fn to_owned_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.to_path(mount_point).into_owned()
}
}