I use Debian, so the solution is based on systemd
cgroup implementation.
The first step is to inspect the cgroups hierarchy:
> systemd-cgls
-.slice
├─user.slice
│ └─user-1000.slice
│ ├─user@1000.service
.....
│ └─session-2.scope
│ ├─1376 lightdm --session-child 14 21
│ ├─1400 x-window-manager
.....
systemd
automatically assigns cgroups to terminal sessions. In cgroup hierarchy we need determine which session-*.scope
has X applications in it. Default X session scope number is always the same.
To set memory limit to all programs in a scope, type
> systemctl set-property session-2.scope MemoryLimit=14G
This command sets memory limit to the session 2 until reboot.
To make this rule permanent, run
> sudo systemctl edit session-2.scope
in text editor type
[Scope]
MemoryLimit=14G
and save. This rule will persist between reboots.
Other resource limits may be set in a same file.
Edit
As derobert pointed out, X session scope number is not guarantied to be the same. More robust solution is to determine this number at runtime.
File /usr/local/bin/resource_limit.sh
:
#!/bin/bash
for s in $(systemd-cgls --no-pager --user-unit \
| grep --extended-regexp --only-matching \
'session-.{1,3}\.scope');do
systemctl set-property --runtime "$s" MemoryLimit="$1"
done
File /etc/systemd/system/resource_limit.service
:
[Unit]
Description=Limit resources
Requires=multi-user.target
After=multi-user.target
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 5
ExecStart=/usr/local/bin/resource_limit.sh 14G
ExecStop=/usr/local/bin/resource_limit.sh 20G
RemainAfterExit=true
[Install]
WantedBy=graphical.target
Copy files above to your system and issue command
systemctl daemon-reload
After this you may set specified limit (in this case 14G) using command
systemctl start resource_limit.service
and unset it (setting some higher limit value) using command
systemctl stop resource_limit.service
In order to run this script on reboot automatically, issue command
systemctl enable resource_limit.service
Note 1
If your X session does not start fast enough, you may want to increase service delay via ExecStartPre
or enable service manually.
Note 2
It is a good idea to also add restrictions to user@1000.service
(where 1000 - is a UID) with slightly bigger limit. This way you will always have resources available for system daemons.
For simple cases, you don't cgroups, it is simpler just using the taskset
command:
taskset --cpu-list 1-7 my_command args ...
The first cpu core is 0, this omits 0 from the list. To omit some other core you could do something like: --cpu-list 0,1,3,4,5,6,7
Best Answer
I found a solution to my problem so I share it.
I defined a cgroup
customssh/limit
using thecgconfig
service from the libcgroup. Here is an extract of mycgconfig.conf
file:fperm = 775
allows users of the groupmygroup
to use this cgroupdevices.deny="c 195:* rwm";
I created the file
/etc/profile.d/ssh.sh
which is run on every login with the following contents: