跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文档 / 管理指南 / 引导 Linux 系统 / systemd 守护程序
适用范围 SUSE Linux Enterprise Server 12 SP5

13 systemd 守护程序

systemd 程序是进程 ID 为 1 的进程。它负责以所需的方式初始化系统。systemd 由内核直接启动,信号 9(该信号通常会终止进程)对它不起作用。所有其他程序都由 systemd 直接启动,或由它的其中一个子进程启动。

SUSE Linux Enterprise Server 12 起,systemd 取代了常用的 System V init 守护程序。systemd 与 System V init 完全兼容(通过支持 init 脚本实现)。systemd 的其中一个主要优点是可通过激进方式并行启动多项服务来大幅加快引导速度。另外,systemd 只在确实有需要时才会启动服务。守护程序并不是在系统引导时无条件地启动,而是在第一次需要时启动。systemd 还支持内核控制组 (cgroups),以拍摄系统状态快照以及恢复系统状态等等。有关详细信息,请参见http://www.freedesktop.org/wiki/Software/systemd/

13.1 systemd 概念

本节将详细介绍有关 systemd 的概念。

13.1.1 systemd 是什么

systemd 是适用于 Linux 的系统和会话管理器,它与 System V 及 LSB init 脚本兼容。主要功能包括:

  • 提供激进式并行化功能

  • 使用套接字及 D-Bus 激活来启动服务

  • 提供按需启动守护程序功能

  • 使用 Linux cgroups 跟踪进程

  • 支持拍摄系统状态快照及恢复系统状态

  • 维护安装点和自动安装点

  • 实施精细的、基于事务依赖项的服务控制逻辑

13.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

13.2 基本用途

System V init 系统使用若干命令来处理服务:init 脚本、insservtelinit 及其他。systemd 使服务管理变得简单,要运行大部分服务处理任务,只需要记住一条命令:systemctl。它使用命令加子命令表示法,与 gitzypper 相似:

systemctl GENERAL OPTIONS SUBCOMMAND SUBCOMMAND OPTIONS

有关完整的手册,请参见 man 1 systemctl

提示
提示:终端输出和 Bash 补全

如果输出传递到某个终端(而不是某个管道或文件),systemd 命令默认会将长输出发送到分页器。使用 --no-pager 选项可关闭分页模式。

systemd 还支持 bash 补全,允许您输入子命令的头几个字母,然后按 →| 自动补全子命令。此功能只能在 bash 外壳中使用,并且需要安装 bash-completion 包。

13.2.1 管理正在运行的系统中的服务

用于管理服务的子命令与使用 System V init 管理服务的子命令相同(startstop 等)。服务管理命令的一般语法如下所示:

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 脚本,而是执行如下命令:

systemctl start MY_1ST_SERVICE MY_2ND_SERVICE

要列出系统上所有可用的服务,请运行:

systemctl list-unit-files --type=service

下表列出了 systemd 和 System V init 最重要的服务管理命令:

表 13.1︰ 服务管理命令

任务

systemd 命令

System V init 命令

启动:

start
start

停止:

stop
stop

重启动: 关闭服务,然后再启动这些服务。如果某项服务尚未运行,它将会启动。

restart
restart

有条件地重启动: 如果服务当前正在运行,则重启动它们。对未在运行的服务不执行任何操作。

try-restart
try-restart

重新装载: 让服务在不中断操作的情况下重新装载它们的配置文件。使用案例:让 Apache 重新装载修改过的 httpd.conf 配置文件。请注意,并非所有服务都支持重新装载。

reload
reload

重新装载或重启动: 如果支持重新装载则重新装载服务,否则重启动服务。如果某项服务尚未运行,它将会启动。

reload-or-restart
n/a

有条件地重新装载或重启动: 如果支持重新装载则重新装载服务,否则,如果服务当前正在运行,则重启动服务。对未在运行的服务不执行任何操作。

reload-or-try-restart
n/a

获得详细的状态信息: 列出服务状态的相关信息。systemd 命令会显示说明、可执行文件、状态、cgroup 及服务发出的最新讯息等细节(请参见第 13.6.9 节 “调试服务”)。使用 System V init 显示的详细程度因服务而异。

status
status

获得简要的状态信息: 显示服务是否处于活动状态。

is-active
status

13.2.2 永久启用/禁用服务

