cargo fmt

Signed-off-by: bin liu <bin@hyper.sh>
This commit is contained in:
bin liu
2020-09-09 16:42:55 +08:00
parent ff6a0ea82a
commit 250ada183a
27 changed files with 534 additions and 448 deletions

View File

@@ -12,8 +12,8 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
BlkIoResources, ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem,
@@ -27,7 +27,7 @@ use crate::{
pub struct BlkIoController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
#[derive(Eq, PartialEq, Debug)]
@@ -124,7 +124,7 @@ fn parse_io_service(s: String) -> Result<Vec<IoService>> {
}
fn get_value(s: &str) -> String {
let arr = s.split(':').collect::<Vec<&str>>();
let arr = s.split(':').collect::<Vec<&str>>();
if arr.len() != 2 {
return "0".to_string();
}
@@ -134,7 +134,8 @@ fn get_value(s: &str) -> String {
fn parse_io_stat(s: String) -> Result<Vec<IoStat>> {
// line:
// 8:0 rbytes=180224 wbytes=0 rios=3 wios=0 dbytes=0 dios=0
let v = s.lines()
let v = s
.lines()
.filter(|x| x.split_whitespace().collect::<Vec<_>>().len() == 7)
.map(|x| {
let arr = x.split_whitespace().collect::<Vec<&str>>();
@@ -356,7 +357,8 @@ impl ControllerInternal for BlkIoController {
let _ = self.set_weight_for_device(dev.major, dev.minor, weight as u64);
}
if let Some(leaf_weight) = dev.leaf_weight {
let _ = self.set_leaf_weight_for_device(dev.major, dev.minor, leaf_weight as u64);
let _ =
self.set_leaf_weight_for_device(dev.major, dev.minor, leaf_weight as u64);
}
}
@@ -412,7 +414,10 @@ fn read_string_from(mut file: File) -> Result<String> {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
@@ -421,23 +426,23 @@ impl BlkIoController {
/// Constructs a new `BlkIoController` with `oroot` serving as the root of the control group.
pub fn new(oroot: PathBuf, v2: bool) -> Self {
let mut root = oroot;
if !v2{
if !v2 {
root.push(Self::controller_type().to_string());
}
Self {
base: root.clone(),
path: root,
v2: v2,
v2: v2,
}
}
fn blkio_v2(&self) -> BlkIo {
let mut blkio: BlkIo = Default::default();
blkio.io_stat = self
.open_path("io.stat", false)
.and_then(read_string_from)
.and_then(parse_io_stat)
.unwrap_or(Vec::new());
.open_path("io.stat", false)
.and_then(read_string_from)
.and_then(parse_io_stat)
.unwrap_or(Vec::new());
blkio
}
@@ -684,12 +689,7 @@ impl BlkIoController {
}
/// Same as `set_leaf_weight()`, but settable per each block device.
pub fn set_leaf_weight_for_device(
&self,
major: u64,
minor: u64,
weight: u64,
) -> Result<()> {
pub fn set_leaf_weight_for_device(&self, major: u64, minor: u64, weight: u64) -> Result<()> {
self.open_path("blkio.leaf_weight_device", true)
.and_then(|mut file| {
file.write_all(format!("{}:{} {}", major, minor, weight).as_ref())
@@ -708,85 +708,61 @@ impl BlkIoController {
/// Throttle the bytes per second rate of read operation affecting the block device
/// `major:minor` to `bps`.
pub fn throttle_read_bps_for_device(
&self,
major: u64,
minor: u64,
bps: u64,
) -> Result<()> {
pub fn throttle_read_bps_for_device(&self, major: u64, minor: u64, bps: u64) -> Result<()> {
let mut file = "blkio.throttle.read_bps_device";
let mut content = format!("{}:{} {}", major, minor, bps);
if self.v2 {
file = "io.max";
content = format!("{}:{} rbps={}", major, minor, bps);
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Throttle the I/O operations per second rate of read operation affecting the block device
/// `major:minor` to `bps`.
pub fn throttle_read_iops_for_device(
&self,
major: u64,
minor: u64,
iops: u64,
) -> Result<()> {
pub fn throttle_read_iops_for_device(&self, major: u64, minor: u64, iops: u64) -> Result<()> {
let mut file = "blkio.throttle.read_iops_device";
let mut content = format!("{}:{} {}", major, minor, iops);
if self.v2 {
file = "io.max";
content = format!("{}:{} riops={}", major, minor, iops);
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Throttle the bytes per second rate of write operation affecting the block device
/// `major:minor` to `bps`.
pub fn throttle_write_bps_for_device(
&self,
major: u64,
minor: u64,
bps: u64,
) -> Result<()> {
pub fn throttle_write_bps_for_device(&self, major: u64, minor: u64, bps: u64) -> Result<()> {
let mut file = "blkio.throttle.write_bps_device";
let mut content = format!("{}:{} {}", major, minor, bps);
if self.v2 {
file = "io.max";
content = format!("{}:{} wbps={}", major, minor, bps);
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Throttle the I/O operations per second rate of write operation affecting the block device
/// `major:minor` to `bps`.
pub fn throttle_write_iops_for_device(
&self,
major: u64,
minor: u64,
iops: u64,
) -> Result<()> {
pub fn throttle_write_iops_for_device(&self, major: u64, minor: u64, iops: u64) -> Result<()> {
let mut file = "blkio.throttle.write_iops_device";
let mut content = format!("{}:{} {}", major, minor, iops);
if self.v2 {
file = "io.max";
content = format!("{}:{} wiops={}", major, minor, iops);
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(content.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Set the weight of the control group's tasks.
@@ -796,20 +772,14 @@ impl BlkIoController {
if self.v2 {
file = "io.bfq.weight";
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(w.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(w.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Same as `set_weight()`, but settable per each block device.
pub fn set_weight_for_device(
&self,
major: u64,
minor: u64,
weight: u64,
) -> Result<()> {
pub fn set_weight_for_device(&self, major: u64, minor: u64, weight: u64) -> Result<()> {
let mut file = "blkio.weight_device";
if self.v2 {
// Attation: there is no weight for device in runc
@@ -817,11 +787,10 @@ impl BlkIoController {
// may depends on IO schedulers https://wiki.ubuntu.com/Kernel/Reference/IOSchedulers
file = "io.bfq.weight";
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(format!("{}:{} {}", major, minor, weight).as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(format!("{}:{} {}", major, minor, weight).as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
}
@@ -887,10 +856,7 @@ Total 61823067136
#[test]
fn test_parse_io_service_total() {
let ok = parse_io_service_total(TEST_VALUE.to_string()).unwrap();
assert_eq!(
ok,
61823067136
);
assert_eq!(ok, 61823067136);
}
#[test]
@@ -938,10 +904,7 @@ Total 61823067136
]
);
let err = parse_io_service(TEST_WRONG_VALUE.to_string()).unwrap_err();
assert_eq!(
err.kind(),
&ErrorKind::ParseError,
);
assert_eq!(err.kind(), &ErrorKind::ParseError,);
}
#[test]

View File

@@ -6,8 +6,8 @@
//! This module handles cgroup operations. Start here!
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::libc_rmdir;
@@ -85,7 +85,11 @@ impl<'b> Cgroup<'b> {
///
/// Note that if the handle goes out of scope and is dropped, the control group is _not_
/// destroyed.
pub fn new_with_relative_paths<P: AsRef<Path>>(hier: Box<&'b dyn Hierarchy>, path: P, relative_paths: HashMap<String, String>) -> Cgroup<'b> {
pub fn new_with_relative_paths<P: AsRef<Path>>(
hier: Box<&'b dyn Hierarchy>,
path: P,
relative_paths: HashMap<String, String>,
) -> Cgroup<'b> {
let cg = Cgroup::load_with_relative_paths(hier, path, relative_paths);
cg.create();
cg
@@ -99,7 +103,11 @@ impl<'b> Cgroup<'b> {
///
/// Note that if the handle goes out of scope and is dropped, the control group is _not_
/// destroyed.
pub fn load_with_relative_paths<P: AsRef<Path>>(hier: Box<&'b dyn Hierarchy>, path: P, relative_paths: HashMap<String, String>) -> Cgroup<'b> {
pub fn load_with_relative_paths<P: AsRef<Path>>(
hier: Box<&'b dyn Hierarchy>,
path: P,
relative_paths: HashMap<String, String>,
) -> Cgroup<'b> {
let path = path.as_ref();
let mut subsystems = hier.subsystems();
if path.as_os_str() != "" {
@@ -147,7 +155,7 @@ impl<'b> Cgroup<'b> {
p.push(self.path);
libc_rmdir(p.to_str().unwrap());
}
return
return;
}
self.subsystems.into_iter().for_each(|sub| match sub {
@@ -220,8 +228,8 @@ impl<'b> Cgroup<'b> {
}
} else {
self.subsystems()
.iter()
.try_for_each(|sub| sub.to_controller().add_task(&pid))
.iter()
.try_for_each(|sub| sub.to_controller().add_task(&pid))
}
}
@@ -238,8 +246,7 @@ impl<'b> Cgroup<'b> {
vec![]
}
} else {
self
.subsystems()
self.subsystems()
.iter()
.map(|x| x.to_controller().tasks())
.fold(vec![], |mut acc, mut x| {
@@ -259,16 +266,19 @@ pub const UNIFIED_MOUNTPOINT: &'static str = "/sys/fs/cgroup";
fn enable_controllers(controllers: &Vec<String>, path: &PathBuf) {
let mut f = path.clone();
f.push("cgroup.subtree_control");
for c in controllers{
for c in controllers {
let body = format!("+{}", c);
let _rest = fs::write(f.as_path(), body.as_bytes());
}
}
fn supported_controllers(p: &PathBuf) -> Vec<String>{
fn supported_controllers(p: &PathBuf) -> Vec<String> {
let p = format!("{}/{}", UNIFIED_MOUNTPOINT, "cgroup.controllers");
let ret = fs::read_to_string(p.as_str());
ret.unwrap_or(String::new()).split(" ").map(|x| x.to_string() ).collect::<Vec<String>>()
ret.unwrap_or(String::new())
.split(" ")
.map(|x| x.to_string())
.collect::<Vec<String>>()
}
fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> {
@@ -281,16 +291,16 @@ fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> {
// path: "a/b/c"
let elements = path.split("/").collect::<Vec<&str>>();
let last_index = elements.len() - 1 ;
let last_index = elements.len() - 1;
for (i, ele) in elements.iter().enumerate() {
// ROOT/a
fp.push(ele);
// create dir, need not check if is a file or directory
if !fp.exists(){
if !fp.exists() {
match ::std::fs::create_dir(fp.clone()) {
Err(e) => return Err(Error::with_cause(ErrorKind::FsError, e)),
Ok(_) => {},
}
Ok(_) => {}
}
}
if i < last_index {
@@ -304,7 +314,8 @@ fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> {
pub fn get_cgroups_relative_paths() -> Result<HashMap<String, String>> {
let mut m = HashMap::new();
let content = fs::read_to_string("/proc/self/cgroup").map_err(|e| Error::with_cause(ReadFailed, e))?;
let content =
fs::read_to_string("/proc/self/cgroup").map_err(|e| Error::with_cause(ReadFailed, e))?;
for l in content.lines() {
let fl: Vec<&str> = l.split(':').collect();
if fl.len() != 3 {

View File

@@ -62,7 +62,10 @@
//! ```
use crate::error::*;
use crate::{pid, BlkIoDeviceResource, BlkIoDeviceThrottleResource, Cgroup, DeviceResource, Hierarchy, HugePageResource, MaxValue, NetworkPriority, Resources};
use crate::{
pid, BlkIoDeviceResource, BlkIoDeviceThrottleResource, Cgroup, DeviceResource, Hierarchy,
HugePageResource, MaxValue, NetworkPriority, Resources,
};
macro_rules! gen_setter {
($res:ident, $cont:ident, $func:ident, $name:ident, $ty:ty) => {
@@ -72,7 +75,7 @@ macro_rules! gen_setter {
self.cgroup.resources.$res.$name = $name;
self
}
}
};
}
/// A control group builder instance
@@ -97,46 +100,34 @@ impl<'a> CgroupBuilder<'a> {
/// Builds the memory resources of the control group.
pub fn memory(self) -> MemoryResourceBuilder<'a> {
MemoryResourceBuilder {
cgroup: self,
}
MemoryResourceBuilder { cgroup: self }
}
/// Builds the pid resources of the control group.
pub fn pid(self) -> PidResourceBuilder<'a> {
PidResourceBuilder {
cgroup: self,
}
PidResourceBuilder { cgroup: self }
}
/// Builds the cpu resources of the control group.
pub fn cpu(self) -> CpuResourceBuilder<'a> {
CpuResourceBuilder {
cgroup: self,
}
CpuResourceBuilder { cgroup: self }
}
/// Builds the devices resources of the control group, disallowing or
/// allowing access to certain devices in the system.
pub fn devices(self) -> DeviceResourceBuilder<'a> {
DeviceResourceBuilder {
cgroup: self,
}
DeviceResourceBuilder { cgroup: self }
}
/// Builds the network resources of the control group, setting class id, or
/// various priorities on networking interfaces.
pub fn network(self) -> NetworkResourceBuilder<'a> {
NetworkResourceBuilder {
cgroup: self,
}
NetworkResourceBuilder { cgroup: self }
}
/// Builds the hugepage/hugetlb resources available to the control group.
pub fn hugepages(self) -> HugepagesResourceBuilder<'a> {
HugepagesResourceBuilder {
cgroup: self,
}
HugepagesResourceBuilder { cgroup: self }
}
/// Builds the block I/O resources available for the control group.
@@ -161,12 +152,35 @@ pub struct MemoryResourceBuilder<'a> {
}
impl<'a> MemoryResourceBuilder<'a> {
gen_setter!(memory, MemController, set_kmem_limit, kernel_memory_limit, i64);
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_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);
/// Finish the construction of the memory resources of a control group.
@@ -181,8 +195,13 @@ pub struct PidResourceBuilder<'a> {
}
impl<'a> PidResourceBuilder<'a> {
gen_setter!(pid, PidController, set_pid_max, maximum_number_of_processes, MaxValue);
gen_setter!(
pid,
PidController,
set_pid_max,
maximum_number_of_processes,
MaxValue
);
/// Finish the construction of the pid resources of a control group.
pub fn done(self) -> CgroupBuilder<'a> {
@@ -196,7 +215,6 @@ pub struct CpuResourceBuilder<'a> {
}
impl<'a> CpuResourceBuilder<'a> {
// FIXME this should all changed to options.
gen_setter!(cpu, CpuSetController, set_cpus, cpus, Option<String>);
gen_setter!(cpu, CpuSetController, set_mems, mems, String);
@@ -218,22 +236,22 @@ pub struct DeviceResourceBuilder<'a> {
}
impl<'a> DeviceResourceBuilder<'a> {
/// Restrict (or allow) a device to the tasks inside the control group.
pub fn device(mut self,
major: i64,
minor: i64,
devtype: crate::devices::DeviceType,
allow: bool,
access: Vec<crate::devices::DevicePermissions>)
-> DeviceResourceBuilder<'a> {
pub fn device(
mut self,
major: i64,
minor: i64,
devtype: crate::devices::DeviceType,
allow: bool,
access: Vec<crate::devices::DevicePermissions>,
) -> DeviceResourceBuilder<'a> {
self.cgroup.resources.devices.update_values = true;
self.cgroup.resources.devices.devices.push(DeviceResource {
major,
minor,
devtype,
allow,
access
access,
});
self
}
@@ -250,18 +268,17 @@ pub struct NetworkResourceBuilder<'a> {
}
impl<'a> NetworkResourceBuilder<'a> {
gen_setter!(network, NetclsController, set_class, class_id, u64);
/// Set the priority of the tasks when operating on a networking device defined by `name` to be
/// `priority`.
pub fn priority(mut self, name: String, priority: u64)
-> NetworkResourceBuilder<'a> {
pub fn priority(mut self, name: String, priority: u64) -> NetworkResourceBuilder<'a> {
self.cgroup.resources.network.update_values = true;
self.cgroup.resources.network.priorities.push(NetworkPriority {
name,
priority,
});
self.cgroup
.resources
.network
.priorities
.push(NetworkPriority { name, priority });
self
}
@@ -277,15 +294,14 @@ pub struct HugepagesResourceBuilder<'a> {
}
impl<'a> HugepagesResourceBuilder<'a> {
/// Limit the usage of certain hugepages (determined by `size`) to be at most `limit` bytes.
pub fn limit(mut self, size: String, limit: u64)
-> HugepagesResourceBuilder<'a> {
pub fn limit(mut self, size: String, limit: u64) -> HugepagesResourceBuilder<'a> {
self.cgroup.resources.hugepages.update_values = true;
self.cgroup.resources.hugepages.limits.push(HugePageResource {
size,
limit,
});
self.cgroup
.resources
.hugepages
.limits
.push(HugePageResource { size, limit });
self
}
@@ -302,24 +318,34 @@ pub struct BlkIoResourcesBuilder<'a> {
}
impl<'a> BlkIoResourcesBuilder<'a> {
gen_setter!(blkio, BlkIoController, set_weight, weight, Option<u16>);
gen_setter!(blkio, BlkIoController, set_leaf_weight, leaf_weight, Option<u16>);
gen_setter!(
blkio,
BlkIoController,
set_leaf_weight,
leaf_weight,
Option<u16>
);
/// Set the weight of a certain device.
pub fn weight_device(mut self,
major: u64,
minor: u64,
weight: Option<u16>,
leaf_weight: Option<u16>)
-> BlkIoResourcesBuilder<'a> {
pub fn weight_device(
mut self,
major: u64,
minor: u64,
weight: Option<u16>,
leaf_weight: Option<u16>,
) -> BlkIoResourcesBuilder<'a> {
self.cgroup.resources.blkio.update_values = true;
self.cgroup.resources.blkio.weight_device.push(BlkIoDeviceResource {
major,
minor,
weight,
leaf_weight,
});
self.cgroup
.resources
.blkio
.weight_device
.push(BlkIoDeviceResource {
major,
minor,
weight,
leaf_weight,
});
self
}
@@ -336,35 +362,41 @@ impl<'a> BlkIoResourcesBuilder<'a> {
}
/// Limit the read rate of the current metric for a certain device.
pub fn read(mut self, major: u64, minor: u64, rate: u64)
-> BlkIoResourcesBuilder<'a> {
pub fn read(mut self, major: u64, minor: u64, rate: u64) -> BlkIoResourcesBuilder<'a> {
self.cgroup.resources.blkio.update_values = true;
let throttle = BlkIoDeviceThrottleResource {
major,
minor,
rate,
};
let throttle = BlkIoDeviceThrottleResource { major, minor, rate };
if self.throttling_iops {
self.cgroup.resources.blkio.throttle_read_iops_device.push(throttle);
self.cgroup
.resources
.blkio
.throttle_read_iops_device
.push(throttle);
} else {
self.cgroup.resources.blkio.throttle_read_bps_device.push(throttle);
self.cgroup
.resources
.blkio
.throttle_read_bps_device
.push(throttle);
}
self
}
/// Limit the write rate of the current metric for a certain device.
pub fn write(mut self, major: u64, minor: u64, rate: u64)
-> BlkIoResourcesBuilder<'a> {
pub fn write(mut self, major: u64, minor: u64, rate: u64) -> BlkIoResourcesBuilder<'a> {
self.cgroup.resources.blkio.update_values = true;
let throttle = BlkIoDeviceThrottleResource {
major,
minor,
rate,
};
let throttle = BlkIoDeviceThrottleResource { major, minor, rate };
if self.throttling_iops {
self.cgroup.resources.blkio.throttle_write_iops_device.push(throttle);
self.cgroup
.resources
.blkio
.throttle_write_iops_device
.push(throttle);
} else {
self.cgroup.resources.blkio.throttle_write_bps_device.push(throttle);
self.cgroup
.resources
.blkio
.throttle_write_bps_device
.push(throttle);
}
self
}

View File

@@ -13,8 +13,8 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, CpuResources, Resources, Subsystem,
@@ -29,7 +29,7 @@ use crate::{
pub struct CpuController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
/// The current state of the control group and its processes.
@@ -112,7 +112,10 @@ impl<'a> From<&'a Subsystem> for &'a CpuController {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
@@ -127,7 +130,7 @@ impl CpuController {
Self {
base: root.clone(),
path: root,
v2: v2,
v2: v2,
}
}
@@ -143,7 +146,8 @@ impl CpuController {
Ok(_) => Ok(s),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}).unwrap_or("".to_string()),
})
.unwrap_or("".to_string()),
}
}
@@ -215,22 +219,21 @@ impl CpuController {
return self.set_cfs_period(period);
}
let mut line = "max".to_string();
if quota > 0 {
line = quota.to_string();
if quota > 0 {
line = quota.to_string();
}
let mut p = period;
if period == 0 {
// This default value is documented in
// https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
p = 100000
}
if period == 0 {
// This default value is documented in
// https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
p = 100000
}
line = format!("{} {}", line, p);
self.open_path("cpu.max", true)
.and_then(|mut file| {
file.write_all(line.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path("cpu.max", true).and_then(|mut file| {
file.write_all(line.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
pub fn set_rt_runtime(&self, us: i64) -> Result<()> {

View File

@@ -11,8 +11,8 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem};
@@ -167,7 +167,9 @@ impl CpuAcctController {
/// Reset the statistics the kernel has gathered about the control group.
pub fn reset(&self) -> Result<()> {
self.open_path("cpuacct.usage", true)
.and_then(|mut file| file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e)))
self.open_path("cpuacct.usage", true).and_then(|mut file| {
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
}

View File

@@ -14,8 +14,8 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, CpuResources, Resources, Subsystem,
@@ -29,7 +29,7 @@ use crate::{
pub struct CpuSetController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
/// The current state of the `cpuset` controller for this control group.
@@ -111,7 +111,7 @@ impl ControllerInternal for CpuSetController {
let res: &CpuResources = &res.cpu;
if res.update_values {
if res.cpus.is_some(){
if res.cpus.is_some() {
let _ = self.set_cpus(res.cpus.as_ref().unwrap().as_str());
}
let _ = self.set_mems(&res.mems);
@@ -120,9 +120,9 @@ impl ControllerInternal for CpuSetController {
Ok(())
}
fn post_create(&self){
if self.is_v2(){
return
fn post_create(&self) {
if self.is_v2() {
return;
}
let current = self.get_path();
let parent = match current.parent() {
@@ -132,11 +132,11 @@ impl ControllerInternal for CpuSetController {
if current != self.get_base() {
match copy_from_parent(current.to_str().unwrap(), "cpuset.cpus") {
Ok(_)=>(),
Ok(_) => (),
Err(err) => error!("error create_dir for cpuset.cpus {:?}", err),
}
match copy_from_parent(current.to_str().unwrap(), "cpuset.mems") {
Ok(_)=>(),
Ok(_) => (),
Err(err) => error!("error create_dir for cpuset.mems {:?}", err),
}
}
@@ -148,10 +148,11 @@ fn find_no_empty_parent(from: &str, file: &str) -> Result<(String, Vec<PathBuf>)
let mut v = vec![];
loop {
let current_value = match ::std::fs::read_to_string(current_path.clone().join(file).to_str().unwrap()) {
Ok(cpus) => String::from(cpus.trim()),
Err(e) => return Err(Error::with_cause(ReadFailed, e)),
};
let current_value =
match ::std::fs::read_to_string(current_path.clone().join(file).to_str().unwrap()) {
Ok(cpus) => String::from(cpus.trim()),
Err(e) => return Err(Error::with_cause(ReadFailed, e)),
};
if current_value != "" {
return Ok((current_value, v));
@@ -221,7 +222,10 @@ fn read_string_from(mut file: File) -> Result<String> {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
@@ -267,7 +271,7 @@ impl CpuSetController {
/// Contructs a new `CpuSetController` with `oroot` serving as the root of the control group.
pub fn new(oroot: PathBuf, v2: bool) -> Self {
let mut root = oroot;
if !v2{
if !v2 {
root.push(Self::controller_type().to_string());
}
Self {
@@ -372,9 +376,11 @@ impl CpuSetController {
self.open_path("cpuset.cpu_exclusive", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -385,9 +391,11 @@ impl CpuSetController {
self.open_path("cpuset.mem_exclusive", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -422,9 +430,11 @@ impl CpuSetController {
self.open_path("cpuset.mem_hardwall", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -435,9 +445,11 @@ impl CpuSetController {
self.open_path("cpuset.sched_load_balance", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -459,9 +471,11 @@ impl CpuSetController {
self.open_path("cpuset.memory_migrate", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -472,9 +486,11 @@ impl CpuSetController {
self.open_path("cpuset.memory_spread_page", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -485,9 +501,11 @@ impl CpuSetController {
self.open_path("cpuset.memory_spread_slab", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}
@@ -504,9 +522,11 @@ impl CpuSetController {
self.open_path("cpuset.memory_pressure_enabled", true)
.and_then(|mut file| {
if b {
file.write_all(b"1").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"1")
.map_err(|e| Error::with_cause(WriteFailed, e))
} else {
file.write_all(b"0").map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(b"0")
.map_err(|e| Error::with_cause(WriteFailed, e))
}
})
}

View File

@@ -12,8 +12,8 @@ use std::path::PathBuf;
use log::*;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, DeviceResource, DeviceResources,
@@ -129,8 +129,7 @@ impl DevicePermissions {
return Ok(v);
}
for e in s.chars() {
let perm = DevicePermissions::from_char(e)
.ok_or_else(|| Error::new(ParseError))?;
let perm = DevicePermissions::from_char(e).ok_or_else(|| Error::new(ParseError))?;
v.push(perm);
}

View File

@@ -83,10 +83,7 @@ impl Error {
}
}
pub(crate) fn new(kind: ErrorKind) -> Self {
Self {
kind,
cause: None,
}
Self { kind, cause: None }
}
pub(crate) fn with_cause<E>(kind: ErrorKind, cause: E) -> Self

View File

@@ -12,9 +12,8 @@ use std::path::{Path, PathBuf};
use std::sync::mpsc::{self, Receiver};
use std::thread;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
// notify_on_oom returns channel on which you can expect event about OOM,
// if process died without OOM this channel will be closed.
@@ -31,7 +30,10 @@ pub fn notify_on_oom_v1(key: &str, dir: &PathBuf) -> Result<Receiver<String>> {
// level is one of "low", "medium", or "critical"
pub fn notify_memory_pressure(key: &str, dir: &PathBuf, level: &str) -> Result<Receiver<String>> {
if level != "low" && level != "medium" && level != "critical" {
return Err(Error::from_string(format!("invalid pressure level {}", level)));
return Err(Error::from_string(format!(
"invalid pressure level {}",
level
)));
}
register_memory_event(key, dir, "memory.pressure_level", level)
@@ -46,7 +48,8 @@ fn register_memory_event(
let path = cg_dir.join(event_name);
let event_file = File::open(path).map_err(|e| Error::with_cause(ReadFailed, e))?;
let eventfd = eventfd(0, EfdFlags::EFD_CLOEXEC).map_err(|e| Error::with_cause(ReadFailed, e))?;
let eventfd =
eventfd(0, EfdFlags::EFD_CLOEXEC).map_err(|e| Error::with_cause(ReadFailed, e))?;
let event_control_path = cg_dir.join("cgroup.event_control");
let data;
@@ -71,8 +74,7 @@ fn register_memory_event(
Err(err) => {
return;
}
Ok(_) => {
}
Ok(_) => {}
}
// When a cgroup is destroyed, an event is sent to eventfd.
@@ -85,4 +87,4 @@ fn register_memory_event(
});
Ok(receiver)
}
}

View File

@@ -11,8 +11,8 @@
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem};
@@ -28,7 +28,7 @@ use crate::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subs
pub struct FreezerController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
/// The current state of the control group
@@ -90,7 +90,7 @@ impl FreezerController {
Self {
base: root.clone(),
path: root,
v2: v2,
v2: v2,
}
}

View File

@@ -45,7 +45,6 @@ pub struct V2 {
}
impl Hierarchy for V1 {
fn v2(&self) -> bool {
false
}
@@ -71,7 +70,10 @@ impl Hierarchy for V1 {
subs.push(Subsystem::Devices(DevicesController::new(self.root())));
}
if self.check_support(Controllers::Freezer) {
subs.push(Subsystem::Freezer(FreezerController::new(self.root(), false)));
subs.push(Subsystem::Freezer(FreezerController::new(
self.root(),
false,
)));
}
if self.check_support(Controllers::NetCls) {
subs.push(Subsystem::NetCls(NetClsController::new(self.root())));
@@ -86,20 +88,26 @@ impl Hierarchy for V1 {
subs.push(Subsystem::NetPrio(NetPrioController::new(self.root())));
}
if self.check_support(Controllers::HugeTlb) {
subs.push(Subsystem::HugeTlb(HugeTlbController::new(self.root(), false)));
subs.push(Subsystem::HugeTlb(HugeTlbController::new(
self.root(),
false,
)));
}
if self.check_support(Controllers::Rdma) {
subs.push(Subsystem::Rdma(RdmaController::new(self.root())));
}
if self.check_support(Controllers::Systemd) {
subs.push(Subsystem::Systemd(SystemdController::new(self.root(), false)));
subs.push(Subsystem::Systemd(SystemdController::new(
self.root(),
false,
)));
}
subs
}
fn root_control_group(&self) -> Cgroup {
let b : &Hierarchy = self as &Hierarchy;
let b: &Hierarchy = self as &Hierarchy;
Cgroup::load(Box::new(&*b), "".to_string())
}
@@ -136,17 +144,37 @@ impl Hierarchy for V2 {
let controllers = ret.unwrap().trim().to_string();
let controller_list: Vec<&str> = controllers.split(' ').collect();
for s in controller_list {
match s {
"cpu" => {subs.push(Subsystem::Cpu(CpuController::new(self.root(), true)));},
"io" => {subs.push(Subsystem::BlkIo(BlkIoController::new(self.root(), true)));},
"cpuset" => {subs.push(Subsystem::CpuSet(CpuSetController::new(self.root(), true)));},
"memory" => {subs.push(Subsystem::Mem(MemController::new(self.root(), true)));},
"pids" => {subs.push(Subsystem::Pid(PidController::new(self.root(), true)));},
"freezer" => {subs.push(Subsystem::Freezer(FreezerController::new(self.root(), true)));},
"hugetlb" => {subs.push(Subsystem::HugeTlb(HugeTlbController::new(self.root(), true)));},
_ => {},
"cpu" => {
subs.push(Subsystem::Cpu(CpuController::new(self.root(), true)));
}
"io" => {
subs.push(Subsystem::BlkIo(BlkIoController::new(self.root(), true)));
}
"cpuset" => {
subs.push(Subsystem::CpuSet(CpuSetController::new(self.root(), true)));
}
"memory" => {
subs.push(Subsystem::Mem(MemController::new(self.root(), true)));
}
"pids" => {
subs.push(Subsystem::Pid(PidController::new(self.root(), true)));
}
"freezer" => {
subs.push(Subsystem::Freezer(FreezerController::new(
self.root(),
true,
)));
}
"hugetlb" => {
subs.push(Subsystem::HugeTlb(HugeTlbController::new(
self.root(),
true,
)));
}
_ => {}
}
}
@@ -154,7 +182,7 @@ impl Hierarchy for V2 {
}
fn root_control_group(&self) -> Cgroup {
let b : &Hierarchy = self as &Hierarchy;
let b: &Hierarchy = self as &Hierarchy;
Cgroup::load(Box::new(&*b), "".to_string())
}
@@ -195,7 +223,7 @@ pub fn is_cgroup2_unified_mode() -> bool {
let path = Path::new(UNIFIED_MOUNTPOINT);
let fs_stat = statfs::statfs(path);
if fs_stat.is_err() {
return false
return false;
}
// FIXME notwork, nix will not compile CGROUP2_SUPER_MAGIC because not(target_env = "musl")
@@ -208,10 +236,10 @@ pub const INIT_CGROUP_PATHS: &'static str = "/proc/1/cgroup";
pub fn is_cgroup2_unified_mode() -> bool {
let lines = fs::read_to_string(INIT_CGROUP_PATHS);
if lines.is_err() {
return false
return false;
}
for line in lines.unwrap().lines(){
for line in lines.unwrap().lines() {
let fields: Vec<&str> = line.split(':').collect();
if fields.len() != 3 {
continue;
@@ -227,7 +255,7 @@ pub fn is_cgroup2_unified_mode() -> bool {
pub fn auto() -> Box<dyn Hierarchy> {
if is_cgroup2_unified_mode() {
Box::new(V2::new())
}else{
} else {
Box::new(V1::new())
}
}

View File

@@ -12,13 +12,12 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::flat_keyed_to_vec;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, HugePageResources, Resources,
Subsystem,
ControllIdentifier, ControllerInternal, Controllers, HugePageResources, Resources, Subsystem,
};
/// A controller that allows controlling the `hugetlb` subsystem of a Cgroup.
@@ -27,10 +26,10 @@ use crate::{
/// the control group.
#[derive(Debug, Clone)]
pub struct HugeTlbController {
base: PathBuf,
path: PathBuf,
base: PathBuf,
path: PathBuf,
sizes: Vec<String>,
v2: bool,
v2: bool,
}
impl ControllerInternal for HugeTlbController {
@@ -90,7 +89,10 @@ impl<'a> From<&'a Subsystem> for &'a HugeTlbController {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
@@ -107,7 +109,7 @@ impl HugeTlbController {
base: root.clone(),
path: root,
sizes: sizes,
v2: v2,
v2: v2,
}
}
@@ -115,7 +117,7 @@ impl HugeTlbController {
pub fn size_supported(&self, hugetlb_size: &str) -> bool {
for s in &self.sizes {
if s == hugetlb_size {
return true
return true;
}
}
false
@@ -130,7 +132,10 @@ impl HugeTlbController {
.and_then(flat_keyed_to_vec)
.and_then(|x| {
if x.len() == 0 {
return Err(Error::from_string(format!("get empty from hugetlb.{}.events", hugetlb_size)));
return Err(Error::from_string(format!(
"get empty from hugetlb.{}.events",
hugetlb_size
)));
}
Ok(x[0].1 as u64)
})
@@ -168,7 +173,8 @@ impl HugeTlbController {
self.open_path(
&format!("hugetlb.{}.max_usage_in_bytes", hugetlb_size),
false,
).and_then(read_u64_from)
)
.and_then(read_u64_from)
}
/// Set the limit (in bytes) of how much memory can be backed by hugepages of a certain size
@@ -178,15 +184,13 @@ impl HugeTlbController {
if self.v2 {
file = format!("hugetlb.{}.max", hugetlb_size);
}
self.open_path(&file, true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(&file, true).and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
}
pub const HUGEPAGESIZE_DIR: &'static str = "/sys/kernel/mm/hugepages";
use regex::Regex;
use std::collections::HashMap;
@@ -206,7 +210,7 @@ fn get_hugepage_sizes() -> Result<Vec<String>> {
if parts.len() != 2 {
continue;
}
let bmap= get_binary_size_map();
let bmap = get_binary_size_map();
let size = parse_size(parts[1], &bmap)?;
let dabbrs = get_decimal_abbrs();
m.push(custom_size(size as f64, 1024.0, &dabbrs));
@@ -215,7 +219,6 @@ fn get_hugepage_sizes() -> Result<Vec<String>> {
Ok(m)
}
pub const KB: u128 = 1000;
pub const MB: u128 = 1000 * KB;
pub const GB: u128 = 1000 * MB;
@@ -228,7 +231,6 @@ pub const GiB: u128 = 1024 * MiB;
pub const TiB: u128 = 1024 * GiB;
pub const PiB: u128 = 1024 * TiB;
pub fn get_binary_size_map() -> HashMap<String, u128> {
let mut m = HashMap::new();
m.insert("k".to_string(), KiB);
@@ -249,7 +251,7 @@ pub fn get_decimal_size_map() -> HashMap<String, u128> {
m
}
pub fn get_decimal_abbrs() -> Vec<String> {
pub fn get_decimal_abbrs() -> Vec<String> {
let m = vec![
"B".to_string(),
"KB".to_string(),
@@ -275,7 +277,7 @@ fn parse_size(s: &str, m: &HashMap<String, u128>) -> Result<u128> {
let num = caps.name("num");
let size: u128 = if num.is_some() {
let n = num.unwrap().as_str().trim().parse::<u128>();
if n.is_err(){
if n.is_err() {
return Err(Error::new(InvalidBytesSize));
}
n.unwrap()
@@ -307,4 +309,3 @@ fn custom_size(mut size: f64, base: f64, m: &Vec<String>) -> String {
format!("{}{}", size, m[i].as_str())
}

View File

@@ -8,11 +8,12 @@ use log::*;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Read, BufRead, BufReader, Write};
use std::io::{BufRead, BufReader, Read, Write};
use std::path::{Path, PathBuf};
pub mod blkio;
pub mod cgroup;
pub mod cgroup_builder;
pub mod cpu;
pub mod cpuacct;
pub mod cpuset;
@@ -29,15 +30,14 @@ pub mod perf_event;
pub mod pid;
pub mod rdma;
pub mod systemd;
pub mod cgroup_builder;
use crate::blkio::BlkIoController;
use crate::cpu::CpuController;
use crate::cpuacct::CpuAcctController;
use crate::cpuset::CpuSetController;
use crate::devices::DevicesController;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::freezer::FreezerController;
use crate::hugetlb::HugeTlbController;
use crate::memory::MemController;
@@ -136,8 +136,7 @@ mod sealed {
fn get_base(&self) -> &PathBuf;
/// Hooks running after controller crated, if have
fn post_create(&self){
}
fn post_create(&self) {}
fn is_v2(&self) -> bool {
false
@@ -189,7 +188,6 @@ mod sealed {
std::path::Path::new(p).exists()
}
}
}
@@ -227,7 +225,10 @@ pub trait Controller {
fn v2(&self) -> bool;
}
impl<T> Controller for T where T: ControllerInternal {
impl<T> Controller for T
where
T: ControllerInternal,
{
fn control_type(&self) -> Controllers {
ControllerInternal::control_type(self)
}
@@ -244,7 +245,8 @@ impl<T> Controller for T where T: ControllerInternal {
/// Create this controller
fn create(&self) {
self.verify_path().expect(format!("path should be valid: {:?}", self.path()).as_str());
self.verify_path()
.expect(format!("path should be valid: {:?}", self.path()).as_str());
match ::std::fs::create_dir_all(self.get_path()) {
Ok(_) => self.post_create(),
@@ -293,13 +295,13 @@ impl<T> Controller for T where T: ControllerInternal {
}
}
Ok(v.into_iter().map(CgroupPid::from).collect())
}).unwrap_or(vec![])
})
.unwrap_or(vec![])
}
fn v2(&self) -> bool {
self.is_v2()
}
}
#[doc(hidden)]
@@ -641,8 +643,6 @@ impl Subsystem {
}
}
/// The values for `memory.hight` or `pids.max`
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub enum MaxValue {
@@ -676,7 +676,7 @@ impl MaxValue {
pub fn parse_max_value(s: &String) -> Result<MaxValue> {
if s.trim() == "max" {
return Ok(MaxValue::Max)
return Ok(MaxValue::Max);
}
match s.trim().parse() {
Ok(val) => Ok(MaxValue::Value(val)),
@@ -689,18 +689,20 @@ pub fn parse_max_value(s: &String) -> Result<MaxValue> {
// KEY1 VAL1\n
pub fn flat_keyed_to_vec(mut file: File) -> Result<Vec<(String, i64)>> {
let mut content = String::new();
file.read_to_string(&mut content).map_err(|e| Error::with_cause(ReadFailed, e))?;
file.read_to_string(&mut content)
.map_err(|e| Error::with_cause(ReadFailed, e))?;
let mut v = Vec::new();
for line in content.lines() {
let parts: Vec<&str> = line.split(' ').collect();
if parts.len() == 2 {
match parts[1].parse::<i64>() {
Ok(i) => { v.push((parts[0].to_string(), i)); } ,
Err(_) => {},
Ok(i) => {
v.push((parts[0].to_string(), i));
}
Err(_) => {}
}
}
}
Ok(v)
}
@@ -710,18 +712,20 @@ pub fn flat_keyed_to_vec(mut file: File) -> Result<Vec<(String, i64)>> {
// KEY1 VAL1\n
pub fn flat_keyed_to_hashmap(mut file: File) -> Result<HashMap<String, i64>> {
let mut content = String::new();
file.read_to_string(&mut content).map_err(|e| Error::with_cause(ReadFailed, e))?;
file.read_to_string(&mut content)
.map_err(|e| Error::with_cause(ReadFailed, e))?;
let mut h = HashMap::new();
for line in content.lines() {
let parts: Vec<&str> = line.split(' ').collect();
if parts.len() == 2 {
match parts[1].parse::<i64>() {
Ok(i) => { h.insert(parts[0].to_string(), i); } ,
Err(_) => {},
Ok(i) => {
h.insert(parts[0].to_string(), i);
}
Err(_) => {}
}
}
}
Ok(h)
}
@@ -731,7 +735,8 @@ pub fn flat_keyed_to_hashmap(mut file: File) -> Result<HashMap<String, i64>> {
// KEY1 SUB_KEY0=VAL10 SUB_KEY1=VAL11...
pub fn nested_keyed_to_hashmap(mut file: File) -> Result<HashMap<String, HashMap<String, i64>>> {
let mut content = String::new();
file.read_to_string(&mut content).map_err(|e| Error::with_cause(ReadFailed, e))?;
file.read_to_string(&mut content)
.map_err(|e| Error::with_cause(ReadFailed, e))?;
let mut h = HashMap::new();
for line in content.lines() {
@@ -744,8 +749,10 @@ pub fn nested_keyed_to_hashmap(mut file: File) -> Result<HashMap<String, HashMap
let fields: Vec<&str> = item.split('=').collect();
if fields.len() == 2 {
match fields[1].parse::<i64>() {
Ok(i) => { th.insert(fields[0].to_string(), i); } ,
Err(_) => {},
Ok(i) => {
th.insert(fields[0].to_string(), i);
}
Err(_) => {}
}
}
}
@@ -759,7 +766,5 @@ pub fn nested_keyed_to_hashmap(mut file: File) -> Result<HashMap<String, HashMap
/// with error: `Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }`
pub fn libc_rmdir(p: &str) {
// with int return value
let _ = unsafe {
libc::rmdir(p.as_ptr() as *const i8)
};
let _ = unsafe { libc::rmdir(p.as_ptr() as *const i8) };
}

View File

@@ -12,7 +12,7 @@ use std::collections::HashMap;
use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::sync::mpsc::{Receiver};
use std::sync::mpsc::Receiver;
use crate::error::ErrorKind::*;
use crate::error::*;
@@ -21,7 +21,8 @@ use crate::events;
use crate::flat_keyed_to_hashmap;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, MaxValue, MemoryResources, Resources, Subsystem,
ControllIdentifier, ControllerInternal, Controllers, MaxValue, MemoryResources, Resources,
Subsystem,
};
/// A controller that allows controlling the `memory` subsystem of a Cgroup.
@@ -33,10 +34,9 @@ use crate::{
pub struct MemController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
#[derive(Default, Debug, PartialEq, Eq)]
pub struct SetMemory {
pub low: Option<MaxValue>,
@@ -476,25 +476,29 @@ impl MemController {
Self {
base: root.clone(),
path: root,
v2: v2,
v2: v2,
}
}
// for v2
pub fn set_mem(&self, m: SetMemory) -> Result<()> {
let values = vec![(m.high, "memory.high"),(m.low, "memory.low"),(m.max, "memory.max"),(m.min, "memory.min")];
for value in values{
pub fn set_mem(&self, m: SetMemory) -> Result<()> {
let values = vec![
(m.high, "memory.high"),
(m.low, "memory.low"),
(m.max, "memory.max"),
(m.min, "memory.min"),
];
for value in values {
let v = value.0;
let f = value.1;
if v.is_some() {
let v = v.unwrap().to_string();
self.open_path(f, true)
.and_then(|mut file| {
self.open_path(f, true).and_then(|mut file| {
file.write_all(v.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})?;
}
}
}
Ok(())
}
@@ -652,9 +656,8 @@ impl MemController {
fail_cnt: self
.open_path("memory.swap.events", false)
.and_then(flat_keyed_to_hashmap)
.and_then(|x| {
Ok(*x.get("fail").unwrap_or(&0) as u64)
}).unwrap(),
.and_then(|x| Ok(*x.get("fail").unwrap_or(&0) as u64))
.unwrap(),
limit_in_bytes: self
.open_path("memory.swap.max", false)
.and_then(read_i64_from)
@@ -735,11 +738,10 @@ impl MemController {
if self.v2 {
file = "memory.max";
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Set the kernel memory limit of the control group, in bytes.
@@ -757,11 +759,10 @@ impl MemController {
if self.v2 {
file = "memory.swap.max";
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Set how much kernel memory can be used for TCP-related buffers by the control group.
@@ -782,11 +783,10 @@ impl MemController {
if self.v2 {
file = "memory.low"
}
self.open_path(file, true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
self.open_path(file, true).and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
/// Set how likely the kernel is to swap out parts of the address space used by the control
@@ -809,10 +809,10 @@ impl MemController {
})
}
pub fn register_oom_event(&self, key: &str) -> Result<Receiver<String>>{
if self.v2{
pub fn register_oom_event(&self, key: &str) -> Result<Receiver<String>> {
if self.v2 {
events::notify_on_oom_v2(key, self.get_path())
}else {
} else {
events::notify_on_oom_v1(key, self.get_path())
}
}
@@ -870,10 +870,10 @@ fn read_string_from(mut file: File) -> Result<String> {
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use crate::memory::{
parse_memory_stat, parse_numa_stat, parse_oom_control, MemoryStat, NumaStat, OomControl,
};
use std::collections::HashMap;
static GOOD_VALUE: &str = "\
total=51189 N0=51189 N1=123

View File

@@ -11,12 +11,11 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, NetworkResources, Resources,
Subsystem,
ControllIdentifier, ControllerInternal, Controllers, NetworkResources, Resources, Subsystem,
};
/// A controller that allows controlling the `net_cls` subsystem of a Cgroup.
@@ -81,7 +80,10 @@ impl<'a> From<&'a Subsystem> for &'a NetClsController {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
@@ -102,7 +104,8 @@ impl NetClsController {
self.open_path("net_cls.classid", true)
.and_then(|mut file| {
let s = format!("{:#08X}", class);
file.write_all(s.as_ref()).map_err(|e| Error::with_cause(WriteFailed, e))
file.write_all(s.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}

View File

@@ -12,12 +12,11 @@ use std::fs::File;
use std::io::{BufRead, BufReader, Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, NetworkResources, Resources,
Subsystem,
ControllIdentifier, ControllerInternal, Controllers, NetworkResources, Resources, Subsystem,
};
/// A controller that allows controlling the `net_prio` subsystem of a Cgroup.
@@ -82,7 +81,10 @@ impl<'a> From<&'a Subsystem> for &'a NetPrioController {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}

View File

@@ -12,11 +12,12 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, MaxValue, parse_max_value, PidResources, Resources, Subsystem,
parse_max_value, ControllIdentifier, ControllerInternal, Controllers, MaxValue, PidResources,
Resources, Subsystem,
};
/// A controller that allows controlling the `pids` subsystem of a Cgroup.
@@ -24,7 +25,7 @@ use crate::{
pub struct PidController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
impl ControllerInternal for PidController {
@@ -94,7 +95,10 @@ impl<'a> From<&'a Subsystem> for &'a PidController {
fn read_u64_from(mut file: File) -> Result<u64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string.trim().parse().map_err(|e| Error::with_cause(ParseError, e)),
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
@@ -110,7 +114,7 @@ impl PidController {
Self {
base: root.clone(),
path: root,
v2: v2,
v2: v2,
}
}

View File

@@ -11,8 +11,8 @@ use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem};

View File

@@ -7,8 +7,8 @@
//!
use std::path::PathBuf;
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem};
@@ -18,7 +18,7 @@ use crate::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subs
pub struct SystemdController {
base: PathBuf,
path: PathBuf,
v2: bool,
v2: bool,
}
impl ControllerInternal for SystemdController {
@@ -64,14 +64,13 @@ impl SystemdController {
/// Constructs a new `SystemdController` with `oroot` serving as the root of the control group.
pub fn new(oroot: PathBuf, v2: bool) -> Self {
let mut root = oroot;
if !v2{
if !v2 {
root.push(Self::controller_type().to_string());
}
Self {
base: root.clone(),
path: root,
v2: v2,
v2: v2,
}
}
}

View File

@@ -5,15 +5,15 @@
//
//! Some simple tests covering the builder pattern for control groups.
use cgroups::*;
use cgroups::cpu::*;
use cgroups::devices::*;
use cgroups::pid::*;
use cgroups::memory::*;
use cgroups::net_cls::*;
use cgroups::hugetlb::*;
use cgroups::blkio::*;
use cgroups::cgroup_builder::*;
use cgroups::cpu::*;
use cgroups::devices::*;
use cgroups::hugetlb::*;
use cgroups::memory::*;
use cgroups::net_cls::*;
use cgroups::pid::*;
use cgroups::*;
#[test]
pub fn test_cpu_res_build() {
@@ -21,8 +21,8 @@ pub fn test_cpu_res_build() {
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_cpu_res_build", h)
.cpu()
.shares(85)
.done()
.shares(85)
.done()
.build();
{
@@ -40,10 +40,10 @@ pub fn test_memory_res_build() {
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_memory_res_build", h)
.memory()
.kernel_memory_limit(128 * 1024 * 1024)
.swappiness(70)
.memory_hard_limit(1024 * 1024 * 1024)
.done()
.kernel_memory_limit(128 * 1024 * 1024)
.swappiness(70)
.memory_hard_limit(1024 * 1024 * 1024)
.done()
.build();
{
@@ -64,8 +64,8 @@ pub fn test_pid_res_build() {
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_pid_res_build", h)
.pid()
.maximum_number_of_processes(MaxValue::Value(123))
.done()
.maximum_number_of_processes(MaxValue::Value(123))
.done()
.build();
{
@@ -84,23 +84,23 @@ pub fn test_devices_res_build() {
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_devices_res_build", h)
.devices()
.device(1, 6, DeviceType::Char, true,
vec![DevicePermissions::Read])
.done()
.device(1, 6, DeviceType::Char, true, vec![DevicePermissions::Read])
.done()
.build();
{
let c: &DevicesController = cg.controller_of().unwrap();
assert!(c.allowed_devices().is_ok());
assert_eq!(c.allowed_devices().unwrap(), vec![
DeviceResource {
allow: true,
devtype: DeviceType::Char,
major: 1,
minor: 6,
access: vec![DevicePermissions::Read],
}
]);
assert_eq!(
c.allowed_devices().unwrap(),
vec![DeviceResource {
allow: true,
devtype: DeviceType::Char,
major: 1,
minor: 6,
access: vec![DevicePermissions::Read],
}]
);
}
cg.delete();
}
@@ -110,13 +110,13 @@ pub fn test_network_res_build() {
let h = cgroups::hierarchies::auto();
if h.v2() {
// FIXME add cases for v2
return
return;
}
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_network_res_build", h)
.network()
.class_id(1337)
.done()
.class_id(1337)
.done()
.build();
{
@@ -132,19 +132,22 @@ pub fn test_hugepages_res_build() {
let h = cgroups::hierarchies::auto();
if h.v2() {
// FIXME add cases for v2
return
return;
}
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_hugepages_res_build", h)
.hugepages()
.limit("2MB".to_string(), 4 * 2 * 1024 * 1024)
.done()
.limit("2MB".to_string(), 4 * 2 * 1024 * 1024)
.done()
.build();
{
let c: &HugeTlbController = cg.controller_of().unwrap();
assert!(c.limit_in_bytes(&"2MB".to_string()).is_ok());
assert_eq!(c.limit_in_bytes(&"2MB".to_string()).unwrap(), 4 * 2 * 1024 * 1024);
assert_eq!(
c.limit_in_bytes(&"2MB".to_string()).unwrap(),
4 * 2 * 1024 * 1024
);
}
cg.delete();
}
@@ -156,8 +159,8 @@ pub fn test_blkio_res_build() {
let h = Box::new(&*h);
let cg: Cgroup = CgroupBuilder::new("test_blkio_res_build", h)
.blkio()
.weight(Some(100))
.done()
.weight(Some(100))
.done()
.build();
{

View File

@@ -5,9 +5,9 @@
//
//! Simple unit tests about the control groups system.
use cgroups::{Cgroup, CgroupPid, Hierarchy, Subsystem};
use cgroups::memory::{MemController, SetMemory};
use cgroups::Controller;
use cgroups::{Cgroup, CgroupPid, Hierarchy, Subsystem};
use std::collections::HashMap;
#[test]
@@ -38,11 +38,10 @@ fn test_tasks_iterator() {
cg.delete();
}
#[test]
fn test_cgroup_with_relative_paths() {
if cgroups::hierarchies::is_cgroup2_unified_mode() {
return
return;
}
let h = cgroups::hierarchies::auto();
let cgroup_root = h.root();
@@ -60,14 +59,30 @@ fn test_cgroup_with_relative_paths() {
let cgroup_path = c.path().to_str().unwrap();
let relative_path = "/pids/";
// cgroup_path = cgroup_root + relative_path + cgroup_name
assert_eq!(cgroup_path, format!("{}{}{}", cgroup_root.to_str().unwrap(), relative_path, cgroup_name));
},
assert_eq!(
cgroup_path,
format!(
"{}{}{}",
cgroup_root.to_str().unwrap(),
relative_path,
cgroup_name
)
);
}
Subsystem::Mem(c) => {
let cgroup_path = c.path().to_str().unwrap();
// cgroup_path = cgroup_root + relative_path + cgroup_name
assert_eq!(cgroup_path, format!("{}/memory{}/{}", cgroup_root.to_str().unwrap(), mem_relative_path, cgroup_name));
},
_ => {},
assert_eq!(
cgroup_path,
format!(
"{}/memory{}/{}",
cgroup_root.to_str().unwrap(),
mem_relative_path,
cgroup_name
)
);
}
_ => {}
});
}
cg.delete();
@@ -76,14 +91,14 @@ fn test_cgroup_with_relative_paths() {
#[test]
fn test_cgroup_v2() {
if !cgroups::hierarchies::is_cgroup2_unified_mode() {
return
return;
}
let h = cgroups::hierarchies::auto();
let h = Box::new(&*h);
let cg = Cgroup::new_with_relative_paths(h, String::from("test_v2"), HashMap::new());
let mem_controller: &MemController = cg.controller_of().unwrap();
let (mem, swp, rev) = (4 * 1024 * 1000, 2 * 1024* 1000, 1024 * 1000);
let (mem, swp, rev) = (4 * 1024 * 1000, 2 * 1024 * 1000, 1024 * 1000);
let _ = mem_controller.set_limit(mem);
let _ = mem_controller.set_memswap_limit(swp);

View File

@@ -25,7 +25,6 @@ fn test_cpuset_memory_pressure_root_cg() {
cg.delete();
}
#[test]
fn test_cpuset_set_cpus() {
let h = cgroups::hierarchies::auto();
@@ -48,10 +47,11 @@ fn test_cpuset_set_cpus() {
let set = cpuset.cpuset();
assert_eq!(1, set.cpus.len());
assert_eq!((0,0), set.cpus[0]);
assert_eq!((0, 0), set.cpus[0]);
// all cpus in system
let cpus = fs::read_to_string("/sys/fs/cgroup/cpuset.cpus.effective").unwrap_or("".to_string());
let cpus =
fs::read_to_string("/sys/fs/cgroup/cpuset.cpus.effective").unwrap_or("".to_string());
let cpus = cpus.trim();
if cpus != "" {
let r = cpuset.set_cpus(&cpus);
@@ -93,4 +93,4 @@ fn test_cpuset_set_cpus_add_task() {
assert_eq!(0, tasks.len());
cg.delete();
}
}

View File

@@ -13,7 +13,7 @@ use cgroups::{Cgroup, DeviceResource, Hierarchy};
fn test_devices_parsing() {
// now only v2
if cgroups::hierarchies::is_cgroup2_unified_mode() {
return
return;
}
let h = cgroups::hierarchies::auto();

View File

@@ -5,8 +5,8 @@
//! Integration tests about the hugetlb subsystem
use cgroups::hugetlb::HugeTlbController;
use cgroups::{Cgroup, Hierarchy};
use cgroups::Controller;
use cgroups::{Cgroup, Hierarchy};
use cgroups::error::ErrorKind::*;
use cgroups::error::*;
@@ -15,7 +15,7 @@ use cgroups::error::*;
fn test_hugetlb_sizes() {
// now only v2
if cgroups::hierarchies::is_cgroup2_unified_mode() {
return
return;
}
let h = cgroups::hierarchies::auto();

View File

@@ -5,8 +5,8 @@
//! Integration tests about the hugetlb subsystem
use cgroups::memory::{MemController, SetMemory};
use cgroups::{Cgroup, Hierarchy, MaxValue};
use cgroups::Controller;
use cgroups::{Cgroup, Hierarchy, MaxValue};
use cgroups::error::ErrorKind::*;
use cgroups::error::*;
@@ -24,7 +24,7 @@ fn test_disable_oom_killer() {
assert_eq!(m.oom_control.oom_kill_disable, false);
// FIXME only v1
if !mem_controller.v2(){
if !mem_controller.v2() {
// disable oom killer
let r = mem_controller.disable_oom_killer();
assert_eq!(r.is_err(), false);
@@ -33,7 +33,6 @@ fn test_disable_oom_killer() {
let m = mem_controller.memory_stat();
assert_eq!(m.oom_control.oom_kill_disable, true);
}
}
cg.delete();
}
@@ -42,7 +41,7 @@ fn test_disable_oom_killer() {
fn set_mem_v2() {
let h = cgroups::hierarchies::auto();
if !h.v2() {
return
return;
}
let h = Box::new(&*h);
@@ -59,10 +58,10 @@ fn set_mem_v2() {
assert_eq!(m.max, Some(MaxValue::Max));
// case 2: set parts
let m = SetMemory{
low: Some(MaxValue::Value(1024*1024* 2)),
high: Some(MaxValue::Value(1024*1024*1024* 2)),
min: Some(MaxValue::Value(1024*1024* 3)),
let m = SetMemory {
low: Some(MaxValue::Value(1024 * 1024 * 2)),
high: Some(MaxValue::Value(1024 * 1024 * 1024 * 2)),
min: Some(MaxValue::Value(1024 * 1024 * 3)),
max: None,
};
let r = mem_controller.set_mem(m);
@@ -70,17 +69,15 @@ fn set_mem_v2() {
let m = mem_controller.get_mem().unwrap();
// get
assert_eq!(m.low, Some(MaxValue::Value(1024*1024* 2)));
assert_eq!(m.min, Some(MaxValue::Value(1024*1024* 3)));
assert_eq!(m.high, Some(MaxValue::Value(1024*1024*1024* 2)));
assert_eq!(m.low, Some(MaxValue::Value(1024 * 1024 * 2)));
assert_eq!(m.min, Some(MaxValue::Value(1024 * 1024 * 3)));
assert_eq!(m.high, Some(MaxValue::Value(1024 * 1024 * 1024 * 2)));
assert_eq!(m.max, Some(MaxValue::Max));
// case 3: set parts
let m = SetMemory{
max: Some(MaxValue::Value(1024*1024*1024* 2)),
min: Some(MaxValue::Value(1024*1024* 4)),
let m = SetMemory {
max: Some(MaxValue::Value(1024 * 1024 * 1024 * 2)),
min: Some(MaxValue::Value(1024 * 1024 * 4)),
high: Some(MaxValue::Max),
low: None,
};
@@ -89,9 +86,9 @@ fn set_mem_v2() {
let m = mem_controller.get_mem().unwrap();
// get
assert_eq!(m.low, Some(MaxValue::Value(1024*1024* 2)));
assert_eq!(m.min, Some(MaxValue::Value(1024*1024* 4)));
assert_eq!(m.max, Some(MaxValue::Value(1024*1024*1024* 2)));
assert_eq!(m.low, Some(MaxValue::Value(1024 * 1024 * 2)));
assert_eq!(m.min, Some(MaxValue::Value(1024 * 1024 * 4)));
assert_eq!(m.max, Some(MaxValue::Value(1024 * 1024 * 1024 * 2)));
assert_eq!(m.high, Some(MaxValue::Max));
}

View File

@@ -5,7 +5,7 @@
//
//! Integration tests about the pids subsystem
use cgroups::pid::{PidController};
use cgroups::pid::PidController;
use cgroups::Controller;
use cgroups::{Cgroup, CgroupPid, Hierarchy, MaxValue, PidResources, Resources};

View File

@@ -5,7 +5,7 @@
//
//! Integration test about setting resources using `apply()`
use cgroups::pid::{PidController};
use cgroups::pid::PidController;
use cgroups::{Cgroup, Hierarchy, MaxValue, PidResources, Resources};
#[test]