15 systemd
守护程序 #
systemd
程序是进程 ID 为 1 的进程。它负责以所需的方式初始化系统。systemd
由内核直接启动,信号 9(该信号通常会终止进程)对它不起作用。所有其他程序都由 systemd 直接启动,或由它的其中一个子进程启动。
Systemd 取代了 System V init 守护程序。systemd
与 System V init 完全兼容(通过支持 init 脚本实现)。systemd 的其中一个主要优点是可通过激进方式并行启动多项服务来大幅加快引导速度。另外,systemd 只在确实有需要时才会启动服务。守护程序并不是在系统引导时无条件地启动,而是在第一次需要时启动。systemd 还支持内核控制组 (cgroups),以拍摄系统状态快照以及恢复系统状态等等。有关详细信息,请参见http://www.freedesktop.org/wiki/Software/systemd/。
15.1 systemd 概念 #
本节将详细介绍有关 systemd 的概念。
15.1.1 systemd 是什么 #
systemd 是适用于 Linux 的系统和会话管理器,它与 System V 及 LSB init 脚本兼容。主要功能包括:
提供激进式并行化功能
使用套接字及 D-Bus 激活来启动服务
提供按需启动守护程序功能
使用 Linux cgroups 跟踪进程
支持拍摄系统状态快照及恢复系统状态
维护安装点和自动安装点
实施精细的、基于事务依赖项的服务控制逻辑
15.1.2 单元文件 #
单元配置文件包含有关以下项目的信息:服务、套接字、设备、安装点、自动安装点、交换文件或分区、启动目标、监控的文件系统路径、受 systemd 控制和监管的计时器、临时系统状态快照、资源管理部分或一组外部创建的进程。“单元文件”是 systemd 用于描述下列各项的通用术语:
服务: 进程相关信息(例如运行守护程序);文件以 .service 结尾
目标: 用于将单元分组以及在启动期间用作同步点;文件以 .target 结尾
套接字: IPC 或网络套接字或文件系统 FIFO 相关信息,适用于基于套接字的激活(如
inetd
);文件以 .socket 结尾路径: 用于触发其他单元(例如,在文件更改时运行服务);文件以 .path 结尾
计时器: 受控制计时器相关信息,适用于基于计时器的激活;文件以 .timer 结尾
装入点: 通常由 fstab 生成器自动生成;文件以 .mount 结尾
自动安装点: 文件系统自动安装点相关信息;文件以 .automount 结尾
交换: 内存分页的交换设备或文件相关信息;文件以 .swap 结尾
设备: sysfs/udev(7) 设备树中公开的设备相关信息;文件以 .device 结尾
范围/部分: 有关分层管理一组进程的资源的概念;文件以 .scope/.slice 结尾
有关 systemd.unit 的更多信息,请参见 http://www.freedesktop.org/software/systemd/man/systemd.unit.html
15.2 基本用途 #
System V init 系统使用若干命令来处理服务:init 脚本、insserv
、telinit
及其他。systemd 使服务管理变得简单,要运行大部分服务处理任务,只需要记住一条命令:systemctl
。它使用“命令加子命令”表示法,与 git
或 zypper
相似:
systemctl GENERAL OPTIONS SUBCOMMAND SUBCOMMAND OPTIONS
有关完整的手册,请参见 man 1 systemctl
。
如果输出传递到某个终端(而不是某个管道或文件),systemd 命令默认会将长输出发送到分页器。使用 --no-pager
选项可关闭分页模式。
systemd 还支持 bash 补全,允许您输入子命令的头几个字母,然后按 →| 自动补全子命令。此功能只能在 bash
外壳中使用,并且需要安装 bash-completion
包。
15.2.1 管理正在运行的系统中的服务 #
用于管理服务的子命令与使用 System V init 管理服务的子命令相同(start
、stop
等)。服务管理命令的一般语法如下所示:
- systemd
systemctl reload|restart|start|status|stop|... MY_SERVICE(S)
- System V init
rcMY_SERVICE(S) reload|restart|start|status|stop|...
systemd 允许您一次管理多个服务。不用像 System V init 要逐个执行 init 脚本,而是执行如下命令:
tux >
sudo
systemctl start MY_1ST_SERVICE MY_2ND_SERVICE
要列出系统上所有可用的服务,请运行:
tux >
sudo
systemctl list-unit-files --type=service
下表列出了 systemd 和 System V init 最重要的服务管理命令:
任务 |
systemd 命令 |
System V init 命令 |
---|---|---|
启动: |
start |
start |
停止: |
stop |
stop |
重启动: 关闭服务,然后再启动这些服务。如果某项服务尚未运行,它将会启动。 |
restart |
restart |
有条件地重启动: 如果服务当前正在运行,则重启动它们。对未在运行的服务不执行任何操作。 |
try-restart |
try-restart |
重新装载:
让服务在不中断操作的情况下重新装载它们的配置文件。使用案例:让 Apache 重新装载修改过的 |
reload |
reload |
重新装载或重启动: 如果支持重新装载则重新装载服务,否则重启动服务。如果某项服务尚未运行,它将会启动。 |
reload-or-restart |
n/a |
有条件地重新装载或重启动: 如果支持重新装载则重新装载服务,否则,如果服务当前正在运行,则重启动服务。对未在运行的服务不执行任何操作。 |
reload-or-try-restart |
n/a |
获得详细的状态信息:
列出服务状态的相关信息。 |
status |
status |
获得简要的状态信息: 显示服务是否处于活动状态。 |
is-active |
status |
15.2.2 永久启用/禁用服务 #
上一节中提到的服务管理命令可让您操控当前会话的服务。systemd 还允许您永久启用或禁用服务,让它们在用户要求时自动启动或永远不可用。您可以使用 YaST 或在命令行上运行命令来实现此目的。
15.2.2.1 在命令行上启用/禁用服务 #
下表列出了 systemd 和 System V init 用于启用和禁用服务的命令:
在命令行上启用服务时,服务不会自动启动。它会安排在下一次系统启动或运行级别/目标发生更改时启动。要在启用服务之后立即启动它,请显式运行 systemctl start MY_SERVICE
或 rc MY_SERVICE start
。
任务 |
|
System V init 命令 |
---|---|---|
启用: |
|
|
禁用: |
|
|
检查: 显示某项服务是否启用。 |
|
|
重新启用: 与重启动服务相似,此命令先禁用服务,然后再启用该服务。可用来使用默认值重新启用服务。 |
|
无 |
屏蔽: “禁用”某项服务之后,仍然可以手动启动它。要彻底禁用服务,您需要屏蔽它。须谨慎使用该功能。 |
|
无 |
取消屏蔽: 屏蔽某项服务之后,只有在将其取消屏蔽之后才能再次使用它。 |
|
无 |
15.3 系统启动和目标管理 #
启动和关闭系统的整个过程由 systemd 负责维护。从这一点来看,可以将内核视为一个后台进程,其任务是维护所有其他进程,以及根据其他程序的请求来调整 CPU 时间和硬件访问。
15.3.1 目标与运行级别的比较 #
使用 System V init 时,系统引导到所谓的“运行级别”。运行级别定义系统如何启动以及正在运行的系统中有哪些服务可用。运行级别是有编号的;最知名的运行级别是 0
(关闭系统)、3
(联网的多用户模式)和 5
(联网并使用显示管理器的多用户模式)。
systemd 使用所谓的“目标单元”引入新的概念。不过,它仍然与运行级别概念完全兼容。目标单元用名称而不是编号来标识,并具有特定的作用。例如,目标 local-fs.target
和 swap.target
用于装入本地文件系统和交换空间。
目标 graphical.target
提供联网并使用显示管理器的多用户系统,作用与运行级别 5 相当。复杂目标(如 graphical.target
)通过将一部分其他目标组合起来充当“元”目标。systemd 通过组合现有目标简化了创建自定义目标的工作,从而提供了极大的灵活性。
下面的列表显示了最重要的 systemd 目标单元。有关完整列表,请参见 man 7 systemd.special
。
default.target
默认引导的目标。这并不是“实际”目标,而是指向另一个目标(如
graphic.target
)的符号链接,可通过 YaST 永久更改(请参见第 15.4 节 “使用 YaST 管理 服务”)。要为某个会话更改它,请在引导提示处使用内核参数systemd.unit=MY_TARGET.target
。emergency.target
在控制台上启动紧急外壳。请仅在引导提示处按以下格式使用它:
systemd.unit=emergency.target
。graphical.target
启动联网的具有多用户支持和显示管理器的系统。
halt.target
关闭系统。
mail-transfer-agent.target
启动发送和接收邮件所需的所有服务。
multi-user.target
启动联网的多用户系统。
reboot.target
重新引导系统。
rescue.target
启动不联网的单用户系统。
为了与 System V init 运行级别系统保持兼容,systemd 提供了名为 runlevelX.target
的特殊目标,与编号为 X 的相应运行级别相对应。
如果您想知道当前的目标,请使用命令:systemctl get-default
systemd
目标单元 #
System V 运行级别 |
|
用途 |
---|---|---|
0 |
|
系统关闭 |
1、S |
|
单用户模式 |
2 |
|
无远程联网的本地多用户模式 |
3 |
|
完整的联网多用户模式 |
4 |
|
未使用/用户定义 |
5 |
|
联网并使用显示管理器的完整多用户模式 |
6 |
|
系统重引导 |
/etc/inittab
System V init 系统中的运行级别在 /etc/inittab
中配置。systemd 不使用此配置。有关如何创建您自己的可引导目标的指导,请参考第 15.5.3 节 “创建自定义目标”。
15.3.1.1 用于更改目标的命令 #
可使用下列命令来操作目标单元:
任务 |
systemd 命令 |
System V init 命令 |
---|---|---|
更改当前目标/运行级别 |
|
|
更改为默认目标/运行级别 |
|
无 |
获得当前目标/运行级别 |
使用 systemd 时,一般会有多个活动目标。该命令可列出当前处于活动状态的所有目标。 |
或者
|
永久更改默认运行级别 |
使用服务管理器或运行以下命令:
|
使用服务管理器或更改以下行
( |
更改当前引导进程的默认运行级别 |
在引导提示处输入以下选项
|
在引导提示处输入所需的运行级别编号。 |
显示目标/运行级别的依赖项 |
“Requires” 会列出硬性依赖项(必须解决的依赖项),而 “Wants” 会列出软性依赖项(情况允许时解决的依赖项)。 |
无 |
15.3.2 调试系统的启动 #
systemd 提供了分析系统启动过程的方法。您可以查看所有服务及其状态的列表(而不必分析 /var/log/
)。systemd 还允许您扫描启动过程,以了解每项服务启动用了多长时间。
15.3.2.1 查看服务的启动情况 #
要查看系统引导后所启动服务的完整列表,请输入命令 systemctl
。该命令会列出所有活动服务,如下所示(已精简)。要获得特定服务的详细信息,请使用 systemctl status MY_SERVICE
。
root #
systemctl
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
[...]
iscsi.service loaded active exited Login and scanning of iSC+
kmod-static-nodes.service loaded active exited Create list of required s+
libvirtd.service loaded active running Virtualization daemon
nscd.service loaded active running Name Service Cache Daemon
chronyd.service loaded active running NTP Server Daemon
polkit.service loaded active running Authorization Manager
postfix.service loaded active running Postfix Mail Transport Ag+
rc-local.service loaded active exited /etc/init.d/boot.local Co+
rsyslog.service loaded active running System Logging Service
[...]
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
161 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
要想只列出无法启动的服务,请使用 --failed
选项。
root #
systemctl --failed
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
apache2.service loaded failed failed apache
NetworkManager.service loaded failed failed Network Manager
plymouth-start.service loaded failed failed Show Plymouth Boot Screen
[...]
15.3.2.2 调试启动时间 #
为了调试系统启动时间,systemd 提供了 systemd-analyze
命令。该命令会显示总启动时间及按启动时间排序的服务列表,还可以生成 SVG 图,以显示各服务相对于其他服务的启动时间。
- 列出系统启动时间
root #
systemd-analyze Startup finished in 2666ms (kernel) + 21961ms (userspace) = 24628ms- 列出服务启动时间
root #
systemd-analyze blame 15.000s backup-rpmdb.service 14.879s mandb.service 7.646s backup-sysconfig.service 4.940s postfix.service 4.921s logrotate.service 4.640s libvirtd.service 4.519s display-manager.service 3.921s btrfsmaintenance-refresh.service 3.466s lvm2-monitor.service 2.774s plymouth-quit-wait.service 2.591s firewalld.service 2.137s initrd-switch-root.service 1.954s ModemManager.service 1.528s rsyslog.service 1.378s apparmor.service [...]- 服务启动时间图
root #
systemd-analyze plot > jupiter.example.com-startup.svg
15.3.2.3 查看完整的启动过程 #
上面提到的命令可让您查看已启动的服务以及启动各服务所需的时间。如果您需要知道更多细节,可以在引导提示处输入下列参数,让 systemd
详细记录整个启动过程:
systemd.log_level=debug systemd.log_target=kmsg
现在,systemd
会将日志讯息写入内核环缓冲区。使用 dmesg
查看该缓冲区:
tux >
dmesg -T | less
15.3.3 System V 兼容性 #
systemd 与 System V 兼容,因此,您仍可以使用现有的 System V init 脚本。但是,至少有一个已知问题会导致 System V init 脚本默认不能与 systemd 配合使用:在 init 脚本中通过 su
或 sudo
以其他用户身份启动服务会导致脚本失败,生成“访问被拒绝”错误。
使用 su
或 sudo
更改用户时,会启动 PAM 会话。完成 init 脚本后会终止此会话。因此,init 脚本启动的服务也会终止。要解决此问题,请执行以下步骤:
创建与 init 脚本同名、扩展名为
.service
的服务文件封装程序:[Unit] Description=DESCRIPTION After=network.target [Service] User=USER Type=forking1 PIDFile=PATH TO PID FILE1 ExecStart=PATH TO INIT SCRIPT start ExecStop=PATH TO INIT SCRIPT stop ExecStopPost=/usr/bin/rm -f PATH TO PID FILE1 [Install] WantedBy=multi-user.target2
将 UPPERCASE LETTERS 中写入的所有值替换为适当的值。
使用
systemctl start 应用程序
启动守护程序。
15.4 使用 YaST 管理 服务 #
基本服务管理也可以通过 YaST 服务管理器模块实现。该模块支持启动、停止、启用和禁用服务。它还可让您显示服务的状态以及更改默认目标。要启动 YaST 模块,请选择
› › 。- 更改
要更改系统引导到的目标,请从
下拉框中选择某个目标。最常用的目标是 (启动图形登录屏幕)和 (以命令行模式启动系统)。- 启动或停止服务
从表中选择一个服务。
列显示它当前是( )否( )正在运行。通过选择 可切换其状态。为当前正在运行的会话启动或停止服务会更改其状态。要更改服务在整个重引导过程中的状态,您需要启用或禁用服务。
- 启用或禁用服务
从表中选择一个服务。
列显示它当前 还是 。通过选择 可更改其状态。通过启用或禁用服务,可配置服务在引导期间是否启动(
或 )。此设置不会影响当前的会话。要更改服务在当前会话中的状态,您需要将其启动或停止。- 查看状态讯息
要查看某个服务的状态讯息,请从列表中选择该服务,然后选择
。您看到的输出与systemctl
-l
status MY_SERVICE 命令生成的输出完全相同。
有问题的运行级别设置可能会导致系统无法使用。在应用您的更改之前,请确保您清楚这些设置可能产生的结果。
15.5 systemd
自定义 #
以下几节介绍了 systemd
自定义的一些示例。
一律在 /etc/systemd/
中进行 systemd 自定义设置,切勿在 /usr/lib/systemd/
中进行。否则,您的更改将在 systemd 下次更新时被覆盖。
15.5.1 自定义单元文件 #
systemd 单元文件位于 /usr/lib/systemd/system
中。如果您要自定义服务文件,请执行下列步骤:
将要修改的文件从
/usr/lib/systemd/system
复制到/etc/systemd/system
。将文件名保持不变。根据需要修改
/etc/systemd/system
中的副本。如需配置更改的概述,请使用
systemd-delta
命令。它会比较并识别覆盖了其他配置文件的配置文件。有关细节,请参考systemd-delta
手册页。
/etc/systemd
中修改过的文件优先于 /usr/lib/systemd/system
中的原始文件,前提是它们的文件名相同。
15.5.1.1 将 xinetd
服务转换为 systemd
#
从 SUSE Linux Enterprise Server 15 版本开始,去除了 xinetd
基础架构。本节概述如何将现有的自定义 xinetd
服务文件转换为 systemd
套接字。
对于每个 xinetd
服务文件,您至少要有两个 systemd
单元文件:套接字文件 (*.socket
) 和关联的服务文件 (*.service
)。套接字文件告诉 systemd
要创建哪个套接字,服务文件告诉 systemd
要启动哪个可执行文件。
以下面的 xinetd
服务文件为例:
root #
cat /etc/xinetd.d/example
service example
{
socket_type = stream
protocol = tcp
port = 10085
wait = no
user = user
group = users
groups = yes
server = /usr/libexec/example/exampled
server_args = -auth=bsdtcp exampledump
disable = no
}
要将它转换为 systemd
,需要下面两个配套的文件:
root #
cat /usr/lib/systemd/system/example.socket
[Socket]
ListenStream=0.0.0.0:10085
Accept=false
[Install]
WantedBy=sockets.target
root #
cat /usr/lib/systemd/system/example.service
[Unit]
Description=example
[Service]
ExecStart=/usr/libexec/example/exampled -auth=bsdtcp exampledump
User=user
Group=users
StandardInput=socket
有关 systemd
的“套接字”和“服务”文件选项的完整列表,请参见 systemd.socket 和 systemd.service 手册页(man 5 systemd.socket
、man 5 systemd.service
)。
15.5.2 创建“插入式”文件 #
如果您只想在配置文件中添加几行或修改文件的一小部分,可以使用所谓的“插入式”文件。使用插入式文件,您无需编辑或覆盖单元文件本身,即可扩展单元文件的配置。
例如,要更改位于 /usr/lib/systemd/system/FOOBAR.SERVICE
中 FOOBAR 服务的一个值,请按以下步骤操作:
创建名为
/etc/systemd/system/FOOBAR.service.d/
的目录。注意
.d
后缀。该目录必须命名为与要用插入式文件修补的服务相似的名称。在该目录中,创建
WHATEVERMODIFICATION.conf
文件。确保文件中仅包含要修改的值所在的那一行。
将更改保存到 文件中。它将作为原始文件的扩展。
15.5.3 创建自定义目标 #
System V init SUSE 系统上未使用运行级别 4,以便允许管理员创建自己的运行级别配置。systemd 允许您创建任意数目的自定义目标。建议您从采用 graphical.target
等现有目标开始。
将配置文件
/usr/lib/systemd/system/graphical.target
复制到/etc/systemd/system/MY_TARGET.target
,并根据需要调整该文件。上一步中复制的配置文件已涵盖目标的必要(“硬性”)依赖项。如果还要涵盖需要的(“软性”)依赖项,请创建目录
/etc/systemd/system/MY_TARGET.target.wants
。对每个需要的服务,创建从
/usr/lib/systemd/system
链到/etc/systemd/system/MY_TARGET.target.wants
的符号链接。设置好目标后,重新装载 systemd 配置以使新目标可用。
tux >
sudo
systemctl daemon-reload
15.6 高级用途 #
以下几节介绍了适合系统管理员的高级主题。有关更高级的 systemd 文档,请参考 Lennart Pöttering 撰写的适合管理员的 systemd 相关系列,网址为 http://0pointer.de/blog/projects。
15.6.1 清理临时目录 #
systemd
支持定期清理临时目录。将会自动迁移并激活前一系统版本中的配置。tmpfiles.d
(负责管理临时文件)将从 /etc/tmpfiles.d/*.conf
、/run/tmpfiles.d/*.conf
和 /usr/lib/tmpfiles.d/*.conf
文件中读取其配置。/etc/tmpfiles.d/*.conf
中的配置将覆盖其他两个目录中的相关配置(/usr/lib/tmpfiles.d/*.conf
是包用于储存其配置文件的位置)。
配置格式为每个路径一行,该行包含操作与路径、(可选)模式、所有权、期限和自变量字段,具体取决于操作。以下示例将取消链接 X11 锁定文件:
Type Path Mode UID GID Age Argument r /tmp/.X[0-9]*-lock
要获取 tmpfile 计时器的状态:
tux >
sudo
systemctl status systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static) Active: active (waiting) since Tue 2018-04-09 15:30:36 CEST; 1 weeks 6 days ago Docs: man:tmpfiles.d(5) man:systemd-tmpfiles(8) Apr 09 15:30:36 jupiter systemd[1]: Starting Daily Cleanup of Temporary Directories. Apr 09 15:30:36 jupiter systemd[1]: Started Daily Cleanup of Temporary Directories.
有关处理临时文件的详细信息,请参见 man 5 tmpfiles.d
。
15.6.2 系统日志 #
第 15.6.9 节 “调试服务” 介绍如何查看给定服务的日志讯息。但可显示的日志讯息并不仅限于服务日志。您还可以访问和查询 systemd
写入的完整日志,即所谓的“日记”。使用 journalctl
命令可显示完整的日志讯息,从最早的项开始。有关诸如应用过滤器或更改输出格式的选项,请参考 man 1 journalctl
。
15.6.3 快照 #
您可以使用 isolate
子命令将 systemd
的当前状态保存到指定快照中,并在日后还原到该状态。此功能在测试服务或自定义目标时非常有用,因为它可让您随时回到定义的状态。快照仅在当前会话中可用,重引导时将自动删除。快照名称必须以 .snapshot
结尾。
- 创建快照
tux >
sudo
systemctl snapshot MY_SNAPSHOT.snapshot- 删除快照
tux >
sudo
systemctl delete MY_SNAPSHOT.snapshot- 查看快照
tux >
sudo
systemctl show MY_SNAPSHOT.snapshot- 激活快照
tux >
sudo
systemctl isolate MY_SNAPSHOT.snapshot
15.6.4 装载内核模块 #
通过使用 systemd
以及 /etc/modules-load.d
中的配置文件,可以在引导时自动装载内核模块。该文件应该命名为 MODULE.conf 并包含以下内容:
# load module MODULE at boot time MODULE
如果某个包安装了用于装载内核模块的配置文件,该文件将安装到 /usr/lib/modules-load.d
。如果存在两个同名的配置文件,将优先使用 /etc/modules-load.d
中的那个配置文件。
有关详细信息,请参见 modules-load.d(5)
手册页。
15.6.5 装载服务之前执行必要操作 #
使用 System V init 时,需要在装载服务之前执行的操作必须在 /etc/init.d/before.local
中指定。systemd 不再支持此过程。如果您需要在启动服务之前执行操作,请执行以下步骤:
- 装载内核模块
在
/etc/modules-load.d
目录中创建一个 drop-in 文件(有关语法,请参见man modules-load.d
)- 创建文件或目录、清理目录、更改所有权
在
/etc/tmpfiles.d
中创建一个 drop-in 文件(有关语法,请参见man tmpfiles.d
)- 其它任务
基于下面的模板创建一个系统服务文件,例如
/etc/systemd/system/before.service
:[Unit] Before=NAME OF THE SERVICE YOU WANT THIS SERVICE TO BE STARTED BEFORE [Service] Type=oneshot RemainAfterExit=true ExecStart=YOUR_COMMAND # beware, executable is run directly, not through a shell, check the man pages # systemd.service and systemd.unit for full syntax [Install] # target in which to start the service WantedBy=multi-user.target #WantedBy=graphical.target
创建服务文件后,应运行以下命令(以
root
身份):tux >
sudo
systemctl daemon-reloadtux >
sudo
systemctl enable before每次修改服务文件时,都需要运行:
tux >
sudo
systemctl daemon-reload
15.6.6 内核控制组 (cgroups) #
在传统 System V init 系统上,并不总是能够明确地将某个进程指派给生成它的服务。一些服务(例如 Apache)会生成大量第三方进程(例如 CGI 或 Java 进程),这些进程本身又会生成更多进程。这使得明确指派变得非常困难,甚至无法做到。另外,服务可能不会正常终止,导致部分子服务仍保持运行状态。
systemd 通过将每个服务放入它自己的 cgroup 中,解决了这个问题。cgroups 是一项内核功能,允许将进程及其所有子进程聚合到分层组织的组中。systemd 根据每个 cgroup 的服务名称命名各 cgroup。因为非特权进程不允许“离开”它的 cgroup,这提供了一种行之有效的方式,可通过服务名称来标记该服务生成的所有进程。
要列出属于某个服务的所有进程,请使用命令 systemd-cgls
。结果将如下所示(已精简):
root #
systemd-cgls --no-pager
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 20
├─user.slice
│ └─user-1000.slice
│ ├─session-102.scope
│ │ ├─12426 gdm-session-worker [pam/gdm-password]
│ │ ├─15831 gdm-session-worker [pam/gdm-password]
│ │ ├─15839 gdm-session-worker [pam/gdm-password]
│ │ ├─15858 /usr/lib/gnome-terminal-server
[...]
└─system.slice
├─systemd-hostnamed.service
│ └─17616 /usr/lib/systemd/systemd-hostnamed
├─cron.service
│ └─1689 /usr/sbin/cron -n
├─postfix.service
│ ├─ 1676 /usr/lib/postfix/master -w
│ ├─ 1679 qmgr -l -t fifo -u
│ └─15590 pickup -l -t fifo -u
├─sshd.service
│ └─1436 /usr/sbin/sshd -D
[...]
有关 cgroups 的更多信息,请参见第 9 章 “内核控制组”。
15.6.7 终止服务(发送信号) #
如第 15.6.6 节 “内核控制组 (cgroups) ”中所述,在 System V init 系统中,并不总是能够将某个进程指派给其父服务。这导致终止服务及其所有子进程变得很困难。尚未终止的子进程将一直保持为僵停状态。
systemd 将每个服务限定在某个 cgroup 中的概念使您可以明确识别一个服务的所有子进程,从而向这些进程中的每一个发送信号。您可使用 systemctl kill
向服务发送信号。有关可用信号的列表,请参考 man 7 signals
。
- 向服务发送
SIGTERM
SIGTERM
是发送的默认信号。tux >
sudo
systemctl kill MY_SERVICE- 向服务发送 SIGNAL
可使用
-s
选项指定应该发送的信号。tux >
sudo
systemctl kill -s SIGNAL MY_SERVICE- 选择进程
默认情况下,
kill
命令会向指定 cgroup 的所有
进程发送信号。您可以将发送范围限制为control
或main
进程。后一个选项可用于通过发送SIGHUP
强制服务重新装载其配置的情况:tux >
sudo
systemctl kill -s SIGHUP --kill-who=main MY_SERVICE
15.6.8 有关 D-Bus 服务的重要说明 #
D-Bus 服务是 systemd 客户端与作为 pid 1 运行的 systemd 管理器之间进行通讯的讯息总线。虽然 dbus
是个独立的守护程序,但它也是 init 基础架构的组成部分。
在正在运行的系统中终止或重启动 dbus
的效果类似于尝试终止或重启动 pid 1。此操作将中断 systemd 客户端与服务器间的通讯,并使大部分 systemd 功能不可用。
因此,不建议也不支持终止或重启动 dbus
。
更新 dbus
或与 dbus
有关的包需要重引导。如果不确定是否需要重引导,请运行 sudo zypper ps -s
。如果 dbus
显示在所列服务之中,则表明您需要重引导系统。
请记住,即使自动更新配置为跳过需要重引导的包,dbus
仍会更新。
15.6.9 调试服务 #
默认情况下,systemd 的输出不会太详细。如果服务启动成功,则不会产生任何输出。如果服务启动失败,则会显示简短的错误讯息。不过,systemctl status
提供了调试服务的启动和操作的途径。
systemd 附带了自己的日志记录机制(“日志”)来记录系统讯息。这可让您一并显示服务讯息与状态讯息。status
命令的工作方式与 tail
相似,也可以采用不同的格式显示日志讯息,是一个功能强大的调试工具。
- 显示服务启动失败讯息
每当服务启动失败时,使用
systemctl status MY_SERVICE
可获得详细的错误讯息:root #
systemctl start apache2 Job failed. See system journal and 'systemctl status' for details.root #
systemctl status apache2 Loaded: loaded (/usr/lib/systemd/system/apache2.service; disabled) Active: failed (Result: exit-code) since Mon, 04 Apr 2018 16:52:26 +0200; 29s ago Process: 3088 ExecStart=/usr/sbin/start_apache2 -D SYSTEMD -k start (code=exited, status=1/FAILURE) CGroup: name=systemd:/system/apache2.service Apr 04 16:52:26 g144 start_apache2[3088]: httpd2-prefork: Syntax error on line 205 of /etc/apache2/httpd.conf: Syntax error on li...alHost>- 显示最后 N 条服务讯息
status
子命令的默认行为是显示服务发出的最后 10 条讯息。若要更改要显示的讯息数目,请使用--lines=N
参数:tux >
sudo
systemctl status chronydtux >
sudo
systemctl --lines=20 status chronyd- 以附加模式显示服务讯息
要显示服务讯息的“实时流”,请使用
--follow
选项,效果与tail
-f
相似:tux >
sudo
systemctl --follow status chronyd- 讯息输出格式
--output=模式
参数可让您更改服务讯息的输出格式。最重要的可用模式包括:short
默认格式。显示日志讯息,以及用户能看懂的时戳。
verbose
所有字段的完整输出。
cat
精简输出,不含时戳。
15.7 更多信息 #
有关 systemd 的更多信息,请参考下列联机资源:
- 主页
- systemd for Administrators(面向管理员的 systemd)
作者:Lennart Pöttering,一位 systemd 作家,他撰写了一系列博客(写本章时为 2013 年)。它们可在 http://0pointer.de/blog/projects 找到。