change *limit* in memory from u64 to i64

Signed-off-by: bin liu <bin@hyper.sh>
This commit is contained in:
bin liu
2020-08-25 13:28:36 +08:00
parent c702852fd7
commit 9fe6cb58e4
21 changed files with 700 additions and 166 deletions

View File

@@ -6,14 +6,18 @@ use std::collections::HashMap;
use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::sync::mpsc::{Receiver};
use crate::error::ErrorKind::*;
use crate::error::*;
use crate::events;
use crate::{
ControllIdentifier, ControllerInternal, Controllers, MemoryResources, Resources, Subsystem,
};
use crate::{MaxValue, max_value_to_string, parse_max_value};
/// A controller that allows controlling the `memory` subsystem of a Cgroup.
///
/// In essence, using the memory controller, the user can gather statistics about the memory usage
@@ -23,6 +27,16 @@ use crate::{
pub struct MemController {
base: PathBuf,
path: PathBuf,
v2: bool,
}
#[derive(Default, Debug, PartialEq, Eq)]
pub struct SetMemory {
pub low: Option<MaxValue>,
pub high: Option<MaxValue>,
pub min: Option<MaxValue>,
pub max: Option<MaxValue>,
}
/// Controls statistics and controls about the OOM killer operating in this control group.
@@ -240,8 +254,8 @@ pub struct MemoryStat {
pub inactive_file: u64,
pub active_file: u64,
pub unevictable: u64,
pub hierarchical_memory_limit: u64,
pub hierarchical_memsw_limit: u64,
pub hierarchical_memory_limit: i64,
pub hierarchical_memsw_limit: i64,
pub total_cache: u64,
pub total_rss: u64,
pub total_rss_huge: u64,
@@ -296,8 +310,8 @@ fn parse_memory_stat(s: String) -> Result<MemoryStat> {
inactive_file: *raw.get("inactive_file").unwrap_or(&0),
active_file: *raw.get("active_file").unwrap_or(&0),
unevictable: *raw.get("unevictable").unwrap_or(&0),
hierarchical_memory_limit: *raw.get("hierarchical_memory_limit").unwrap_or(&0),
hierarchical_memsw_limit: *raw.get("hierarchical_memsw_limit").unwrap_or(&0),
hierarchical_memory_limit: *raw.get("hierarchical_memory_limit").unwrap_or(&0) as i64,
hierarchical_memsw_limit: *raw.get("hierarchical_memsw_limit").unwrap_or(&0) as i64,
total_cache: *raw.get("total_cache").unwrap_or(&0),
total_rss: *raw.get("total_rss").unwrap_or(&0),
total_rss_huge: *raw.get("total_rss_huge").unwrap_or(&0),
@@ -326,7 +340,7 @@ pub struct MemSwap {
/// How many times the limit has been hit.
pub fail_cnt: u64,
/// Memory and swap usage limit in bytes.
pub limit_in_bytes: u64,
pub limit_in_bytes: i64,
/// Current usage of memory and swap in bytes.
pub usage_in_bytes: u64,
/// The maximum observed usage of memory and swap in bytes.
@@ -340,7 +354,7 @@ pub struct Memory {
/// How many times the limit has been hit.
pub fail_cnt: u64,
/// The limit in bytes of the memory usage of the control group's tasks.
pub limit_in_bytes: u64,
pub limit_in_bytes: i64,
/// The current usage of memory by the control group's tasks.
pub usage_in_bytes: u64,
/// The maximum observed usage of memory by the control group's tasks.
@@ -362,7 +376,7 @@ pub struct Memory {
pub oom_control: OomControl,
/// Allows setting a limit to memory usage which is enforced when the system (note, _not_ the
/// control group) detects memory pressure.
pub soft_limit_in_bytes: u64,
pub soft_limit_in_bytes: i64,
/// Contains a wide array of statistics about the memory usage of the tasks in the control
/// group.
pub stat: MemoryStat,
@@ -385,7 +399,7 @@ pub struct Tcp {
pub fail_cnt: u64,
/// The limit in bytes of the memory usage of the kernel's TCP buffers by control group's
/// tasks.
pub limit_in_bytes: u64,
pub limit_in_bytes: i64,
/// The current memory used by the kernel's TCP buffers related to these tasks.
pub usage_in_bytes: u64,
/// The observed maximum usage of memory by the kernel's TCP buffers (that originated from
@@ -402,7 +416,7 @@ pub struct Kmem {
/// How many times the limit has been hit.
pub fail_cnt: u64,
/// The limit in bytes of the kernel memory used by the control group's tasks.
pub limit_in_bytes: u64,
pub limit_in_bytes: i64,
/// The current usage of kernel memory used by the control group's tasks, in bytes.
pub usage_in_bytes: u64,
/// The maximum observed usage of kernel memory used by the control group's tasks, in bytes.
@@ -425,6 +439,10 @@ impl ControllerInternal for MemController {
&self.base
}
fn is_v2(&self) -> bool {
self.v2
}
fn apply(&self, res: &Resources) -> Result<()> {
// get the resources that apply to this controller
let memres: &MemoryResources = &res.memory;
@@ -444,15 +462,48 @@ impl ControllerInternal for MemController {
impl MemController {
/// Contructs a new `MemController` with `oroot` serving as the root of the control group.
pub fn new(oroot: PathBuf) -> Self {
pub fn new(oroot: PathBuf, v2: bool) -> Self {
let mut root = oroot;
root.push(Self::controller_type().to_string());
if !v2 {
root.push(Self::controller_type().to_string());
}
Self {
base: root.clone(),
path: root,
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{
let v = value.0;
let f = value.1;
if v.is_some() {
let v = v.unwrap();
let v = max_value_to_string(v);
self.open_path(f, true)
.and_then(|mut file| {
file.write_all(v.as_ref())
.map_err(|e| Error::with_cause(WriteFailed, e))
})?;
}
}
Ok(())
}
// for v2
pub fn get_mem(&self) -> Result<SetMemory> {
let mut m: SetMemory = Default::default();
self.get_max_value("memory.high").map(|x| m.high = Some(x));
self.get_max_value("memory.low").map(|x| m.low = Some(x));
self.get_max_value("memory.max").map(|x| m.max = Some(x));
self.get_max_value("memory.min").map(|x| m.min = Some(x));
Ok(m)
}
/// Gathers overall statistics (and the current state of) about the memory usage of the control
/// group's tasks.
///
@@ -466,7 +517,7 @@ impl MemController {
.unwrap_or(0),
limit_in_bytes: self
.open_path("memory.limit_in_bytes", false)
.and_then(read_u64_from)
.and_then(read_i64_from)
.unwrap_or(0),
usage_in_bytes: self
.open_path("memory.usage_in_bytes", false)
@@ -492,7 +543,7 @@ impl MemController {
.unwrap_or(OomControl::default()),
soft_limit_in_bytes: self
.open_path("memory.soft_limit_in_bytes", false)
.and_then(read_u64_from)
.and_then(read_i64_from)
.unwrap_or(0),
stat: self
.open_path("memory.stat", false)
@@ -519,8 +570,8 @@ impl MemController {
.unwrap_or(0),
limit_in_bytes: self
.open_path("memory.kmem.limit_in_bytes", false)
.and_then(read_u64_from)
.unwrap_or(0),
.and_then(read_i64_from)
.unwrap_or(-1),
usage_in_bytes: self
.open_path("memory.kmem.usage_in_bytes", false)
.and_then(read_u64_from)
@@ -546,7 +597,7 @@ impl MemController {
.unwrap_or(0),
limit_in_bytes: self
.open_path("memory.kmem.tcp.limit_in_bytes", false)
.and_then(read_u64_from)
.and_then(read_i64_from)
.unwrap_or(0),
usage_in_bytes: self
.open_path("memory.kmem.tcp.usage_in_bytes", false)
@@ -569,7 +620,7 @@ impl MemController {
.unwrap_or(0),
limit_in_bytes: self
.open_path("memory.memsw.limit_in_bytes", false)
.and_then(read_u64_from)
.and_then(read_i64_from)
.unwrap_or(0),
usage_in_bytes: self
.open_path("memory.memsw.usage_in_bytes", false)
@@ -618,7 +669,7 @@ impl MemController {
}
/// Set the memory usage limit of the control group, in bytes.
pub fn set_limit(&self, limit: u64) -> Result<()> {
pub fn set_limit(&self, limit: i64) -> Result<()> {
self.open_path("memory.limit_in_bytes", true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
@@ -627,7 +678,7 @@ impl MemController {
}
/// Set the kernel memory limit of the control group, in bytes.
pub fn set_kmem_limit(&self, limit: u64) -> Result<()> {
pub fn set_kmem_limit(&self, limit: i64) -> Result<()> {
self.open_path("memory.kmem.limit_in_bytes", true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
@@ -636,7 +687,7 @@ impl MemController {
}
/// Set the memory+swap limit of the control group, in bytes.
pub fn set_memswap_limit(&self, limit: u64) -> Result<()> {
pub fn set_memswap_limit(&self, limit: i64) -> Result<()> {
self.open_path("memory.memsw.limit_in_bytes", true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
@@ -645,7 +696,7 @@ impl MemController {
}
/// Set how much kernel memory can be used for TCP-related buffers by the control group.
pub fn set_tcp_limit(&self, limit: u64) -> Result<()> {
pub fn set_tcp_limit(&self, limit: i64) -> Result<()> {
self.open_path("memory.kmem.tcp.limit_in_bytes", true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
@@ -657,7 +708,7 @@ impl MemController {
///
/// This limit is enforced when the system is nearing OOM conditions. Contrast this with the
/// hard limit, which is _always_ enforced.
pub fn set_soft_limit(&self, limit: u64) -> Result<()> {
pub fn set_soft_limit(&self, limit: i64) -> Result<()> {
self.open_path("memory.soft_limit_in_bytes", true)
.and_then(|mut file| {
file.write_all(limit.to_string().as_ref())
@@ -684,6 +735,14 @@ impl MemController {
.map_err(|e| Error::with_cause(WriteFailed, e))
})
}
pub fn register_oom_event(&self, key: &str) -> Result<Receiver<String>>{
if self.v2{
events::notify_on_oom_v2(key, self.get_path())
}else {
events::notify_on_oom_v1(key, self.get_path())
}
}
}
impl ControllIdentifier for MemController {
@@ -717,6 +776,17 @@ fn read_u64_from(mut file: File) -> Result<u64> {
}
}
fn read_i64_from(mut file: File) -> Result<i64> {
let mut string = String::new();
match file.read_to_string(&mut string) {
Ok(_) => string
.trim()
.parse()
.map_err(|e| Error::with_cause(ParseError, e)),
Err(e) => Err(Error::with_cause(ReadFailed, e)),
}
}
fn read_string_from(mut file: File) -> Result<String> {
let mut string = String::new();
match file.read_to_string(&mut string) {
@@ -727,6 +797,7 @@ 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,
};
@@ -830,6 +901,7 @@ total_unevictable 81920
#[test]
fn test_parse_memory_stat() {
let ok = parse_memory_stat(GOOD_MEMORYSTAT_VAL.to_string()).unwrap();
let raw = ok.raw.clone();
assert_eq!(
ok,
MemoryStat {
@@ -869,6 +941,7 @@ total_unevictable 81920
total_inactive_file: 1272135680,
total_active_file: 2338816000,
total_unevictable: 81920,
raw: raw,
}
);
}