mirror of
https://github.com/kata-containers/cgroups-rs.git
synced 2026-08-05 02:13:23 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87f05873f0 | ||
|
|
79868d6bfc | ||
|
|
d1d78fe943 | ||
|
|
81d286f31d | ||
|
|
5e538ae286 | ||
|
|
cd5645bb14 | ||
|
|
4a2042068e | ||
|
|
9ac2f5d5ab | ||
|
|
a58cd1d553 | ||
|
|
88a45d4922 | ||
|
|
0c58b5dd84 | ||
|
|
8448548cb3 | ||
|
|
d50245e116 |
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"]
|
keywords = ["linux", "cgroup", "containers", "isolation"]
|
||||||
categories = ["os", "api-bindings", "os::unix-apis"]
|
categories = ["os", "api-bindings", "os::unix-apis"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>", "Levente Kurusa <lkurusa@acm.org>", "Sam Wilson <tecywiz121@hotmail.com>"]
|
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>", "Levente Kurusa <lkurusa@acm.org>", "Sam Wilson <tecywiz121@hotmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
homepage = "https://github.com/kata-containers/cgroups-rs"
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
regex = "1.1"
|
regex = "1.1"
|
||||||
nix = "0.18.0"
|
nix = "0.18.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
procinfo = "0.4.2"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
libc = "0.2.76"
|
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
|
//! Currently, we only support the cgroupv1 hierarchy, but in the future we will add support for
|
||||||
//! the Unified Hierarchy.
|
//! the Unified Hierarchy.
|
||||||
|
|
||||||
use procinfo::pid::{mountinfo_self, Mountinfo};
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::blkio::BlkIoController;
|
use crate::blkio::BlkIoController;
|
||||||
@@ -31,6 +32,75 @@ use crate::{Controllers, Hierarchy, Subsystem};
|
|||||||
|
|
||||||
use crate::cgroup::Cgroup;
|
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".
|
/// The standard, original cgroup implementation. Often referred to as "cgroupv1".
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct V1 {
|
pub struct V1 {
|
||||||
@@ -184,7 +254,7 @@ impl V1 {
|
|||||||
/// can be created.
|
/// can be created.
|
||||||
pub fn new() -> V1 {
|
pub fn new() -> V1 {
|
||||||
V1 {
|
V1 {
|
||||||
mountinfo: mountinfo_self().unwrap(),
|
mountinfo: mountinfo_self(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,3 +323,36 @@ pub fn auto() -> Box<dyn Hierarchy> {
|
|||||||
Box::new(V1::new())
|
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(());
|
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.
|
/// 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)]
|
#[doc(hidden)]
|
||||||
pub trait ControllIdentifier {
|
pub trait ControllIdentifier {
|
||||||
fn controller_type() -> Controllers;
|
fn controller_type() -> Controllers;
|
||||||
|
|||||||
Reference in New Issue
Block a user