上一节中提到的服务管理命令可让您操控当前会话的服务。systemd 还允许您永久启用或禁用服务,让它们在用户要求时自动启动或永远不可用。您可以使用 YaST 或在命令行上运行命令来实现此目的。

13.2.2.1 在命令行上启用/禁用服务

下表列出了 systemd 和 System V init 用于启用和禁用服务的命令:

重要
重要:启动服务

在命令行上启用服务时,服务不会自动启动。它会安排在下一次系统启动或运行级别/目标发生更改时启动。要在启用服务之后立即启动它,请显式运行 systemctl start MY_SERVICErc MY_SERVICE start

表 13.2︰ 用于启用和禁用服务的命令

任务

systemd 命令

System V init 命令

启用:

systemctl enable MY_SERVICE(S)

insserv MY_SERVICE(S), chkconfig -a MY_SERVICE(S)

禁用:

systemctl disable MY_SERVICE(S).service

insserv -r MY_SERVICE(S)chkconfig -d MY_SERVICE(S)

检查: 显示某项服务是否启用。

systemctl is-enabled MY_SERVICE

chkconfig MY_SERVICE

重新启用: 与重启动服务相似,此命令先禁用服务,然后再启用该服务。可用来使用默认值重新启用服务。

systemctl reenable MY_SERVICE

屏蔽: 禁用某项服务之后,仍然可以手动启动它。要彻底禁用服务,您需要屏蔽它。须谨慎使用该功能。

systemctl mask MY_SERVICE

取消屏蔽: 屏蔽某项服务之后,只有在将其取消屏蔽之后才能再次使用它。

systemctl unmask MY_SERVICE

13.3 系统启动和目标管理

启动和关闭系统的整个过程由 systemd 负责维护。从这一点来看,可以将内核视为一个后台进程,其任务是维护所有其他进程,以及根据其他程序的请求来调整 CPU 时间和硬件访问。

13.3.1 目标与运行级别的比较

使用 System V init 时,系统引导到所谓的运行级别。运行级别定义系统如何启动以及正在运行的系统中有哪些服务可用。运行级别是有编号的;最知名的运行级别是 0(关闭系统)、3(联网的多用户模式)和 5(联网并使用显示管理器的多用户模式)。

systemd 使用所谓的目标单元引入新的概念。不过,它仍然与运行级别概念完全兼容。目标单元用名称而不是编号来标识,并具有特定的作用。例如,目标 local-fs.targetswap.target 用于装入本地文件系统和交换空间。

目标 graphical.target 提供联网并使用显示管理器的多用户系统,作用与运行级别 5 相当。复杂目标(如 graphical.target)通过将一部分其他目标组合起来充当目标。systemd 通过组合现有目标简化了创建自定义目标的工作,从而提供了极大的灵活性。

下面的列表显示了最重要的 systemd 目标单元。有关完整列表,请参见 man 7 systemd.special

选定的 systemd 目标单元
default.target

默认引导的目标。这并不是实际目标,而是指向另一个目标(如 graphic.target)的符号链接,可通过 YaST 永久更改(请参见第 13.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

表 13.3︰ System V 运行级别和 systemd 目标单元

System V 运行级别

systemd 目标

用途

0

runlevel0.targethalt.targetpoweroff.target

系统关闭

1、S

runlevel1.targetrescue.target

单用户模式

2

runlevel2.targetmulti-user.target

无远程联网的本地多用户模式

3

runlevel3.targetmulti-user.target

完整的联网多用户模式

4

runlevel4.target

未使用/用户定义

5

runlevel5.targetgraphical.target

联网并使用显示管理器的完整多用户模式

6

runlevel6.targetreboot.target

系统重引导

重要
重要:systemd 会忽略 /etc/inittab

System V init 系统中的运行级别在 /etc/inittab 中配置。systemd 使用此配置。有关如何创建您自己的可引导目标的指导,请参考第 13.5.3 节 “创建自定义目标”

13.3.1.1 用于更改目标的命令

可使用下列命令来操作目标单元:

任务

systemd 命令

System V init 命令

更改当前目标/运行级别

systemctl isolate MY_TARGET.target

telinit X

更改为默认目标/运行级别

systemctl default

获得当前目标/运行级别

systemctl list-units --type=target

使用 systemd 时,一般会有多个活动目标。该命令可列出当前处于活动状态的所有目标。

who -r

或者

运行级别

永久更改默认运行级别

使用服务管理器或运行以下命令:

ln -sf /usr/lib/systemd/system/ MY_TARGET.target /etc/systemd/system/default.target

使用服务管理器或更改以下行

id: X:initdefault:

/etc/inittab 中)

