Support customized attributes for CpuController and MemController

Customized attributes are useful for customized kernels.

Usage:
	let resource = &mut cgroups::Resources::default();
	resource.cpu.attrs.insert("cpu.cfs_init_buffer_us", "10".to_string());
	// apply here

Signed-off-by: Tim Zhang <tim@hyper.sh>
This commit is contained in:
Tim Zhang
2020-11-04 18:03:42 +08:00
parent ca610bb57e
commit 0c18b0855e
3 changed files with 50 additions and 5 deletions

View File

@@ -18,8 +18,8 @@ use crate::error::*;
use crate::{parse_max_value, read_i64_from};
use crate::{
ControllIdentifier, ControllerInternal, Controllers, CpuResources, MaxValue, Resources,
Subsystem,
ControllIdentifier, ControllerInternal, Controllers, CpuResources, CustomizedAttribute,
MaxValue, Resources, Subsystem,
};
/// A controller that allows controlling the `cpu` subsystem of a Cgroup.
@@ -91,6 +91,10 @@ impl ControllerInternal for CpuController {
return Err(Error::new(ErrorKind::Other));
}
res.attrs.iter().for_each(|(k, v)| {
let _ = self.set(k, v);
})
// TODO: rt properties (CONFIG_RT_GROUP_SCHED) are not yet supported
}
@@ -306,6 +310,8 @@ impl CpuController {
}
}
impl CustomizedAttribute for CpuController {}
fn parse_cfs_quota_and_period(mut file: File) -> Result<CFSQuotaAndPeriod> {
let mut content = String::new();
file.read_to_string(&mut content)

View File

@@ -189,9 +189,22 @@ mod sealed {
std::path::Path::new(p).exists()
}
}
pub trait CustomizedAttribute: ControllerInternal {
fn set(&self, key: &str, value: &str) -> Result<()> {
self.open_path(key, true).and_then(|mut file| {
file.write_all(value.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
fn get(&self, key: &str) -> Result<String> {
self.open_path(key, false).and_then(read_str_from)
}
}
}
pub(crate) use crate::sealed::ControllerInternal;
pub(crate) use crate::sealed::{ControllerInternal, CustomizedAttribute};
/// A Controller is a subsystem attached to the control group.
///
@@ -363,6 +376,14 @@ pub struct MemoryResources {
/// Note, however, that a value of zero does not mean the process is never swapped out. Use the
/// traditional `mlock(2)` system call for that purpose.
pub swappiness: u64,
/// Customized key-value attributes
///
/// # Usage:
/// ```
/// let resource = &mut cgroups::Resources::default();
/// resource.memory.attrs.insert("memory.numa_balancing", "true".to_string());
/// // apply here
pub attrs: std::collections::HashMap<&'static str, String>,
}
/// Resources limits on the number of processes.
@@ -402,6 +423,14 @@ pub struct CpuResources {
pub realtime_runtime: i64,
/// This is currently a no-operation.
pub realtime_period: u64,
/// Customized key-value attributes
/// # Usage:
/// ```
/// let resource = &mut cgroups::Resources::default();
/// resource.cpu.attrs.insert("cpu.cfs_init_buffer_us", "10".to_string());
/// // apply here
/// ```
pub attrs: std::collections::HashMap<&'static str, String>,
}
/// A device resource that can be allowed or denied access to.
@@ -791,3 +820,11 @@ pub fn read_i64_from(mut file: File) -> Result<i64> {
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
pub fn read_str_from(mut file: File) -> Result<String> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => Ok(string.trim().to_owned()),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}

View File

@@ -21,8 +21,8 @@ use crate::events;
use crate::flat_keyed_to_hashmap;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, MaxValue, MemoryResources, Resources,
Subsystem,
ControllIdentifier, ControllerInternal, Controllers, CustomizedAttribute, MaxValue,
MemoryResources, Resources, Subsystem,
};
/// A controller that allows controlling the `memory` subsystem of a Cgroup.
@@ -834,6 +834,8 @@ impl ControllIdentifier for MemController {
}
}
impl CustomizedAttribute for MemController {}
impl<'a> From<&'a Subsystem> for &'a MemController {
fn from(sub: &'a Subsystem) -> &'a MemController {
unsafe {