cgroup v2에 프로세스를 추가하려고 할 때 EBUSY

cgroup v2에 프로세스를 추가하려고 할 때 EBUSY

나는 cgroups v2( Fedora 35커널 5.15.5-200.fc35.x86_64)을 가지고 놀고 있습니다.

문제 없이 테스트 cpu하고 제어 할 수 있습니다 . 하지만 , 또는 나는 곤경에 빠졌습니다. 다음은 컨트롤러에서 이 문제를 재현하는 방법에 대한 단계 목록 입니다 (모든 명령은 루트로 실행됨).cpusetpidsmemoryhugetlbiomemory

  1. 루트 cgroup에서 메모리 컨트롤러가 활성화되어 있는지 확인하십시오.

    # cat cgroup.subtree_control
    cpu io memory hugetlb pids
    
  2. 새 cgroup을 생성합니다:

    # mkdir example
    # cd example/
    
  3. 메모리 컨트롤러 활성화:

    # echo "+memory" > cgroup.subtree_control 
    
  4. 제어 그룹에 프로세스를 추가합니다.

    # 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 #

관련 정보