use crate::fs::{
BlkIoDeviceResource, BlkIoDeviceThrottleResource, Cgroup, DeviceResource, Error, Hierarchy,
HugePageResource, MaxValue, NetworkPriority, Resources,
};
macro_rules! gen_setter {
($res:ident, $cont:ident, $func:ident, $name:ident, $ty:ty) => {
pub fn $name(mut self, $name: $ty) -> Self {
self.cgroup.resources.$res.$name = Some($name);
self
}
};
}
pub struct CgroupBuilder {
name: String,
resources: Resources,
specified_controllers: Option<Vec<String>>,
}
impl CgroupBuilder {
pub fn new(name: &str) -> CgroupBuilder {
CgroupBuilder {
name: name.to_owned(),
resources: Resources::default(),
specified_controllers: None,
}
}
pub fn memory(self) -> MemoryResourceBuilder {
MemoryResourceBuilder { cgroup: self }
}
pub fn pid(self) -> PidResourceBuilder {
PidResourceBuilder { cgroup: self }
}
pub fn cpu(self) -> CpuResourceBuilder {
CpuResourceBuilder { cgroup: self }
}
pub fn devices(self) -> DeviceResourceBuilder {
DeviceResourceBuilder { cgroup: self }
}
pub fn network(self) -> NetworkResourceBuilder {
NetworkResourceBuilder { cgroup: self }
}
pub fn hugepages(self) -> HugepagesResourceBuilder {
HugepagesResourceBuilder { cgroup: self }
}
pub fn blkio(self) -> BlkIoResourcesBuilder {
BlkIoResourcesBuilder {
cgroup: self,
throttling_iops: false,
}
}
pub fn build(self, hier: Box<dyn Hierarchy>) -> Result<Cgroup, Error> {
if let Some(controllers) = self.specified_controllers {
let cg = Cgroup::new_with_specified_controllers(hier, self.name, Some(controllers))?;
cg.apply(&self.resources)?;
Ok(cg)
} else {
let cg = Cgroup::new(hier, self.name)?;
cg.apply(&self.resources)?;
Ok(cg)
}
}
pub fn set_specified_controllers(mut self, specified_controllers: Vec<String>) -> Self {
self.specified_controllers = Some(specified_controllers);
self
}
}
pub struct MemoryResourceBuilder {
cgroup: CgroupBuilder,
}
impl MemoryResourceBuilder {
gen_setter!(
memory,
MemController,
set_kmem_limit,
kernel_memory_limit,
i64
);
gen_setter!(memory, MemController, set_limit, memory_hard_limit, i64);
gen_setter!(
memory,
MemController,
set_soft_limit,
memory_soft_limit,
i64
);
gen_setter!(
memory,
MemController,
set_tcp_limit,
kernel_tcp_memory_limit,
i64
);
gen_setter!(
memory,
MemController,
set_memswap_limit,
memory_swap_limit,
i64
);
gen_setter!(memory, MemController, set_swappiness, swappiness, u64);
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}
pub struct PidResourceBuilder {
cgroup: CgroupBuilder,
}
impl PidResourceBuilder {
gen_setter!(
pid,
PidController,
set_pid_max,
maximum_number_of_processes,
MaxValue
);
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}
pub struct CpuResourceBuilder {
cgroup: CgroupBuilder,
}
impl CpuResourceBuilder {
gen_setter!(cpu, CpuSetController, set_cpus, cpus, String);
gen_setter!(cpu, CpuSetController, set_mems, mems, String);
gen_setter!(cpu, CpuController, set_shares, shares, u64);
gen_setter!(cpu, CpuController, set_cfs_quota, quota, i64);
gen_setter!(cpu, CpuController, set_cfs_period, period, u64);
gen_setter!(cpu, CpuController, set_rt_runtime, realtime_runtime, i64);
gen_setter!(cpu, CpuController, set_rt_period, realtime_period, u64);
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}
pub struct DeviceResourceBuilder {
cgroup: CgroupBuilder,
}
impl DeviceResourceBuilder {
pub fn device(
mut self,
major: i64,
minor: i64,
devtype: crate::fs::devices::DeviceType,
allow: bool,
access: Vec<crate::fs::devices::DevicePermissions>,
) -> DeviceResourceBuilder {
self.cgroup.resources.devices.devices.push(DeviceResource {
allow,
devtype,
major,
minor,
access,
});
self
}
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}
pub struct NetworkResourceBuilder {
cgroup: CgroupBuilder,
}
impl NetworkResourceBuilder {
gen_setter!(network, NetclsController, set_class, class_id, u64);
pub fn priority(mut self, name: String, priority: u64) -> NetworkResourceBuilder {
self.cgroup
.resources
.network
.priorities
.push(NetworkPriority { name, priority });
self
}
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}
pub struct HugepagesResourceBuilder {
cgroup: CgroupBuilder,
}
impl HugepagesResourceBuilder {
pub fn limit(mut self, size: String, limit: u64) -> HugepagesResourceBuilder {
self.cgroup
.resources
.hugepages
.limits
.push(HugePageResource { size, limit });
self
}
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}
pub struct BlkIoResourcesBuilder {
cgroup: CgroupBuilder,
throttling_iops: bool,
}
impl BlkIoResourcesBuilder {
gen_setter!(blkio, BlkIoController, set_weight, weight, u16);
gen_setter!(blkio, BlkIoController, set_leaf_weight, leaf_weight, u16);
pub fn weight_device(
mut self,
major: u64,
minor: u64,
weight: Option<u16>,
leaf_weight: Option<u16>,
) -> BlkIoResourcesBuilder {
self.cgroup
.resources
.blkio
.weight_device
.push(BlkIoDeviceResource {
major,
minor,
weight,
leaf_weight,
});
self
}
pub fn throttle_iops(mut self) -> BlkIoResourcesBuilder {
self.throttling_iops = true;
self
}
pub fn throttle_bps(mut self) -> BlkIoResourcesBuilder {
self.throttling_iops = false;
self
}
pub fn read(mut self, major: u64, minor: u64, rate: u64) -> BlkIoResourcesBuilder {
let throttle = BlkIoDeviceThrottleResource { major, minor, rate };
if self.throttling_iops {
self.cgroup
.resources
.blkio
.throttle_read_iops_device
.push(throttle);
} else {
self.cgroup
.resources
.blkio
.throttle_read_bps_device
.push(throttle);
}
self
}
pub fn write(mut self, major: u64, minor: u64, rate: u64) -> BlkIoResourcesBuilder {
let throttle = BlkIoDeviceThrottleResource { major, minor, rate };
if self.throttling_iops {
self.cgroup
.resources
.blkio
.throttle_write_iops_device
.push(throttle);
} else {
self.cgroup
.resources
.blkio
.throttle_write_bps_device
.push(throttle);
}
self
}
pub fn done(self) -> CgroupBuilder {
self.cgroup
}
}