更改当前引导进程的默认运行级别

在引导提示处输入以下选项

systemd.unit= MY_TARGET.target

在引导提示处输入所需的运行级别编号。

显示目标/运行级别的依赖项

systemctl show -p "Requires" MY_TARGET.target

systemctl show -p "Wants" MY_TARGET.target

Requires 会列出硬性依赖项(必须解决的依赖项),而 Wants 会列出软性依赖项(情况允许时解决的依赖项)。

13.3.2 调试系统的启动

systemd 提供了分析系统启动过程的方法。您可以查看所有服务及其状态的列表(而不必分析 /varlog/)。systemd 还允许您扫描启动过程,以了解每项服务启动用了多长时间。

13.3.2.1 查看服务的启动情况

要查看系统引导后所启动服务的完整列表,请输入命令 systemctl。该命令会列出所有活动服务,如下所示(已精简)。要获得特定服务的详细信息,请使用 systemctl status MY_SERVICE

例 13.1︰ 列出活动服务
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
ntpd.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 选项。

例 13.2︰ 列出失败的服务
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

[...]

13.3.2.2 调试启动时间

为了调试系统启动时间,systemd 提供了 systemd-analyze 命令。该命令会显示总启动时间及按启动时间排序的服务列表,还可以生成 SVG 图,以显示各服务相对于其他服务的启动时间。

列出系统启动时间
root # systemd-analyze
Startup finished in 2666ms (kernel) + 21961ms (userspace) = 24628ms
列出服务启动时间
root # systemd-analyze blame
  6472ms systemd-modules-load.service
  5833ms remount-rootfs.service
  4597ms network.service
  4254ms systemd-vconsole-setup.service
  4096ms postfix.service
  2998ms xdm.service
  2483ms localnet.service
  2470ms SuSEfirewall2_init.service
  2189ms avahi-daemon.service
  2120ms systemd-logind.service
  1210ms xinetd.service
  1080ms ntp.service
[...]
    75ms fbset.service
    72ms purge-kernels.service
    47ms dev-vda1.swap
    38ms bluez-coldplug.service
    35ms splash_early.service
服务启动时间图
root # systemd-analyze plot > jupiter.example.com-startup.svg
Image

13.3.2.3 查看完整的启动过程

上面提到的命令可让您查看已启动的服务以及启动各服务所需的时间。如果您需要知道更多细节,可以在引导提示处输入下列参数,让 systemd 详细记录整个启动过程:

systemd.log_level=debug systemd.log_target=kmsg

现在,systemd 会将日志讯息写入内核环缓冲区。使用 dmesg 查看该缓冲区:

dmesg -T | less

13.3.3 System V 兼容性

systemd 与 System V 兼容,因此,您仍可以使用现有的 System V init 脚本。但是,至少有一个已知问题会导致 System V init 脚本默认不能与 systemd 配合使用:在 init 脚本中通过 susudo 以其他用户身份启动服务会导致脚本失败,生成访问被拒绝错误。

使用 susudo 更改用户时,会启动 PAM 会话。完成 init 脚本后会终止此会话。因此,init 脚本启动的服务也会终止。要解决此问题,请执行以下步骤:

  1. 创建与 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 中写入的所有值替换为适当的值。

    1

    可选 — 仅当 init 脚本启动守护程序时才使用。

    2

    multi-user.target 在引导进入 graphical.target 时也会启动 init 脚本。如果只应在引导进入显示管理器时才将它启动,请在此处使用 graphical.target

  2. 使用 systemctl start 应用程序启动守护程序。

13.4 使用 YaST 管理 服务

基本服务管理也可以通过 YaST 服务管理器模块实现。该模块支持启动、停止、启用和禁用服务。它还可让您显示服务的状态以及更改默认目标。要启动 YaST 模块,请选择 YaST ›  系统 ›  服务管理器

服务管理器
图 13.1︰ 服务管理器
更改默认系统目标

要更改系统引导到的目标,请从默认系统目标下拉框中选择某个目标。最常用的目标是图形界面(启动图形登录屏幕)和多用户(以命令行模式启动系统)。

启动或停止服务

从表中选择一个服务。活动列显示它当前是(活动)否(非活动)正在运行。通过选择启动/停止可切换其状态。

