systemd.resource-control 中文手册

译者:金步国


版权声明

本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。

其他作品

本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:

联系方式

由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。


手册索引 . 指令索引systemd-235

名称

systemd.resource-control — 单元的资源限制

大纲

slice.slice, scope.scope, service.service, socket.socket, mount.mount, swap.swap

描述

slice, scope, service, socket, mount, swap 单元共享一组用于限制进程资源占用的配置选项(亦称"配置指令"或"单元属性")。 本质上,这些选项依赖于Linux内核的 cgroups(Control Groups) 功能: 将一组进程组织成树形层次结构,并对其允许占用的各种资源进行限制。

systemd.unit(5) 列出了通用于所有单元的配置选项, 而本文列出的配置选项仅通用于如下六种单元: systemd.slice(5), systemd.scope(5), systemd.service(5), systemd.socket(5), systemd.mount(5), systemd.swap(5) 。 注意, 根据所处单元类型的不同, 应该将本文的配置选项分别放置到对应的 [Slice], [Scope], [Service], [Socket], [Mount], [Swap] 小节中。

另外, 用于控制被 systemd 调用的程序的资源占用的配置选项位于 systemd.exec(5) 手册中。 那些配置选项可以视为对本文所列配置选项的补充。

参见 New Control Group Interfaces 文档以了解如何在程序中利用资源控制API

隐含依赖

下列依赖关系是自动隐含的:

  • 所有设置了 Slice= 的单元都会自动添加对指定 slice 单元的 Requires=After= 依赖。

新式资源控制选项

从Linux-4.5开始,内核正式引入了新式的单一层次(unified hierarchy)资源控制接口, 参见"cgroup-v2.txt"。 新接口最大的变化在于同一个进程现在只能属于单个层次(hierarchy),而不是原来的多个层次,从而降低了代码复杂度并且更易于理解。 新接口不仅增强了资源控制的能力,也导致了某些资源控制选项的名称发生了变化:

CPU

由于内核社区目前尚未形成统一共识的原因, 目前 cgroup-v2 对 CPU 资源的控制还依赖于官方内核树之外的第三方补丁(参见 cgroup-v2-cpu.txt)。

新式的 CPUWeight=StartupCPUWeight= 选项分别取代了原有的 CPUShares=StartupCPUShares= 选项。

"cpuacct" 控制器在新式的 cgroup-v2 中不再独立存在。

Memory

新式的 MemoryMax= 选项取代了原有的 MemoryLimit= 选项; 同时新增了 MemoryLow=MemoryHigh= 选项。

IO

IO 为前缀的新选项取代了原来以 BlockIO 为前缀的选项,并且新增了一些原来没有的选项。 现在这些新式的IO资源控制选项也可以作用于有缓存的写操作。

尽管 systemd 开发者已经尽了最大努力来确保可以在新旧两组选项之间平滑过度。但是对于每一种控制器(CPU/内存/IO)来说, 用户还是必须确保要么统一使用新式选项(内核版本大于4.5)、要么统一使用旧式选项(内核版本小于4.5), 混合使用新旧两种选项可能会导致意想不到的结果。

因为传统的资源控制接口(也被称为"cgroup-v1",参见 cgroups.txt) 无法确保非特权进程安全的使用资源控制器,所以 systemd 用户实例无法使用传统的资源控制器。 参见 systemd(1) 手册。

选项

可以识别的资源控制选项(亦称"指令"或"属性")如下:

CPUAccounting=

若设为"yes"则表示为此单元开启CPU占用统计。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的CPU占用统计。 此选项的默认值由 DefaultCPUAccounting= 决定(参见 systemd-system.conf(5)手册)。

CPUWeight=weight, StartupCPUWeight=weight

为此单元的进程设置CPU时间的分配权重, 这两个选项控制着cgroup的 "cpu.weight" 属性值, 这两个选项的默认值都是100,取值范围都是 1-10000 之间的整数。 详见 cgroup-v2.txtsched-design-CFS.txt 文档。 总的可用CPU时间会在同一 slice 内的每个单元之间,依据各单元的分配权重进行分配。

StartupCPUWeight= 仅用于系统启动过程, 而 CPUWeight= 则用于系统正常运行过程,并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupCPUWeight= 让特定的服务在系统启动过程中拥有与运行时不一样的CPU优先级。

这两个选项都隐含了 "CPUAccounting=yes"

这两个选项分别取代了原有的 CPUShares=StartupCPUShares= 选项。

CPUQuota=

