#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum NonRootCgroup
{
#[allow(missing_docs)]
ChildOfRoot
{
name: CgroupName,
},
#[allow(missing_docs)]
ChildOfAChild
{
parent: Rc<NonRootCgroup>,
name: CgroupName,
}
}
impl Cgroup for NonRootCgroup
{
#[inline(always)]
fn to_path<'b>(&self, mount_point: &'b CgroupMountPoint) -> Cow<'b, Path>
{
use self::NonRootCgroup::*;
let path = match self
{
&ChildOfRoot { ref name} => RootCgroup.to_owned_path(mount_point).append(name),
&ChildOfAChild { ref name, ref parent } => parent.to_owned_path(mount_point).append(name),
};
Cow::Owned(path)
}
#[inline(always)]
fn child(self: Rc<Self>, name: CgroupName) -> Rc<Self>
{
Rc::new(NonRootCgroup::ChildOfAChild { parent: self, name })
}
}
impl NonRootCgroup
{
#[inline(always)]
pub fn name(&self) -> &CgroupName
{
use self::NonRootCgroup::*;
match self
{
&ChildOfRoot { ref name} => name,
&ChildOfAChild { ref name, .. } => name,
}
}
#[inline(always)]
pub fn create(&self, mount_point: &CgroupMountPoint) -> io::Result<()>
{
let folder_path = self.to_path(mount_point);
if folder_path.exists()
{
return Ok(())
}
create_dir_all(&folder_path)
}
pub fn remove(&self, mount_point: &CgroupMountPoint) -> io::Result<()>
{
let folder_path = self.to_path(mount_point);
if !folder_path.exists()
{
return Ok(())
}
remove_dir(&folder_path)
}
#[inline(always)]
pub fn read_type(&self, mount_point: &CgroupMountPoint) -> io::Result<NonRootCgroupType>
{
self.cgroup_type_file_path(mount_point).read_value()
}
#[inline(always)]
pub fn make_type_threaded(&self, mount_point: &CgroupMountPoint) -> io::Result<()>
{
let path = self.cgroup_type_file_path(mount_point);
path.write_value(b"threaded\n" as &[u8])
}
#[inline(always)]
pub fn freeze(&self, mount_point: &CgroupMountPoint) -> io::Result<()>
{
self.cgroup_freeze_file_path(mount_point).write_value(true)
}
#[inline(always)]
pub fn thaw(&self, mount_point: &CgroupMountPoint) -> io::Result<()>
{
self.cgroup_freeze_file_path(mount_point).write_value(false)
}
#[inline(always)]
pub fn is_frozen(&self, mount_point: &CgroupMountPoint) -> io::Result<bool>
{
self.cgroup_freeze_file_path(mount_point).read_zero_or_one_bool()
}
#[inline(always)]
pub fn read_events(&self, mount_point: &CgroupMountPoint) -> Result<EventStatistics, StatisticsParseError>
{
EventStatistics::from_file(&self.cgroup_events_file_path(mount_point))
}
#[inline(always)]
pub fn events_file_descriptor_for_epoll(&self, mount_point: &CgroupMountPoint) -> io::Result<RawFd>
{
let file: File = File::open(self.cgroup_events_file_path(mount_point))?;
Ok(file.into_raw_fd())
}
#[inline(always)]
pub fn read_cpu_weight(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<CpuWeight>>
{
self.cpu_weight_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_cpu_weight(&self, mount_point: &CgroupMountPoint, cpu_weight: CpuWeight) -> io::Result<()>
{
self.cpu_weight_file_path(mount_point).write_value(cpu_weight)
}
#[inline(always)]
pub fn read_cpu_weight_nice(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<Nice>>
{
self.cpu_weight_nice_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_cpu_weight_nice(&self, mount_point: &CgroupMountPoint, nice: Nice) -> io::Result<()>
{
self.cpu_weight_nice_file_path(mount_point).write_value(nice)
}
#[inline(always)]
pub fn read_cpu_maximum_bandwidth_limit(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<CpuMaximumBandwidthLimit>>
{
self.cpu_max_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_cpu_maximum_bandwidth_limit(&self, mount_point: &CgroupMountPoint, cpu_maximum_bandwidth_limit: CpuMaximumBandwidthLimit) -> io::Result<()>
{
self.cpu_max_file_path(mount_point).write_value(cpu_maximum_bandwidth_limit)
}
pub fn read_cpuset_hyper_threads(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<HyperThreads>>
{
self.cpuset_cpus_file_path(mount_point).read_hyper_thread_or_numa_node_list_if_exists().map(|option| option.map(HyperThreads))
}
pub fn write_cpuset_hyper_threads(&self, mount_point: &CgroupMountPoint, hyper_threads: &HyperThreads) -> io::Result<()>
{
hyper_threads.set_affinity_list(self.cpuset_cpus_file_path(mount_point))
}
pub fn read_cpuset_numa_nodes(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<NumaNodes>>
{
self.cpuset_mems_file_path(mount_point).read_hyper_thread_or_numa_node_list_if_exists().map(|option| option.map(NumaNodes))
}
pub fn write_cpuset_numa_nodes(&self, mount_point: &CgroupMountPoint, numa_nodes: &NumaNodes) -> io::Result<()>
{
numa_nodes.set_affinity_list(self.cpuset_mems_file_path(mount_point))
}
#[inline(always)]
pub fn read_cpuset_hyper_threads_partition(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<ReadPartition>>
{
self.cpuset_cpus_partition_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_cpuset_hyper_threads_partition(&self, mount_point: &CgroupMountPoint, partition: Partition) -> io::Result<()>
{
self.cpuset_cpus_partition_file_path(mount_point).write_value(partition)
}
#[inline(always)]
pub fn read_hugetlb_current(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> io::Result<Option<usize>>
{
self.hugetlb_current_file_path(mount_point, huge_page_size).read_value_if_exists()
}
#[inline(always)]
pub fn read_hugetlb_maximum(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> io::Result<Option<MaximumNumber<usize>>>
{
self.hugetlb_max_file_path(mount_point, huge_page_size).read_value_if_exists()
}
#[inline(always)]
pub fn write_hugetlb_maximum(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize, maximum: MaximumNumber<usize>) -> io::Result<()>
{
self.hugetlb_max_file_path(mount_point, huge_page_size).write_value(maximum)
}
#[inline(always)]
pub fn read_hugetlb_reserved_current(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> io::Result<Option<usize>>
{
self.hugetlb_rsvd_current_file_path(mount_point, huge_page_size).read_value_if_exists()
}
#[inline(always)]
pub fn read_hugetlb_reserved_maximum(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> io::Result<Option<MaximumNumber<usize>>>
{
self.hugetlb_rsvd_max_file_path(mount_point, huge_page_size).read_value_if_exists()
}
#[inline(always)]
pub fn write_hugetlb_reserved_maximum(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize, maximum: MaximumNumber<usize>) -> io::Result<()>
{
self.hugetlb_rsvd_max_file_path(mount_point, huge_page_size).write_value(maximum)
}
#[inline(always)]
pub fn read_hugetlb_events(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> Result<HugetlbEventStatistics, StatisticsParseError>
{
let path = self.hugetlb_events_file_path(mount_point, huge_page_size);
HugetlbEventStatistics::from_file(&path)
}
#[inline(always)]
pub fn read_hugetlb_events_local(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> Result<HugetlbEventStatistics, StatisticsParseError>
{
let path = self.hugetlb_events_local_file_path(mount_point, huge_page_size);
HugetlbEventStatistics::from_file(&path)
}
#[inline(always)]
pub fn read_memory_current(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<u64>>
{
self.memory_current_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn read_memory_minimum(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<u64>>
{
self.memory_min_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_memory_minimum(&self, mount_point: &CgroupMountPoint, minimum: u64) -> io::Result<()>
{
self.memory_min_file_path(mount_point).write_value(UnpaddedDecimalInteger(minimum))
}
#[inline(always)]
pub fn read_memory_low(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<u64>>
{
self.memory_low_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_memory_low(&self, mount_point: &CgroupMountPoint, low: u64) -> io::Result<()>
{
self.memory_low_file_path(mount_point).write_value(UnpaddedDecimalInteger(low))
}
#[inline(always)]
pub fn read_memory_high(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<MaximumNumber<u64>>>
{
self.memory_high_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_memory_high(&self, mount_point: &CgroupMountPoint, high: MaximumNumber<u64>) -> io::Result<()>
{
self.memory_high_file_path(mount_point).write_value(high)
}
#[inline(always)]
pub fn read_memory_maximum(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<MaximumNumber<u64>>>
{
self.memory_max_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_memory_maximum(&self, mount_point: &CgroupMountPoint, maximum: MaximumNumber<u64>) -> io::Result<()>
{
self.memory_max_file_path(mount_point).write_value(maximum)
}
#[inline(always)]
pub fn read_memory_events(&self, mount_point: &CgroupMountPoint) -> Result<MemoryEventStatistics, StatisticsParseError>
{
let path = self.memory_events_file_path(mount_point);
MemoryEventStatistics::from_file(&path)
}
#[inline(always)]
pub fn read_memory_events_local(&self, mount_point: &CgroupMountPoint) -> Result<MemoryEventStatistics, StatisticsParseError>
{
let path = self.memory_events_local_file_path(mount_point);
MemoryEventStatistics::from_file(&path)
}
#[inline(always)]
pub fn read_memory_statistics(&self, mount_point: &CgroupMountPoint) -> Result<MemoryStatistics, StatisticsParseError>
{
let path = self.memory_stat_file_path(mount_point);
MemoryStatistics::from_file(&path)
}
#[inline(always)]
pub fn read_memory_swap_current(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<u64>>
{
self.memory_swap_current_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn read_memory_swap_maximum(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<MaximumNumber<u64>>>
{
self.memory_swap_max_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn write_memory_swap_maximum(&self, mount_point: &CgroupMountPoint, maximum: MaximumNumber<u64>) -> io::Result<()>
{
self.memory_swap_max_file_path(mount_point).write_value(maximum)
}
#[inline(always)]
pub fn read_memory_swap_events(&self, mount_point: &CgroupMountPoint) -> Result<MemorySwapEventStatistics, StatisticsParseError>
{
let path = self.memory_swap_events_file_path(mount_point);
MemorySwapEventStatistics::from_file(&path)
}
#[inline(always)]
pub fn read_process_identifiers_count_current(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<usize>>
{
self.pids_current_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn read_process_identifiers_count_maximum(&self, mount_point: &CgroupMountPoint) -> io::Result<Option<ProcessIdentifiersMaximum>>
{
self.pids_max_file_path(mount_point).read_value_if_exists()
}
#[inline(always)]
pub fn read_process_identifiers_events(&self, mount_point: &CgroupMountPoint) -> Result<ProcessIdentifiersEventStatistics, StatisticsParseError>
{
let path = self.pids_events_file_path(mount_point);
ProcessIdentifiersEventStatistics::from_file(&path)
}
#[inline(always)]
pub fn write_process_identifiers_count_maximum(&self, mount_point: &CgroupMountPoint, maximum: ProcessIdentifiersMaximum) -> io::Result<()>
{
self.pids_max_file_path(mount_point).write_value(maximum)
}
#[inline(always)]
pub fn read_rdma_current(&self, mount_point: &CgroupMountPoint) -> Result<RdmaFile, RdmaParseError>
{
let file_path = self.rdma_current_file_path(mount_point);
RdmaFile::from_file(&file_path)
}
#[inline(always)]
pub fn read_rdma_maximum(&self, mount_point: &CgroupMountPoint) -> Result<RdmaFile, RdmaParseError>
{
let file_path = self.rdma_max_file_path(mount_point);
RdmaFile::from_file(&file_path)
}
#[inline(always)]
pub fn write_rdma_maximum(&self, mount_point: &CgroupMountPoint, maximum: &RdmaFile) -> io::Result<()>
{
maximum.to_file(&self.rdma_max_file_path(mount_point))
}
#[inline(always)]
fn cgroup_events_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.events")
}
#[inline(always)]
fn cgroup_freeze_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.freeze")
}
#[inline(always)]
fn cgroup_type_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cgroup.type")
}
#[inline(always)]
fn cpu_weight_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpu.weight")
}
#[inline(always)]
fn cpu_weight_nice_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpu.weight.nice")
}
#[inline(always)]
fn cpu_max_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpu.max")
}
#[inline(always)]
fn cpuset_cpus_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpuset.cpus")
}
#[inline(always)]
fn cpuset_cpus_partition_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpuset.cpus.partition")
}
#[inline(always)]
fn cpuset_mems_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "cpuset.mems")
}
#[inline(always)]
fn hugetlb_current_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> PathBuf
{
self.hugetlb_file_path(mount_point, huge_page_size, "current")
}
#[inline(always)]
fn hugetlb_events_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> PathBuf
{
self.hugetlb_file_path(mount_point, huge_page_size, "events")
}
#[inline(always)]
fn hugetlb_events_local_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> PathBuf
{
self.hugetlb_file_path(mount_point, huge_page_size, "events.local")
}
#[inline(always)]
fn hugetlb_max_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> PathBuf
{
self.hugetlb_file_path(mount_point, huge_page_size, "max")
}
#[inline(always)]
fn hugetlb_rsvd_current_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> PathBuf
{
self.hugetlb_file_path(mount_point, huge_page_size, "rsvd.current")
}
#[inline(always)]
fn hugetlb_rsvd_max_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize) -> PathBuf
{
self.hugetlb_file_path(mount_point, huge_page_size, "rsvd.max")
}
#[inline(always)]
fn hugetlb_file_path(&self, mount_point: &CgroupMountPoint, huge_page_size: HugePageSize, file_extension: &str) -> PathBuf
{
self.file_path(mount_point, &format!("hugetlb.{}.{}", huge_page_size.cgroup_file_name_fragment(), file_extension))
}
#[inline(always)]
fn memory_current_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.current")
}
#[inline(always)]
fn memory_min_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.min")
}
#[inline(always)]
fn memory_low_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.low")
}
#[inline(always)]
fn memory_high_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.high")
}
#[inline(always)]
fn memory_max_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.max")
}
#[inline(always)]
fn memory_events_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.events")
}
#[inline(always)]
fn memory_events_local_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.events.local")
}
#[inline(always)]
fn memory_stat_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.stat")
}
#[inline(always)]
fn memory_swap_current_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.swap.current")
}
#[inline(always)]
fn memory_swap_max_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.swap.max")
}
#[inline(always)]
fn memory_swap_events_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "memory.swap.events")
}
#[inline(always)]
fn pids_current_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "pids.current")
}
#[inline(always)]
fn pids_events_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "pids.events")
}
#[inline(always)]
fn pids_max_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "pids.max")
}
#[inline(always)]
fn rdma_max_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "rdma.max")
}
#[inline(always)]
fn rdma_current_file_path(&self, mount_point: &CgroupMountPoint) -> PathBuf
{
self.file_path(mount_point, "rdma.current")
}
#[inline(always)]
fn file_path(&self, mount_point: &CgroupMountPoint, file_name: &str) -> PathBuf
{
self.to_path(mount_point).to_path_buf().append(file_name)
}
}