我想保留少量的 cpu 和内存,以便在紧急情况下能够创建 tty 会话并杀死占用内存的 X 应用程序。cgroups提供此功能。如何自动将所有 X 应用程序放入 cgroup 中?
答案1
我使用Debian,所以解决方案是基于systemd
cgroup实现。
第一步是检查 cgroups 层次结构:
> systemd-cgls
-.slice
├─user.slice
│ └─user-1000.slice
│ ├─[email protected]
.....
│ └─session-2.scope
│ ├─1376 lightdm --session-child 14 21
│ ├─1400 x-window-manager
.....
systemd
自动将 cgroup 分配给终端会话。在 cgroup 层次结构中,我们需要确定其中session-*.scope
有 X 个应用程序。默认 X 会话范围编号始终相同。
要为某个范围内的所有程序设置内存限制,请键入
> systemctl set-property session-2.scope MemoryLimit=14G
此命令将内存限制设置为会话 2,直至重新启动。
要使此规则永久生效,请运行
> sudo systemctl edit session-2.scope
在文本编辑器中输入
[Scope]
MemoryLimit=14G
并保存。此规则将在重新启动之间持续存在。其他资源限制可以在同一文件中设置。
编辑
正如 derobert 指出的那样,不保证 X 会话范围号相同。更可靠的解决方案是在运行时确定该数字。
文件/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
文件/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
将上述文件复制到您的系统并发出命令
systemctl daemon-reload
之后,您可以使用命令设置指定的限制(在本例中为 14G)
systemctl start resource_limit.service
并使用命令取消设置(设置一些更高的限值)
systemctl stop resource_limit.service
为了在重新启动时自动运行此脚本,请发出命令
systemctl enable resource_limit.service
注1
如果您的 X 会话启动速度不够快,您可能需要通过ExecStartPre
手动启用服务来增加服务延迟。
笔记2
最好还添加[email protected]
稍大一点的限制(其中 1000 - 是 UID)。这样,您将始终拥有可供系统守护程序使用的资源。