为此单元的进程设置CPU时间限额,必须设为一个以"%"结尾的百分数, 表示该单元最多可使用单颗CPU总时间的百分之多少。 若设为大于 100% 的值则表示可以占用多颗CPU资源。 此选项控制着 cgroup-v2 的 "cpu.max" 属性值 或者 cgroup-v1 的 "cpu.cfs_quota_us" 属性值。 详见 cgroup-v2.txtsched-design-CFS.txt 文档。

例如 CPUQuota=20% 能够确保 此单元的进程永远不会使用超过 20% 的单颗CPU时间。

此选项隐含了 "CPUAccounting=yes"

MemoryAccounting=

若设为"yes"则表示为此单元开启内存占用统计。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的内存占用统计。 此选项的默认值由 DefaultMemoryAccounting= 决定(参见 systemd-system.conf(5) 手册)。

MemoryLow=bytes

尽可能保障该单元中的进程至少可以使用多少内存。 如果该单元及其所有父单元的内存用量都低于最低保障线,那么只要还可以从其他未受保护的单元回收内存, 就不会回收该单元占用的内存。

选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存)。 此选项控制着cgroup的 "memory.low" 属性值, 详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项。 同时也废除了老旧的 MemoryLimit= 选项。

MemoryHigh=bytes

尽可能限制该单元中的进程最多可以使用多少内存。 虽然这是一个允许被突破的柔性限制,但是突破限制后,进程的运行速度将会大打折扣, 并且系统将会尽可能尽快回收超出的内存。此选项的目的在于柔性限制内存使用量。

选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存), 还可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.high" 属性值,详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项。 同时也废除了老旧的 MemoryLimit= 选项。

MemoryMax=bytes

绝对刚性的限制该单元中的进程最多可以使用多少内存。 这是一个不允许突破的刚性限制,触碰此限制会导致进程由于内存不足而被强制杀死。 建议将 MemoryHigh= 用作主要的内存限制手段, 而将 MemoryMax= 用作不可突破的底线。

选项值可以是以字节为单位的绝对大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对大小(相对于系统的全部物理内存), 还可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.max" 属性值,详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项。它取代了旧式的 MemoryLimit= 选项。

MemorySwapMax=bytes

绝对刚性的限制该单元中的进程最多可以使用多少交换空间。

选项值可以是以字节为单位的绝对大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.swap.max" 属性值,详见 cgroup-v2.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项是新式资源控制选项。 同时也废除了老旧的 MemoryLimit= 选项。

TasksAccounting=

若设为"yes"则表示为此单元开启 任务数量统计(内核空间线程数+用户空间进程数)。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的任务数量统计。 此选项的默认值由 DefaultTasksAccounting= 决定 (参见 systemd-system.conf(5) 手册)。

TasksMax=N

为此单元设置总任务数量限制。 可以设为一个正整数绝对值,也可以设为一个相对于系统全局所允许的最大任务数量的百分比, 而特殊值 "infinity" 表示不作任何限制。 此选项控制着cgroup的 "pids.max" 属性值, 详见 pids.txt 文档。

此选项隐含着 "TasksAccounting=yes" 。 此选项的默认值由 DefaultTasksMax= 决定(参见 systemd-system.conf(5) 手册)。

IOAccounting=

若设为"yes"则表示为此单元开启块设备IO统计。 注意,这同时也隐含的开启了该单元所属的 slice 以及父 slice 内所有单元的块设备IO统计。 此选项的默认值由 DefaultIOAccounting= 决定(参见 systemd-system.conf(5) 手册)。

此选项是新式资源控制选项,取代了旧式的 BlockIOAccounting= 选项。 同时也废除了老旧的以 BlockIOStartupBlockIO 为前缀的选项。

IOWeight=weight, StartupIOWeight=weight

为此单元的进程设置默认的块设备IO带宽的分配权重。 这两个选项的默认值都是"100",取值范围都是 1-10000 之间的整数。 这两个选项控制着cgroup的 "io.weight" 属性值, 详见 cgroup-v2.txt 文档。 总的可用块设备IO带宽会在同一个 slice 内的每个单元之间,依据各单元的分配权重进行分配。

StartupIOWeight= 仅用于系统启动过程, 而 IOWeight= 则用于系统正常运行过程, 并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupIOWeight= 让特定的服务 在系统启动过程中拥有与运行时不一样的IO优先级。

这两个选项都隐含着 "IOAccounting=yes"

此选项是新式资源控制选项,取代了旧式的 BlockIOWeight=StartupBlockIOWeight= 选项。 同时也废除了老旧的以 BlockIOStartupBlockIO 为前缀的选项。

IODeviceWeight=device weight

