![[Pasted image 20250218211832.png]] Control groups, usually referred to as cgroups, are a Linux kernel feature which allow processes to be organized into hierarchical groups whose usage of various types of resources can then be limited and monitored. ## Configuring a cgroup using cgroupfs There's no API (syscalls) to modify these groups, it's all done with creating folders and naming files with special names at ```/sys/fs/cgroup```. The exact set of file created for a new cgroup depends on the enabled controllers (cgroup.controllers) Since these are managed by pseudo-filesystem folders and files we can give access to non-root users to create new cgroups. If we need to restrict controller access for a child cgroup it can be done writing to the parent's cgroup.subtree_control file. ``` echo "+cpu +memory -io" > /sys/fs/cgroup/<parent>/cgroup.subtree_control ``` This is known as cgroup delegation. To add a process to a cgroup we need to write its PID into cgroup.procs. > When a process is started, it inherits the cgroup of its parent process. So, if we move our shell into cgroup.procs and run anything in it, it's going to have the same restrictions as the shell's cgroup. > To see the current shell process `echo $` ## Configuring a cgroup using libcgroup ```sh cgcreate -g <controllers>:<path> cgset -r cpu.max="50000 100000" <path> cgset -r memory.max="100M" <path> cgclassify -g cpu,memory:<path> <PID> cgset -r memory.oom.group=1 <path> // To run a binary inside a cgroup cgexec -g cpu,memory:<path> <binary> cgdelete -g cpu,memory:<path> ``` ## Using systemd-run to run a restricted process ``` systemd-run -u hog -p CPUQuota=50% -p MemoryMax=100M ~/hog ``` This command will create a transient service unit `hog.service` with the specified resource limits. ``` // List all cgroups systemd-cgls --all // List by resource usage systemd-cgtop ``` ## Using a systemd slice to create a "persistent" cgroup If you want to create a cgroup that outlives the process and even survives a full system reboot, you can use a systemd _slice unit_. ```sh cat <<EOF > /etc/systemd/system/hog_pen.slice [Slice] CPUQuota=50% MemoryMax=100M EOF ``` ``` systemd-run -u hog1 --slice=hog_pen.slice ~/hog systemd-run -u hog2 --slice=hog_pen.slice ~/hog ``` > Every process in the `hog_pen.slice` slice will be placed in its own child cgroup, which inherits the resource limits set for the slice. Thus, the cumulative CPU and memory usage of all processes in the `hog_pen.slice` slice will be limited to 50% CPU and 100MB of memory.