3个不稳定版本

0.3.0 2020年3月29日
0.2.1 2019年9月15日
0.2.0 2019年9月11日

#265 in Unix APIs

Download history 196/week @ 2024-04-04 130/week @ 2024-04-11 139/week @ 2024-04-18 24/week @ 2024-04-25 26/week @ 2024-05-02 35/week @ 2024-05-09 100/week @ 2024-05-16 132/week @ 2024-05-23 88/week @ 2024-05-30 132/week @ 2024-06-06 233/week @ 2024-06-13 156/week @ 2024-06-20 396/week @ 2024-06-27 267/week @ 2024-07-04 102/week @ 2024-07-11 67/week @ 2024-07-18

890 每月下载量

MIT/Apache

310KB
6.5K SLoC

controlgroup-rs

Build Status Docs

原生Rust包,用于cgroup操作。

目前此包仅支持cgroup v1层次结构,实现在 v1 模块中。

支持

未实现的功能

以下功能尚未以方便的方式实现,但您可以通过低级API直接读取和写入cgroup文件。

  • 内存子系统:读取 memory.kmem.slabinfo 文件

测试的发行版

此包已在以下系统上测试:

  • Ubuntu 16.04 (Xenial)
  • Ubuntu 18.04 (Bionic)

在Travis-CI上。

未测试的功能

  • CPU子系统
    • 读取和写入实时任务的调度参数
  • Cpuset子系统
    • 获取cgroup面临的内存压力
  • 内存子系统
    • 在NUMA系统上获取每个NUMA节点的统计信息
  • HugeTLB子系统
    • 监控cgroup的巨大页TLB使用情况
  • BlkIO子系统
    • 设置设备的权重
    • 监控cgroup消耗的blkio吞吐量
  • RDMA子系统

v1层次结构的示例

创建由CPU子系统控制的cgroup

use std::path::PathBuf;
use controlgroup::{Pid, v1::{cpu, Cgroup, CgroupPath, SubsystemKind, Resources}};

// Define and create a new cgroup controlled by the CPU subsystem.
let mut cgroup = cpu::Subsystem::new(
    CgroupPath::new(SubsystemKind::Cpu, PathBuf::from("students/charlie")));
cgroup.create()?;

// Attach the self process to the cgroup.
let pid = Pid::from(std::process::id());
cgroup.add_task(pid)?;

// Define resource limits and constraints for this cgroup.
// Here we just use the default for an example.
let resources = Resources::default();

// Apply the resource limits.
cgroup.apply(&resources)?;

// Low-level file operations are also supported.
let stat_file = cgroup.open_file_read("cpu.stat")?;

// Do something ...

// Now, remove self process from the cgroup.
cgroup.remove_task(pid)?;

// ... and delete the cgroup.
cgroup.delete()?;

// Note that subsystem handlers does not implement `Drop` and therefore when the
// handler is dropped, the cgroup will stay around.

创建由多个子系统控制的cgroup集合

v1::Builder 通过构建器模式提供配置cgroup的方法。

use std::path::PathBuf;
use controlgroup::{
    Max,
    v1::{devices, hugetlb::{self, HugepageSize}, net_cls, rdma, Builder, SubsystemKind},
};

let mut cgroups =
    // Start building a (set of) cgroup(s).
    Builder::new(PathBuf::from("students/charlie"))
    // Start configuring the CPU resource limits.
    .cpu()
        .shares(1000)
        .cfs_quota_us(500 * 1000)
        .cfs_period_us(1000 * 1000)
        // Finish configuring the CPU resource limits.
        .done()
    // Start configuring the cpuset resource limits.
    .cpuset()
        .cpus([0].iter().copied().collect())
        .mems([0].iter().copied().collect())
        .memory_migrate(true)
        .done()
    .memory()
        .limit_in_bytes(4 * (1 << 30))
        .soft_limit_in_bytes(3 * (1 << 30))
        .use_hierarchy(true)
        .done()
    .hugetlb()
        .limits(
            [
                (HugepageSize::Mb2, hugetlb::Limit::Pages(4)),
                (HugepageSize::Gb1, hugetlb::Limit::Pages(2)),
            ].iter().copied()
        )
        .done()
    .devices()
        .deny(vec!["a *:* rwm".parse::<devices::Access>().unwrap()])
        .allow(vec!["c 1:3 mr".parse::<devices::Access>().unwrap()])
        .done()
    .blkio()
        .weight(1000)
        .weight_device([([8, 0].into(), 100)].iter().copied())
        .read_bps_device([([8, 0].into(), 10 * (1 << 20))].iter().copied())
        .write_iops_device([([8, 0].into(), 100)].iter().copied())
        .done()
    .rdma()
        .max(
            [(
                "mlx4_0".to_string(),
                rdma::Limit {
                    hca_handle: 2.into(),
                    hca_object: Max::Max,
                },
            )].iter().cloned(),
        )
        .done()
    .net_prio()
        .ifpriomap(
            [("lo".to_string(), 0), ("wlp1s0".to_string(), 1)].iter().cloned(),
        )
        .done()
    .net_cls()
        .classid([0x10, 0x1].into())
        .done()
    .pids()
        .max(42.into())
        .done()
    .freezer()
        // Tasks in this cgroup will be frozen.
        .freeze()
        .done()
    // Enable CPU accounting for this cgroup.
    // Cpuacct subsystem has no parameter, so this method does not return a subsystem builder,
    // just enables the accounting.
    .cpuacct()
    // Enable monitoring this cgroup via `perf` tool.
    // Like `cpuacct()` method, this method does not return a subsystem builder.
    .perf_event()
    // Skip creating directories for Cpuacct subsystem and net_cls subsystem.
    // This is useful when some subsystems share hierarchy with others.
    .skip_create(vec![SubsystemKind::Cpuacct, SubsystemKind::NetCls])
    // Actually build cgroups with the configuration.
    .build()?;

let pid = std::process::id().into();
cgroups.add_task(pid)?;

// Do something ...

cgroups.remove_task(pid)?;
cgroups.delete()?;

在一个或多个cgroup中启动进程

v1::CommandExt 扩展了 std::process::Command 构建器,以便在启动时将命令进程附加到一个或多个cgroup上。

use std::path::PathBuf;
use controlgroup::v1::{cpu, Cgroup, CgroupPath, SubsystemKind};
// Import extension trait
use controlgroup::v1::CommandExt as _;

let mut cgroup = cpu::Subsystem::new(
    CgroupPath::new(SubsystemKind::Cpu, PathBuf::from("students/charlie")));
cgroup.create()?;

let mut child = std::process::Command::new("sleep")
    .arg("1")
    // Attach this command process to a cgroup on start
    .cgroup(&mut cgroup)
    // This process will run within the cgroup
    .spawn()
    .unwrap();

println!("{:?}", cgroup.stat()?);

child.wait().unwrap();
cgroup.delete()?;

MSRV(最小支持的Rust版本)

rustc 1.37.0 (eae3437df 2019-08-13)

如果您想使用此包与较旧的Rust版本,请在 问题 #1 上留言。

免责声明

此项目最初作为 levex/cgroups-rs 的分支开始,通过重新设计和重新实现整个项目进行开发。 levex/cgroups-rs 依据MIT OR Apache-2.0许可。

请参阅LICENSE获取详细信息。

许可证

版权所有 2019 Hidehito Yabuuchi <[email protected]>

根据MIT许可证<LICENSE-MIT 或 http://opensource.org/licenses/MIT>或Apache许可证2.0版<LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0>进行许可,具体取决于您的选择。所有带有此类声明的项目文件,不得复制、修改或分发,除非符合这些条款。

除非您明确表示,否则您提交给作品的所有有意贡献,如Apache-2.0许可证中定义的,将按上述方式双重许可,不附加任何额外的条款或条件。

无运行时依赖