mirror of
https://github.com/kata-containers/cgroups-rs.git
synced 2026-08-05 02:13:23 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87f05873f0 | ||
|
|
79868d6bfc | ||
|
|
d1d78fe943 | ||
|
|
81d286f31d | ||
|
|
5e538ae286 | ||
|
|
cd5645bb14 | ||
|
|
4a2042068e | ||
|
|
9ac2f5d5ab | ||
|
|
a58cd1d553 | ||
|
|
88a45d4922 | ||
|
|
0c58b5dd84 | ||
|
|
8448548cb3 | ||
|
|
d50245e116 | ||
|
|
bbdfa88596 | ||
|
|
853ed46993 | ||
|
|
15b65c5e5e |
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'bug, needs-review'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/enhancement-request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/enhancement-request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Enhancement request
|
||||
about: Suggest an improvement to an existing feature
|
||||
title: ''
|
||||
labels: enhancement, needs-review
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Which feature do you think can be improved?**
|
||||
|
||||
Specify the feature you think could be made better.
|
||||
|
||||
**How can it be improved?**
|
||||
|
||||
Describe how specifically you think it could be improved.
|
||||
|
||||
**Additional Information**
|
||||
|
||||
Anything else to add?
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'feature, needs-review'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
26
.github/workflows/bvt.yaml
vendored
Normal file
26
.github/workflows/bvt.yaml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: BVT
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: make debug
|
||||
|
||||
fmt:
|
||||
name: Format Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: rustup component add rustfmt
|
||||
- run: make fmt
|
||||
test:
|
||||
name: Run Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: make test
|
||||
|
||||
31
.travis.yml
31
.travis.yml
@@ -1,31 +0,0 @@
|
||||
# Copyright (c) 2018 Levente Kurusa
|
||||
# Copyright (c) 2020 Ant Group
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
dist: bionic
|
||||
os: linux
|
||||
language: rust
|
||||
cache: cargo
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
|
||||
install:
|
||||
- rustup component add rustfmt
|
||||
|
||||
script:
|
||||
- RUSTFLAGS="--deny warnings" cargo build
|
||||
- if [ "$TRAVIS_CPU_ARCH" == "amd64" ]; then cargo test -- --color always --nocapture ; fi
|
||||
- cargo fmt -- --check
|
||||
|
||||
rust:
|
||||
- 1.44.1
|
||||
- nightly
|
||||
|
||||
jobs:
|
||||
allow_failures:
|
||||
- rust: nightly
|
||||
fast_finish: true
|
||||
@@ -5,16 +5,17 @@ repository = "https://github.com/kata-containers/cgroups-rs"
|
||||
keywords = ["linux", "cgroup", "containers", "isolation"]
|
||||
categories = ["os", "api-bindings", "os::unix-apis"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
version = "0.2.1"
|
||||
version = "0.2.3"
|
||||
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>", "Levente Kurusa <lkurusa@acm.org>", "Sam Wilson <tecywiz121@hotmail.com>"]
|
||||
edition = "2018"
|
||||
homepage = "https://github.com/kata-containers/cgroups-rs"
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
regex = "1.1"
|
||||
nix = "0.18.0"
|
||||
libc = "0.2"
|
||||
procinfo = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
libc = "0.2.76"
|
||||
|
||||
37
Makefile
Normal file
37
Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
all: debug fmt test
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
.PHONY: debug
|
||||
debug:
|
||||
RUSTFLAGS="--deny warnings" cargo build
|
||||
|
||||
.PHONY: release
|
||||
release:
|
||||
cargo build --release
|
||||
|
||||
.PHONY: build
|
||||
build: debug
|
||||
|
||||
#
|
||||
# Tests and linters
|
||||
#
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
cargo test -- --color always --nocapture
|
||||
|
||||
.PHONY: check
|
||||
check: fmt clippy
|
||||
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
cargo fmt --all -- --check
|
||||
|
||||
.PHONY: clippy
|
||||
clippy:
|
||||
cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
//! Currently, we only support the cgroupv1 hierarchy, but in the future we will add support for
|
||||
//! the Unified Hierarchy.
|
||||
|
||||
use procinfo::pid::{mountinfo_self, Mountinfo};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::blkio::BlkIoController;
|
||||
@@ -31,6 +32,75 @@ use crate::{Controllers, Hierarchy, Subsystem};
|
||||
|
||||
use crate::cgroup::Cgroup;
|
||||
|
||||
/// Process mounts information.
|
||||
///
|
||||
/// See `proc(5)` for format details.
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Mountinfo {
|
||||
/// Mount pathname relative to the process's root.
|
||||
pub mount_point: PathBuf,
|
||||
/// Filesystem type (main type with optional sub-type).
|
||||
pub fs_type: (String, Option<String>),
|
||||
/// Superblock options.
|
||||
pub super_opts: Vec<String>,
|
||||
}
|
||||
|
||||
pub(crate) fn parse_mountinfo_for_line(line: &str) -> Option<Mountinfo> {
|
||||
let s_values: Vec<_> = line.split(" - ").collect();
|
||||
if s_values.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let s0_values: Vec<_> = s_values[0].trim().split(' ').collect();
|
||||
let s1_values: Vec<_> = s_values[1].trim().split(' ').collect();
|
||||
if s0_values.len() < 6 || s1_values.len() < 3 {
|
||||
return None;
|
||||
}
|
||||
let mount_point = PathBuf::from(s0_values[4]);
|
||||
let fs_type_values: Vec<_> = s1_values[0].trim().split('.').collect();
|
||||
let fs_type = match fs_type_values.len() {
|
||||
1 => (fs_type_values[0].to_string(), None),
|
||||
2 => (
|
||||
fs_type_values[0].to_string(),
|
||||
Some(fs_type_values[1].to_string()),
|
||||
),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let super_opts: Vec<String> = s1_values[2].trim().split(',').map(String::from).collect();
|
||||
Some(Mountinfo {
|
||||
mount_point,
|
||||
fs_type,
|
||||
super_opts,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses the provided mountinfo file.
|
||||
fn mountinfo_file(file: &mut File) -> Vec<Mountinfo> {
|
||||
let mut r = Vec::new();
|
||||
for line in BufReader::new(file).lines() {
|
||||
match line {
|
||||
Ok(line) => {
|
||||
if let Some(mi) = parse_mountinfo_for_line(&line) {
|
||||
if mi.fs_type.0 == "cgroup" {
|
||||
r.push(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => continue,
|
||||
}
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
/// Returns mounts information for the current process.
|
||||
pub fn mountinfo_self() -> Vec<Mountinfo> {
|
||||
match File::open("/proc/self/mountinfo") {
|
||||
Ok(mut file) => mountinfo_file(&mut file),
|
||||
Err(_) => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// The standard, original cgroup implementation. Often referred to as "cgroupv1".
|
||||
#[derive(Debug)]
|
||||
pub struct V1 {
|
||||
@@ -184,7 +254,7 @@ impl V1 {
|
||||
/// can be created.
|
||||
pub fn new() -> V1 {
|
||||
V1 {
|
||||
mountinfo: mountinfo_self().unwrap(),
|
||||
mountinfo: mountinfo_self(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,3 +323,36 @@ pub fn auto() -> Box<dyn Hierarchy> {
|
||||
Box::new(V1::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_mount() {
|
||||
let mountinfo = vec![
|
||||
("29 26 0:26 / /sys/fs/cgroup/cpuset,cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,cpuset,cpu,cpuacct",
|
||||
Mountinfo{mount_point: PathBuf::from("/sys/fs/cgroup/cpuset,cpu,cpuacct"), fs_type: ("cgroup".to_string(), None), super_opts: vec![
|
||||
"rw".to_string(),
|
||||
"cpuset".to_string(),
|
||||
"cpu".to_string(),
|
||||
"cpuacct".to_string(),
|
||||
]}),
|
||||
("121 1731 0:42 / /shm rw,nosuid,nodev,noexec,relatime shared:68 master:66 - tmpfs shm rw,size=65536k",
|
||||
Mountinfo{mount_point: PathBuf::from("/shm"), fs_type: ("tmpfs".to_string(), None), super_opts: vec![
|
||||
"rw".to_string(),
|
||||
"size=65536k".to_string(),
|
||||
]}),
|
||||
("121 1731 0:42 / /shm rw,nosuid,nodev,noexec,relatime shared:68 master:66 - tmpfs.123 shm rw,size=65536k",
|
||||
Mountinfo{mount_point: PathBuf::from("/shm"), fs_type: ("tmpfs".to_string(), Some("123".to_string())), super_opts: vec![
|
||||
"rw".to_string(),
|
||||
"size=65536k".to_string(),
|
||||
]}),
|
||||
];
|
||||
|
||||
for mi in mountinfo {
|
||||
let info = parse_mountinfo_for_line(mi.0).unwrap();
|
||||
assert_eq!(info, mi.1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
src/lib.rs
26
src/lib.rs
@@ -330,7 +330,7 @@ where
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fs::remove_dir(self.get_path()).map_err(|e| Error::with_cause(ErrorKind::RemoveFailed, e))
|
||||
remove_dir(self.get_path())
|
||||
}
|
||||
|
||||
/// Attach a task to this controller.
|
||||
@@ -379,6 +379,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// remove_dir aims to remove cgroup path. It does so recursively,
|
||||
// by removing any subdirectories (sub-cgroups) first.
|
||||
fn remove_dir(dir: &PathBuf) -> Result<()> {
|
||||
// try the fast path first.
|
||||
if fs::remove_dir(dir).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if dir.exists() {
|
||||
if dir.is_dir() {
|
||||
for entry in fs::read_dir(dir).map_err(|e| Error::with_cause(ReadFailed, e))? {
|
||||
let entry = entry.map_err(|e| Error::with_cause(ReadFailed, e))?;
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
remove_dir(&path)?;
|
||||
}
|
||||
}
|
||||
fs::remove_dir(dir).map_err(|e| Error::with_cause(RemoveFailed, e))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait ControllIdentifier {
|
||||
fn controller_type() -> Controllers;
|
||||
|
||||
@@ -460,6 +460,10 @@ impl ControllerInternal for MemController {
|
||||
update!(self, set_tcp_limit, memres.kernel_tcp_memory_limit);
|
||||
update!(self, set_swappiness, memres.swappiness);
|
||||
|
||||
memres.attrs.iter().for_each(|(k, v)| {
|
||||
let _ = self.set(k, v);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user