TenForward

技術ブログ。はてなダイアリーから移転しました

cgroup namespace (1)

以前、RHEL6 のころに ns cgroup ってサブシステムが cgroup にありましたが、それとは別のお話。

4.6 カーネルに入る cgroup namespace のお話です (Ubuntu 16.04 のカーネルには入るようです) 。namespace ごとに別の cgroup ツリーが見えるようにするものかな。

軽く試してみました。

準備

(2016-04-12 追記) 今だと 4.6-rc? で試せます

とりあえず cgroup namespace の機能が入ったカーネル

の "2016-03-21/nsroot" というブランチのものを使いました。出来上がったカーネルはこんな

$ uname -r
4.5.0-rc1-plamo64-cgns-00009-g37bbd8c-dirty

(-plamo64 は make menuconfig で指定してる文字列)

cgroup namespace が作れる unshare を含む util-linux

から。こちらも "2016-03-02/cgns" というブランチを元にパッチを作って util-linux-2.27.1 に当てました。

実行

とりあえず /proc/$PID/cgroup ファイルで見える cgroup のパスが Namespace ごとに独立して見えるみたい。この様子を見てみました。

まずは現在のシェルを cgroup に所属させます。memory サブシステムのみ "test01" に所属させてみました。

# echo $$ > /sys/fs/cgroup/memory/test01/tasks

この状態で同じシェル上で /proc/self/cgroup を確認してみましょう。

# cat /proc/self/cgroup 
13:debug:/
12:pids:/
11:hugetlb:/
10:net_prio:/
9:perf_event:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/test01
4:blkio:/
3:cpuacct:/
2:cpu:/
1:cpuset:/

memory は /test01 になっていますね。

ここでパッチを当てた unshare コマンドで新しい cgroup namespace を作成します。-C が cgroup namespace を作るオプションです。

# unshare -C
# cat /proc/self/cgroup
13:debug:/
12:pids:/
11:hugetlb:/
10:net_prio:/
9:perf_event:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/
4:blkio:/
3:cpuacct:/
2:cpu:/
1:cpuset:/
# echo $$
22302

memory の部分が "/test01" でなく、"/" になっていますね。最後に現在のシェルの PID を確認しています。

この PID の cgroup 情報を別のシェル (元の cgroup namespace にいるシェル) から見てみます。

# cat /proc/22302/cgroup 
13:debug:/
12:pids:/
11:hugetlb:/
10:net_prio:/
9:perf_event:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/test01
4:blkio:/
3:cpuacct:/
2:cpu:/
1:cpuset:/

作成した namespace の外から見るとちゃんと "/test01" になっていますね。

/proc/$PID/ns/cgroup ファイルも確認しておきましょう。

# ls -l /proc/1/ns/cgroup 
lrwxrwxrwx 1 root root 0  4月  6日  06:59 /proc/1/ns/cgroup -> cgroup:[4026531835]
# ls -l /proc/22273/ns/cgroup 
lrwxrwxrwx 1 root root 0  4月  6日  07:17 /proc/22302/ns/cgroup -> cgroup:[4026532404]

リンク先が異なりますので違う namespace にいることがわかります。これはこれまでの他の namespace と同じですね。

プロセスが cgroup 間を移動したとき

プロセスを cgroup 間で移動させると面白い見え方をします。まず "test01" と同じ階層に "test02" を作成し、先ほどのプロセスを "test01" から "test02" に移動させます。

# mkdir /sys/fs/cgroup/memory/test02
# echo 22302 > /sys/fs/cgroup/memory/test02/tasks

先ほど unshare して作った namespace 内のシェルから /proc/$PID/cgroup ファイルを見てみると、

# cat /proc/self/cgroup 
13:debug:/
12:pids:/
11:hugetlb:/
10:net_prio:/
9:perf_event:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/../test02
4:blkio:/
3:cpuacct:/
2:cpu:/
1:cpuset:/

相対パスのように見えます。

とりあえずここまで。これだけだとすでにマウントされている cgroupfs はそのままの元のディレクトリ階層で見えるので、/proc/$PID/cgroup だけ見え方が変わっても意味がないような気がしますが、改めて cgroupfs のマウントを試すとエラーになりますし、どうするものなのかちょっとまだ見えてないので、またわかれば続編を書く予定です。

(続くかも?)