You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash脚本正确创建cgroup?I/O error报错怎么解决?

Cgroup初始化脚本错误排查与修复

问题描述

我尝试编写init_cgroup.sh脚本,用于创建带有参数指定资源限制的容器。逻辑是先判断cgroup版本、完成挂载,再配置对应资源参数。目标是让组内任务仅在单个核心执行,临时分配给随机CPU。

原实现代码

#!/bin/sh

# args:
# $1 - mem_limit (not used at the moment)
# $2 - core usage percentage (e.g. 0.1)
# $3 - container name
GROUP_ID=$3
GROUP_PATH="/sys/fs/cgroup"

mount -t tmpfs -o rw,nosuid,nodev,noexec,relatime,size=0k cgroup_root $GROUP_PATH
mount -t cgroup2 none $GROUP_PATH
if [ $? != "0" ]; then
    mkdir "$GROUP_PATH/$GROUP_ID"
    mount -t cgroup -o cpu,cpuset,cpuacct,memory cgroup_cpu "$GROUP_PATH/$GROUP_ID"
    echo 100000 > "$GROUP_PATH/$GROUP_ID/cpu.cfs_quota_us"
    echo "100000*$2" > "$GROUP_PATH/$GROUP_ID/cpu.cpu.cfs_period_us"
    cpus_count=$(grep -c processor /proc/cpuinfo)
    rand_cpu=$RANDOM%cpus_count
    echo $rand_cpu > "$GROUP_PATH/$GROUP_ID/cpuset.cpus"
else 
    {
    echo "+cpu" 
    echo "+cpuset" 
    echo "+memory"
    } >> "$GROUP_PATH/cgroup.subtree_control"
    mkdir "$GROUP_PATH/$GROUP_ID"
    cpus_count=$(grep -c processor /proc/cpuinfo)
    rand_cpu=$RANDOM%$cpus_count
    echo "$rand_cpu" > "$GROUP_PATH/$GROUP_ID/cpuset.cpus"
fi

运行错误

使用sudo运行脚本时,能在/sys/fs/cgroup下创建文件夹,但输出错误:

> sudo ./init_cgroup.sh 0 0.1 testt

> ./init_cgroup.sh: 29: echo: echo: I/O error

我推测I/O error是因为即使sudo也无足够权限写入系统文件夹,请问该如何解决?我的实现是否正确?


错误原因与修复方案

1. I/O错误的核心原因

不是权限问题,而是脚本存在多个逻辑和操作错误:

  • cgroup v1挂载逻辑错误:直接在自定义分组目录挂载cgroup子系统不符合标准流程,应该先将子系统挂载到根目录下的对应子文件夹,再在子系统目录内创建分组。
  • 文件路径笔误:cpu.cpu.cfs_period_us多写了一个cpu.,正确路径是cpu.cfs_period_us。
  • 算术表达式未计算:echo "100000*$2"会把字符串直接写入文件,而非计算后的数值,需要用工具完成数值计算。
  • 随机CPU计算语法错误:rand_cpu=$RANDOM%cpus_count未正确展开变量,无法得到有效CPU编号。
  • cgroup v2依赖配置缺失:设置cpuset.cpus前必须先配置cpuset.mems(绑定内存节点),否则会触发I/O错误。

2. 关键修正要点

  • 优化cgroup版本检测:通过/proc/filesystems和挂载信息判断系统使用的cgroup版本,而非直接尝试挂载cgroup2。
  • 修正cgroup v1挂载流程:遵循标准挂载方式,先挂载子系统到根目录下的对应目录,再创建分组。
  • 修复数值计算与文件路径:修正笔误,用bc或$(( ))完成算术计算后写入文件。
  • 补充cgroup v2 cpuset依赖:设置cpuset.cpus前先配置cpuset.mems=0(默认内存节点)。

3. 完整修正脚本

#!/bin/sh

# args:
# $1 - mem_limit (not used at the moment)
# $2 - core usage percentage (e.g. 0.1)
# $3 - container name
GROUP_ID=$3
CGROUP_ROOT="/sys/fs/cgroup"
CPU_PERIOD_US=100000

# 计算CPU配额:quota = period * 百分比,兼容整数和小数
if echo "$2" | grep -q "\."; then
    CALCULATED_QUOTA=$(echo "$CPU_PERIOD_US * $2" | bc | awk '{print int($1)}')
else
    CALCULATED_QUOTA=$((CPU_PERIOD_US * $2))
fi

# 获取CPU核心数并生成随机核心编号
CPUS_COUNT=$(grep -c processor /proc/cpuinfo)
RAND_CPU=$((RANDOM % CPUS_COUNT))

# 判断系统使用的cgroup版本
if grep -q cgroup2 /proc/filesystems && mount | grep -q "type cgroup2"; then
    # cgroup v2 逻辑
    # 确保所需子系统已加入控制列表
    for ctrl in cpu cpuset memory; do
        if ! grep -q "+$ctrl" "$CGROUP_ROOT/cgroup.subtree_control"; then
            echo "+$ctrl" >> "$CGROUP_ROOT/cgroup.subtree_control"
        fi
    done

    # 创建分组目录
    mkdir -p "$CGROUP_ROOT/$GROUP_ID"
    # 先设置内存节点,再绑定CPU核心
    echo "0" > "$CGROUP_ROOT/$GROUP_ID/cpuset.mems"
    echo "$RAND_CPU" > "$CGROUP_ROOT/$GROUP_ID/cpuset.cpus"
    # 设置CPU使用率限制(cgroup v2用cpu.max,格式为quota period)
    echo "$CALCULATED_QUOTA $CPU_PERIOD_US" > "$CGROUP_ROOT/$GROUP_ID/cpu.max"
else
    # cgroup v1 逻辑
    # 确保cpu/cpuset子系统已挂载
    CPU_CGROUP_DIR="$CGROUP_ROOT/cpu"
    if [ ! -d "$CPU_CGROUP_DIR" ]; then
        mkdir -p "$CPU_CGROUP_DIR"
        mount -t cgroup -o cpu,cpuset,cpuacct cgroup_cpu "$CPU_CGROUP_DIR"
    fi

    # 创建分组目录
    GROUP_DIR="$CPU_CGROUP_DIR/$GROUP_ID"
    mkdir -p "$GROUP_DIR"
    # 设置CPU使用率限制
    echo "$CALCULATED_QUOTA" > "$GROUP_DIR/cpu.cfs_quota_us"
    echo "$CPU_PERIOD_US" > "$GROUP_DIR/cpu.cfs_period_us"
    # 绑定CPU核心和内存节点
    echo "$RAND_CPU" > "$GROUP_DIR/cpuset.cpus"
    echo "0" > "$GROUP_DIR/cpuset.mems"
fi

echo "Cgroup $GROUP_ID 创建成功,绑定至CPU核心 $RAND_CPU"

4. 使用说明

  • 必须以sudo权限运行:sudo ./init_cgroup.sh 0 0.1 testt
  • 脚本会自动适配cgroup v1或v2系统
  • 已修复所有导致I/O错误的问题,确保资源限制配置生效

内容的提问来源于stack exchange,提问作者ippishio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:21:01