Introduction
One common question with terminal server solutions like ThinLinc, where multiple users are often sharing the same hardware, is how to allocate resources fairly. If one user runs a resource-intensive task, there may not be enough RAM, GPU, or storage space available for other users on the system. This can result in poor performance, or even prevent users from running applications in their session.
Storage space is generally easy to limit using filesystem quotas or partitioning schemas. Resources like RAM and CPU however can be a bit trickier. One method of doing this is by using a feature of the Linux kernel called Control Groups (aka cgroups).
Control Groups allow administrators to define how much RAM, CPU, or disk I/O each user is allowed to consume. They can also be used to limit the number of processes each user can start, however there is currently no way to limit GPU usage with cgroups. On modern Linux systems, the cgroups heirarchy is managed by systemd.
Using systemd to manage CPU usage
In the following simple example, we use a systemd drop-in to limit the amount of CPU time users are allowed to consume. To illustrate, we can place high load on the CPU by running /usr/bin/yes:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
74564 cendio 20 0 220948 1664 1664 R 99.7 0.0 0:15.38 yes
As shown in the output from top above, the process is consuming close to 100% of available CPU time. This will likely cause problems for other system users.
To restrict how much CPU user cendio is allowed to consume, first we need to know the user ID:
$ id -u
1000
We can then create a new systemd drop-in file at the following location:
$ cat /etc/systemd/system/user-1000.slice.d/50-cpu.conf
[Slice]
CPUQuota=10%
$ sudo systemctl daemon-reload
In this example, we want to restrict the user to 10% of a single CPU. On multi-CPU systems, this number scales linearly. So to restrict a user to 10% of a 12-CPU system, you would need to set CPUQuota to 120%.
After running yes again, we can take another look at the output of top:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
74724 cendio 20 0 220948 1664 1664 R 7.1 0.0 0:00.91 yes
The process is now using much less CPU. Note that the restriction applies to the user, not the process, and other processes run by cendio will also be consuming CPU time. So the usage shown here is less than 10%, but it should never be more.
Advanced usage
In the above example, we restricted the user cendio to 10% of a single CPU, but other users will still be unrestricted. There are many different ways to limit resource usage with cgroups and systemd, including limiting other resources such as RAM, limiting for all users, and limiting for individual processes. For further details regarding advanced usage, see the following documentation:
https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html
https://www.freedesktop.org/software/systemd/man/latest/systemd-run.html
If you have any specific configuration, tips, or tricks around using cgroups to restrict resource usage in a ThinLinc environment, please feel free to comment below.