Difference between revisions of "Systemd (简体中文)"

From ArchWiki
Jump to: navigation, search
(疑难解答)
(小写title首字母)
 
(89 intermediate revisions by 13 users not shown)
Line 2: Line 2:
 
[[Category:Daemons and system services (简体中文)]]
 
[[Category:Daemons and system services (简体中文)]]
 
[[Category:Boot process (简体中文)]]
 
[[Category:Boot process (简体中文)]]
 +
[[Category:Init (简体中文)]]
 
[[ar:Systemd]]
 
[[ar:Systemd]]
 +
[[de:Systemd]]
 +
[[el:Systemd]]
 
[[en:Systemd]]
 
[[en:Systemd]]
 
[[es:Systemd]]
 
[[es:Systemd]]
 +
[[fa:Systemd]]
 
[[fr:Systemd]]
 
[[fr:Systemd]]
 
[[it:Systemd]]
 
[[it:Systemd]]
 
[[ja:Systemd]]
 
[[ja:Systemd]]
 +
[[pt:Systemd]]
 
[[ru:Systemd]]
 
[[ru:Systemd]]
[[zh-TW:Systemd]]
+
[[zh-hant:Systemd]]
{{Article summary start|概览}}
+
{{Related articles start (简体中文)}}
{{Article summary text|本文介绍 Systemd 的安装和配置。}}
+
{{Related|systemd/User (简体中文)}}
{{Article summary heading|相关页面}}
+
{{Related|systemd/Timers (简体中文)}}
{{Article summary wiki|Systemd/Services}}
+
{{Related|Systemd FAQ (简体中文)}}
{{Article summary wiki|systemd/User}}
+
{{Related|Daemons#List of deamons}}
{{Article summary wiki|Systemd FAQ}}
+
{{Related|udev (简体中文)}}
{{Article summary wiki|init Rosetta}}
+
{{Related|Improve Boot Performance (简体中文)}}
{{Article summary wiki|Daemons List}}
+
{{Related|Allow users to shutdown}}
{{Article summary wiki|udev (简体中文)}}
+
{{Related articles end}}
{{Article summary end}}
+
{{TranslationStatus (简体中文)|Systemd|2018-05-09|517689}}
{{TranslationStatus (简体中文)|Systemd|2013-03-14|250286}}
+
摘自[http://freedesktop.org/wiki/Software/systemd 项目主页]
摘自[http://freedesktop.org/wiki/Software/systemd 项目主页]:
 
  
'''''systemd''' 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本。systemd 的特性有:支持并行化任务;同时采用 socket 式与 [[D-Bus (简体中文)|D-Bus]] 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 [[cgroups|cgroups]] 监视进程;支持快照和系统恢复;维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。systemd 完全可以替代 Arch 曾经使用的 [[SysVinit (简体中文)|sysvinit]] 启动系统。''
+
:''systemd'' 是一个 Linux 系统基础组件的集合,提供了一个系统和服务管理器,运行为 PID 1 并负责启动其它程序。功能包括:支持并行化任务;同时采用 socket 式与 [[D-Bus (简体中文)|D-Bus]] 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 [[cgroups]] 监视进程;支持快照和系统恢复;维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。''systemd'' 支持 SysV 和 LSB 初始脚本,可以替代 sysvinit。除此之外,功能还包括日志进程、控制基础系统配置,维护登陆用户列表以及系统账户、运行时目录和设置,可以运行容器和虚拟机,可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。
  
{{注意|[https://bbs.archlinux.org/viewtopic.php?pid=1149530#p1149530 这个帖子]详细解释了 Arch systemd 迁移的原因。}}
+
{{注意|1= [https://bbs.archlinux.org/viewtopic.php?pid=1149530#p1149530 Arch Linux 论坛的这篇帖子] 详细地解释了 Arch Linux 迁移到 systemd 的原因。}}
  
另见[[Wikipedia:zh:systemd|维基百科上的介绍]]。
+
== systemd 基本工具 ==
  
== 迁移前需考虑 ==
+
监视和控制systemd的主要命令是{{ic|systemctl}}。该命令可用于查看系统状态和管理系统及服务。详见{{man|1|systemctl}}。、
  
* 阅读[http://freedesktop.org/wiki/Software/systemd/ 该站],了解 systemd。
+
{{提示|
* systemd 自己有一套日志('''journal''')系统,用于代替 '''syslog'''。两者也可以共存,参见后面的[[#日志|日志部分]]
+
* 在 {{ic|systemctl}} 参数中添加 {{ic|-H <用户名>@<主机名>}} 可以实现对其他机器的远程控制。该功能使用 [[SSH (简体中文)|SSH]] 连接。
* 虽然 systemd 可以替换 '''cron'''、'''acpid'''、'''xinetd''' 等的部分功能。至少目前还可以继续使用这些服务,无需立即切换。
+
* [[Plasma]] 用户可以安装 ''systemctl'' 图形前端 {{AUR|systemd-kcm}}。安装后可以在 ''System administration'' 下找到。}}
* 交互式 initscripts 启动脚本在 systemd 中无法工作。例如 '''netcfg-menu''' 无法{{Bug|31377}})在启动时显示。
 
  
== 安装 ==
+
=== 分析系统状态 ===
{{注意|从[https://www.archlinux.org/news/systemd-is-now-the-default-on-new-installations/ 2012-10-13版安装介质]开始,安装程序已经默认安装{{pkg|systemd}} 和 {{pkg|systemd-sysvcompat}}。}}
 
  
{{注意|如果是在 VPS 中使用 Arch,请先阅读:[[Virtual_Private_Server#Moving_your_VPS_from_initscripts_to_systemd]]。}}
+
显示 '''系统状态''':
  
本部分帮助还在使用{{AUR|sysvinit}} 和 initscripts 的用户迁移到 '''systemd'''.
+
$ systemctl status
  
# 从[[Official_Repositories_(简体中文)|官方软件仓库]]安装 {{pkg|systemd}} 并添加[[Kernel parameters|内核参数]]{{Ic|1=init=/usr/lib/systemd/systemd}}
+
输出激活的单元:
# 使用 {{ic|systemctl enable <服务名>}} 启用需要的服务(大致相当于以前 {{ic|DAEMONS}} 数组的作用,新的服务名称参见 [[Daemons_List_(简体中文)]])。
 
# 重启系统,执行命令 {{ic|cat /proc/1/comm}},如果返回{{ic|systemd}},表示 systemd 已经正常启动。
 
# 确认主机名已经正确设置:{{ic|hostnamectl set-hostname myhostname}}。
 
# 删除 initscripts 和 sysvinit,并安装{{pkg|systemd-sysvcompat}}.
 
# (可选)删除{{ic|1=init=/usr/lib/systemd/systemd}}内核参数,现在已经不需要它了。{{pkg|systemd-sysvcompat}} 软件包提供了一个软链接,使 systemd 成为默认 init。
 
  
=== 附加信息 ===
+
$ systemctl
* 如果内核参数中有 {{ic|quiet}},建议在一开始先去掉,以便调试。
 
{{Accuracy|reason=据有的用户称,systemd 并未对用户组有特殊要求。尽管有很多不常用的用户组,但从 consolekit 切换到 logind 后这些用户组没有发生改变。''(据译者理解:如果你碰到特殊的权限问题,可能仍需要加入这些用户组才能解决。)''}}
 
* 使用 systemd 的时候'''无需'''将用户加入特殊[[Users and Groups (简体中文)|用户组]](如{{ic|sys}}、{{ic|disk}}、{{ic|lp}}、{{ic|network}}、{{ic|video}}、{{ic|audio}}、{{ic|optical}}、{{ic|storage}}、{{ic|scanner}}、{{ic|power}}等等)。加入这些组反而会有问题,例如audio组会导致程序阻塞软件混声。每个 PAM 登录都拥有一个 logind 会话,它通过[[Wikipedia:Access control list|POSIX ACLs]],赋予本地会话以声音设备访问权限、通过[[udisks]]挂载和卸载移动设备的权限等。
 
{{警告|如果您准备将用户移出UNIX通用的基础用户组,请三思而后行。某些应用程序,如 '''mplayer''' 和 '''fbida''',需要访问 {{ic|/dev/fb*}} 的权限,因此必须加入 '''video''' 用户组。还有 k3b,需要用户加入 '''optical''' 组以访问旧式光学设备。正确的方法是使用 [https://mailman.archlinux.org/pipermail/arch-general/2012-October/031808.html udev] 获取[https://bbs.archlinux.org/viewtopic.php?pid&#61;1183731#p1183731 访问权限]。}}
 
* 阅读 [[Network Configuration (简体中文)]],了解如何配置网络。
 
  
== 原生 systemd 配置文件 ==
+
以下命令等效:
{{注意|可能需要手动创建某些文件。所有文件的权限都是644,属主 root,属组 root。}}
 
  
=== 虚拟控制台 ===
+
$ systemctl list-units
{{ic|/etc/vconsole.conf}} 文件用来配置虚拟控制台,包括键盘布局和控制台字体:
 
{{hc|/etc/vconsole.conf|<nowiki>
 
KEYMAP=us
 
FONT=lat9w-16
 
FONT_MAP=8859-1_to_uni</nowiki>}}
 
  
{{注意|{{ic|{{Pkg|systemd}}-194}} 默认使用内核字体和键盘布局,因此以后不必在上述文件中留下空的 {{ic|1=KEYMAP=}} 和 {{ic|1=FONT=}} 设置。}}
+
输出运行失败的单元:
  
还可以通过命令设置键盘布局:
+
  $ systemctl --failed
  # localectl set-keymap de
 
  
{{ic|localectl}} 也可以设置X11的键盘布局:
+
所有可用的单元文件存放在 {{ic|/usr/lib/systemd/system/}} 和 {{ic|/etc/systemd/system/}} 目录(后者优先级更高)。查看所有已安装服务:
 +
$ systemctl list-unit-files
  
# localectl set-x11-keymap de
+
=== 使用单元 ===
  
详情参见 {{ic|man 1 localectl}} {{ic|man 5 vconsole.conf}}。
+
一个单元配置文件可以描述如下内容之一:系统服务({{ic|.service}})、挂载点({{ic|.mount}})、sockets({{ic|.sockets}}) 、系统设备({{ic|.device}})、交换分区({{ic|.swap}})、文件路径({{ic|.path}})、启动目标({{ic|.target}})、由 systemd 管理的计时器({{ic|.timer}})。详情参阅 {{man|5|systemd.unit}} 。
  
* 另参阅 [[Fonts (简体中文)#控制台字体|控制台字体]] [[KEYMAP (简体中文)#键盘布局|键盘布局]]
+
使用 {{ic|systemctl}} 控制单元时,通常需要使用单元文件的全名,包括扩展名(例如 {{ic|sshd.service}} )。但是有些单元可以在 {{ic|systemctl}} 中使用简写方式。
 +
* 如果无扩展名,systemctl 默认把扩展名当作 {{ic|.service}} 。例如 {{ic|netcfg}} {{ic|netcfg.service}} 是等价的。
 +
* 挂载点会自动转化为相应的 {{ic|.mount}} 单元。例如 {{ic|/home}} 等价于 {{ic|home.mount}} 。
 +
* 设备会自动转化为相应的 {{ic|.device}} 单元,所以 {{ic|/dev/sda2}} 等价于 {{ic|dev-sda2.device}}
  
=== 硬件时钟 ===
+
{{注意|有一些单元的名称包含一个 {{ic|@}} 标记(例如: {{ic|name@''string''.service}} ),这意味着它是模板单元 {{ic|name@.service}} 的一个 [http://0pointer.de/blog/projects/instances.html 实例]。 {{ic|''string''}} 被称作实例标识符,在 ''systemctl'' 调用模板单元时,会将其当作一个参数传给模板单元,模板单元会使用这个传入的参数代替模板中的 {{ic|%I}} 指示符。
  
'''systemd''' 默认硬件时钟为协调世界时(UTC)。
+
在实例化之前,''systemd'' 会先检查 {{ic|name@string.suffix}} 文件是否存在(如果存在,就直接使用这个文件,而不是模板实例化)。大多数情况下,包含 {{ic|@}} 标记都意味着这个文件是模板。如果一个模板单元没有实例化就调用,该调用会返回失败,因为模板单元中的 {{ic|%I}} 指示符没有被替换。
 +
}}
  
{{小贴士|推荐使用[[NTP (简体中文)|NTP服务]]来在线同步硬件时钟。}}
+
{{提示|
 +
* 下面的大部分命令都可以跟多个单元名, 详细信息参见 {{man|1|systemctl}}。
 +
* {{ic|systemctl}}命令在{{ic|enable}}、{{ic|disable}}和{{ic|mask}}子命令中增加了{{ic|--now}}选项,可以实现激活的同时启动服务,取消激活的同时停止服务。
 +
* 一个软件包可能会提供多个不同的单元。如果你已经安装了软件包,可以通过{{ic|pacman -Qql ''package'' <nowiki>|</nowiki> grep systemd}}命令检查这个软件包提供了哪些单元。
 +
}}
  
==== 硬件时钟设定为地方时 ====
+
立即激活单元:
  
将硬件时钟配置为地方时('''不建议'''):
+
# systemctl start <单元>
  
  # timedatectl set-local-rtc true
+
立即停止单元:
 +
  # systemctl stop <单元>
  
重新调整为 UTC:
+
重启单元:
  
  # timedatectl set-local-rtc false
+
  # systemctl restart <单元>
  
如果设置成本地时间,处理夏令时有些麻烦。如果夏令时调整发生在关机时,下次启动时时间会出现问题([http://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html 更多信息])。最新的内核直接从实时时钟芯片(RTC)读取时间,不使用 {{ic|hwclock}},内核把从 RTC 读取的时间当作 UTC 处理。所以如果硬件时间是地方时,系统启动一开始识别的时间是错误的,之后很快会进行矫正。这可能导致一些问题(尤其是时间倒退时)。
+
重新加载配置:
  
如果同时安装了 Windows 操作系统([http://blogs.msdn.com/b/oldnewthing/archive/2004/09/02/224672.aspx 默认使用地方时]),那么一般 RTC 会被设置为地方时。Windows 其实也能处理 UTC,需要[[Time (简体中文)#Windows 系统使用 UTC|修改注册表]]。建议让 Windows 使用 UTC,而非让 Linux 使用地方时。Windows 使用 UTC 后,请记得禁用 Windows 的时间同步功能,以防 Windows 错误设置硬件时间。如上文所说,Linux 可以使用[[NTP (简体中文)|NTP服务]]来在线同步硬件时钟。
+
# systemctl reload <单元>
  
* 详情参阅 [[Time (简体中文)]]。
+
输出单元运行状态:
  
=== 内核模块 ===
+
$ systemctl status <单元>
目前,所有必要模块的加载均由 [[udev]] 自动完成。所以,如果不需要使用任何额外的模块,就没有必要在任何配置文件中添加启动时加载的模块。但是,有些情况下可能需要在系统启动时加载某个额外的模块,或者将某个模块列入黑名单以便使系统正常运行。
 
  
==== 开机加载 ====
+
检查单元是否配置为自动启动:
systemd 读取 {{ic|/etc/modules-load.d/}} 中的配置加载额外的内核模块。配置文件名称通常为 {{ic|/etc/modules-load.d/<program>.conf}}。格式很简单,一行一个要读取的模块名,而空行以及第一个非空格字符为{{ic|#}}或{{ic|;}}的行会被忽略,如:
+
$ systemctl is-enabled <单元>
{{hc|/etc/modules-load.d/virtio-net.conf|<nowiki>
 
# Load virtio-net.ko at boot
 
virtio-net</nowiki>}}
 
  
另见{{ic|man 5 modules-load.d}}。
+
开机自动激活单元:
  
==== 配置内核模块参数 ====
+
# systemctl enable <单元>
  
在 {{ic|/etc/modprobe.d/modprobe.conf}} 中设置额外的模块参数。
+
设置单元为自动启动并立即启动这个单元:
  
例如:
+
# systemctl enable --now ''unit''
  
* 我们已经在 {{ic|/etc/modules-load.d/loop.conf}} 中添加文本 {{ic|loop}},告诉系统开机自动加载该模块。
+
取消开机自动激活单元:
  
* 在 {{ic|/etc/modprobe.d/modprobe.conf}} 设置额外的参数,如:{{ic|options loop max_loop&#61;64}}。
+
# systemctl disable <单元>
  
最后,可以通过 {{ic|cat /sys/module/loop/parameters/max_loop}} 命令检查配置是否生效。
+
禁用一个单元(禁用后,间接启动也是不可能的):
  
==== 禁用内核模块 ====
+
# systemctl mask <单元>
禁用内核模块的方法和 Arch 默认的 {{Pkg|initscripts}} 相同,因为该过程实际由 {{Pkg|kmod}} 处理。参见:[[Kernel modules (简体中文)#黑名单]]。
 
  
=== 文件系统挂载 ===
+
取消禁用一个单元:
  
默认行为是:在启动一个需要挂载特定分区的服务之前,系统自动检查并挂载分区。{{ic|/etc/fstab}} 中设定的网络文件系统(如 [[NFS (简体中文)|NFS]]、[[Samba (简体中文)|Samba]])无需配置即可正常工作,systemd 将确保网络文件系统在网络链接就绪后挂载。
+
# systemctl unmask <单元>
  
详情参阅:{{ic|man 5 systemd.mount}}。
+
显示单元的手册页(必须由单元文件提供):
  
==== 自动挂载 ====
+
# systemctl help <单元>
  
* 如果 {{ic|/home}} 分区较大,可以让不依赖 {{ic|/home}} 分区的服务先启动。把下面的参数添加到 {{ic|/etc/fstab}} 文件中 {{ic|/home}} 项目的参数部分即可:
+
重新载入 systemd,扫描新的或有变动的单元:
 +
# systemctl daemon-reload
  
noauto,x-systemd.automount
+
=== 电源管理 ===
  
这样 {{ic|/home}} 分区只有需要访问时才会被挂载。内核会缓存所有的文件操作,直到 {{ic|/home}} 分区准备完成。
+
安装 [[polkit]] 后才能以普通用户身份使用电源管理。
  
{{注意|这样做会使 {{ic|/home}} 的文件系统类型被识别为 {{ic|autofs}},造成 [[mlocate]] 查询时忽略该目录。实际加速效果因配置而异,所以请自己权衡是否需要。}}
+
如果你正登录在一个本地的 {{ic|systemd-logind}} 用户会话,且当前没有其它活动的会话,那么以下命令无需 root 权限即可执行。否则(例如,当前有另一个用户登录在某个 tty ), systemd 将会自动请求输入root密码。
  
* 挂载远程文件系统也是同理。如果你仅想在需要的时候才挂载,也可以添加 {{ic|noauto,x-systemd.automount}} 参数。另外,可以设置 {{ic|1=x-systemd.device-timeout=#}} 参数,设置超时时间,以防止网络资源不能访问的时候浪费时间。
+
重启:
  
* 如果你的加密文件系统需要密钥,则需要添加 {{ic|noauto}} 参数到 {{ic|/etc/crypttab}} 文件中的对应位置。systemd 开机的时候就不会打开这个加密设备,会一直等待到设备被访问时再使用密钥文件挂载。比如在使用加密RAID设备的时候可以节省一定的时间,因为 systemd 不必等到设备可用后才能访问。例如:
+
$ systemctl reboot
  
{{hc|/etc/crypttab|
+
退出系统并关闭电源:
data /dev/md0 /root/key noauto}}
 
  
==== LVM ====
+
$ systemctl poweroff
  
如果装有不通过 [[Mkinitcpio (简体中文)|initramfs]] 激活的[[LVM (简体中文)|LVM]]卷,则需启动 {{ic|lvm-monitoring}} 服务(由 {{pkg|lvm2}} 软件包提供):
+
待机:
  
  # systemctl enable lvm-monitoring
+
  $ systemctl suspend
 +
 
 +
休眠:
 +
 
 +
$ systemctl hibernate
 +
 
 +
混合休眠模式(同时休眠到硬盘并待机):
 +
 
 +
$ systemctl hybrid-sleep
  
=== ACPI 电源管理 ===
+
== 编写单元文件 ==
'''systemd''' 能够处理某些电源相关的 [[Wikipedia:Advanced_Configuration_and_Power_Interface|ACPI]] 事件,通过 {{ic|/etc/systemd/logind.conf}} 的下列选项配置:
 
* {{ic|HandlePowerKey}}:按下电源键后的动作
 
* {{ic|HandleSleepKey}}:按下挂起键后的动作
 
* {{ic|HandleHibernateKey}}: 按下休眠键后的动作
 
* {{ic|HandleLidSwitch}}:合上笔记本盖后待机
 
  
动作可以是 {{ic|ignore}}{{ic|poweroff}}{{ic|reboot}}{{ic|halt}}、{{ic|suspend}}、{{ic|hibernate}}、{{ic|hybrid-sleep}}、{{ic|lock}} 或 {{ic|kexec}}
+
{{ic|systemd}} [http://www.freedesktop.org/software/systemd/man/systemd.unit.html 单元文件]的语法来源于 XDG 桌面项配置文件{{ic|.desktop}}文件,最初的源头则是Microsoft Windows的{{ic|.ini}}文件。单元文件可以从多个地方加载,{{ic|1=systemctl show --property=UnitPath}} 可以按优先级从低到高显示加载目录:
  
系统默认设置为:
+
* {{ic|/usr/lib/systemd/system/}} :软件包安装的单元
HandlePowerKey=poweroff
+
* {{ic|/etc/systemd/system/}} :系统管理员安装的单元
HandleSuspendKey=suspend
 
HandleHibernateKey=hibernate
 
HandleLidSwitch=suspend
 
  
不用图形界面、或者使用 [[i3 (简体中文)|i3]]、[[awesome (简体中文)|awesome]] 这样简单的桌面管理器时,systemd 可以替代 [[acpid (简体中文)|acpid]] 处理 ACPI 事件。
+
{{注意|
 +
* 当 {{ic|systemd}} 运行在[[systemd/User#How it works|用户模式]]下时,使用的加载路径是完全不同的。
 +
* systemd 单元名仅能包含 ASCII 字符,下划线和点号和有特殊意义的字符('@', '-')。其它字符需要用 C-style "\x2d" 替换。参阅 {{man|5|systemd.unit}} 和 {{man|1|systemd-escape}} 。}}
  
{{注意|运行 {{ic|systemctl restart systemd-logind}},使上述更改立即生效。}}
+
单元文件的语法,可以参考系统已经安装的单元,也可以参考 {{man|5|systemd.service}} 中的[http://www.freedesktop.org/software/systemd/man/systemd.service.html#Examples EXAMPLES章节]。
  
{{注意|systemd 无法处理交流电源和电池 ACPI 事件,所以还得使用 [[Laptop Mode Tools (简体中文)|Laptop Mode Tools]] 或 [[acpid (简体中文)|acpid]] 工具。}}
+
{{提示| 以 {{ic|#}} 开头的注释可能也能用在 unit-files 中,但是只能在新行中使用。不要在 ''systemd'' 的参数后面使用行末注释, 否则 unit 将会启动失败。}}
  
在当前版本的 systemd 中,这些 {{ic|Handle}} 选项将会被应用到整个系统当中,除非它们被别的程序——例如某个桌面环境中的电源管理器——给“阻止”(inhibited)。如果其它的程序没有阻止这些 {{ic|Handle}} ,你可能会先被 systemd 挂起你的系统,然后当系统被唤醒之后,电源管理器又会再次将系统挂起。
+
=== 处理依赖关系 ===
  
{{警告|目前只有[[GNOME]] 和 [[KDE]] 支持 "inhibited" 命令。在其它的桌面管理器同样实现该功能之前,如果你想使用[[Xfce]]、[[acpid]] 或者其它程序来管理 ACPI 事件,你需要把 {{ic|Handle}} 选项设置为 {{ic|ignore}}}}
+
使用 systemd 时,可通过正确编写单元配置文件来解决其依赖关系。典型的情况是,单元 {{ic|A}} 要求单元 {{ic|B}} 在 {{ic|A}} 启动之前运行。在此情况下,向单元 {{ic|A}} 配置文件中的 {{ic|[Unit]}} 段添加 {{ic|1=Requires=B}} 和 {{ic|1=After=B}} 即可。若此依赖关系是可选的,可添加 {{ic|1=Wants=B}} 和 {{ic|1=After=B}} 。请注意 {{ic|1=Wants=}} 和 {{ic|1=Requires=}} 并不意味着 {{ic|1=After=}} ,即如果 {{ic|1=After=}} 选项没有制定,这两个单元将被并行启动。
  
{{注意|除了内核默认的待机支持后端(用于处理待机/休眠),systemd 也可以使用其他后端(比如 [[Uswsusp]] 或 [[TuxOnIce]])。}}
+
依赖关系通常被用在服务(service)而不是[[#目标(target)|目标(target)]]上。例如, {{ic|network.target}} 一般会被某个配置网络接口的服务引入,所以,将自定义的单元排在该服务之后即可,因为 {{ic|network.target}} 已经启动。
  
要令 {{ic|systemctl hibernate}} 工作,需要按照[[Pm-utils#Hibernation_.28suspend2disk.29|休眠]]和 [[Pm-utils#Mkinitcpio_Resume_Hook|mkinitcpio 唤醒扩展]]的设置步骤进行操作。(不必安装 {{ic|pm-utils}})
+
=== 服务类型 ===
  
==== 休眠时执行的脚本 ====
+
编写自定义的 service 文件时,可以选择几种不同的服务启动方式。启动方式可通过配置文件 {{ic|[Service]}} 段中的 {{ic|1=Type=}} 参数进行设置。
  
使用 {{ic|systemctl suspend}}{{ic|systemctl hibernate}} {{ic|systemctl hybrid-sleep}} 命令执行待机/休眠时,systemd 不会调用 [[pm-utils (简体中文)|pm-utils]]。[[pm-utils (简体中文)|pm-utils]] 的钩子扩展(hook)——包括 [[pm-utils (简体中文)#建立你自己的钩子|自定义钩子]]——会失效。不过,systemd 提供了两种类似的待机/休眠时执行脚本的机制。
+
* {{ic|1=Type=simple}} :(默认值) systemd认为该服务将立即启动。服务进程不会 fork 。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket 激活型。
 +
* {{ic|1=Type=forking}} :systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定 {{ic|1=PIDFile=}},以便 systemd 能够跟踪服务的主进程。
 +
* {{ic|1=Type=oneshot}} :这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 {{ic|1=RemainAfterExit=yes}} 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
 +
* {{ic|1=Type=notify}} :与 {{ic|1=Type=simple}} 相同,但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由 {{ic|libsystemd-daemon.so}} 提供。
 +
* {{ic|1=Type=dbus}} :若以此方式启动,当指定的 {{ic|BusName}} 出现在DBus系统总线上时,systemd认为服务就绪。
 +
* {{ic|1=Type=idle}} :{{ic|systemd}}会等待所有任务处理完成后,才开始执行 {{ic|idle}} 类型的单元。其他行为与 {{ic|1=Type=simple}} 类似。
  
===== 使用服务文件 =====
+
{{ic|type}} 的更多解释可以参考 [http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= systemd.service(5)]。
  
可以将服务文件附在 suspend.target、hibernate.target 或 sleep.target 中,这样就能在待机/休眠前后执行某些操作。用户级操作和root/系统级操作应该使用不同的服务文件。要启用用户级服务文件,使用 {{ic|# systemctl enable suspend@<用户名> && systemctl enable resume@<用户名>}}。例如:
+
=== 修改现存单元文件 ===
  
{{hc|/etc/systemd/system/suspend@.service|2=<nowiki>
+
为了避免和 pacman 冲突,不应该直接编辑软件包提供的文件。有两种方法可以不改动原始文件就做到修改单元文件:创建一个优先级更高的本地单元文件或创建一个片段,应用到原始单元文件之上。两种方法都需要在修改后重新加载单元,用 {{ic|systemctl edit}} 编辑单元(会自动重载单元)或通过下面命令重新加载单元:
[Unit]
+
 
Description=User suspend actions
+
# systemctl daemon-reload
Before=sleep.target
+
 
 +
{{提示|
 +
* {{ic|systemd-delta}} 命令用来查看哪些单元文件被覆盖、哪些被修改。系统维护的时候需要及时了解哪些单元已经有了更新。
 +
* 使用 {{ic|systemctl cat ''unit''}} 可以查看单元的内容和所有相关的片段.
 +
* 安装 {{Pkg|vim-systemd}} 软件包,可以使单元配置文件在 [[Vim]] 下支持语法高亮。
 +
}}
  
[Service]
+
==== 替换单元文件 ====
User=%I
 
Type=forking
 
Environment=DISPLAY=:0
 
ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ; /usr/bin/mysql -e 'slave stop'
 
ExecStart=/usr/bin/sflock
 
  
[Install]
+
要替换 {{ic|/usr/lib/systemd/system/''unit''}}, 创建文件 {{ic|/etc/systemd/system/''unit''}} 并重新启用单元以更新链接:
WantedBy=sleep.target</nowiki>}}
 
  
{{hc|/etc/systemd/system/resume@.service|2=<nowiki>
+
# systemctl reenable ''unit''
[Unit]
 
Description=User resume actions
 
After=suspend.target
 
  
[Service]
+
或者运行:
User=%I
 
Type=simple
 
ExecStartPre=/usr/local/bin/ssh-connect.sh
 
ExecStart=/usr/bin/mysql -e 'slave start'
 
  
[Install]
+
# systemctl edit --full ''unit''
WantedBy=suspend.target</nowiki>}}
 
  
至于root/系统级服务(使用 {{ic|# systemctl enable root-suspend}} 激活):
+
这将会在记事本中打开 {{ic|/etc/systemd/system/''unit''}},如果文件不存在,可以将安装的版本复制到这里,在编辑完成之后,会自动加载新版本。
  
{{hc|/etc/systemd/system/root-resume.service|2=<nowiki>
+
{{注意|即使 Pacman 更新了新的单元文件,软件包中的版本也不会被使用,所以这个方式会增加系统维护的难度,推荐使用下面一种方法。}}
[Unit]
 
Description=Local system resume actions
 
After=suspend.target
 
  
[Service]
+
==== 附加配置片段 ====
Type=simple
 
ExecStart=/usr/bin/systemctl restart mnt-media.automount
 
  
[Install]
+
要附加配置片段,先创建名为 {{ic|/etc/systemd/system/<单元名>.d/}} 的目录,然后放入 {{ic|*.conf}} 文件,其中可以添加或重置参数。这里设置的参数优先级高于原来的单元文件。下面的更新方式比较简单:
WantedBy=suspend.target</nowiki>}}
 
  
{{hc|/etc/systemd/system/root-suspend.service|2=<nowiki>
+
# systemctl edit ''unit''
[Unit]
 
Description=Local system suspend actions
 
Before=sleep.target
 
  
[Service]
+
这将会在编辑器中打开文件 {{ic|/etc/systemd/system/''unit''.d/override.conf}},编辑完成之后自动加载。
Type=simple
 
ExecStart=-/usr/bin/pkill sshfs
 
  
[Install]
+
{{Note|并不是所有参数都会被子配置文件覆盖。例如要修改 {{ic|1=Conflicts=}} 就必须 [https://lists.freedesktop.org/archives/systemd-devel/2017-June/038976.html 替换原始文件]。}}
WantedBy=sleep.target</nowiki>}}
 
  
上述服务文件的一些解释(详见 {{ic|man systemd.service}}):
+
==== 重置到软件包版本 ====
* 如果设置 {{ic|1=<nowiki>Type=OneShot</nowiki>}},那么可以使用多个 {{ic|1=<nowiki>ExecStart=</nowiki>}} 参数。否则只能写一个,替代方案是在 {{ic|ExecStartPre}} 中添加命令,或使用分号分隔不同命令(见第一个例子,分号前后的空格都是'''必须'''的)。
 
* 若命令前加上一个“-”(半角减号),则命令返回非零值时会被忽略、当作正常执行处理。
 
* 有关调试,最好的方法是用 {{ic|journalctl}} 查看日志。
 
  
===== 合并待机和唤醒服务文件 =====
+
要回退单元的变更,使用 {{ic|systemctl edit}} 并执行:
  
利用下面这种自定义的一体化待机和唤醒服务,使用单一的钩子扩展即可对不同操作(待机/休眠/混合休眠)的不同阶段(进入/唤醒)进行控制。
+
# systemctl revert ''unit''
  
例子和解释:
+
==== 示例 ====
 +
例如,如果想添加一个额外的依赖,创建如下文件即可:
  
{{hc|/etc/systemd/system/wicd-sleep.service|2=<nowiki>
+
{{hc|/etc/systemd/system/<unit>.d/customdependency.conf|2=
 
[Unit]
 
[Unit]
Description=Wicd sleep hook
+
Requires=<新依赖>
Before=sleep.target
+
After=<新依赖>}}
StopWhenUnneeded=yes
+
 
 +
要修改一个非  {{ic|oneshot}} 单元的 {{ic|ExecStart}} 命令,创建下面文件:
  
 +
{{hc|/etc/systemd/system/''unit''.d/customexec.conf|2=
 
[Service]
 
[Service]
Type=oneshot
+
ExecStart=
RemainAfterExit=yes
+
ExecStart=''new command''
ExecStart=-/usr/share/wicd/daemon/suspend.py
+
}}
ExecStop=-/usr/share/wicd/daemon/autoconnect.py
 
  
[Install]
+
修改 {{ic|ExecStart}} 前必须将其置空,参见 ([https://bugzilla.redhat.com/show_bug.cgi?id=756787#c9] 。所有可能多次赋值的变量都需要这个操作,例如定时器的 {{ic|OnCalendar}}
WantedBy=sleep.target</nowiki>}}
 
  
* {{ic|1=<nowiki>RemainAfterExit=yes</nowiki>}}:服务启动后,除非显式地停止,否则就认为是活动的。
+
下面是自动重启服务的一个例子:
* {{ic|1=<nowiki>StopWhenUnneeded=yes</nowiki>}}:服务活动时,如果无其他服务依赖该服务,就停止它。在本例中,该服务会在 sleep.target 停止后停止活动。
 
* 由于 sleep.target 会被 suspend.target、hibernate.target、hybrid-sleep.target 调用,且 sleep.target 本身设置了 StopWhenUnneeded,该服务文件对以上各种操作都是有效的。
 
  
===== 使用 /usr/lib/systemd/system-sleep =====
+
{{hc|/etc/systemd/system/''unit''.d/restart.conf|2=
 +
[Service]
 +
Restart=always
 +
RestartSec=30
 +
}}
  
systemd 在待机/休眠时执行 {{ic|/usr/lib/systemd/system-sleep/}} 里的所有脚本,传递下面两个参数:
+
== 目标(target) ==
 +
 
 +
运行级别(runlevel)是一个旧的概念。现在,systemd 引入了一个和运行级别功能相似又不同的概念——目标(target)。不像数字表示的启动级别,每个''目标''都有名字和独特的功能,并且能同时启用多个。一些''目标''继承其他''目标''的服务,并启动新服务。systemd 提供了一些模仿 sysvinit 运行级别的''目标'',仍可以使用旧的 {{ic|telinit 运行级别}} 命令切换。
 +
 
 +
=== 获取当前目标 ===
 +
不要使用 {{ic|runlevel}} 命令了:
 +
$ systemctl list-units --type=target
  
* 参数1:若是准备进入待机/休眠状态,则为 {{ic|pre}};唤醒时为 {{ic|post}}
+
=== 创建新目标 ===
* 参数2:事件名称,{{ic|suspend}}{{ic|hibernate}} 或 {{ic|hybrid-sleep}}
+
在 Fedora 中,运行级别 0、1、3、5、6 都被赋予特定用途,并且都对应一个 systemd 的''目标''。然而,移植用户定义的运行级别(2、4)没有什么好方法。要实现类似功能,可以以原有的启动级别为基础,创建一个新的''目标'' {{ic|/etc/systemd/system/<新目标>}}(可以参考 {{ic|/usr/lib/systemd/system/graphical.target}}),创建 {{ic|/etc/systemd/system/<新目标>.wants}} 目录,向其中加入额外服务的链接(指向 {{ic|/usr/lib/systemd/system/}} 中的单元文件)。
  
systemd 会同时执行所有脚本,而不是像 [[pm-utils (简体中文)|pm-utils]] 那样顺序执行。
+
=== 目标表 ===
 +
{| class="wikitable"
 +
!SysV 运行级别!!Systemd 目标!!注释
 +
|-
 +
| 0 || runlevel0.target, poweroff.target || 中断系统(halt)
 +
|-
 +
| 1, s, single || runlevel1.target, rescue.target || 单用户模式
 +
|-
 +
| 2, 4 || runlevel2.target, runlevel4.target, multi-user.target || 用户自定义运行级别,通常识别为级别3。
 +
|-
 +
| 3 || runlevel3.target, multi-user.target || 多用户,无图形界面。用户可以通过终端或网络登录。
 +
|-
 +
| 5 || runlevel5.target, graphical.target || 多用户,图形界面。继承级别3的服务,并启动图形界面服务。
 +
|-
 +
| 6 || runlevel6.target, reboot.target || 重启
 +
|-
 +
| emergency || emergency.target || 急救模式(Emergency shell)
 +
|-
 +
|}
  
脚本输出会记录在相关服务({{ic|systemd-suspend.service}}、{{ic|systemd-hibernate.service}} 或 {{ic|systemd-hybrid-sleep.service}})中。通过[[#日志|日志]]查看:
+
=== 切换运行级别/目标 ===
# journalctl -b -u systemd-suspend
+
systemd 中,运行级别通过“目标单元”访问。通过如下命令切换:
 +
# systemctl isolate graphical.target
 +
该命令对下次启动无影响。等价于{{ic|telinit 3}} 或 {{ic|telinit 5}}
  
{{注意|除了使用自定义脚本,还可以利用 {{ic|sleep.target}}、{{ic|suspend.target}}{{ic|hibernate.target}} 或 {{ic|hybrid-sleep.target}} 来为单元(unit)添加睡眠状态策略。}}
+
=== 修改默认运行级别/目标 ===
 +
开机启动的目标是 {{ic|default.target}},默认链接到 {{ic|graphical.target}} (大致相当于原来的运行级别5)。可以通过[[Kernel parameters (简体中文)|内核参数]]更改默认运行级别:
  
脚本示范:
+
* {{ic|1=systemd.unit=multi-user.target}} (大致相当于级别3)
{{hc|/usr/lib/systemd/system-sleep/example.sh|
+
* {{ic|1=systemd.unit=rescue.target}} (大致相当于级别1)
#!/bin/sh
 
case $1/$2 in
 
  pre/*)
 
    echo "进入 $2 状态..."
 
    ;;
 
  post/*)
 
    echo "从 $2 状态唤醒..."
 
    ;;
 
esac}}
 
  
记得添加可执行权限:
+
另一个方法是修改 {{ic|default.target}}。可以通过 {{ic|systemctl}} 修改它:
# chmod a+x /usr/lib/systemd/system-sleep/example.sh
 
  
详情参见 {{ic|man 7 systemd.special}} 和 {{ic|man 8 systemd-sleep}}。
+
# systemctl set-default multi-user.target
  
=== 临时文件 ===
+
== 临时文件 ==
 
{{ic|/usr/lib/tmpfiles.d/}} 和 {{ic|/etc/tmpfiles.d/}} 中的文件描述了 systemd-tmpfiles 如何创建、清理、删除临时文件和目录,这些文件和目录通常存放在 {{ic|/run}} 和 {{ic|/tmp}} 中。配置文件名称为 {{ic|/etc/tmpfiles.d/<program>.conf}}。此处的配置能覆盖 {{ic|/usr/lib/tmpfiles.d/}} 目录中的同名配置。
 
{{ic|/usr/lib/tmpfiles.d/}} 和 {{ic|/etc/tmpfiles.d/}} 中的文件描述了 systemd-tmpfiles 如何创建、清理、删除临时文件和目录,这些文件和目录通常存放在 {{ic|/run}} 和 {{ic|/tmp}} 中。配置文件名称为 {{ic|/etc/tmpfiles.d/<program>.conf}}。此处的配置能覆盖 {{ic|/usr/lib/tmpfiles.d/}} 目录中的同名配置。
  
Line 323: Line 316:
 
}}
 
}}
  
详情参见 {{ic|man 5 tmpfiles.d}}。
+
详情参见{{ic|systemd-tmpfiles(8)}} 和 {{man|5|tmpfiles.d}}。
  
{{注意|该方法不能向 {{ic|/sys}} 中的配置文件添加参数,因为 {{ic|systemd-tmpfiles-setup}} 有可能在相关模块加载前运行。这种情况下,需要首先通过 {{ic|modinfo <模块名>}} 确认需要的参数,并在 [[Kernel modules (简体中文)#选项|{{ic|/etc/modprobe.d}} 下的一个文件]]中设置改参数。另外,还可以使用 [[udev (简体中文)#udev规则|udev 规则]],在设备就绪时设置相应属性。}}
+
{{注意|该方法不能向 {{ic|/sys}} 中的配置文件添加参数,因为 {{ic|systemd-tmpfiles-setup}} 有可能在相关模块加载前运行。这种情况下,需要首先通过 {{ic|modinfo <模块名>}} 确认需要的参数,然后在 [[Kernel modules (简体中文)#选项|{{ic|/etc/modprobe.d}} 目录下的配置文件]]{{Broken section link}}中修改配置参数。另外,还可以使用 [[udev (简体中文)#udev 规则|udev 规则]],在设备就绪时设置相应属性。}}
  
=== 单元(unit) ===
+
== 定时器 ==
一个单元配置文件可以描述如下内容之一:系统服务、socket、系统设备、挂载点、交换分区/文件、启动目标(target)、文件系统路径、由 systemd 管理的计时器。文件格式受 .desktop 文件启发,而最初起源是 Windows 下的 .ini 文件。
 
  
详情参阅 {{ic|man 5 systemd.unit}}.
+
一个定时器是一个以 {{ic|.timer}} 为结尾的单元配置文件并包含由 {{ic|systemd}} 控制和监督的信息。[[systemd/Timers (简体中文)]]
  
== 从 initscripts 迁移到 systemd ==
+
{{注意|定时器很大程度上可取代 {{ic|cron}}。[[systemd/Timers (简体中文)#替代 cron]]}}
  
=== initscripts 模拟 ===
+
== 挂载 ==
  
{{Pkg|initscripts}} 软件包提供了 systemd 和 Arch 传统配置的整合。当同时安装了{{Pkg|initscripts}}和systemd时,若以systemd启动系统,systemd将执行以下操作:
+
因为 systemd 也负责按 {{ic|/etc/fstab}} 挂载目录。在系统启动和重新加载系统管理器时,{{man|8|systemd-fstab-generator}} 会将 {{ic|/etc/fstab}} 中的配置转化为 systemd 单元。
  
# 解析{{ic|/etc/rc.conf}}中的{{ic|DAEMONS}}数组,并在系统启动时,启动所有列出的守护进程
+
''systemd'' 扩展了 [[fstab]] 的传统功能,提供了额外的挂载选项。例如可以确保一个挂载仅在网络已经连接时进行,或者仅当另外一个分区已挂载时再挂载。这些选项通常以 {{ic|x-systemd.}} 开头,{{man|5|systemd.mount|FSTAB}} 中包含了完整说明。
# 在启动过程中执行{{ic|/etc/rc.local}}
 
# 在系统关闭过程中执行{{ic|/etc/rc.local.shutdown}}
 
  
Initscripts模拟仅仅是作为用户迁移到systemd时的过渡措施,这一方案最终将'''不再可行'''。原生的systemd并不依赖于{{ic|rc.conf}}文件的集中式配置,因此推荐使用[[#原生 systemd 配置文件|原生的systemd配置文件]]。原生systemd配置文件比{{ic|/etc/rc.conf}}具有更高优先级。
+
''automounting'' 也是一个例子,可以在使用时,而不是启动时挂载分区,详情请参考 [[fstab#Automount with systemd]]
  
{{注意|替换{{ic|/etc/rc.local}}的推荐方式是针对系统启动时要运行的程序编写自定义的service文件,详见相关[[#自己编写_.service_文件|章节]].}}
+
== 日志 ==
 +
systemd 提供了自己的日志系统(logging system),称为 journal。使用 systemd 日志,无需额外安装日志服务(syslog)。读取日志的命令:
  
{{注意|如果你曾经在{{ic|/etc/inittab}}中禁用了以{{keypress|Ctrl+Alt+Del}}重启系统,则需要以root执行{{ic|systemctl mask ctrl-alt-del.target}}以使其对systemd重新生效。}}
+
# journalctl
  
{{警告|如果同时安装 systemd(197-4 及后续版本)和 initscripts,那么 {{ic|/etc/rc.local}} 脚本会导致启动过程无法结束(原因是 getty@tty1.service 自 197-4 版本起不再等待 rc-local.service 执行,getty 无法启动)。请删除或重命名 {{ic|/etc/rc.local}}}}
+
默认情况下(当 {{ic|1=Storage=}} 在文件 {{ic|/etc/systemd/journald.conf}} 中被设置为 {{ic|auto}}),日志记录将被写入 {{ic|/var/log/journal/}}。该目录是 {{pkg|systemd}} 软件包的一部分。若被删除,systemd '''不会'''自动创建它,直到下次升级软件包时重建该目录。如果该目录缺失,systemd 会将日志记录写入 {{ic|/run/systemd/journal}}。这意味着,系统重启后日志将丢失。
  
=== 迁移 DAEMONS 列表 ===
+
{{提示|如果 {{ic|/var/log/journal/}} 位于 [[btrfs]] 文件系统,应该考虑对这个目录禁用写入时复制,方法参阅[[Btrfs#Copy-on-Write (CoW)]]。}}
  
若要用纯 systemd 环境,则应当删除 {{ic|/etc/rc.conf}} 文件,并完全通过 {{ic|systemctl}} 命令来启动服务。对于 {{ic|DAEMONS}} 列表里面的每个 {{ic|<服务名>}},现在可以用以下命令设置成自动启动:
+
Systemd 日志事件提示信息的记录安装优先级和更能进行分离,符合经典的 BSD syslog 协议风格([[wikipedia:Syslog|维基百科]],[https://tools.ietf.org/html/rfc5424 RFC 5424])。
  
# systemctl enable <服务名>.service
+
===优先级===
  
{{小贴士|[[Daemons List|这里]]有一份 initscripts 和 systemd 下常见服务的对应列表。}}
+
A syslog severity code (in systemd called priority) is used to mark the importance of a message [https://tools.ietf.org/html/rfc5424#section-6.2.1 RFC 5424 Section 6.2.1].
  
如果提示 {{ic|<service_name>.service}} 不存在:
+
{| class="wikitable"
 +
|-
 +
! Value !! Severity !! Keyword  !! Description || Examples
 +
|-
 +
| 0 || Emergency || emerg || System is unusable || Severe Kernel BUG, systemd dumped core.<br>This level should not be used by applications.
 +
|-
 +
| 1 || Alert || alert || Should be corrected immediately || Vital subsystem goes out of work. Data loss. <br>{{ic|kernel: BUG: unable to handle kernel paging request at ffffc90403238ffc|}}.
 +
|-
 +
| 2 || Critical || crit || Critical conditions || Crashes, coredumps. Like familiar flash:<br>{{ic|systemd-coredump[25319]: Process 25310 (plugin-containe) of user 1000 dumped core}}<br>Failure in the system primary application, like X11.
 +
|-
 +
| 3 || Error || err || Error conditions || Not severe error reported:<br>{{ic|kernel: usb 1-3: 3:1: cannot get freq at ep 0x84}},<br>{{ic|systemd[1]: Failed unmounting /var.}},<br>{{ic|libvirtd[1720]: internal error: Failed to initialize a valid firewall backend}}).
 +
|-
 +
| 4 || Warning || warning || May indicate that an error will occur if action is not taken. ||  A non-root file system has only 1GB free.<br>{{ic|org.freedesktop. Notifications[1860]: (process:5999): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale}}.
 +
|-
 +
| 5 || Notice || notice || Events that are unusual, but not error conditions. || {{ic|systemd[1]: var.mount: Directory /var to mount over is not empty, mounting anyway}}. {{ic|gcr-prompter[4997]: Gtk: GtkDialog mapped without a transient parent. This is discouraged}}.
 +
|-
 +
| 6 || Informational || info ||  Normal operational messages that require no action. || {{ic|lvm[585]:  7 logical volume(s) in volume group "archvg" now active}}.
 +
|-
 +
| 7 || Debug || debug || Information useful to developers for debugging the application. || {{ic|kdeinit5[1900]: powerdevil: Scheduling inhibition from ":1.14" "firefox" with cookie 13 and reason "screen"}}.
 +
|}
  
* 很有可能是 systemd 用了不同的服务名。比如 {{ic|crond}} 服务替换成 {{ic|cronie.service}};{{ic|alsa}} 服务替换成了 {{ic|alsa-store.service}} 和 {{ic|alsa-restore.service}} 两个服务。另一个值得注意的是 {{ic|network}} 服务,它被替换为一整套服务文件(详情参见 [[Configuring_Network_(简体中文)]])。
+
If issue you are looking for, was not found on according level, search it on couple of priority levels above and below. This rules are recommendations. Some errors considered a normal occasion for program so they marked low in priority by developer, and on the contrary, sometimes too many messages plaques too high priorities for them, but often it's an arguable situation. And often you really should solve an issue, also to understand architecture and adopt best practices.
* 另外,有些程序尚未提供 .service 文件,还得继续用 {{ic|rc.conf}} 来配置开机自动启动。
 
  
{{小贴士|用下面这个命令来查看已安装软件包包含的服务文件:
+
Examples:
$ pacman -Ql cronie
+
* Info message:  {{bc|pulseaudio[2047]: W: [pulseaudio] alsa-mixer.c: Volume element Master has 8 channels. That's too much! I can't handle that!}} It is an warning or error by definition.
[...]
+
* Plaguing alert message: {{bc|1=sudo[21711]:    user : a password is required ; TTY=pts/0 ; PWD=/home/user ; USER=root ; COMMAND=list /usr/bin/pacman --color auto -Sy}} The [https://bbs.archlinux.org/viewtopic.php?id=184455 reason] - user was manually added to sudoers file, not to wheel group, which is arguably normal action, but sudo produced an alert on every occasion.
cronie /etc/rc.d/crond                            # DAEMONS 列表中使用的 initscript 服务 (原生 systemd 配置中不再使用)
 
[...]
 
cronie /usr/lib/systemd/system/cronie.service    # 原生 systemd 服务文件
 
[...]
 
}}
 
  
* 有些服务不需要用户明确配置自启动。比如安装 {{ic|dbus-core}} 软件包后 {{ic|dbus.service}} 就会自动被配置为自启动。而 {{ic|alsa-store.service}} 和 {{ic|alsa-restore.service}} 也会由 systemd 自动启动。可以用 {{ic|systemctl list-unit-files}} 命令来查看服务列表并检查运行状态。
+
=== 功能 ===
  
== systemd 基本工具 ==
+
A syslog facility code is used to specify the type of program that is logging the message [https://tools.ietf.org/html/rfc5424#section-6.2.1 RFC 5424 Section 6.2.1].
  
检视和控制systemd的主要命令是{{ic|systemctl}}。该命令可用于查看系统状态和管理系统及服务。详见{{ic|man 1 systemctl}}
+
{| class="wikitable"
 +
! Facility code !! Keyword !! Description !! Info
 +
|-
 +
| 0 || kern || kernel messages
 +
|-
 +
| 1 || user || user-level messages
 +
|-
 +
| 2 || mail || mail system || Archaic POSIX still supported and sometimes used system, for more {{man|1|mail}})
 +
|-
 +
| 3 || daemon || system daemons || All deamons, including systemd and its subsystems
 +
|-
 +
| 4 || auth || security/authorization messages || Also watch for different facility 10
 +
|-
 +
| 5 || syslog || messages generated internally by syslogd || As it standartized for syslogd, not used by systemd (see facility 3)
 +
|-
 +
| 6 || lpr || line printer subsystem (archaic subsystem)
 +
|-
 +
| 7 || news || network news subsystem (archaic subsystem)
 +
|-
 +
| 8 || uucp || UUCP subsystem (archaic subsystem)
 +
|-
 +
| 9 || || clock daemon || systemd-timesyncd
 +
|-
 +
| 10 || authpriv || security/authorization messages || Also watch for different facility 4
 +
|-
 +
| 11 || ftp || FTP daemon
 +
|-
 +
| 12 || - || NTP subsystem
 +
|-
 +
| 13 || - || log audit
 +
|-
 +
| 14 || - || log alert
 +
|-
 +
| 15 || cron || scheduling daemon
 +
|-
 +
| 16 || local0 || local use 0  (local0)
 +
|-
 +
| 17 || local1 || local use 1 (local1)
 +
|-
 +
| 18 || local2 || local use 2  (local2)
 +
|-
 +
| 19 || local3 || local use 3  (local3)
 +
|-
 +
| 20 || local4 || local use 4  (local4)
 +
|-
 +
| 21 || local5 || local use 5  (local5)
 +
|-
 +
| 22 || local6 || local use 6  (local6)
 +
|-
 +
| 23 || local7 || local use 7  (local7)
 +
|}
  
{{小贴士|在 {{ic|systemctl}} 参数中添加 {{ic|-H <用户名>@<主机名>}} 可以实现对其他机器的远程控制。该过程使用 [[SSH (简体中文)|SSH]] 链接。}}
+
So, useful facilities to watch: 0,1,3,4,9,10,15.
  
{{注意|{{ic|systemadm}} 是 systemd 的官方图形前端。由 [[AUR (简体中文)|AUR]] 中的软件包 {{AUR|systemd-ui-git}} 提供。}}
+
=== 过滤输出 ===
  
=== 分析系统状态 ===
+
{{ic|journalctl}}可以根据特定字段过滤输出。如果过滤的字段比较多,需要较长时间才能显示出来。
  
输出激活的单元:
+
示例:
  
$ systemctl
+
显示本次启动后的所有日志:
  
以下命令等效:
+
  # journalctl -b
 
 
  $ systemctl list-units
 
 
 
输出运行失败的单元:
 
  
$ systemctl --failed
+
不过,一般大家更关心的不是本次启动后的日志,而是上次启动时的(例如,刚刚系统崩溃了)。可以使用 {{ic|-b}} 参数:
 +
* {{ic|journalctl -b -0}} 显示本次启动的信息
 +
* {{ic|journalctl -b -1}} 显示上次启动的信息
 +
* {{ic|journalctl -b -2}} 显示上上次启动的信息 {{ic|journalctl -b -2}}
 +
* 只显示错误、冲突和重要告警信息 {{bc|# journalctl -p err..alert}} 也可以使用数字, {{ic|journalctl -p 3..1}}。If single number/keyword used, {{ic|journalctl -p 3}} - all higher priority levels also included.
  
所有可用的单元文件存放在 {{ic|/usr/lib/systemd/system/}} {{ic|/etc/systemd/system/}} 目录(后者优先级更高)。查看所有已安装服务:
+
* 显示从某个日期 ( 或时间 ) 开始的消息: {{bc|1=# journalctl --since="2012-10-30 18:17:16"}}
$ systemctl list-unit-files
+
* 显示从某个时间 ( 例如 20分钟前 ) 的消息: {{bc|1=# journalctl --since "20 min ago"}}
 +
* 显示最新信息{{bc|# journalctl -f}}
 +
* 显示特定程序的所有消息: {{bc|# journalctl /usr/lib/systemd/systemd}}
 +
* 显示特定进程的所有消息: {{bc|1=# journalctl _PID=1}}
 +
* 显示指定单元的所有消息:{{bc|# journalctl -u netcfg}}
 +
* 显示内核环缓存消息r: {{bc|1=# journalctl -k}}
 +
* Show auth.log equivalent by filtering on syslog facility: {{bc|1=# journalctl -f -l SYSLOG_FACILITY=10}}
  
=== 使用单元 ===
+
详情参阅{{man|1|journalctl}}{{man|7|systemd.journal-fields}},以及 Lennert 的这篇[http://0pointer.de/blog/projects/journalctl.html 博文]。
一个单元可以是系统服务({{ic|.service}})、挂载点({{ic|.mount}})、sockets({{ic|.sockets}})。
 
  
使用 {{ic|systemctl}} 控制单元时,通常需要使用单元文件的全名,包括扩展名(例如 {{ic|sshd.service}})。但是有些单元可以在{{ic|systemctl}}中使用简写方式。
+
=== 日志大小限制 ===
* 如果无扩展名,systemctl 默认把扩展名当作 {{ic|.service}}。例如 {{ic|netcfg}} 和 {{ic|netcfg.service}} 是等价的。
 
* 挂载点会自动转化为相应的 {{ic|.mount}} 单元。例如 {{ic|/home}} 等价于 {{ic|home.mount}}。
 
* 设备会自动转化为相应的 {{ic|.device}} 单元,所以 {{ic|/dev/sda2}} 等价于 {{ic|dev-sda2.device}}。
 
  
立即激活单元:
+
如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果 {{ic|/var/log/journal}} 储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改配置文件指定最大限制。如限制日志最大 50MiB:
  
  # systemctl start <单元>
+
{{hc|/etc/systemd/journald.conf|2=
 +
  SystemMaxUse=50M
 +
}}
  
立即停止单元:
+
还可以通过配置片段而不是全局配置文件进行设置:
# systemctl stop <单元>
 
  
重启单元:
+
{{hc|/etc/systemd/journald.conf.d/00-journal-size.conf|2=
 
+
[Journal]
# systemctl restart <单元>
+
SystemMaxUse=50M
 
 
命令单元重新读取配置:
 
 
 
# systemctl reload <单元>
 
 
 
输出单元运行状态:
 
 
 
$ systemctl status <单元>
 
 
 
检查单元是否配置为自动启动:
 
$ systemctl is-enabled <单元>
 
 
 
开机自动激活单元:
 
 
 
# systemctl enable <单元>
 
 
{{注意|如果服务没有{{ic|Install}}段落,一般意味着应该通过其它服务自动调用它们。如果真的需要手动安装,可以直接连接服务,如下(将{{ic|foo}}替换为真实的服务名):
 
{{bc|# ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/}}
 
 
}}
 
}}
  
取消开机自动激活单元:
+
修改配置后要立即生效,请[[Restart|重启]] {{ic|systemd-journald.service}} 服务。
  
# systemctl disable <单元>
+
详情参见 {{man|5|journald.conf}}.
  
显示单元的手册页(必须由单元文件提供):
+
=== 配合 syslog 使用 ===
 +
systemd 提供了 socket {{ic|/run/systemd/journal/syslog}},以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 {{ic|/dev/log}}([http://lwn.net/Articles/474968/ 官方说明])。Arch 软件仓库中的 {{pkg|syslog-ng}} 已经包含了需要的配置。
  
  # systemctl help <单元>
+
{{ic|journald.conf}} 使用 {{ic|no}} 转发socket . 为了使 ''syslog-ng'' 配合 ''journald'' , 你需要在 {{ic|/etc/systemd/journald.conf}} 中设置  {{ic|1=ForwardToSyslog=yes}} . 参阅 [[Syslog-ng#Overview]] 了解更多细节.
 +
 +
如果你选择使用 {{AUR|rsyslog}} , 因为 [[rsyslog]] 从日志中 [http://lists.freedesktop.org/archives/systemd-devel/2014-August/022295.html#journald 直接] 传出消息,所以不再必要改变那个选项..
  
重新载入 systemd,扫描新的或有变动的单元:
+
设置开机启动 syslog-ng:
# systemctl daemon-reload
+
  # systemctl enable syslog-ng
  
=== 电源管理 ===
+
[http://0pointer.de/blog/projects/ 这里]有一份很不错的 {{ic|journalctl}} 指南。
  
安装 {{ic|polkit}} 后才可使用电源管理。
+
=== 手动清理日志 ===
  
如果你正登录在一个本地的{{ic|systemd-logind}}用户会话,且当前没有其它活动的会话,那么以下命令无需root权限即可执行。否则(例如,当前有另一个用户登录在某个tty),systemd 将会自动请求输入root密码。
+
{{ic|/var/log/journal}} 存放着日志, {{ic|rm}} 应该能工作. 或者使用{{ic|journalctl}},
  
重启:
+
例如:
  
$ systemctl reboot
+
* 清理日志使总大小小于 100M: {{bc|1=# journalctl --vacuum-size=100M}}
 +
* 清理最早两周前的日志. {{bc|1=# journalctl --vacuum-time=2weeks}}
  
退出系统并停止电源:
+
参阅 {{man|1|journalctl}} 获得更多信息.
  
$ systemctl poweroff
+
=== Journald in conjunction with syslog ===
  
待机:
+
Compatibility with a classic, non-journald aware [[Syslog-ng|syslog]] implementation can be provided by letting ''systemd'' forward all messages via the socket {{ic|/run/systemd/journal/syslog}}. To make the syslog daemon work with the journal, it has to bind to this socket instead of {{ic|/dev/log}} ([http://lwn.net/Articles/474968/ official announcement]).
  
$ systemctl suspend
+
As of ''systemd'' 216 the default {{ic|journald.conf}} for forwarding to the socket was changed to {{ic|1=ForwardToSyslog=no}} to avoid system overhead, because [[rsyslog]] or [[syslog-ng]] (since 3.6) pull the messages from the journal by [http://lists.freedesktop.org/archives/systemd-devel/2014-August/022295.html#journald itself].
  
休眠:
+
See [[Syslog-ng#Overview]] and [[Syslog-ng#syslog-ng and systemd journal]], or [[rsyslog]] respectively, for details on configuration.
  
$ systemctl hibernate
+
===转发 journald 到 /dev/tty12 ===
  
混合休眠模式(同时休眠到硬盘并待机):
+
建立一个 [[#Editing provided units|drop-in directory]]{{Broken section link}} {{ic|/etc/systemd/journald.conf.d}} 然后在其中建立 {{ic|fw-tty12.conf}} :
  
$ systemctl hybrid-sleep
+
{{hc|1=/etc/systemd/journald.conf.d/fw-tty12.conf|2=
 +
[Journal]
 +
ForwardToConsole=yes
 +
TTYPath=/dev/tty12
 +
MaxLevelConsole=info
 +
}}
  
== 启动登录管理器 ==
+
然后重新启动  systemd-journald.
  
通过启动[[Display Manager (简体中文)|登录管理器]](或称显示管理器),即可进行图形界面登录。
+
=== 查看特定位置的日志 ===
要启用图形界面登录,运行适当的[[Display Manager (简体中文)|登录管理器]](或称显示管理器)即可。目前,Arch 提供了 [[GDM (简体中文)|GDM]]、[[KDM (简体中文)|KDM]]、[[SLiM (简体中文)|SLiM]]、[[XDM (简体中文)|XDM]]、[[LXDM (简体中文)|LXDM]]、[[LightDM (简体中文)|LightDM]] 和 {{AUR|SDDM}} 的 systemd 服务文件。以 KDM 为例,配置开机启动:
+
有时你希望查看另一个系统上的日志.例如从 Live 环境修复现存的系统.
# systemctl enable kdm.service
 
  
执行上述命令后,登录管理器应当能正常工作了。如果不是的话,很可能是因为你修改了{{ic|default.target}}。默认情况应当如下:
+
这种情况下你可以挂载目标系统 ( 例如挂载到 {{ic|/mnt}} ),然后用 {{ic|-D}}/{{ic|--directory}} 参数指定目录,像这样:
  
{{hc|# ls -l /etc/systemd/system/default.target|/etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target}}
+
$ journalctl -D ''/mnt''/var/log/journal -xe
  
删除被修改的 {{ic|default.target}} 即可,systemd 会自动使用默认配置(即 {{ic|graphical.target}}):
+
== Tips and tricks ==
  
# rm /etc/systemd/system/default.target
+
=== Running services after the network is up ===
  
=== 使用 systemd-logind ===
+
To delay a service after the network is up, include the following dependencies in the ''.service'' file:
  
{{注意|自 2012-10-30 起, [[ConsoleKit]] 已被 [https://www.archlinux.org/news/consolekit-replaced-by-logind/ systemd-logind 取代] ,作为登录到桌面环境的默认方式。}}
+
{{hc|/etc/systemd/system/''foo''.service|2=
 +
[Unit]
 +
...
 +
'''Wants=network-online.target'''
 +
'''After=network-online.target'''
 +
...
 +
}}
  
可使用 {{ic|loginctl}} 来查看用户会话的状态。所有 [[PolicyKit]] 操作,如挂起系统、挂载外部驱动器,都无需配置即可使用。
+
The network wait service of the particular application that manages the network, must also be enabled so that {{ic|network-online.target}} properly reflects the network status.
  
$ loginctl show-session $XDG_SESSION_ID
+
* For the ones using [[NetworkManager]], [[enable]] {{ic|NetworkManager-wait-online.service}}.
 +
* If using [[systemd-networkd]], {{ic|systemd-networkd-wait-online.service}} is by default enabled automatically whenever {{ic|systemd-networkd.service}} has been enabled; check this is the case with {{ic|systemctl is-enabled systemd-networkd-wait-online.service}}, there is no other action needed.
  
== 自己编写 .service 文件 ==
+
For more detailed explanations see [https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ Running services after the network is up] in the systemd wiki.
''参见:[[Systemd/Services]]''
 
  
=== 处理依赖关系 ===
+
=== Enable installed units by default ===
 +
 +
{{Expansion|How does it work with instantiated units?}}
  
使用systemd时,可通过正确编写单元配置文件来解决其依赖关系。典型的情况是,单元{{ic|A}}要求单元{{ic|B}}在{{ic|A}}启动之前运行。在此情况下,向单元{{ic|A}}配置文件中的 {{ic|[Unit]}} 段添加 {{ic|1=Requires=B}} 和 {{ic|1=After=B}} 即可。若此依赖关系是可选的,可添加 {{ic|1=Wants=B}} 和 {{ic|1=After=B}}。请注意 {{ic|1=Wants=}} 和 {{ic|1=Requires=}} 并不意味着 {{ic|1=After=}},即如果 {{ic|1=After=}} 选项没有制定,这两个单元将被并行启动。
+
Arch Linux ships with {{ic|/usr/lib/systemd/system-preset/99-default.preset}} containing {{ic|disable *}}. This causes ''systemctl preset'' to disable all units by default, such that when a new package is installed, the user must manually enable the unit.
  
依赖关系通常被用在服务(service)而不是[[#目标(target)|目标(target)]]上。例如, {{ic|network.target}} 一般会被某个配置网络接口的服务引入,所以,将自定义的单元排在该服务之后即可,因为 {{ic|network.target}} 已经启动。
+
If this behavior is not desired, simply create a symlink from {{ic|/etc/systemd/system-preset/99-default.preset}} to {{ic|/dev/null}} in order to override the configuration file. This will cause ''systemctl preset'' to enable all units that get installed—regardless of unit type—unless specified in another file in one ''systemctl preset'''s configuration directories. User units are not affected. See the manpage for {{ic|systemd.preset}} for more information.
  
=== 启动方式 ===
+
{{Note|Enabling all units by default may cause problems with packages that contain two or more mutually exclusive units. ''systemctl preset'' is designed to be used by distributions and spins or system administrators. In the case where two conflicting units would be enabled, you should explicitly specify which one is to be disabled in a preset configuration file as specified in the manpage for {{ic|systemd.preset}}.}}
  
编写自定义的service文件时,可以选择几种不同的服务启动方式。启动方式可通过配置文件 {{ic|[Service]}} 段中的 {{ic|1=Type=}} 参数进行设置。具体的参数说明请参阅 {{ic|man systemd.service}} 。
+
=== Sandboxing application environments ===
  
* {{ic|1=Type=simple}}(默认值):systemd认为该服务将立即启动。服务进程不会fork。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket激活型。
+
A unit file can be created as a sandbox to isolate applications and their processes within a hardened virtual environment. systemd leverages [[wikipedia:Linux_namespaces|namespaces]], white-/blacklisting of [[Capabilities]], and [[control groups]] to container processes through an extensive [https://www.freedesktop.org/software/systemd/man/systemd.exec.html execution environment configuration].
* {{ic|1=Type=forking}}:systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定 {{ic|1=PIDFile=}},以便systemd能够跟踪服务的主进程。
 
* {{ic|1=Type=oneshot}}:这一选项适用于只执行一项任务随后退出的服务。你可能需要同时设置 {{ic|1=RemainAfterExit=yes}} 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
 
* {{ic|1=Type=notify}}:与 {{ic|1=Type=simple}} 相同,但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由 {{ic|libsystemd-daemon.so}} 提供。
 
* {{ic|1=Type=dbus}}:若以此方式启动,当指定的 {{ic|BusName}} 出现在DBus系统总线上时,systemd认为服务就绪。
 
  
=== 修改现存单元文件 ===
+
The enhancement of an existing systemd unit file with application sandboxing typically requires trial-and-error tests accompanied by the generous use of {{Pkg|strace}}, [[wikipedia:Standard_streams#Standard_error_.28stderr.29|stderr]] and [https://www.freedesktop.org/software/systemd/man/journalctl.html journalctl] error logging and output facilities. You may want to first search upstream documentation for already done tests to base trials on.
  
To edit a unit file provided by a package, you can create a directory called {{ic|/etc/systemd/system/<unit>.d/}} for example {{ic|/etc/systemd/system/httpd.service.d/}} and place {{ic|*.conf}} files in there to override or add new options. '''systemd''' will parse these {{ic|*.conf}} files and apply them on top of the original unit. For example, if you simply want to add an additional dependency to a unit, you may create the following file:
+
Some examples on how sandboxing with systemd can be deployed:
  
{{hc|/etc/systemd/system/<unit>.d/customdependency.conf|2=
+
* {{Ic|CapabilityBoundingSet}} defines a whitelisted set of allowed capabilities, but may also be used to blacklist a specific capability for a unit.
[Unit]
+
** The {{Ic|CAP_SYS_ADM}} capability, for example, which should be one of the [https://lwn.net/Articles/486306/ goals of a secure sandbox]: {{ic|1=CapabilityBoundingSet=~ CAP_SYS_ADM}}
Requires=<新依赖>
 
After=<新依赖>}}
 
  
然后运行以下命令使更改生效:
+
== 疑难解答 ==
 +
=== 寻找错误 ===
  
# systemctl daemon-reload
+
这个例子中的失败的服务是 {{ic|systemd-modules-load}} :
# systemctl restart <单元>
 
  
Alternatively you can copy the old unit file from {{ic|/usr/lib/systemd/system/}} to {{ic|/etc/systemd/system/}} and make your changes there. A unit file in {{ic|/etc/systemd/system/}} always overrides the same unit in {{ic|/usr/lib/systemd/system/}}. Note that when the original unit in {{ic|/usr/lib/}} is changed due to a package upgrade, these changes will not automatically apply to your custom unit file in {{ic|/etc/}}. Additionally you will have to manually reenable the unit with {{ic|systemctl reenable <unit>}}. It is therefore recommended to use the {{ic|*.conf}} method described before instead.
+
'''1.''' 通过 ''systemd'' 寻找启动失败的服务:
  
{{小贴士|可以用 {{ic|systemd-delta}} 命令来查看哪些单元文件被覆盖、哪些被修改。}}
+
{{hc|1=$ systemctl --state=failed|2=
 +
systemd-modules-load.service  loaded '''failed failed'''  Load Kernel Modules}}
  
=== 单元配置文件的 vim 语法高亮支持 ===
+
或者使用 ''systemd'' 消息:
 +
$ journalctl -fp err
  
可从 [[Official Repositories|官方仓库]] 安装 {{Pkg|vim-systemd}} 软件包,使 unit 配置文件在 [[Vim]] 下支持语法高亮。
+
'''2.''' 我们发现了启动失败的 {{ic|systemd-modules-load}} 服务. 我们想知道更多信息:
  
== 目标(target) ==
+
{{hc|$ systemctl status systemd-modules-load|2=
启动级别(runlevel)是一个旧的概念。现在,systemd 引入了一个和启动级别功能相似又不同的概念——目标(target)。不像数字表示的启动级别,每个''目标''都有名字和独特的功能,并且能同时启用多个。一些''目标''继承其他''目标''的服务,并启动新服务。systemd 提供了一些模仿 sysvinit 启动级别的''目标'',仍可以使用旧的 {{ic|telinit 启动级别}} 命令切换。
+
systemd-modules-load.service - Load Kernel Modules
 +
  Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
 +
  Active: '''failed''' (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
 +
    Docs: man:systemd-modules-load.service(8).
 +
          man:modules-load.d(5)
 +
  Process: '''15630''' ExecStart=/usr/lib/systemd/systemd-modules-load ('''code=exited, status=1/FAILURE''')
 +
}}
  
=== 获取当前目标 ===
+
如果没列出 {{ic|Process ID}}, 通过 {{ic|systemctl}} 重新启动失败的服务 ( 例如 {{ic|systemctl restart systemd-modules-load}} )
不要使用 {{ic|runlevel}} 命令了:
 
$ systemctl list-units --type=target
 
  
=== 创建新目标 ===
+
'''3.''' 现在得到了 PID ,你就可以进一步探查错误的详细信息了.通过下列的命令收集日志,PID 参数是你刚刚得到的 {{ic|Process ID}} (例如 15630):
在 Fedora 中,启动级别 0、1、3、5、6 都被赋予特定用途,并且都对应一个 systemd 的''目标''。然而,没有什么很好的移植用户定义的启动级别(2、4)的方法。要实现类似功能,可以以原有的启动级别为基础,创建一个新的''目标'' {{ic|/etc/systemd/system/<新目标>}}(可以参考 {{ic|/usr/lib/systemd/system/graphical.target}}),创建 {{ic|/etc/systemd/system/<新目标>.wants}} 目录,向其中加入额外服务的链接(指向 {{ic|/usr/lib/systemd/system/}} 中的单元文件)。
 
  
=== 目标表 ===
+
{{hc|1=$ journalctl -b _PID=15630|2=
{| border="1"
+
-- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. --
!SysV 启动级别!!Systemd 目标!!注释
+
Aug 25 11:48:13 mypc systemd-modules-load[15630]: '''Failed to find module 'blacklist usblp''''
|-
+
Aug 25 11:48:13 mypc systemd-modules-load[15630]: '''Failed to find module 'install usblp /bin/false''''
| 0 || runlevel0.target, poweroff.target || 中断系统(halt)
+
}}
|-
 
| 1, s, single || runlevel1.target, rescue.target || 单用户模式
 
|-
 
| 2, 4 || runlevel2.target, runlevel4.target, multi-user.target || 用户自定义启动级别,通常识别为级别3。
 
|-
 
| 3 || runlevel3.target, multi-user.target || 多用户,无图形界面。用户可以通过终端或网络登录。
 
|-
 
| 5 || runlevel5.target, graphical.target || 多用户,图形界面。继承级别3的服务,并启动图形界面服务。
 
|-
 
| 6 || runlevel6.target, reboot.target || 重启
 
|-
 
| emergency || emergency.target || 急救模式(Emergency shell)
 
|-
 
|}
 
  
=== 切换启动级别/目标 ===
+
'''4.''' 我们发现有些内核模块的配置文件不正确,因此在 {{ic|/etc/modules-load.d/}} 中检查一下:
systemd 中,启动级别通过“目标单元”访问。通过如下命令切换:
 
  # systemctl isolate graphical.target
 
该命令对下次启动无影响。等价于{{ic|telinit 3}} 或 {{ic|telinit 5}}
 
  
=== 修改默认启动级别/目标 ===
+
{{hc|$ ls -Al /etc/modules-load.d/|
开机启动进的目标是 {{ic|default.target}},默认链接到 {{ic|graphical.target}} (大致相当于原来的启动级别5)。可以通过[[Kernel parameters (简体中文)|内核参数]]更改默认启动级别:
+
...
 +
-rw-r--r--  1 root root    79  1. Dez 2012  blacklist.conf
 +
-rw-r--r--  1 root root    1  2. Mär 14:30 encrypt.conf
 +
-rw-r--r--  1 root root    3  5. Dez 2012  printing.conf
 +
-rw-r--r--  1 root root    6 14. Jul 11:01 realtek.conf
 +
-rw-r--r--  1 root root    65  2. Jun 23:01 virtualbox.conf
 +
...
 +
}}
  
{{小贴士|可以省略扩展名 {{ic|.target}}。}}
+
'''5.''' 错误消息 {{ic|Failed to find module 'blacklist usblp'}} 也许和  {{ic|blacklist.conf}} 相关. 让我们注释掉第三步发现的错误的选项:
  
* {{ic|1=systemd.unit=multi-user.target}} (大致相当于级别3)
+
{{hc|/etc/modules-load.d/blacklist.conf|
* {{ic|1=systemd.unit=rescue.target}} (大致相当于级别1)
+
'''#''' blacklist usblp
 +
'''#''' install usblp /bin/false
 +
}}
  
另一个方法是修改 {{ic|default.target}}。可以通过 {{ic|systemctl}} 修改它:
+
'''6.''' 最后重新启动 {{ic|systemd-modules-load}} 服务:
  
  # systemctl enable multi-user.target
+
  $ systemctl start systemd-modules-load
  
命令执行情况由 {{ic|systemctl}} 显示:链接 {{ic|/etc/systemd/system/default.target}} 被创建,指向新的默认启动级别。该方法当且仅当目标配置文件中有以下内容时有效:
+
如果服务成功启动,不会有任何输出.如果你还是遇到了错误,回到步骤三,获得新的 PID 来跟踪日志并解决错误.
  
[Install]
+
可以像这样确认服务成功启动:
Alias=default.target
 
  
目前,{{ic|multi-user.target}}、{{ic|graphical.target}} 都包含这段内容。
+
{{hc|$ systemctl status systemd-modules-load|2=
 +
systemd-modules-load.service - Load Kernel Modules
 +
  Loaded: '''loaded''' (/usr/lib/systemd/system/systemd-modules-load.service; static)
 +
  Active: '''active (exited)''' since So 2013-08-25 12:22:31 CEST; 34s ago
 +
    Docs: man:systemd-modules-load.service(8)
 +
          man:modules-load.d(5)
 +
Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
 +
Aug 25 12:22:31 mypc systemd[1]: '''Started Load Kernel Modules'''.
 +
}}  
  
== 日志 ==
+
=== 诊断启动问题 ===
systemd 提供了自己日志系统(logging system),称为 journal. 使用 systemd 日志,无需额外安装日志服务(syslog)。读取日志的命令:
 
# journalctl
 
  
默认情况下(当 {{ic|1=Storage=}} 在文件 {{ic|/etc/systemd/journald.conf}} 中被设置为 {{ic|auto}}),日志记录将被写入 {{ic|/var/log/journal/}}。该目录是 {{pkg|systemd}} 软件包的一部分。若被删除,systemd '''不会'''自动创建它,直到下次升级软件包时重建该目录。如果该目录缺失,systemd 会将日志记录写入 {{ic|/run/systemd/journal}}。这意味着,系统重启后日志将丢失。
+
使用如下内核参数引导:
 +
{{ic|<nowiki>systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M</nowiki>}}
  
=== 过滤输出 ===
+
更多有关调试的信息,参见[http://freedesktop.org/wiki/Software/systemd/Debugging 该文]。
  
{{ic|journalctl}}可以根据特定字段过滤输出,例如:
+
=== 诊断一个服务 ===
  
显示本次启动后的所有日志:
+
如果某个 ''systemd'' 服务的工作状况不合预期,希望调试的话,设置 {{ic|SYSTEMD_LOG_LEVEL}} [[environment variable|环境变量]] 为 {{ic|debug}} . 例如以调试模式运行 ''systemd-networkd'' 服务:
  
# journalctl -b
+
在此服务的配置文件片段中加入:
  
不过,一般大家更关心的不是本次启动后的日志,而是上次启动时的(例如,刚刚系统崩溃了)。目前还没有这项功能,正在 [http://comments.gmane.org/gmane.comp.sysutils.systemd.devel/6608 systemd-devel@lists.freedesktop.org] 讨论中。
+
[Service]
 +
Environment=SYSTEMD_LOG_LEVEL=debug
  
目前的折中方案是:
+
或者等价的,临时编辑系统单元文件,例如:
  
# journalctl --since=today | tac | sed -n '/-- Reboot --/{n;:r;/-- Reboot --/q;p;n;b r}' | tac
+
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd
  
以上命令输出本日内的所有启动信息。但要注意,如果日志很多,该命令执行时间会比较漫长。
+
[[restart|重启]] ''systemd-networkd'' 服务,用 {{ic|--follow}} 选项检查日志。
  
动态跟踪最新信息:
+
=== 关机/重启十分缓慢 ===
# journalctl -f
 
  
显示特定程序的所有消息:
+
如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再尝试杀死它。请阅读[http://freedesktop.org/wiki/Software/systemd/Debugging#Shutdown_Completes_Eventually 这篇文章],确认你是否是该问题受害者。
{{bc|# journalctl /usr/lib/systemd/systemd}}
 
  
显示特定进程的所有消息:
+
=== 短时进程无日志记录 ===
{{bc|1=# journalctl _PID=1}}
 
  
显示指定单元的所有消息:
+
若 {{ic|journalctl -u foounit.service}} 没有显示某个短时进程的任何输出,那么改用 PID 试试。例如,若 {{ic|systemd-modules-load.service}} 执行失败,那么先用 {{ic|systemctl status systemd-modules-load}} 查询其 PID(比如是123),然后检索该 PID 相关的日志 {{ic|journalctl -b _PID&#61;123}}。运行时进程的日志元数据(诸如 _SYSTEMD_UNIT 和 _COMM)被乱序收集在 {{ic|/proc}} 目录。要修复该问题,必须修改内核,使其通过套接字连接来提供上述数据,该过程类似于 SCM_CREDENTIALS。
# journalctl -u netcfg
 
  
详情参阅{{ic|man journalctl}}、{{ic|man systemd.journal-fields}},以及 Lennert 的这篇[http://0pointer.de/blog/projects/journalctl.html 博文]。
+
=== 禁止在程序崩溃时转储内存 ===
 +
要使用老的内核转储,创建下面文件:
 +
{{hc|/etc/sysctl.d/49-coredump.conf|2=<nowiki>
 +
kernel.core_pattern = core
 +
kernel.core_uses_pid = 0</nowiki>}}
  
=== 日志大小限制 ===
+
然后运行:
 
+
  # /usr/lib/systemd/systemd-sysctl
如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果 {{ic|/var/log/journal}} 储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改 {{ic|/etc/systemd/journald.conf}} 中的 {{ic|SystemMaxUse}} 来指定该最大限制。如限制日志最大 50MiB:
 
 
 
  SystemMaxUse=50M
 
 
 
详情参见 {{ic|man journald.conf}}.
 
 
 
=== 配合 syslog 使用 ===
 
systemd 提供了 socket {{ic|/run/systemd/journal/syslog}},以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 {{ic|/dev/log}}([http://lwn.net/Articles/474968/ 官方说明])。Arch 软件仓库中的 {{pkg|syslog-ng}} 已经包含了需要的配置。
 
 
 
设置开机启动 syslog-ng:
 
  # systemctl enable syslog-ng
 
 
 
[http://0pointer.de/blog/projects/ 这里]有一份很不错的 {{ic|journalctl}} 指南。
 
 
 
== 优化 ==
 
 
 
参阅:[[Improve Boot Performance (简体中文)]]。
 
 
 
=== 启动过程分析 ===
 
systemd 提供了一个分析启动过程的工具 —— {{ic|systemd-analyze}}。可以用它看看哪些单元拖慢了开机过程,并据此进行优化。
 
 
 
查看开机过程在内核/用户空间消耗的时间:
 
$ systemd-analyze
 
{{小贴士|
 
* 如果在 {{ic|/etc/mkinitcpio.conf}} 的 {{ic|HOOKS}} 数组添加 {{ic|timestamp}},并重新生成启动内存镜像({{ic|mkinitcpio -p linux}}),{{ic|systemd-analyze}} 还可以显示处理该启动镜像花费的时间。
 
* 如果使用 [[UEFI]] 引导,且启动引导器实现了 systemd 的 [http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface Boot Loader Interface](目前只有 [[Gummiboot]] 实现了),'''systemd-analyze''' 还可以显示 EFI 固件和启动引导器自身花费的时间。}}
 
 
 
按照耗费时间顺序,输出启动每个单元耗费的时间:
 
$ systemd-analyze blame
 
 
 
生成类似于 [[Bootchart (简体中文)|bootchart]] 的开机过程图表:
 
$ systemd-analyze plot > plot.svg
 
  
==== 使用 systemd-bootchart ====
+
同样可能需要执行“unlimit”设置文件大小:
 +
$ ulimit -c unlimited
  
自2012年10月17日,bootchart 工具已经合并进 systemd 中,使用方法和原来的 bootchart 大同小异,添加下列内容到内核参数即可:
+
更多信息请参阅 [http://www.freedesktop.org/software/systemd/man/sysctl.d.html sysctl.d] 和 [https://www.kernel.org/doc/Documentation/sysctl/kernel.txt /proc/sys/kernel 文档]。
  
initcall_debug printk.time=y init=/usr/lib/systemd/systemd-bootchart
+
=== 启动的时间太长 ===
  
==== 使用 bootchart2 ====
+
不少用户用了 {{ic|systemd-analyze}} 命令以后报告启动的时间比预计的要长,通常会说 {{ic|systemd-analyze}} 分析结果表示 [[NetworkManager]] 占据了太多的启动的时间.
 
 
由于没有办法在内核参数设置两个 init,所以不能使用源里的 bootchart。不过,[[AUR (简体中文)|AUR]] 软件包 {{AUR|bootchart2-git}} 提供了一个的 systemd 服务,这样就可以和 systemd 一起使用。安装后启用即可:
 
{{bc|# systemctl enable bootchart.service}}
 
详情参阅 [https://github.com/mmeeks/bootchart bootchart 文档]
 
 
 
=== 预读 ===
 
systemd 自己实现了一个 readahead,可以用来提高开机效率。不过,效果会因内核版本和硬件情况而不同(极少数情况下还会变慢)。开启 readahead:
 
 
 
# systemctl enable systemd-readahead-collect.service systemd-readahead-replay.service
 
 
 
要知道,readahead 的超级牛力只有在重启几次后才会显现。
 
 
 
== 疑难解答 ==
 
 
 
=== 关机/重启十分缓慢 ===
 
  
如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再尝试杀死它。请阅读[http://freedesktop.org/wiki/Software/systemd/Debugging#Shutdown_Completes_Eventually 这篇文章],确认你是否是该问题受害者。
+
有些用户的问题是 {{ic|/var/log/journal}} 文件夹似乎过大.这也许也会对像{{ic|systemctl status}} 或 {{ic|journalctl}} 的命令有影响.一种解决方案是删除其中的文件 (但最好将它们备份到某处) 然后限制日志文件的大小.
  
=== 短时进程无日志记录 ===
+
=== systemd-tmpfiles-setup.service 在启动时启动失败 ===
 +
从 systemd 219 开始, {{ic|/usr/lib/tmpfiles.d/systemd.conf}} 指定 {{ic|/var/log/journal}} 的 ACL 属性和目录, 因此日志所在的文件系统上要启用ACL.
  
若 {{ic|journalctl -u foounit.service}} 没有显示某个短时进程的任何输出,那么改用 PID 试试。例如,若 {{ic|systemd-modules-load.service}} 执行失败,那么先用 {{ic|systemctl status systemd-modules-load}} 查询其 PID(比如是123),然后检索该 PID 相关的日志 {{ic|journalctl -b _PID&#61;123}}。运行时进程的日志元数据(诸如 _SYSTEMD_UNIT 和 _COMM)被乱序收集在 {{ic|/proc}} 目录。要修复该问题,必须修改内核,使其通过套接字连接来提供上述数据,该过程类似于 SCM_CREDENTIALS。
+
参阅 [[Access Control Lists#Enabling ACL]] 获得如何包含 {{ic|/var/log/journal}} 启动 ACL 的详细信息.
  
=== 诊断启动问题 ===
+
=== 启动时显示的 systemd 版本和安装版本不一致 ===
  
使用如下内核参数引导:
+
需要 [[Mkinitcpio#Image_creation_and_activation|重新生成 initramfs]]。
{{ic|<nowiki>systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M</nowiki>}}
 
  
更多有关调试的信息,参见[http://freedesktop.org/wiki/Software/systemd/Debugging 该文]
+
{{提示|1=可以使用 pacman 钩子在更新 {{pkg|systemd}}时重新生成 initramfs。参考 [https://bbs.archlinux.org/viewtopic.php?id=215411 这个帖子] 和 [[Pacman#Hooks]].}}
  
=== 禁止在程序崩溃时转储内存 ===
+
=== 禁用远程机器的 emergency 模式 ===
  
把 {{ic|/etc/sysctl.d/coredump.conf}} 链接到 {{ic|/dev/null}},然后应用 sysctl 即可([https://bbs.archlinux.org/viewtopic.php?id=154511 来源]):
+
如果远程机器位于云主机,emergency 模式会导致系统无法远程连接,可以通过下面方式禁用紧急模式:
  
  # ln -s /dev/null /etc/sysctl.d/coredump.conf
+
  # systemctl mask emergency.service
  # /usr/lib/systemd/systemd-sysctl
+
  # systemctl mask emergency.target
# ulimit -c unlimited
 
  
 
== 相关资源 ==
 
== 相关资源 ==
  
*[http://www.freedesktop.org/wiki/Software/systemd 官方网站]
+
*[[Wikipedia:systemd|Wikipedia article]]
*[http://0pointer.de/public/systemd-man/ man 手册页]
+
*[http://www.freedesktop.org/wiki/Software/systemd systemd Official web site]
*[http://freedesktop.org/wiki/Software/systemd/Optimizations systemd 优化]
+
*[http://www.freedesktop.org/wiki/Software/systemd/Optimizations systemd optimizations]
*[http://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions 常见问题 FAQ]
+
*[http://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions systemd FAQ]
*[http://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks 小技巧]
+
*[http://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks systemd Tips and tricks]
 +
*[http://wiki.gentoo.org/wiki/Systemd Gentoo Wiki systemd page]
 +
*[http://fedoraproject.org/wiki/Systemd Fedora Project - About systemd]
 +
*[http://fedoraproject.org/wiki/How_to_debug_Systemd_problems Fedora Project - How to debug systemd problems]
 +
*[http://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet Fedora Project - SysVinit to systemd cheatsheet]
 +
*[[debian:systemd|Debian Wiki systemd page]]
 +
*[http://0pointer.de/public/systemd-man/ Manual pages]
 +
*[http://0pointer.de/blog/projects/systemd.html Lennart's blog story], [http://0pointer.de/blog/projects/systemd-update.html update 1], [http://0pointer.de/blog/projects/systemd-update-2.html update 2], [http://0pointer.de/blog/projects/systemd-update-3.html update 3], [http://0pointer.de/blog/projects/why.html summary]
 
*[http://0pointer.de/public/systemd-ebook-psankar.pdf systemd for Administrators (PDF)]
 
*[http://0pointer.de/public/systemd-ebook-psankar.pdf systemd for Administrators (PDF)]
*[http://fedoraproject.org/wiki/Systemd Fedora 项目对 systemd 的介绍]
+
*[https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units How To Use Systemctl to Manage Systemd Services and Units ]
*[http://fedoraproject.org/wiki/How_to_debug_Systemd_problems 如何调试 systemd 故障]
+
*[https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/ Session management with systemd-logind]
*''The H Open'' 杂志上的[http://www.h-online.com/open/features/Control-Centre-The-systemd-Linux-init-system-1565543.html ][http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html ]科普文章
+
*[[Emacs#Syntax highlighting for systemd Files|Emacs Syntax highlighting for Systemd files]]
*[http://0pointer.de/blog/projects/systemd.html Lennart 的博文]
+
*[http://www.h-online.com/open/features/Control-Centre-The-systemd-Linux-init-system-1565543.html Two] [http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html part] introductory article in ''The H Open'' magazine.
*[http://0pointer.de/blog/projects/systemd-update.html 更新报告]
 
*[http://0pointer.de/blog/projects/systemd-update-2.html 更新报告2]
 
*[http://0pointer.de/blog/projects/systemd-update-3.html 更新报告3]
 
*[http://0pointer.de/blog/projects/why.html 最新动态]
 
*[https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet/zh Fedora Wiki 上的 SysVinit 和 systemd 命令对比表]
 

Latest revision as of 08:45, 14 July 2018

翻译状态: 本文是英文页面 Systemd翻译,最后翻译时间:2018-05-09,点击这里可以查看翻译后英文页面的改动。

摘自项目主页

systemd 是一个 Linux 系统基础组件的集合,提供了一个系统和服务管理器,运行为 PID 1 并负责启动其它程序。功能包括:支持并行化任务;同时采用 socket 式与 D-Bus 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 cgroups 监视进程;支持快照和系统恢复;维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。systemd 支持 SysV 和 LSB 初始脚本,可以替代 sysvinit。除此之外,功能还包括日志进程、控制基础系统配置,维护登陆用户列表以及系统账户、运行时目录和设置,可以运行容器和虚拟机,可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。
注意: Arch Linux 论坛的这篇帖子 详细地解释了 Arch Linux 迁移到 systemd 的原因。

systemd 基本工具

监视和控制systemd的主要命令是systemctl。该命令可用于查看系统状态和管理系统及服务。详见systemctl(1)。、

提示:
  • systemctl 参数中添加 -H <用户名>@<主机名> 可以实现对其他机器的远程控制。该功能使用 SSH 连接。
  • Plasma 用户可以安装 systemctl 图形前端 systemd-kcmAUR。安装后可以在 System administration 下找到。

分析系统状态

显示 系统状态

$ systemctl status

输出激活的单元:

$ systemctl

以下命令等效:

$ systemctl list-units

输出运行失败的单元:

$ systemctl --failed

所有可用的单元文件存放在 /usr/lib/systemd/system//etc/systemd/system/ 目录(后者优先级更高)。查看所有已安装服务:

$ systemctl list-unit-files

使用单元

一个单元配置文件可以描述如下内容之一:系统服务(.service)、挂载点(.mount)、sockets(.sockets) 、系统设备(.device)、交换分区(.swap)、文件路径(.path)、启动目标(.target)、由 systemd 管理的计时器(.timer)。详情参阅 systemd.unit(5)

使用 systemctl 控制单元时,通常需要使用单元文件的全名,包括扩展名(例如 sshd.service )。但是有些单元可以在 systemctl 中使用简写方式。

  • 如果无扩展名,systemctl 默认把扩展名当作 .service 。例如 netcfgnetcfg.service 是等价的。
  • 挂载点会自动转化为相应的 .mount 单元。例如 /home 等价于 home.mount
  • 设备会自动转化为相应的 .device 单元,所以 /dev/sda2 等价于 dev-sda2.device
注意: 有一些单元的名称包含一个 @ 标记(例如: name@string.service ),这意味着它是模板单元 name@.service 的一个 实例string 被称作实例标识符,在 systemctl 调用模板单元时,会将其当作一个参数传给模板单元,模板单元会使用这个传入的参数代替模板中的 %I 指示符。

在实例化之前,systemd 会先检查 name@string.suffix 文件是否存在(如果存在,就直接使用这个文件,而不是模板实例化)。大多数情况下,包含 @ 标记都意味着这个文件是模板。如果一个模板单元没有实例化就调用,该调用会返回失败,因为模板单元中的 %I 指示符没有被替换。

提示:
  • 下面的大部分命令都可以跟多个单元名, 详细信息参见 systemctl(1)
  • systemctl命令在enabledisablemask子命令中增加了--now选项,可以实现激活的同时启动服务,取消激活的同时停止服务。
  • 一个软件包可能会提供多个不同的单元。如果你已经安装了软件包,可以通过pacman -Qql package | grep systemd命令检查这个软件包提供了哪些单元。

立即激活单元:

# systemctl start <单元>

立即停止单元:

# systemctl stop <单元>

重启单元:

# systemctl restart <单元>

重新加载配置:

# systemctl reload <单元>

输出单元运行状态:

$ systemctl status <单元>

检查单元是否配置为自动启动:

$ systemctl is-enabled <单元>

开机自动激活单元:

# systemctl enable <单元>

设置单元为自动启动并立即启动这个单元:

# systemctl enable --now unit

取消开机自动激活单元:

# systemctl disable <单元>

禁用一个单元(禁用后,间接启动也是不可能的):

# systemctl mask <单元>

取消禁用一个单元:

# systemctl unmask <单元>

显示单元的手册页(必须由单元文件提供):

# systemctl help <单元>

重新载入 systemd,扫描新的或有变动的单元:

# systemctl daemon-reload

电源管理

安装 polkit 后才能以普通用户身份使用电源管理。

如果你正登录在一个本地的 systemd-logind 用户会话,且当前没有其它活动的会话,那么以下命令无需 root 权限即可执行。否则(例如,当前有另一个用户登录在某个 tty ), systemd 将会自动请求输入root密码。

重启:

$ systemctl reboot

退出系统并关闭电源:

$ systemctl poweroff

待机:

$ systemctl suspend

休眠:

$ systemctl hibernate

混合休眠模式(同时休眠到硬盘并待机):

$ systemctl hybrid-sleep

编写单元文件

systemd 单元文件的语法来源于 XDG 桌面项配置文件.desktop文件,最初的源头则是Microsoft Windows的.ini文件。单元文件可以从多个地方加载,systemctl show --property=UnitPath 可以按优先级从低到高显示加载目录:

  • /usr/lib/systemd/system/ :软件包安装的单元
  • /etc/systemd/system/ :系统管理员安装的单元
注意:
  • systemd 运行在用户模式下时,使用的加载路径是完全不同的。
  • systemd 单元名仅能包含 ASCII 字符,下划线和点号和有特殊意义的字符('@', '-')。其它字符需要用 C-style "\x2d" 替换。参阅 systemd.unit(5)systemd-escape(1)

单元文件的语法,可以参考系统已经安装的单元,也可以参考 systemd.service(5) 中的EXAMPLES章节

提示: # 开头的注释可能也能用在 unit-files 中,但是只能在新行中使用。不要在 systemd 的参数后面使用行末注释, 否则 unit 将会启动失败。

处理依赖关系

使用 systemd 时,可通过正确编写单元配置文件来解决其依赖关系。典型的情况是,单元 A 要求单元 BA 启动之前运行。在此情况下,向单元 A 配置文件中的 [Unit] 段添加 Requires=BAfter=B 即可。若此依赖关系是可选的,可添加 Wants=BAfter=B 。请注意 Wants=Requires= 并不意味着 After= ,即如果 After= 选项没有制定,这两个单元将被并行启动。

依赖关系通常被用在服务(service)而不是目标(target)上。例如, network.target 一般会被某个配置网络接口的服务引入,所以,将自定义的单元排在该服务之后即可,因为 network.target 已经启动。

服务类型

编写自定义的 service 文件时,可以选择几种不同的服务启动方式。启动方式可通过配置文件 [Service] 段中的 Type= 参数进行设置。

  • Type=simple :(默认值) systemd认为该服务将立即启动。服务进程不会 fork 。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket 激活型。
  • Type=forking :systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定 PIDFile=,以便 systemd 能够跟踪服务的主进程。
  • Type=oneshot :这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
  • Type=notify :与 Type=simple 相同,但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由 libsystemd-daemon.so 提供。
  • Type=dbus :若以此方式启动,当指定的 BusName 出现在DBus系统总线上时,systemd认为服务就绪。
  • Type=idlesystemd会等待所有任务处理完成后,才开始执行 idle 类型的单元。其他行为与 Type=simple 类似。

type 的更多解释可以参考 systemd.service(5)

修改现存单元文件

为了避免和 pacman 冲突,不应该直接编辑软件包提供的文件。有两种方法可以不改动原始文件就做到修改单元文件:创建一个优先级更高的本地单元文件或创建一个片段,应用到原始单元文件之上。两种方法都需要在修改后重新加载单元,用 systemctl edit 编辑单元(会自动重载单元)或通过下面命令重新加载单元:

# systemctl daemon-reload
提示:
  • systemd-delta 命令用来查看哪些单元文件被覆盖、哪些被修改。系统维护的时候需要及时了解哪些单元已经有了更新。
  • 使用 systemctl cat unit 可以查看单元的内容和所有相关的片段.
  • 安装 vim-systemd 软件包,可以使单元配置文件在 Vim 下支持语法高亮。

替换单元文件

要替换 /usr/lib/systemd/system/unit, 创建文件 /etc/systemd/system/unit 并重新启用单元以更新链接:

# systemctl reenable unit

或者运行:

# systemctl edit --full unit

这将会在记事本中打开 /etc/systemd/system/unit,如果文件不存在,可以将安装的版本复制到这里,在编辑完成之后,会自动加载新版本。

注意: 即使 Pacman 更新了新的单元文件,软件包中的版本也不会被使用,所以这个方式会增加系统维护的难度,推荐使用下面一种方法。

附加配置片段

要附加配置片段,先创建名为 /etc/systemd/system/<单元名>.d/ 的目录,然后放入 *.conf 文件,其中可以添加或重置参数。这里设置的参数优先级高于原来的单元文件。下面的更新方式比较简单:

# systemctl edit unit

这将会在编辑器中打开文件 /etc/systemd/system/unit.d/override.conf,编辑完成之后自动加载。

Note: 并不是所有参数都会被子配置文件覆盖。例如要修改 Conflicts= 就必须 替换原始文件

重置到软件包版本

要回退单元的变更,使用 systemctl edit 并执行:

# systemctl revert unit

示例

例如,如果想添加一个额外的依赖,创建如下文件即可:

/etc/systemd/system/<unit>.d/customdependency.conf
[Unit]
Requires=<新依赖>
After=<新依赖>

要修改一个非 oneshot 单元的 ExecStart 命令,创建下面文件:

/etc/systemd/system/unit.d/customexec.conf
[Service]
ExecStart=
ExecStart=new command

修改 ExecStart 前必须将其置空,参见 ([1] 。所有可能多次赋值的变量都需要这个操作,例如定时器的 OnCalendar

下面是自动重启服务的一个例子:

/etc/systemd/system/unit.d/restart.conf
[Service]
Restart=always
RestartSec=30

目标(target)

运行级别(runlevel)是一个旧的概念。现在,systemd 引入了一个和运行级别功能相似又不同的概念——目标(target)。不像数字表示的启动级别,每个目标都有名字和独特的功能,并且能同时启用多个。一些目标继承其他目标的服务,并启动新服务。systemd 提供了一些模仿 sysvinit 运行级别的目标,仍可以使用旧的 telinit 运行级别 命令切换。

获取当前目标

不要使用 runlevel 命令了:

$ systemctl list-units --type=target

创建新目标

在 Fedora 中,运行级别 0、1、3、5、6 都被赋予特定用途,并且都对应一个 systemd 的目标。然而,移植用户定义的运行级别(2、4)没有什么好方法。要实现类似功能,可以以原有的启动级别为基础,创建一个新的目标 /etc/systemd/system/<新目标>(可以参考 /usr/lib/systemd/system/graphical.target),创建 /etc/systemd/system/<新目标>.wants 目录,向其中加入额外服务的链接(指向 /usr/lib/systemd/system/ 中的单元文件)。

目标表

SysV 运行级别 Systemd 目标 注释
0 runlevel0.target, poweroff.target 中断系统(halt)
1, s, single runlevel1.target, rescue.target 单用户模式
2, 4 runlevel2.target, runlevel4.target, multi-user.target 用户自定义运行级别,通常识别为级别3。
3 runlevel3.target, multi-user.target 多用户,无图形界面。用户可以通过终端或网络登录。
5 runlevel5.target, graphical.target 多用户,图形界面。继承级别3的服务,并启动图形界面服务。
6 runlevel6.target, reboot.target 重启
emergency emergency.target 急救模式(Emergency shell)

切换运行级别/目标

systemd 中,运行级别通过“目标单元”访问。通过如下命令切换:

# systemctl isolate graphical.target

该命令对下次启动无影响。等价于telinit 3telinit 5

修改默认运行级别/目标

开机启动的目标是 default.target,默认链接到 graphical.target (大致相当于原来的运行级别5)。可以通过内核参数更改默认运行级别:

  • systemd.unit=multi-user.target (大致相当于级别3)
  • systemd.unit=rescue.target (大致相当于级别1)

另一个方法是修改 default.target。可以通过 systemctl 修改它:

# systemctl set-default multi-user.target

临时文件

/usr/lib/tmpfiles.d//etc/tmpfiles.d/ 中的文件描述了 systemd-tmpfiles 如何创建、清理、删除临时文件和目录,这些文件和目录通常存放在 /run/tmp 中。配置文件名称为 /etc/tmpfiles.d/<program>.conf。此处的配置能覆盖 /usr/lib/tmpfiles.d/ 目录中的同名配置。

临时文件通常和服务文件同时提供,以生成守护进程需要的文件和目录。例如 Samba 服务需要目录 /run/samba 存在并设置正确的权限位,就象这样:

/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root

此外,临时文件还可以用来在开机时向特定文件写入某些内容。比如,要禁止系统从USB设备唤醒,利用旧的 /etc/rc.local 可以用 echo USBE > /proc/acpi/wakeup,而现在可以这么做:

/etc/tmpfiles.d/disable-usb-wake.conf
w /proc/acpi/wakeup - - - - USBE

详情参见systemd-tmpfiles(8)tmpfiles.d(5)

注意: 该方法不能向 /sys 中的配置文件添加参数,因为 systemd-tmpfiles-setup 有可能在相关模块加载前运行。这种情况下,需要首先通过 modinfo <模块名> 确认需要的参数,然后在 /etc/modprobe.d 目录下的配置文件[broken link: invalid section]中修改配置参数。另外,还可以使用 udev 规则,在设备就绪时设置相应属性。

定时器

一个定时器是一个以 .timer 为结尾的单元配置文件并包含由 systemd 控制和监督的信息。systemd/Timers (简体中文)

注意: 定时器很大程度上可取代 cronsystemd/Timers (简体中文)#替代 cron

挂载

因为 systemd 也负责按 /etc/fstab 挂载目录。在系统启动和重新加载系统管理器时,systemd-fstab-generator(8) 会将 /etc/fstab 中的配置转化为 systemd 单元。

systemd 扩展了 fstab 的传统功能,提供了额外的挂载选项。例如可以确保一个挂载仅在网络已经连接时进行,或者仅当另外一个分区已挂载时再挂载。这些选项通常以 x-systemd. 开头,systemd.mount(5) 中包含了完整说明。

automounting 也是一个例子,可以在使用时,而不是启动时挂载分区,详情请参考 fstab#Automount with systemd

日志

systemd 提供了自己的日志系统(logging system),称为 journal。使用 systemd 日志,无需额外安装日志服务(syslog)。读取日志的命令:

# journalctl

默认情况下(当 Storage= 在文件 /etc/systemd/journald.conf 中被设置为 auto),日志记录将被写入 /var/log/journal/。该目录是 systemd 软件包的一部分。若被删除,systemd 不会自动创建它,直到下次升级软件包时重建该目录。如果该目录缺失,systemd 会将日志记录写入 /run/systemd/journal。这意味着,系统重启后日志将丢失。

提示: 如果 /var/log/journal/ 位于 btrfs 文件系统,应该考虑对这个目录禁用写入时复制,方法参阅Btrfs#Copy-on-Write (CoW)

Systemd 日志事件提示信息的记录安装优先级和更能进行分离,符合经典的 BSD syslog 协议风格(维基百科RFC 5424)。

优先级

A syslog severity code (in systemd called priority) is used to mark the importance of a message RFC 5424 Section 6.2.1.

Value Severity Keyword Description Examples
0 Emergency emerg System is unusable Severe Kernel BUG, systemd dumped core.
This level should not be used by applications.
1 Alert alert Should be corrected immediately Vital subsystem goes out of work. Data loss.
kernel: BUG: unable to handle kernel paging request at ffffc90403238ffc.
2 Critical crit Critical conditions Crashes, coredumps. Like familiar flash:
systemd-coredump[25319]: Process 25310 (plugin-containe) of user 1000 dumped core
Failure in the system primary application, like X11.
3 Error err Error conditions Not severe error reported:
kernel: usb 1-3: 3:1: cannot get freq at ep 0x84,
systemd[1]: Failed unmounting /var.,
libvirtd[1720]: internal error: Failed to initialize a valid firewall backend).
4 Warning warning May indicate that an error will occur if action is not taken. A non-root file system has only 1GB free.
org.freedesktop. Notifications[1860]: (process:5999): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale.
5 Notice notice Events that are unusual, but not error conditions. systemd[1]: var.mount: Directory /var to mount over is not empty, mounting anyway. gcr-prompter[4997]: Gtk: GtkDialog mapped without a transient parent. This is discouraged.
6 Informational info Normal operational messages that require no action. lvm[585]: 7 logical volume(s) in volume group "archvg" now active.
7 Debug debug Information useful to developers for debugging the application. kdeinit5[1900]: powerdevil: Scheduling inhibition from ":1.14" "firefox" with cookie 13 and reason "screen".

If issue you are looking for, was not found on according level, search it on couple of priority levels above and below. This rules are recommendations. Some errors considered a normal occasion for program so they marked low in priority by developer, and on the contrary, sometimes too many messages plaques too high priorities for them, but often it's an arguable situation. And often you really should solve an issue, also to understand architecture and adopt best practices.

Examples:

  • Info message:
    pulseaudio[2047]: W: [pulseaudio] alsa-mixer.c: Volume element Master has 8 channels. That's too much! I can't handle that!
    It is an warning or error by definition.
  • Plaguing alert message:
    sudo[21711]:     user : a password is required ; TTY=pts/0 ; PWD=/home/user ; USER=root ; COMMAND=list /usr/bin/pacman --color auto -Sy
    The reason - user was manually added to sudoers file, not to wheel group, which is arguably normal action, but sudo produced an alert on every occasion.

功能

A syslog facility code is used to specify the type of program that is logging the message RFC 5424 Section 6.2.1.

Facility code Keyword Description Info
0 kern kernel messages
1 user user-level messages
2 mail mail system Archaic POSIX still supported and sometimes used system, for more mail(1))
3 daemon system daemons All deamons, including systemd and its subsystems
4 auth security/authorization messages Also watch for different facility 10
5 syslog messages generated internally by syslogd As it standartized for syslogd, not used by systemd (see facility 3)
6 lpr line printer subsystem (archaic subsystem)
7 news network news subsystem (archaic subsystem)
8 uucp UUCP subsystem (archaic subsystem)
9 clock daemon systemd-timesyncd
10 authpriv security/authorization messages Also watch for different facility 4
11 ftp FTP daemon
12 - NTP subsystem
13 - log audit
14 - log alert
15 cron scheduling daemon
16 local0 local use 0 (local0)
17 local1 local use 1 (local1)
18 local2 local use 2 (local2)
19 local3 local use 3 (local3)
20 local4 local use 4 (local4)
21 local5 local use 5 (local5)
22 local6 local use 6 (local6)
23 local7 local use 7 (local7)

So, useful facilities to watch: 0,1,3,4,9,10,15.

过滤输出

journalctl可以根据特定字段过滤输出。如果过滤的字段比较多,需要较长时间才能显示出来。

示例:

显示本次启动后的所有日志:

# journalctl -b

不过,一般大家更关心的不是本次启动后的日志,而是上次启动时的(例如,刚刚系统崩溃了)。可以使用 -b 参数:

  • journalctl -b -0 显示本次启动的信息
  • journalctl -b -1 显示上次启动的信息
  • journalctl -b -2 显示上上次启动的信息 journalctl -b -2
  • 只显示错误、冲突和重要告警信息
    # journalctl -p err..alert
    也可以使用数字, journalctl -p 3..1。If single number/keyword used, journalctl -p 3 - all higher priority levels also included.
  • 显示从某个日期 ( 或时间 ) 开始的消息:
    # journalctl --since="2012-10-30 18:17:16"
  • 显示从某个时间 ( 例如 20分钟前 ) 的消息:
    # journalctl --since "20 min ago"
  • 显示最新信息
    # journalctl -f
  • 显示特定程序的所有消息:
    # journalctl /usr/lib/systemd/systemd
  • 显示特定进程的所有消息:
    # journalctl _PID=1
  • 显示指定单元的所有消息:
    # journalctl -u netcfg
  • 显示内核环缓存消息r:
    # journalctl -k
  • Show auth.log equivalent by filtering on syslog facility:
    # journalctl -f -l SYSLOG_FACILITY=10

详情参阅journalctl(1)systemd.journal-fields(7),以及 Lennert 的这篇博文

日志大小限制

如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果 /var/log/journal 储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改配置文件指定最大限制。如限制日志最大 50MiB:

/etc/systemd/journald.conf
SystemMaxUse=50M

还可以通过配置片段而不是全局配置文件进行设置:

/etc/systemd/journald.conf.d/00-journal-size.conf
[Journal]
SystemMaxUse=50M

修改配置后要立即生效,请重启 systemd-journald.service 服务。

详情参见 journald.conf(5).

配合 syslog 使用

systemd 提供了 socket /run/systemd/journal/syslog,以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 /dev/log官方说明)。Arch 软件仓库中的 syslog-ng 已经包含了需要的配置。

journald.conf 使用 no 转发socket . 为了使 syslog-ng 配合 journald , 你需要在 /etc/systemd/journald.conf 中设置 ForwardToSyslog=yes . 参阅 Syslog-ng#Overview 了解更多细节.

如果你选择使用 rsyslogAUR , 因为 rsyslog 从日志中 直接 传出消息,所以不再必要改变那个选项..

设置开机启动 syslog-ng:

 # systemctl enable syslog-ng

这里有一份很不错的 journalctl 指南。

手动清理日志

/var/log/journal 存放着日志, rm 应该能工作. 或者使用journalctl,

例如:

  • 清理日志使总大小小于 100M:
    # journalctl --vacuum-size=100M
  • 清理最早两周前的日志.
    # journalctl --vacuum-time=2weeks

参阅 journalctl(1) 获得更多信息.

Journald in conjunction with syslog

Compatibility with a classic, non-journald aware syslog implementation can be provided by letting systemd forward all messages via the socket /run/systemd/journal/syslog. To make the syslog daemon work with the journal, it has to bind to this socket instead of /dev/log (official announcement).

As of systemd 216 the default journald.conf for forwarding to the socket was changed to ForwardToSyslog=no to avoid system overhead, because rsyslog or syslog-ng (since 3.6) pull the messages from the journal by itself.

See Syslog-ng#Overview and Syslog-ng#syslog-ng and systemd journal, or rsyslog respectively, for details on configuration.

转发 journald 到 /dev/tty12

建立一个 drop-in directory[broken link: invalid section] /etc/systemd/journald.conf.d 然后在其中建立 fw-tty12.conf :

/etc/systemd/journald.conf.d/fw-tty12.conf
[Journal]
ForwardToConsole=yes
TTYPath=/dev/tty12
MaxLevelConsole=info

然后重新启动 systemd-journald.

查看特定位置的日志

有时你希望查看另一个系统上的日志.例如从 Live 环境修复现存的系统.

这种情况下你可以挂载目标系统 ( 例如挂载到 /mnt ),然后用 -D/--directory 参数指定目录,像这样:

$ journalctl -D /mnt/var/log/journal -xe

Tips and tricks

Running services after the network is up

To delay a service after the network is up, include the following dependencies in the .service file:

/etc/systemd/system/foo.service
[Unit]	
...
Wants=network-online.target
After=network-online.target	
...

The network wait service of the particular application that manages the network, must also be enabled so that network-online.target properly reflects the network status.

  • For the ones using NetworkManager, enable NetworkManager-wait-online.service.
  • If using systemd-networkd, systemd-networkd-wait-online.service is by default enabled automatically whenever systemd-networkd.service has been enabled; check this is the case with systemctl is-enabled systemd-networkd-wait-online.service, there is no other action needed.

For more detailed explanations see Running services after the network is up in the systemd wiki.

Enable installed units by default

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: How does it work with instantiated units? (Discuss in Talk:Systemd (简体中文)#)

Arch Linux ships with /usr/lib/systemd/system-preset/99-default.preset containing disable *. This causes systemctl preset to disable all units by default, such that when a new package is installed, the user must manually enable the unit.

If this behavior is not desired, simply create a symlink from /etc/systemd/system-preset/99-default.preset to /dev/null in order to override the configuration file. This will cause systemctl preset to enable all units that get installed—regardless of unit type—unless specified in another file in one systemctl preset's configuration directories. User units are not affected. See the manpage for systemd.preset for more information.

Note: Enabling all units by default may cause problems with packages that contain two or more mutually exclusive units. systemctl preset is designed to be used by distributions and spins or system administrators. In the case where two conflicting units would be enabled, you should explicitly specify which one is to be disabled in a preset configuration file as specified in the manpage for systemd.preset.

Sandboxing application environments

A unit file can be created as a sandbox to isolate applications and their processes within a hardened virtual environment. systemd leverages namespaces, white-/blacklisting of Capabilities, and control groups to container processes through an extensive execution environment configuration.

The enhancement of an existing systemd unit file with application sandboxing typically requires trial-and-error tests accompanied by the generous use of strace, stderr and journalctl error logging and output facilities. You may want to first search upstream documentation for already done tests to base trials on.

Some examples on how sandboxing with systemd can be deployed:

  • CapabilityBoundingSet defines a whitelisted set of allowed capabilities, but may also be used to blacklist a specific capability for a unit.
    • The CAP_SYS_ADM capability, for example, which should be one of the goals of a secure sandbox: CapabilityBoundingSet=~ CAP_SYS_ADM

疑难解答

寻找错误

这个例子中的失败的服务是 systemd-modules-load :

1. 通过 systemd 寻找启动失败的服务:

$ systemctl --state=failed
systemd-modules-load.service   loaded failed failed  Load Kernel Modules

或者使用 systemd 消息:

$ journalctl -fp err

2. 我们发现了启动失败的 systemd-modules-load 服务. 我们想知道更多信息:

$ systemctl status systemd-modules-load
systemd-modules-load.service - Load Kernel Modules
   Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
   Active: failed (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
     Docs: man:systemd-modules-load.service(8).
           man:modules-load.d(5)
  Process: 15630 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)

如果没列出 Process ID, 通过 systemctl 重新启动失败的服务 ( 例如 systemctl restart systemd-modules-load )

3. 现在得到了 PID ,你就可以进一步探查错误的详细信息了.通过下列的命令收集日志,PID 参数是你刚刚得到的 Process ID (例如 15630):

$ journalctl -b _PID=15630
-- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. --
Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'blacklist usblp'
Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'install usblp /bin/false'

4. 我们发现有些内核模块的配置文件不正确,因此在 /etc/modules-load.d/ 中检查一下:

$ ls -Al /etc/modules-load.d/
...
-rw-r--r--   1 root root    79  1. Dez 2012  blacklist.conf
-rw-r--r--   1 root root     1  2. Mär 14:30 encrypt.conf
-rw-r--r--   1 root root     3  5. Dez 2012  printing.conf
-rw-r--r--   1 root root     6 14. Jul 11:01 realtek.conf
-rw-r--r--   1 root root    65  2. Jun 23:01 virtualbox.conf
...

5. 错误消息 Failed to find module 'blacklist usblp' 也许和 blacklist.conf 相关. 让我们注释掉第三步发现的错误的选项:

/etc/modules-load.d/blacklist.conf
# blacklist usblp
# install usblp /bin/false

6. 最后重新启动 systemd-modules-load 服务:

$ systemctl start systemd-modules-load

如果服务成功启动,不会有任何输出.如果你还是遇到了错误,回到步骤三,获得新的 PID 来跟踪日志并解决错误.

可以像这样确认服务成功启动:

$ systemctl status systemd-modules-load
systemd-modules-load.service - Load Kernel Modules
   Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
   Active: active (exited) since So 2013-08-25 12:22:31 CEST; 34s ago
     Docs: man:systemd-modules-load.service(8)
           man:modules-load.d(5)
 Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
Aug 25 12:22:31 mypc systemd[1]: Started Load Kernel Modules.

诊断启动问题

使用如下内核参数引导: systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M

更多有关调试的信息,参见该文

诊断一个服务

如果某个 systemd 服务的工作状况不合预期,希望调试的话,设置 SYSTEMD_LOG_LEVEL 环境变量debug . 例如以调试模式运行 systemd-networkd 服务:

在此服务的配置文件片段中加入:

[Service]
Environment=SYSTEMD_LOG_LEVEL=debug

或者等价的,临时编辑系统单元文件,例如:

  1. SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd

重启 systemd-networkd 服务,用 --follow 选项检查日志。

关机/重启十分缓慢

如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再尝试杀死它。请阅读这篇文章,确认你是否是该问题受害者。

短时进程无日志记录

journalctl -u foounit.service 没有显示某个短时进程的任何输出,那么改用 PID 试试。例如,若 systemd-modules-load.service 执行失败,那么先用 systemctl status systemd-modules-load 查询其 PID(比如是123),然后检索该 PID 相关的日志 journalctl -b _PID=123。运行时进程的日志元数据(诸如 _SYSTEMD_UNIT 和 _COMM)被乱序收集在 /proc 目录。要修复该问题,必须修改内核,使其通过套接字连接来提供上述数据,该过程类似于 SCM_CREDENTIALS。

禁止在程序崩溃时转储内存

要使用老的内核转储,创建下面文件:

/etc/sysctl.d/49-coredump.conf
kernel.core_pattern = core
kernel.core_uses_pid = 0

然后运行:

# /usr/lib/systemd/systemd-sysctl

同样可能需要执行“unlimit”设置文件大小:

$ ulimit -c unlimited

更多信息请参阅 sysctl.d/proc/sys/kernel 文档

启动的时间太长

不少用户用了 systemd-analyze 命令以后报告启动的时间比预计的要长,通常会说 systemd-analyze 分析结果表示 NetworkManager 占据了太多的启动的时间.

有些用户的问题是 /var/log/journal 文件夹似乎过大.这也许也会对像systemctl statusjournalctl 的命令有影响.一种解决方案是删除其中的文件 (但最好将它们备份到某处) 然后限制日志文件的大小.

systemd-tmpfiles-setup.service 在启动时启动失败

从 systemd 219 开始, /usr/lib/tmpfiles.d/systemd.conf 指定 /var/log/journal 的 ACL 属性和目录, 因此日志所在的文件系统上要启用ACL.

参阅 Access Control Lists#Enabling ACL 获得如何包含 /var/log/journal 启动 ACL 的详细信息.

启动时显示的 systemd 版本和安装版本不一致

需要 重新生成 initramfs

提示: 可以使用 pacman 钩子在更新 systemd时重新生成 initramfs。参考 这个帖子Pacman#Hooks.

禁用远程机器的 emergency 模式

如果远程机器位于云主机,emergency 模式会导致系统无法远程连接,可以通过下面方式禁用紧急模式:

# systemctl mask emergency.service
# systemctl mask emergency.target

相关资源