为此单元的进程设置针对特定块设备的IO带宽的分配权重。选项的值由空格分隔的两部分组成(例如"/dev/sda 1000"): device 可以是以"/dev/"开头的块设备节点路径, 也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 weight 是针对此块设备的IO带宽的分配权重, 是一个介于1-10000之间的整数,默认值为"100"。 此选项控制着cgroup的 "io.weight" 属性值, 详见 cgroup-v2.txt 文档。

此选项隐含着 "IOAccounting=yes"

此选项是新式资源控制选项,取代了旧式的 BlockIODeviceWeight= 选项。 同时也废除了老旧的以 BlockIOStartupBlockIO 为前缀的选项。

IOReadBandwidthMax=device bytes, IOWriteBandwidthMax=device bytes

为此单元的进程设置针对特定块设备的读/写速率刚性上限。 这是一种非工作保留模式(non-work-conserving)的限制, 也就是说即使设备当前处于空闲状态,该单元中的进程也不允许超限使用。 选项的值由空格分隔的两部分组成(例如"/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"): device 可以是以"/dev/"开头的块设备节点路径,也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 bytes 是针对此块设备的读/写速率上限(单位是"字节/秒"), 其值是一个正整数,且可以使用以1000为基数的 K, M, G, T 后缀。 这两个选项控制着cgroup的 "io.max" 属性值, 详见 cgroup-v2.txt 文档。 可以分别针对多个不同的块设备多次使用这两个选项。

这两个选项都隐含着 "IOAccounting=yes"

这两个选项是新式资源控制选项,取代了旧式的 BlockIOReadBandwidth=BlockIOWriteBandwidth= 选项。同时也废除了老旧的以 BlockIOStartupBlockIO 为前缀的选项。

IOReadIOPSMax=device IOPS, IOWriteIOPSMax=device IOPS

为此单元的进程设置针对特定块设备的读/写IOPS刚性上限。 这是一种非工作保留模式(non-work-conserving)的限制, 也就是说即使设备当前处于空闲状态,该单元中的进程也不允许超限使用。 选项的值由空格分隔的两部分组成(例如"/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 1K"): device 可以是以"/dev/"开头的块设备节点路径,也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 IOPS 是针对此块设备的读/写IOPS上限(单位是"次/秒"), 其值是一个正整数,且可以使用以1000为基数的 K, M, G, T 后缀。 这两个选项控制着cgroup的 "io.max" 属性值, 详见 cgroup-v2.txt 文档。 可以分别针对多个不同的块设备多次使用这两个选项。

这两个选项都隐含着 "IOAccounting=yes"

这两个选项是新式资源控制选项。 同时也废除了老旧的以 BlockIOStartupBlockIO 为前缀的选项。

IPAccounting=

是否为此单元开启网络流量统计。 对于非 socket 单元来说, 设为"yes"表示统计该单元内所有进程创建的全部 IPv4 与 IPv6 套接字上的流量(发送与接收)。 对于 socket 单元来说, 设为"yes"表示统计该单元封装的全部 IPv4 与 IPv6 套接字(监听套接字与连接套接字)上的流量(发送与接收)。 注意,对于基于套接字启动的服务单元来说, 此选项的设置以及网络流量的统计与关联的套接字单元是互不相关、相互独立的,并且也是分别独立显示的。 换句话说,封装在 socket 单元内的套接字上的流量仅计入 socket 单元,而不计入被启动的 service 单元(即使它是该套接字的实际使用者)。 注意,暂时还不支持对 slice 单元进行网络流量统计,也就是 slice 单元暂时会忽略此选项。 此选项的默认值由 DefaultIPAccounting= 决定(参见 systemd-system.conf(5) 手册)。

IPAddressAllow=ADDDRESS[/PREFIXLENGTH]…, IPAddressDeny=ADDRESS[/PREFIXLENGTH]…

为此单元的 AF_INET 与 AF_INET6 套接字设置基于IP地址段的访问控制。 每个选项都可以接受一个空格分隔的 IPv4 或 IPv6 地址段(使用 "/" 字符表示前缀长度)列表。 如果省略了后缀,那么表示一个单独的主机地址(对于 IPv4 来说相当于前缀长度为32 ,对于 IPv6 来说相当于前缀长度为128)。

对于非 socket 单元来说,访问控制列表作用于该单元内所有进程创建的全部套接字。 对于 socket 单元来说,访问控制列表作用于该单元封装的全部套接字。 注意,最终实际生效的访问控制列表由该单元自身设置的列表与该单元的全部上级 slice 单元所设置的列表组合而成。 对于每个单元来说,列表默认为空。允许列表与禁止列表的作用规则如下:

  • 如果对端地址匹配 IPAddressAllow= 中的地址段,那么允许访问;

  • 否则,如果对端地址匹配 IPAddressDeny= 中的地址段,那么拒绝访问;

  • 否则,允许访问。

