CLONE_INTO_CGROUP Menempatkan Child ke cgroup Target Saat Dibuat

Proses yang dibuat di satu cgroup lalu dipindahkan ke cgroup lain memiliki interval singkat tetapi nyata di cgroup awal. Selama interval itu, accounting, resource control, dan freezer state berasal dari penempatan awal, bukan dari tujuan. Linux menyediakan CLONE_INTO_CGROUP agar clone3() dapat menempatkan child langsung ke target cgroup v2 sebagai bagian dari pembuatan proses.

Mekanisme ini mengubah batas penempatan. Alih-alih membuat task lalu memperbaiki membership cgroup sesudahnya, pemanggil menentukan tujuan sebelum child ada.

Target direpresentasikan oleh file descriptor

CLONE_INTO_CGROUP memakai field cgroup pada struct clone_args. Field tersebut berisi file descriptor yang merujuk ke direktori cgroup v2. Direktori dapat dibuka dengan O_RDONLY atau O_PATH.

int cgfd = open("/sys/fs/cgroup/workload",
                O_RDONLY | O_DIRECTORY | O_CLOEXEC);

struct clone_args args = {
    .flags = CLONE_INTO_CGROUP,
    .cgroup = cgfd,
    .exit_signal = SIGCHLD,
};

pid_t pid = syscall(SYS_clone3, &args, sizeof(args));

Descriptor membuat target sudah berupa objek kernel yang ter-resolve ketika call dilakukan. Operasi tidak bergantung pada resolusi ulang pathname setelah child dibuat.

Pola ini sejalan dengan interface Linux lain yang memakai file descriptor untuk membawa identitas objek melintasi batas system call. Namun, permission check cgroup tetap berlaku: pembatasan cgroup v2 yang normal untuk menempatkan proses ke target tetap diterapkan.

Penempatan menjadi bagian dari pembuatan proses

Tanpa flag ini, child umumnya mulai berada di cgroup v2 yang sama dengan parent. Manager yang memerlukan penempatan lain dapat menulis PID child ke cgroup.procs milik tujuan setelah proses dibuat.

Urutan tersebut memiliki dua transisi state terpisah:

buat child di cgroup parent
            |
            v
child dapat berada di bawah accounting parent
            |
            v
pindahkan child ke cgroup target

Dengan CLONE_INTO_CGROUP, penempatan yang diminta melekat pada operasi pembuatan:

buka cgroup target
        |
        v
clone3(CLONE_INTO_CGROUP)
        |
        v
child ada di cgroup target

Perbedaannya tetap relevan meski migrasi berikutnya berlangsung cepat. CPU time atau aktivitas lain sebelum migrasi tercatat pada cgroup awal, dan manager harus mengoordinasikan task yang sudah ada sambil mengubah membership-nya. Penempatan langsung menghapus state membership perantara tersebut.

cgroup yang frozen mengubah state runnable awal child

Target cgroup dapat dibekukan melalui interface freezer cgroup v2. Membuat child langsung di target tersebut memungkinkan child lahir di dalam cgroup yang frozen, bukan berjalan lebih dulu lalu dipindahkan ke sana.

Sifat ini berguna bagi manager yang perlu menetapkan penempatan sebelum eksekusi berlanjut. Mekanismenya berbeda dari membuat proses, menghentikannya dengan mekanisme terpisah, memindahkannya, lalu melanjutkannya. State cgroup sudah menjadi bagian dari penempatan yang dipilih saat pembuatan.

Freezer tetap merupakan mekanisme cgroup, bukan jaminan scheduling baru dari clone3(). CLONE_INTO_CGROUP memilih target; state cgroup target menentukan constraint yang dihasilkan.

Flag tidak melewati aturan topologi cgroup

Penempatan langsung bukan migrasi privileged yang disembunyikan di dalam clone3(). Kernel tetap memvalidasi target sesuai aturan cgroup v2. Pemanggil tidak dapat memakai flag ini untuk menempatkan child ke lokasi yang akan ditolak oleh operasi cgroup terkait.

Target harus berupa cgroup pada cgroup v2. Flag ini tidak memberi efek penempatan pada hierarchy cgroup v1. Batas tersebut penting bagi software yang mendukung host dengan konfigurasi cgroup berbeda: keberadaan clone3() saja tidak berarti hierarchy yang diminta dapat menerima CLONE_INTO_CGROUP.

Karena itu, error handling berada pada batas pembuatan proses. Jika descriptor target atau penempatan yang diminta tidak valid, pembuatan proses dapat gagal tanpa menghasilkan child yang kemudian harus dibersihkan oleh tahap migrasi terpisah.

cgroup saat pembuatan berbeda dari cgroup namespace

CLONE_INTO_CGROUP dan CLONE_NEWCGROUP mengontrol state yang berbeda. Yang pertama memilih membership cgroup untuk task baru. Yang kedua membuat cgroup namespace baru dan mengubah path cgroup yang terlihat melalui interface yang peka terhadap namespace.

Pemanggil dapat memerlukan salah satunya tanpa memerlukan yang lain. Service manager sering hanya perlu menempatkan proses ke subtree resource control tanpa mengubah susunan namespace. Container runtime dapat menggabungkan penempatan dengan pembuatan namespace, tetapi keduanya tetap merupakan dimensi terpisah dalam request clone3().

Pemisahan ini mencegah membership cgroup tercampur dengan namespace yang mengontrol pandangan proses terhadap path cgroup.

Penempatan saat pembuatan mempersempit race pada lifecycle

Efek utama CLONE_INTO_CGROUP bukan menambahkan resource controller baru. Flag ini memindahkan keputusan penempatan cgroup yang sudah ada ke operasi yang membuat task.

Bagi service manager dan container runtime, mekanisme tersebut menghapus celah lifecycle antara keberadaan proses dan membership cgroup yang dituju. Accounting dimulai pada target yang dipilih, target frozen dapat membatasi child sejak penempatan awal, dan kegagalan menetapkan membership dilaporkan saat pembuatan, bukan setelah child yang terlihat terpisah telanjur muncul.

Batasnya tetap spesifik: policy cgroup v2, permission, konfigurasi controller, dan semantik namespace tetap berlaku secara independen. Flag ini mengubah kapan membership ditetapkan, bukan aturan yang mengendalikan membership tersebut.