为当前正在运行的会话启动或停止服务会更改其状态。要更改服务在整个重引导过程中的状态,您需要启用或禁用服务。

启用或禁用服务

从表中选择一个服务。已启用列显示它当前已启用还是已禁用。通过选择启用/禁用可更改其状态。

通过启用或禁用服务,可配置服务在引导期间是否启动(已启用已禁用)。此设置不会影响当前的会话。要更改服务在当前会话中的状态,您需要将其启动或停止。

查看状态讯息

要查看某个服务的状态讯息,请从列表中选择该服务,然后选择显示细节。您看到的输出与 systemctl -l status MY_SERVICE 命令生成的输出完全相同。

警告
警告:有问题的运行级别设置可能会对您的系统造成损害

有问题的运行级别设置可能会导致系统无法使用。在应用您的更改之前,请确保您清楚这些设置可能产生的结果。

13.5 systemd 自定义

以下几节介绍了 systemd 自定义的一些示例。

警告
警告:避免自定义被覆盖

一律在 /etc/systemd/ 中进行 systemd 自定义设置,切勿/usr/lib/systemd/ 中进行。否则,您的更改将在 systemd 下次更新时被覆盖。

13.5.1 自定义服务文件

systemd 服务文件位于 /usr/lib/systemd/system 中。如果您要自定义服务文件,请执行下列步骤:

  1. 将要修改的文件从 /usr/lib/systemd/system 复制到 /etc/systemd/system。将文件名保持不变。

  2. 根据需要修改 /etc/systemd/system 中的副本。

  3. 如需配置更改的概述,请使用 systemd-delta 命令。它会比较并识别覆盖了其他配置文件的配置文件。有关细节,请参考 systemd-delta 手册页。

/etc/systemd 中修改过的文件优先于 /usr/lib/systemd/system 中的原始文件,前提是它们的文件名相同。

13.5.2 创建插入式文件

如果您只想在配置文件中添加几行或修改文件的一小部分,可以使用所谓的插入式文件。使用插入式文件,您无需编辑或覆盖单元文件本身,即可扩展单元文件的配置。

例如,要更改位于 /usr/lib/systemd/system/FOOBAR.SERVICEFOOBAR 服务的一个值,请按以下步骤操作:

  1. 创建名为 /etc/systemd/system/MY_SERVICE.service.d/ 的目录。

    注意 .d 后缀。该目录必须命名为与要用插入式文件修补的服务相似的名称。

  2. 在该目录中,创建 WHATEVERMODIFICATION.conf 文件。

    确保文件中仅包含要修改的值所在的那一行。

  3. 将更改保存到 文件中。它将作为原始文件的扩展。

13.5.3 创建自定义目标

System V init SUSE 系统上未使用运行级别 4,以便允许管理员创建自己的运行级别配置。systemd 允许您创建任意数目的自定义目标。建议您从采用 graphical.target 等现有目标开始。

  1. 将配置文件 /usr/lib/systemd/system/graphical.target 复制到 /etc/systemd/system/MY_TARGET.target,并根据需要调整该文件。

  2. 上一步中复制的配置文件已涵盖目标的必要(硬性)依赖项。如果还要涵盖需要的(软性)依赖项,请创建目录 /etc/systemd/system/MY_TARGET.target.wants

  3. 对每个需要的服务,创建从 /usr/lib/systemd/system 链到 /etc/systemd/system/我的目标.target.wants 的符号链接。

  4. 设置好目标后,重新装载 systemd 配置以让新目标可用。

    systemctl daemon-reload

13.6 高级用途

以下几节介绍了适合系统管理员的高级主题。有关更高级的 systemd 文档,请参考 Lennart Pöttering 撰写的适合管理员的 systemd 相关系列,网址为 http://0pointer.de/blog/projects

13.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 计时器的状态:

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 2014-09-09 15:30:36 CEST; 1 weeks 6 days ago
   Docs: man:tmpfiles.d(5)
         man:systemd-tmpfiles(8)

Sep 09 15:30:36 jupiter systemd[1]: Starting Daily Cleanup of Temporary Directories.
Sep 09 15:30:36 jupiter systemd[1]: Started Daily Cleanup of Temporary Directories.

有关处理临时文件的详细信息,请参见 man 5 tmpfiles.d

13.6.2 系统日志

