前回の最後で
毎年、
今回は4.
nsdelegate オプション
第38回でcgroup v2のマウント方法を紹介しました。第38回で使用していた4.
その後、nsdelegate
というマウントオプションがひとつだけ追加されました。現時点でもcgroup v2のマウントで指定できるオプションは、nsdelegate
のみです。
このオプションは、
このオプションは、
それでは、
cgroup間のプロセスの移動
cgroup名前空間は第34回で説明したとおり、
詳しくは第34回を参照していただくとして、
次の例は4./test01
"にいるはずのプロセスから所属しているcgroupを確認すると、/
)
$ sudo mkdir /sys/fs/cgroup/test01 (test01 cgroupを作成) $ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs (カレントシェルをtest01に登録) 27668 $ sudo unshare --cgroup /bin/bash (cgroup名前空間を作成) # echo $$ (自身のPIDを確認) 27700 # cat /proc/self/cgroup (自分が所属するcgroupを確認) 0::/
念のため、/test01
"にいることが確認できます。
$ sudo cat /proc/27700/cgroup 0::/test01
nsdelegateオプションを指定しない場合
上記の例はnsdelegate
を指定せずにcgroup v2をマウントしていますので、
# mkdir /sys/fs/cgroup/test02 (root直下にtest02を作成) # echo $$ > /sys/fs/cgroup/test02/cgroup.procs (カレントシェルをtest02に移動) # cat /proc/self/cgroup (現在のcgroupを確認) 0::/../test02
元々、/test01
"にいたプロセスを、/test02
に移動させました。すると、/../
"に所属していると表示されました。rootの親cgroupの配下の"test02" cgroupに所属しているということで、
名前空間を作るという操作は、
早速試してみましょう。
nsdelegateオプションを指定した場合
すでにcgroup v2をマウントしている場合、nsdelegate
オプションを指定してマウントできます。そして、
$ sudo mount -t cgroup2 -o remount,nsdelegate /sys/fs/cgroup/ (nsdelegateオプションを指定して再マウント) $ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs 27668 $ sudo unshare --cgroup /bin/bash (cgroup名前空間を作成) # cat /proc/self/cgroup (自分が所属するcgroupを確認) 0::/
ここまでは先のnsdelegateを指定していないときの例と同じです。それではカレントシェルのPIDを"test02"に移動させてみましょう。
# echo $$ > /sys/fs/cgroup/test02/cgroup.procs bash: echo: write error: No such file or directory # ls /sys/fs/cgroup/test02/cgroup.procs /sys/fs/cgroup/test02/cgroup.procs
上のように"No such file or directory"とエラーになりました。しかし"test02" cgroupは存在しています。
つまり"/test01
"をrootとしてcgroup名前空間が作られているので、
ちなみに、

cgroupの権限委譲
連載の第40回で説明したとおり、
- cgroup
(ディレクトリ) への書き込み権限 - cgroup内の
cgroup.
ファイルへの書き込み権限procs
そして、