要想实现基于白名单的IP防火墙,推荐的做法是首先将 IPAddressDeny=any 放置到上层 slice 单元中。 例如,放到最顶级的 -.slice 单元 或者包含所有系统服务的 system.slice 单元中(详见 systemd.special(7) 手册)。然后,再针对每个服务单元设置专属的 IPAddressAllow= 白名单。

注意,对基于套接字启动的服务来说,在关联 socket 单元中配置的IP访问控制列表, 仅作用于该 socket 单元封装的全部套接字,而不会作用于被启动的服务单元所创建的套接字。 同样,在服务单元中配置的IP访问控制列表,仅作用于该服务单元所创建的套接字, 而不会作用于从关联 socket 单元传递进来的套接字(即使该服务单元是套接字的实际使用者)。 因此,通常需要在一对关联的 socket 与 service 单元之间互相复制IP访问控制列表。

可以多次使用同一选项以增加新的地址段, 也可以将选项的值设为空字符串以清空该选项所有先前的设置。

某些特殊的地址段可以使用专门的名称来表示。 具体如下表:

表 1. 特殊的地址段名称

名称含义解释
any0.0.0.0/0 ::/0任意主机
localhost127.0.0.0/8 ::1/128所有本地回环地址
link-local169.254.0.0/16 fe80::/64所有本地链接地址
multicast224.0.0.0/4 ff00::/8所有组播地址

注意,因为这些选项需要底层操作系统内核或容器管理器支持 eBPF 控制组功能(某些发行版可能缺乏此功能), 所以不应该仅仅依赖于此处的选项去实现网络访问控制,而应该同时结合其他限制措施。

DeviceAllow=device mode

为此单元的进程设置设备访问权限白名单。 此选项控制着cgroup的 "devices.allow" 与 "devices.deny" 属性值, 详见 devices.txt 文档。 选项的值由空格分隔的两部分组成:

device 可以是以 /dev/ 开头的设备节点路径, 例如 /dev/sda5 表示第一块ATA或SCSI硬盘; 也可以是以 "char-" 或 "block-" 开头、 后跟设备组名称(/proc/devices)的字符串, 例如 "char-pts" 与 "char-alsa" 就分别涵盖了所有伪终端与所有ALSA声卡。 后一种表示法可以一次性作用于一组设备 (包括当前已有的与未来可能出现的)。 最后,还可以在后一种表示法的设备组名称中使用 "*" 与 "?" 通配符,例如 "char-cpu/*" 表示所有与CPU相关的设备组。

moder, w, m 三个字母的组合,分别表示: 读取此设备(read)、 写入此设备(write)、 创建此设备(mknod)

DevicePolicy=auto|closed|strict

为此单元的进程设置设备访问策略:

strict

仅允许在 DeviceAllow= 中明确允许的访问, 默认拒绝一切其他访问。

closed

在 strict 的基础上 额外允许对如下标准伪设备的访问: /dev/null, /dev/zero, /dev/full, /dev/random, /dev/urandom

auto

这是默认值。 对于已在 DeviceAllow= 中列出的设备,仅允许在 DeviceAllow= 中明确允许的访问; 对于未在 DeviceAllow= 中列出的设备,默认允许一切形式的访问(相当于拥有"rwm"权限)。

Slice=

将此单元放到哪个 slice 单元中。 对于非 slice 单元来说, 非实例化单元的默认值是 system.slice , 实例化单元的默认值是 system.slice 之下 与模版单元同名的 slice 单元。

利用此选项, 可将各单元按照 slice 单元的层次结构组织起来, 以便分层次、分组的对单元进行资源分配。

对于 slice 单元来说, 因为此选项仅允许设为父 slice 单元, 所以此选项没有实际的意义, 也不需要设置此选项。

当依赖于默认 slice 分配规则时, 需要特别小心那些明确设置了 DefaultDependencies=no 的实例化服务单元。详见 systemd.service(5) 手册的"默认依赖"小节。

Delegate=

设为"yes"表示允许此单元对其拥有的资源, 在该单元内部进行更进一步的划分与分配。 对于非特权服务(也就是使用了 User= 设置), 这表示允许进程在其自身所处的cgroup路径之下创建自己的子层次结构。 对于 scope 与特权服务, 这表示允许进程使用所有的 cgroup controller

反对使用的选项

下面这些都是过时老旧的选项。应该尽量避免使用它们:

CPUShares=weight, StartupCPUShares=weight