第 13.6.9 节 “调试服务” 介绍如何查看给定服务的日志讯息。但可显示的日志讯息并不仅限于服务日志。您还可以访问和查询 systemd 写入的完整日志,即所谓的日记。使用 journalctl 命令可显示完整的日志讯息,从最早的项开始。有关诸如应用过滤器或更改输出格式的选项,请参考 man 1 journalctl

13.6.3 快照

您可以使用 isolate 子命令将 systemd 的当前状态保存到指定快照中,并在日后还原到该状态。此功能在测试服务或自定义目标时非常有用,因为它可让您随时回到定义的状态。快照仅在当前会话中可用,重引导时将自动删除。快照名称必须以 .snapshot 结尾。

创建快照
systemctl snapshot MY_SNAPSHOT.snapshot
删除快照
systemctl delete MY_SNAPSHOT.snapshot
查看快照
systemctl show MY_SNAPSHOT.snapshot
激活快照
systemctl isolate MY_SNAPSHOT.snapshot

13.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) 手册页。

13.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 身份):

systemctl daemon-reload
systemctl enable before

每次修改服务文件时,都需要运行:

systemctl daemon-reload

13.6.6 内核控制组 (cgroups)

在传统 System V init 系统上,并不总是能够明确地将某个进程指派给生成它的服务。一些服务(例如 Apache)会生成大量第三方进程(例如 CGI 或 Java 进程),这些进程本身又会生成更多进程。这使得明确指派变得非常困难,甚至无法做到。另外,服务可能不会正常终止,导致部分子服务仍保持运行状态。

systemd 通过将每个服务放入它自己的 cgroup 中,解决了这个问题。cgroups 是一项内核功能,允许将进程及其所有子进程聚合到分层组织的组中。systemd 根据每个 cgroup 的服务名称命名各 cgroup。因为非特权进程不允许离开它的 cgroup,这提供了一种行之有效的方式,可通过服务名称来标记该服务生成的所有进程。

要列出属于某个服务的所有进程,请使用命令 systemd-cgls。结果将如下所示(已精简):

例 13.3︰ 列出属于某个服务的所有进程
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
  ├─ntpd.service
  │ └─1328 /usr/sbin/ntpd -p /var/run/ntp/ntpd.pid -g -u ntp:ntp -c /etc/ntp.conf
  ├─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 的更多信息,请参见Chapter 9, Kernel Control Groups

13.6.7 终止服务(发送信号)

第 13.6.6 节 “内核控制组 (cgroups) ”中所述,在 System V init 系统中,并不总是能够将某个进程指派给其父服务。这导致终止服务及其所有子进程变得很困难。尚未终止的子进程将一直保持为僵停状态。

systemd 将每个服务限定在某个 cgroup 中的概念使您可以明确识别一个服务的所有子进程,从而向这些进程中的每一个发送信号。您可使用 systemctl kill 向服务发送信号。有关可用信号的列表,请参考 man 7 signals

向服务发送 SIGTERM

SIGTERM 是发送的默认信号。

systemctl kill MY_SERVICE
向服务发送 SIGNAL

可使用 -s 选项指定应该发送的信号。

systemctl kill -s SIGNAL MY_SERVICE
选择进程

默认情况下,kill 命令会向指定 cgroup 的所有进程发送信号。您可以将发送范围限制为 controlmain 进程。后一个选项可用于通过发送 SIGHUP 强制服务重新装载其配置的情况:

systemctl kill -s SIGHUP --kill-who=main MY_SERVICE

13.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 仍会更新。

13.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 Jun 2012 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

Jun 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 参数:

systemctl status ntp
systemctl --lines=20 status ntp
以附加模式显示服务讯息

要显示服务讯息的实时流,请使用 --follow 选项,效果与 tail -f 相似:

systemctl --follow status ntp
讯息输出格式

--output=模式参数可让您更改服务讯息的输出格式。最重要的可用模式包括:

short

默认格式。显示日志讯息,以及用户能看懂的时戳。

verbose

所有字段的完整输出。

cat

精简输出,不含时戳。

13.7 更多信息

有关 systemd 的更多信息,请参考下列联机资源:

主页

http://www.freedesktop.org/wiki/Software/systemd

systemd for Administrators(面向管理员的 systemd)

作者:Lennart Pöttering,一位 systemd 作家,他撰写了一系列博客(写本章时为 2013 年)。它们可在 http://0pointer.de/blog/projects 找到。