この権限委譲を行うには、nsdelegate
オプションが導入されてからは、nsdelegate
オプション付きでcgroup v2をマウントするという方法が採れるようになりました。
nsdelegateオプションを指定しない場合
まずはnsdelegate
を指定しない方法を改めて紹介します。ここではあえて対象となるcgroupで、
準備として、io
、pids
、memory
コントローラが使えるように設定します。
$ sudo mount -t cgroup2 cgroup2 /sys/fs/cgroup/ (マウント) $ echo "+io +pids +memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgroupでio, pids, memoryコントローラが使えるように設定) +io +pids +memory $ cat /sys/fs/cgroup/cgroup.subtree_control io memory pids (設定された)
このあたりの操作は第38回で紹介したとおりです。
ここで"test01" cgroupを作成します。そして一般ユーザである"gihyo"ユーザに対して、
$ sudo mkdir /sys/fs/cgroup/test01 (cgroup作成) $ sudo chown gihyo /sys/fs/cgroup/test01 (ディレクトリ所有権をgihyoに) $ sudo chown gihyo /sys/fs/cgroup/test01/* (ディレクトリ内のファイル所有権をgihyoに)
通常はディレクトリとcgroup.
ファイルにのみアクセス権を与えることが一般的です。ここでは、nsdelegate
オプションを指定した場合との比較のためにあえてこのようにしています。
カレントシェルのPIDを"test01" cgroupに登録します。
$ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs
(カレントシェルをtest01に登録)
4352
ここでユーザ名前空間とともにcgroup名前空間を作成します。現在のユーザである"gihyo"ユーザをユーザ名前空間内の"root"ユーザにマッピングするために--map-root-user
オプションを指定しています。
$ unshare --user --cgroup --map-root-user /bin/bash (cgroup名前空間を作成しbashを実行) # cat /proc/self/cgroup (cgroup名前空間内でrootにいることを確認) 0::/
ここではpids.
に制限を設定することにして、pids.
ファイルに制限値を設定してみます。
# ls -l /sys/fs/cgroup/test01/pids.max (pids.maxファイルに書き込み権があることを確認) -rw-r--r-- 1 root nogroup 0 11月 30日 19:51 /sys/fs/cgroup/test01/pids.max # echo 50 > /sys/fs/cgroup/test01/pids.max (制限値の書き込み) # cat /sys/fs/cgroup/test01/pids.max 50 (書き込めたことを確認)
無事にファイルに制限値を書き込めたことが確認できました。アクセス権から考えて予想できる動きではないかと思います。
nsdelegateオプションを指定した場合
それではnsdelegate
オプションを指定してcgroup v2をマウントして試してみましょう。
マウント後、io
、pids
、memory
コントローラが使えるようにします。
$ sudo mount -t cgroup2 -o nsdelegate cgroup2 /sys/fs/cgroup/ (マウント) $ echo "+io +pids +memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgroupでio, pids, memoryコントローラが使えるように設定) +io +pids +memory $ cat /sys/fs/cgroup/cgroup.subtree_control io memory pids (設定された)
そして、
$ sudo mkdir /sys/fs/cgroup/test01 (cgroup作成) $ sudo chown gihyo /sys/fs/cgroup/test01 (ディレクトリ所有権をgihyoに) $ sudo chown gihyo /sys/fs/cgroup/test01/* (ディレクトリ内のファイル所有権をgihyoに)
ここでも、nsdelegate
オプションを指定しないときの例と同様に、
$ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs
(カレントシェルをtest01に登録)
4399
次に、
$ unshare --user --cgroup --map-root-user /bin/bash (cgroup名前空間を作成しbashを実行) # cat /proc/self/cgroup 0::/ (cgroup名前空間内でrootにいることを確認)
所有権を設定していますので"test01"直下に存在するpid.
ファイルには書き込み権があります。
# ls -l /sys/fs/cgroup/test01/pids.max (pids.maxファイルに書き込み権があることを確認) -rw-r--r-- 1 root nogroup 0 11月 30日 20:02 /sys/fs/cgroup/test01/pids.max # echo 50 > /sys/fs/cgroup/test01/pids.max -bash: echo: write error: Operation not permitted (書き込めない)
上の例のように、EPERM
が返ります)。
cgroup v2コアで使用する4.14カーネルで追加されたファイル
第38回でcgroup v2コアで使用するファイルについて紹介しました。いずれもcgroup.
で始まるファイルでした。
その後、
いずれも4.
ファイル名 | 説明 | 可能な操作 | デフォルト値 |
---|---|---|---|
cgroup. |
そのcgroupの現在のタイプ。root以外に存在 | 読み書き | - |
cgroup. |
そのcgroupに属するスレッドの登録、 |
読み書き | - |
cgroup. |
そのcgroupが持てる子孫の深さ | 読み書き | max |
cgroup. |
そのcgroupが持てる子孫の最大数 | 読み書き | max |
cgroup. |
cgroupのステータス | 読み込み | - |
表1が4.
$ uname -r 4.14.44-plamo64 $ sudo mount -t cgroup2 cgroup2 /sys/fs/cgroup/ $ ls /sys/fs/cgroup/ (cgroup rootにあるファイルを確認) cgroup.controllers cgroup.procs cgroup.threads cgroup.max.depth cgroup.stat cgroup.max.descendants cgroup.subtree_control (cgroup.threads, cgroup.max.depth, cgroup.max.descendants, cgroup.statが存在) $ sudo mkdir /sys/fs/cgroup/test01 $ ls /sys/fs/cgroup/test01 cgroup.controllers cgroup.max.descendants cgroup.subtree_control io.max cgroup.events cgroup.procs cgroup.threads io.stat cgroup.max.depth cgroup.stat cgroup.type (cgroup rootでなければcgroup.typeファイルが存在)
それでは、
スレッドモード
4.
表1で紹介した、
- cgroup.
type - cgroup.
threads
cgroup.
ファイルは、
cgroup.
ファイルは、cgroup.
ファイルのスレッド版で、tasks
ファイルと同様のファイルです。
スレッドモードを説明すると長くなりますので、
cgroupの子孫の制御
4.
これは、
cgroup.max.depth
cgroup.
ファイルは、max
であり、
"test1" cgroupを作成し、cgroup.
ファイルに2
を書き込み、
$ sudo mkdir /sys/fs/cgroup/test1 (cgroupの作成) $ echo 2 | sudo tee /sys/fs/cgroup/test1/cgroup.max.depth (子孫の深さを2に制限) 2 $ cat /sys/fs/cgroup/test1/cgroup.max.depth (設定を確認) 2
制限を2に設定しました。設定が確認できましたので、
$ sudo mkdir /sys/fs/cgroup/test1/test2 (子cgroupを作成) $ sudo mkdir /sys/fs/cgroup/test1/test2/test3 (孫cgroupを作成) $ sudo mkdir /sys/fs/cgroup/test1/test2/test3/test4 mkdir: cannot create directory ‘/sys/fs/cgroup/test1/test2/test3/test4’: Resource temporarily unavailable (ひ孫cgroupを作成しようとするとエラーになる)
"test1" cgroupの子として"test2"、
cgroup.
の制限にひっかかった場合は、EAGAIN
が返ります。
ここで"test2"、cgroup.
ファイルはどうなっているのか確認してみましょう。
$ cat /sys/fs/cgroup/test1/test2/cgroup.max.depth
max
$ cat /sys/fs/cgroup/test1/test2/test3/cgroup.max.depth
max
(制限値を書き込んでいないcgroupではmaxのまま)
このように特に設定していないcgroupの制限は"max"となっています。この場合でも上位の"test1"で設定した制限が効いていますので、

cgroup.max.descendants
cgroup.
ファイルは、cgroup.
と同じく"max"であり、
"test1"のcgroup.
ファイルに2
を書き込み、
$ sudo mkdir /sys/fs/cgroup/test1 (cgroupの作成) $ echo 2 | sudo tee /sys/fs/cgroup/test1/cgroup.max.descendants (子孫の数を2に制限) 2 $ cat /sys/fs/cgroup/test1/cgroup.max.descendants (設定を確認) 2
制限を2に設定しました。設定が確認できましたので、
$ sudo mkdir /sys/fs/cgroup/test1/test2 (ひとつめの子cgroupを作成) $ sudo mkdir /sys/fs/cgroup/test1/test3 (ふたつめの子cgroupを作成) $ sudo mkdir /sys/fs/cgroup/test1/test4 mkdir: cannot create directory '/sys/fs/cgroup/test1/test4': Resource temporarily unavailable (3つめの子cgroupを作成しようとするとエラーになる)
3つめのcgroupを作るところでエラーになりました。cgroup.
と同様にEAGAIN
が返ります。

cgroup.stat
cgroupの統計情報が含まれているファイルで、
nr_
descendants - 利用できる子孫cgroupの数
nr_
dying_ descendants - 消滅途中の子孫cgroupの数
「消滅途中」
先のcgroup.
の例で、cgroup.
ファイルを確認してみましょう。
$ cat /sys/fs/cgroup/test1/cgroup.stat nr_descendants 2 nr_dying_descendants 0
子cgroupをふたつ作成したので、nr_
が2となっています。
まとめ
今回はcgroup v2に追加された新機能を紹介しました。
nsdelegateマウントオプションは、
そして、
次回からは、