LoginSignup
1
1

More than 3 years have passed since last update.

CGroup V2 を一般(非root)ユーザーからシェルで操作する

Posted at

Fedora 31のようにCGroup V2 (Unified CGroup Hierarchy) で起動されsystemdが動いているシステムの上で、一般ユーザーがシェルでCGroupのツリーを構成しリソース制限を掛ける手順の例です。CGroup V2の日本語のウェブ上の記事としては

などがあります。またリソース制限を掛けるだけならLinux cgroup v2で実メモリ占有量を制限するにある手順で十分です。以下の手順を実行する前準備としてLinux cgroup v2で実メモリ占有量を制限するを用いてsystemd-run --user --scope /bin/bashが使えるようにしてください。

一般ユーザーが書き込み(操作)できるCGroupツリーを作成する

$ export CGROUPDIR=/sys/fs/cgroup/user.slice/user-$UID.slice/user@$UID.service/myshell.scope

ディレクトリ名が長いから名前を付ける。

$ systemd-run --unit=myshell --user --scope -p "Delegate=cpu io memory pids" /bin/bash
Running scope as unit: myshell.scope

これで /sys/fs/cgroup/user.slice/user-$UID.slice/user@$UID.service/myshell.scope が書き込み可能なCGroupツリーとして作成されて、そこに所属するbashのプロンプトが現れる。

$ systemctl --user status myshell.scope
● myshell.scope - /bin/bash
   Loaded: loaded (/run/user/1000/systemd/transient/myshell.scope; transient)
Transient: yes
   Active: active (running) since Sat 2019-12-07 12:38:53 JST; 1min 24s ago
    Tasks: 2 (limit: 4915)
   Memory: 2.9M
      CPU: 45ms
   CGroup: /user.slice/user-1000.slice/user@1000.service/myshell.scope
           ├─10574 /bin/bash
           └─10621 systemctl --user status myshell.scope

CGroupツリーの様子は上記の通り

サブツリー1を作るを作りbashをそこに移動する

シェル変数$$はbashのプロセスID (PID)を表す

$ mkdir $CGROUPDIR/tree1
$ echo $$ >$CGROUPDIR/tree1/cgroup.procs
$ systemctl --user status myshell.scope
● myshell.scope - /bin/bash
   Loaded: loaded (/run/user/1000/systemd/transient/myshell.scope; transient)
Transient: yes
   Active: active (running) since Sat 2019-12-07 12:38:53 JST; 4min 25s ago
    Tasks: 2 (limit: 4915)
   Memory: 3.0M
      CPU: 58ms
   CGroup: /user.slice/user-1000.slice/user@1000.service/myshell.scope
           └─tree1
             ├─10574 /bin/bash
             └─10645 systemctl --user status myshell.scope

サブツリー2を作りそこで新たなプロセスを作成する

$ mkdir $CGROUPDIR/tree2
$ bash -c 'echo $$ >$CGROUPDIR/tree2/cgroup.procs; sleep 100000' &
[1] 10672
$ systemctl --user status myshell.scope
● myshell.scope - /bin/bash
   Loaded: loaded (/run/user/1000/systemd/transient/myshell.scope; transient)
Transient: yes
   Active: active (running) since Sat 2019-12-07 12:38:53 JST; 9min ago
    Tasks: 4 (limit: 4915)
   Memory: 3.6M
      CPU: 74ms
   CGroup: /user.slice/user-1000.slice/user@1000.service/myshell.scope
           ├─tree1
           │ ├─10574 /bin/bash
           │ └─10674 systemctl --user status myshell.scope
           └─tree2
             ├─10672 bash -c echo $$ >$CGROUPDIR/tree2/cgroup.procs; sleep 1000…
             └─10673 sleep 100000

ツリー1とツリー2にCGroupコントローラーを追加しリソース制限を書き加える

$ echo +pids +memory >$CGROUPDIR/cgroup.subtree_control
$ cat $CGROUPDIR/tree2/cgroup.controllers
memory pids
$ echo 2G >$CGROUPDIR/tree2/memory.high
$ cat $CGROUPDIR/tree2/memory.high
2147483648

systemd-run --user で起動したbashが終了してもCGroupは存続する

$ exit
$ systemctl --user status myshell.scope
● myshell.scope - /bin/bash
   Loaded: loaded (/run/user/1000/systemd/transient/myshell.scope; transient)
Transient: yes
   Active: active (running) since Sat 2019-12-07 12:38:53 JST; 17min ago
    Tasks: 2 (limit: 4915)
   Memory: 3.1M
      CPU: 173ms
   CGroup: /user.slice/user-1000.slice/user@1000.service/myshell.scope
           └─tree2
             ├─10672 bash -c echo $$ >$CGROUPDIR/tree2/cgroup.procs; sleep 1000…
             └─10673 sleep 100000

注意点

  • ディレクトリ/cgroup.procs が空でないときにはそのディレクトリのcgroup.subtree_controlにコントローラーを追加・削除できない
  • 子ディレクトリを持たないディレクトリのcgroup.procsがプロセスを持てる原則なので、あるCGroupの下に子ディレクトリを掘りたいときには、そのCGroupにいるプロセスを子ディレクトリに速やかに移動する
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1