为此单元的进程设置CPU时间的分配权重, 这两个选项控制着cgroup的 "cpu.shares" 属性值, 这两个选项的默认值都是1024,取值范围都是 2-262144 之间的整数。详见 sched-design-CFS.txt 文档。 总的可用CPU时间会在同一 slice 内的每个单元之间,依据各单元的分配权重进行分配。

StartupCPUShares= 仅用于系统启动过程,而 CPUShares= 则用于系统正常运行过程,并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupCPUShares= 让特定的服务 在系统启动过程中拥有与运行时不一样的CPU优先级。

这两个选项都隐含着 "CPUAccounting=true"

这些选项已经被反对使用,建议使用 CPUWeight=StartupCPUWeight= 来代替。

MemoryLimit=bytes

绝对刚性的限制该单元中的进程最多可以使用多少内存。 这是一个不允许突破的刚性限制,触碰此限制会导致进程由于内存不足而被强制杀死。 选项值可以是以字节为单位的绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小(相对于系统的全部物理内存), 还可以设为特殊值 "infinity" 表示不作限制。 此选项控制着cgroup的 "memory.limit_in_bytes" 属性值, 详见 memory.txt 文档。

此选项隐含着 "MemoryAccounting=yes"

此选项已经被反对使用,建议使用 MemoryMax= 来代替。

BlockIOAccounting=

若设为"yes"则表示为此单元开启块设备IO统计。 注意,这同时也隐含的开启了该单元 所属的 slice 以及父 slice 内所有单元的块设备IO统计。 此选项的默认值由 DefaultBlockIOAccounting= 决定(参见 systemd-system.conf(5) 手册)。

此选项已经被反对使用,建议使用 IOAccounting= 来代替。

BlockIOWeight=weight, StartupBlockIOWeight=weight

为此单元的进程设置默认的块设备IO带宽的分配权重。这两个选项的默认值都是500,取值范围都是 10-1000 之间的整数。 这两个选项控制着cgroup的 "blkio.weight" 属性值, 详见 blkio-controller.txt 文档。 总的可用块设备IO带宽会在同一 slice 内的每个单元之间,依据各单元的分配权重进行分配。

StartupBlockIOWeight= 仅用于系统启动过程, 而 BlockIOWeight= 则用于系统正常运行过程, 并且在前者未设置时亦可作用于系统启动过程。 通常使用 StartupBlockIOWeight= 让特定的服务在系统启动过程中拥有与运行时不一样的IO优先级。

这两个选项都隐含着 "BlockIOAccounting=yes"

这些选项已经被反对使用,建议使用 IOWeight=StartupIOWeight= 来代替。

BlockIODeviceWeight=device weight

为此单元的进程设置针对特定块设备的IO带宽的分配权重。 选项的值由空格分隔的两部分组成(例如"/dev/sda 500"): device 可以是块设备节点路径(以"/dev/"开头),也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 weight 是针对此块设备的IO带宽的分配权重,是一个介于10-1000之间的整数。 可以分别针对多个不同的块设备多次使用此选项。 此选项控制着cgroup的 "blkio.weight_device" 属性值(默认值为1000), 详见 blkio-controller.txt 文档。

此选项隐含着 "BlockIOAccounting=yes"

此选项已经被反对使用,建议使用 IODeviceWeight= 来代替。

BlockIOReadBandwidth=device bytes, BlockIOWriteBandwidth=device bytes

为此单元的进程设置针对特定块设备的读/写速率上限。 选项的值由空格分隔的两部分组成(例如"/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"): device 可以是块设备节点路径(以"/dev/"开头), 也可以是一个普通的文件路径(表示此文件所在文件系统的底层块设备)。 bytes 是针对此块设备的读/写速率上限(单位是"字节/秒"),其值是一个正整数, 且可以使用以1000为基数的 K, M, G, T 后缀。 可以分别针对多个不同的块设备多次使用这两个选项。 这两个选项控制着cgroup的 "blkio.throttle.read_bps_device" 与 "blkio.throttle.write_bps_device" 属性值, 详见 blkio-controller.txt 文档。

此选项隐含着 "BlockIOAccounting=yes"

这些选项已经被反对使用,建议使用 IOReadBandwidthMax=IOWriteBandwidthMax= 来代替。

参见

systemd(1), systemd.unit(5), systemd.service(5), systemd.slice(5), systemd.scope(5), systemd.socket(5), systemd.mount(5), systemd.swap(5), systemd.exec(5), systemd.directives(7), systemd.special(7), 有关控制组(control groups)与各种控制器的文档: cgroups.txt, cpuacct.txt, memory.txt, blkio-controller.txt.