cgexec/README.md

116 lines
4.5 KiB
Markdown
Raw Permalink Normal View History

# Linux Control Groups
Linux Control Groups, commonly referred to as cgroups, is a feature in the Linux kernel that provides a way to organise and manage system resources for processes. It allows you to allocate and limit resources like CPU, memory, and I/O bandwidth among different processes or groups of processes.
There are two versions of cgroups, the original version 1 and the `unified`, version 2.
2023-12-16 18:58:46 +01:00
# cgexec
cgexec is a Bash script that allows users to execute a command within a cgroup, providing control over resource limits such as CPU, I/O, and memory.
The script requires v2/unified cgroups to function.
Documentation is available at <https://wiki.tnonline.net/w/Linux/cgexec>.
## Usage
```
Attaches a program <cmd> to a unified cgroup with defined limits.
Usage: cgexec [options] <cmd> [cmd args]
Options:
-c cpu.weight (0-10000) Set CPU priority
-C cpu.max (1-100) Set max CPU time in percent
-i io.weight (1-10000) Set I/O weight
-m memory.high (0-max) Set soft memory limit
-M memory.max (0-max) Set hard memory limit
-g group Create or attach to existing cgroup. Default is to use an ephemeral group
-b path Use <path> as cgroup root
Requires Linux Control Groups v2 mounted at <path>.
```
## Examples
Execute a command with default settings
```
cgexec echo "Hello, cgroups!"
```
Limit CPU and memory for a command
```
cgexec -c 50 -m 1G my_command
```
Attach to an existing cgroup
```
cgexec -g mygroup my_command
```
Use a custom cgroup root
```
cgexec -b /sys/fs/cgroup/mysubsystem my_command
```
# Enable user cgroups
It is possible to allow normal users to create their own cgroups by creating an initial cgroup container that is owned by the user.
First set up a container for the user
```
mkdir -p /sys/fs/cgroup/user/forza/main
echo "+cpu +memory +io" > /sys/fs/cgroup/user/cgroup.subtree_control
echo "+cpu +memory +io" > /sys/fs/cgroup/user/forza/cgroup.subtree_control
chown forza:forza /sys/fs/cgroup/user/forza
chown forza:forza /sys/fs/cgroup/user/forza/cgroup.procs
chown forza:forza /sys/fs/cgroup/user/forza/cgroup.threads
chown -R forza:forza /sys/fs/cgroup/user/forza/main
chmod 775 /sys/fs/cgroup/user/forza
chmod 775 /sys/fs/cgroup/user/forza/main
```
User `<forza>` can now create new nested cgroups in `/sys/fs/cgroup/user/forza` and attach processes to it.
The catch-22 of cgroups is that all programs by default reside in in the root `/sys/fs/cgroup/cgroup.procs`, and even though a user can write to its own cgroup, they can not remove themselves from the root cgroup.
One solution is to let the user start a `screen` or `tmux` session and then use root/sudo to move it to the user's cgroup.
Then as root, check what `pids` belong to the uaer session and add them to the user cgroup:
```
# ps af -u forza
5309 pts/0 S+ 0:00 | \_ screen
5310 ? Ss 0:00 | \_ SCREEN
5311 pts/1 Ss 0:00 | \_ -/bin/bash
5483 pts/1 R+ 0:00 | \_ ps af -u forza
# echo 5309 > /sys/fs/cgroup/user/forza/main/cgroup.procs
# echo 5310 > /sys/fs/cgroup/user/forza/main/cgroup.procs
# echo 5311 > /sys/fs/cgroup/user/forza/main/cgroup.procs
```
Now, the user's screen session is in the `main` cgroup and the user can create additional cgroups and move processes started from within this session to that cgroup.
2023-12-17 14:48:38 +01:00
## Helper utility
The `user_cgroup` helper utility can automate the process of setting of user cgroups.
- `user_cgroup.initd` is an OpenRC init script that creates a cgroup hierarchy for specified users.
- `user_cgroup.confd` is the configuration file for OpenRC.
- `user_cgroup.sudoersd` is a sudo config file for allowing users to use the `user_cgroup` utility.
- `user_cgroup` small tool to move a uaer's shell to the user cgroup.
The sudo file is optional, but allows a user to put the script in `~/.bash_profile` for automatic use.
Once installed, a user can simply run `user_cgroup` to move itselslf to the user cgroup. Now it is possible for the user to create its own sub cgroups with `cgexec`.
```
# ./cgexec ls -l
* Creating cgroup: /sys/fs/cgroup/user/forza/cmd-GEP0
* Executing: ls -l
total 60
-rwxr-xr-x 1 forza forza 4402 Dec 17 14:20 cgexec
-rw-r--r-- 1 forza forza 34580 Dec 16 19:02 LICENSE
drwxr-xr-x 1 forza forza 72 Dec 16 21:16 openrc
-rw-r--r-- 1 forza forza 4106 Dec 17 13:57 README.md
-rwxr-xr-x 1 forza forza 315 Dec 17 13:37 user_cgroup
-rw-r--r-- 1 forza forza 79 Dec 17 13:40 user_cgroup.sudoersd
* Cleaning up cgroup /sys/fs/cgroup/user/forza/cmd-GEP0
2023-12-17 14:48:38 +01:00
```