编辑

编辑

我想保留少量的 cpu 和内存,以便在紧急情况下能够创建 tty 会话并杀死占用内存的 X 应用程序。cgroups提供此功能。如何自动将所有 X 应用程序放入 cgroup 中?

答案1

我使用Debian,所以解决方案是基于systemdcgroup实现。

第一步是检查 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)。这样,您将始终拥有可供系统守护程序使用的资源。

相关内容