私はcgroups v2
(Fedora 35
カーネル5.15.5-200.fc35.x86_64
)で遊んでいます。
問題なくテストcpu
して制御できます。しかし、または私は困った。以下は、コントローラでこの問題を再現する方法の手順の一覧です(すべてのコマンドはrootとして実行されます)。cpuset
pids
memory
hugetlb
io
memory
ルートcgroupでメモリコントローラが有効になっていることを確認してください。
# cat cgroup.subtree_control cpu io memory hugetlb pids
新しいcgroupを作成します。
# mkdir example # cd example/
メモリコントローラを有効にする:
# echo "+memory" > cgroup.subtree_control
制御グループにプロセスを追加します。
# echo $$ > cgroup.procs bash: echo: write error: Device or resource busy
最初にコントローラにプロセスを追加してからコントローラをアクティブにしようcgroup
とすると、最後のステップで同じエラーが発生します。
私は何が間違っていましたか?
答え1
これは、cgroups v2の「内部プロセスなし」ルールによるものです。
The "no internal processes" rule is in fact more subtle than
stated above. More precisely, the rule is that a (nonroot)
cgroup can't both (1) have member processes, and (2) distribute
resources into child cgroups—that is, have a nonempty
cgroup.subtree_control file. Thus, it is possible for a cgroup
to have both member processes and child cgroups, but before
controllers can be enabled for that cgroup, the member processes
must be moved out of the cgroup (e.g., perhaps into the child
cgroups).
With the Linux 4.14 addition of "thread mode" (described below),
the "no internal processes" rule has been relaxed in some cases.
源泉:cグループ(7)
カーネルソースコードも参照してください。
https://elixir.bootlin.com/linux/v5.19/source/kernel/cgroup/cgroup.c#L2586
**
* cgroup_migrate_vet_dst - verify whether a cgroup can be migration destination
* @dst_cgrp: destination cgroup to test
*
* On the default hierarchy, except for the mixable, (possible) thread root
* and threaded cgroups, subtree_control must be zero for migration
* destination cgroups with tasks so that child cgroups don't compete
* against tasks.
*/
int cgroup_migrate_vet_dst(struct cgroup *dst_cgrp)
{
// [..]
/* apply no-internal-process constraint */
if (dst_cgrp->subtree_control)
return -EBUSY;
return 0;
}
たとえば、次のように動作します。
# cd /sys/fs/cgroup
/sys/fs/cgroup # rmdir deleteme
/sys/fs/cgroup # mkdir deleteme
/sys/fs/cgroup # cd deleteme
/sys/fs/cgroup/deleteme # mkdir leaf
/sys/fs/cgroup/deleteme # echo '+memory' > cgroup.subtree_control
/sys/fs/cgroup/deleteme # echo $$ > leaf/cgroup.procs
/sys/fs/cgroup/deleteme #