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

From ArchWiki
Jump to: navigation, search
m (时区: rm space)
(simplification and beautification of wikilinks, fixing whitespace, capitalization and section fragments (https://github.com/lahwaacz/wiki-scripts/blob/master/link-checker.py (interactive)))
 
(119 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 (简体中文)]]
 +
[[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]]
 +
[[pt:Systemd]]
 
[[ru:Systemd]]
 
[[ru:Systemd]]
[[zh-TW:Systemd]]
+
[[zh-tw:Systemd]]
{{Article summary start}}
+
{{Related articles start (简体中文)}}
{{Article summary text|本文介绍 Systemd 的安装和配置。}}
+
{{Related|systemd/User (简体中文)}}
{{Article summary heading|相关页面}}
+
{{Related|Systemd FAQ (简体中文)}}
{{Article summary wiki|Systemd/Services}}
+
{{Related|init Rosetta}}
{{Article summary wiki|systemd/User}}
+
{{Related|Daemons#List of deamons}}
{{Article summary wiki|Systemd FAQ}}
+
{{Related|udev (简体中文)}}
{{Article summary wiki|Init to systemd cheatsheet}}
+
{{Related|Improve Boot Performance (简体中文)}}
{{Article summary wiki|udev (简体中文)}}
+
{{Related|Allow users to shutdown}}
{{Article summary end}}
+
{{Related articles end}}
{{TranslationStatus (简体中文)|Systemd|2012-11-13|235107}}
+
{{TranslationStatus (简体中文)|Systemd|2016-03-16|417725}}
 
摘自[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 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本。systemd 的特性有:支持并行化任务;同时采用 socket 式与 [[D-Bus (简体中文)|D-Bus]] 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 [[cgroups]] 监视进程;支持快照和系统恢复;维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。''
  
{{提示|[https://bbs.archlinux.org/viewtopic.php?pid=1149530#p1149530 这个帖子]详细解释了 Arch systemd 迁移的原因。}}
+
{{Note|1= [https://bbs.archlinux.org/viewtopic.php?pid=1149530#p1149530 Arch Linux 论坛的这篇帖子] 详细的解释了 Arch Linux 迁移到 systemd 的原因.}}
  
另见[[Wikipedia:Systemd|维基百科上的介绍]]。
 
  
== 迁移前需考虑 ==
+
== systemd 基本工具 ==
  
* 最好先参照 [[rc.conf (简体中文)]] 按照最新格式配置 '''initscripts'''。完成后,基本上就没什么需要配置的了。
+
检视和控制systemd的主要命令是{{ic|systemctl}}。该命令可用于查看系统状态和管理系统及服务。详见{{ic|man 1 systemctl}}。
* 阅读[http://freedesktop.org/wiki/Software/systemd/ 该站],了解 systemd。
+
* systemd 自己有一套日志('''journal''')系统,用于代替 '''syslog'''。两者也可以共存,参见后面的日志部分。
+
* 虽然 systemd 可以替换 '''cron'''、'''acpid'''、'''xinetd''' 等的部分功能。至少目前还可以继续使用这些服务,无需立即切换。
+
* 交互 initscripts 在 systemd 中无法工作。例如 '''netcfg-menu''' [https://bugs.archlinux.org/task/31377 无法]在启动时显示。
+
  
== 安装 ==
+
{{小贴士|
{{注意|[https://www.archlinux.org/news/systemd-is-now-the-default-on-new-installations/ 2012-10-13]开始,安装程序已经默认安装{{pkg|systemd}} {{pkg|systemd-sysvcompat}}}}
+
* 在 {{ic|systemctl}} 参数中添加 {{ic|-H <用户名>@<主机名>}} 可以实现对其他机器的远程控制。该过程使用 [[SSH (简体中文)|SSH]]连接。
 +
* {{ic|systemadm}} 是 systemd 的官方图形前端。[[official repositories|官方软件仓库]] 提供了稳定版本 {{Pkg|systemd-ui}}
 +
* [[Plasma]] 用户可以安装 ''systemctl'' 图形前端 {{Pkg|systemd-kcm}}。安装后可以在 ''System administration'' 下找到}}
  
本部分帮助还在使用{{pkg|sysvinit}} 和 {{pkg|initscripts}} 的用户迁移到{{pkg|systemd}}.
+
=== 分析系统状态 ===
  
# 从[[Official_Repositories_(简体中文)|官方软件仓库]]安装 {{pkg|systemd}} 并添加[[Kernel parameters|内核参数]]{{Ic|1=init=/usr/lib/systemd/systemd}}
+
显示 '''系统状态''':
# 用 {{ic|systemctl enable ''daemonname''}} [[#使用单元|启用]] {{ic|/etc/rc.conf}} 中的守护进程。从 {{ic|/etc/rc.conf}} 到 systemd 服务的转换可以参考:[[Daemons_List_(简体中文)|守护进程列表]] 和 [[Systemd/Services|Services]]。
+
# 重启系统,执行命令{{ic|$ cat /proc/1/comm}},如果返回{{ic|systemd}},表示 systemd 已经正常启动。
+
# 删除 {{pkg|initscripts}} 和 {{pkg|sysvinit}},并安装{{pkg|systemd-sysvcompat}}.
+
# 最后,删除{{ic|1=init=/usr/lib/systemd/systemd}}内核参数,现在已经不需要它了。
+
  
=== 附加信息 ===
+
$ systemctl status
* 如果内核参数中有 {{ic|quiet}},可以先删除它以协助调试。
+
* 使用 Systemd 的时候无需将用户加入{{ic|optical}}, {{ic|audio}}, {{ic|scanner}} 等[[Users and Groups|群组]]。加入这些组反而会有问题,例如audio组会导致程序阻塞软件混声。每个 PAM 登录都提供了一个登录会话,本地会话都会通过[[Wikipedia:Access control list|POSIX ACLs]]赋予声音设备访问权限和[[udisks]]移动设备挂载和卸载权限.
+
{{注意|Systemd-logind 替代了[[ConsoleKit]],ConsoleKit 已经从源中删除,系统已 Systemd 启动才能完全正常工作,参阅 [https://www.archlinux.org/news/consolekit-replaced-by-logind/ 新闻通知]。}}
+
  
== 原生 systemd 配置文件 ==
+
输出激活的单元:
{{注意|可能需要手动创建文件,将权限设置为 644,属于 root:root.}}
+
如果下列文件不存在,{{Pkg|systemd}} 会从 {{ic|/etc/rc.conf}} 读取相关配置。这只是一个临时解决方案,建议所有系统都使用 systemd 的配置文件,这也是目前 initscripts 推荐的配置方式。
+
{{小贴士|某些文件可能需要手动创建。}}
+
  
=== 主机名 ===
+
  $ systemctl
The hostname is configured in {{ic|/etc/hostname}}. The file should not contain the system's domain, if any. To set the hostname, do:
+
  # hostnamectl set-hostname '''myhostname'''
+
  
See {{ic|man 5 hostname}} and {{ic|man 1 hostnamectl}} for details.
+
以下命令等效:
  
示例文件:
+
$ systemctl list-units
{{hc|/etc/hostname|
+
myhostname
+
}}
+
  
=== 本地化设置 ===
+
输出运行失败的单元:
The default system locale is configured in {{ic|/etc/locale.conf}}. To set the default locale, do:
+
# localectl set-locale LANG="de_DE.utf8"
+
  
{{Note|Before you set the default locale, you first need to enable locales available to the system by uncommenting them in {{ic|/etc/locale.gen}} and then executing {{ic|locale-gen}} as root. The locale set via {{ic|localectl}} must be one of the '''uncommented''' locales in {{ic|/etc/locale.gen}}.}}
+
$ systemctl --failed
  
See {{ic|man 1 localectl}} and {{ic|man 5 locale.conf}} for details.
+
所有可用的单元文件存放在 {{ic|/usr/lib/systemd/system/}} {{ic|/etc/systemd/system/}} 目录(后者优先级更高)。查看所有已安装服务:
 +
$ systemctl list-unit-files
  
详情请参阅[[Locale]]。
+
=== 使用单元 ===
  
示例文件:
+
一个单元配置文件可以描述如下内容之一:系统服务({{ic|.service}})、挂载点({{ic|.mount}})、sockets({{ic|.sockets}}) 、系统设备({{ic|.device}})、交换分区({{ic|.swap}})、文件路径({{ic|.path}})、启动目标({{ic|.target}})、由 systemd 管理的计时器({{ic|.timer}})。详情参阅 {{ic|man 5 systemd.unit}}
{{hc|/etc/locale.conf|<nowiki>
+
LANG=en_US.utf8
+
</nowiki>}}
+
  
=== 虚拟控制台 ===
+
使用 {{ic|systemctl}} 控制单元时,通常需要使用单元文件的全名,包括扩展名(例如 {{ic|sshd.service}})。但是有些单元可以在{{ic|systemctl}}中使用简写方式。
{{ic|/etc/vconsole.conf}} 文件用来配置虚拟控制台,包括键盘映射和控制台字体:
+
* 如果无扩展名,systemctl 默认把扩展名当作 {{ic|.service}}。例如 {{ic|netcfg}} 和 {{ic|netcfg.service}} 是等价的。
{{hc|/etc/vconsole.conf|<nowiki>
+
* 挂载点会自动转化为相应的 {{ic|.mount}} 单元。例如 {{ic|/home}} 等价于 {{ic|home.mount}}
KEYMAP=us
+
* 设备会自动转化为相应的 {{ic|.device}} 单元,所以 {{ic|/dev/sda2}} 等价于 {{ic|dev-sda2.device}}
FONT=lat9w-16
+
FONT_MAP=8859-1_to_uni</nowiki>}}
+
  
{{Note|{{ic|{{Pkg|systemd}}-194}} uses the kernel font and keymap by default. It is not necessary to have empty {{ic|1=KEYMAP=}} and {{ic|1=FONT=}} settings anymore.}}
+
{{Note|有一些单元的名称包含一个 {{ic|@}} 标记, (e.g. {{ic|name@''string''.service}}): 这意味着它是模板单元 {{ic|name@.service}} 的一个 [http://0pointer.de/blog/projects/instances.html 实例]。 {{ic|''string''}} 被称作实例标识符, 在 ''systemctl'' 调用模板单元时,会将其当作一个参数传给模板单元,模板单元会使用这个传入的参数代替模板中的 {{ic|%I}} 指示符。
  
Another way to set the keyboard mapping (keymap) is doing:
+
在实例化之前,''systemd'' 会先检查 {{ic|name@string.suffix}} 文件是否存在(如果存在,应该就是直接使用这个文件,而不是模板实例化了)。大多数情况下,包换 {{ic|@}} 标记都意味着这个文件是模板。如果一个模板单元没有实例化就调用,该调用会返回失败,因为模板单元中的 {{ic|%I}} 指示符没有被替换。
# localectl set-keymap de
+
}}
  
This has the advantage that it will also set the same keymap for use in X11.
+
{{Tip|
See {{ic|man 1 localectl}} and {{ic|man 5 vconsole.conf}} for details.
+
* 下面的大部分命令都可以跟多个单元名, 详细信息参见 {{ic|man systemctl}}
 +
* 从[https://github.com/systemd/systemd/blob/master/NEWS#L323-L326 systemd 220版本]开始, {{ic|systemctl}}命令在{{ic|enable}}、{{ic|disable}}和{{ic|mask}}子命令中增加了{{ic|--now}}选项,可以实现激活的同时启动服务,取消激活的同时停止服务。
 +
* 一个软件包可能会提供多个不同的单元。如果你已经安装了软件包,可以通过{{ic|pacman -Qql ''package'' <nowiki>|</nowiki> grep systemd}}命令检查这个软件包提供了哪些单元。
 +
}}
  
详情参阅 [[Fonts#Console_fonts|控制台字体]]和[[KEYMAP#Keyboard_layouts|Keymap]].
+
立即激活单元:
  
=== 时区 ===
+
# systemctl start <单元>
The time zone is configured by creating an appropriate {{ic|/etc/localtime}} relative symlink, pointing to a zoneinfo file under {{ic|/usr/share/zoneinfo/}}. To do this automatically:
+
  
  # timedatectl set-timezone Asia/Shanghai
+
立即停止单元:
 +
  # systemctl stop <单元>
  
See {{ic|man 1 timedatectl}}, {{ic|man 5 localtime}}, and {{ic|man 7 archlinux}} for more details.
+
重启单元:
  
手动创建链接也行:
+
  # systemctl restart <单元>
  # ln -sf ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
  
=== 硬件时钟 ===
+
重新加载配置:
  
systemd 默认识别硬件时钟为协调世界时(UTC)。
+
# systemctl reload <单元>
  
{{注意|推荐使用[[NTP (简体中文)|NTP服务]]来确保硬件时钟同步。}}
+
输出单元运行状态:
  
==== Hardware clock in localtime ====
+
$ systemctl status <单元>
  
If you want to change the hardware clock to use local time ('''STRONGLY DISCOURAGED''') do:
+
检查单元是否配置为自动启动:
 +
$ systemctl is-enabled <单元>
  
# timedatectl set-local-rtc true
+
开机自动激活单元:
  
If you want to revert to the hardware clock being in UTC, do:
+
# systemctl enable <单元>
  
# timedatectl set-local-rtc false
+
取消开机自动激活单元:
  
如果设置成本地时间,处理夏令时有些麻烦,如果夏令时调整发生在关机时,下次启动时时间会出现问题([http://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html 更多信息])。最新的内核直接从实时时钟芯片(RTC)读取时间,不使用 {{ic|hwclock}},内核把从 RTC 读取的时间当作 UTC 处理。所以如果硬件时间是地方时,系统启动一开始识别的时间是错误的,之后很快会进行矫正。这可能导致一些问题(尤其是时间倒退时)。
+
# systemctl disable <单元>
  
如果同时安装了 Windows 操作系统([http://blogs.msdn.com/b/oldnewthing/archive/2004/09/02/224672.aspx 默认使用地方时]),那么一般 RTC 会被设置为地方时。Windows 其实也能处理 UTC,在注册表中设置下列DWORD键值为{{ic|1}}即可:
+
禁用一个单元(禁用后,间接启动也是不可能的):
{{bc|HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal}}
+
  
详情参阅[[Time]].
+
# systemctl mask <单元>
  
=== Kernel modules ===
+
取消禁用一个单元:
Today, all necessary module loading is handled automatically by [[udev]], so that, if you don't want/need to use any out-of-tree kernel modules, there is no need to put modules that should be loaded at boot in any config file. However, there are cases where you might want to load an extra module during the boot process, or blacklist another one for your computer to function properly.
+
  
==== 开机加载 ====
+
# systemctl unmask <单元>
systemd 读取 {{ic|/etc/modules-load.d/}} 中的配置加载额外的内核模块。配置文件名称通常为 {{ic|/etc/modules-load.d/<program>.conf}}。格式很简单,一行一个要读取的模块名,而空行以及第一个非空格字符为{{ic|#}}或{{ic|;}}的行会被忽略,如:
+
{{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 help <单元>
禁用内核模块的方法和 Arch 默认的 {{Pkg|initscripts}} 相同,因为该过程实际由 {{Pkg|kmod}} 处理。参见:[[Kernel modules (简体中文)#黑名单]]。
+
  
也可以使用[[#自动挂载|自动挂载]]功能,使得网络文件系统仅在访问时挂载。添加 {{ic|1=x-systemd.device-timeout=超时时间}} 到 {{ic|/etc/fstab}} 的 <options> 部分即可。
+
重新载入 systemd,扫描新的或有变动的单元:
 +
# systemctl daemon-reload
  
详情参见 {{ic|man systemd.mount}}。
+
=== 电源管理 ===
  
=== Filesystem mounts ===
+
安装 [[polkit]] 后才可以一般用户身份使用电源管理。
  
The default setup will automatically fsck and mount filesystems before starting services that need them to be mounted.{{ic|/etc/fstab}} 中设定的网络文件系统(如 [[NFS (简体中文)|NFS]]、[[Samba (简体中文)|Samba]])无需配置即可正常工作,systemd 将确保网络文件系统在网络链接就绪后挂载。{{ic|/etc/fstab}}中设置的本地和远程文件系统应该能够正常工作。
+
如果你正登录在一个本地的{{ic|systemd-logind}}用户会话,且当前没有其它活动的会话,那么以下命令无需root权限即可执行。否则(例如,当前有另一个用户登录在某个tty),systemd 将会自动请求输入root密码。
  
See {{ic|man 5 systemd.mount}} for details.
+
重启:
  
==== Automount ====
+
$ systemctl reboot
  
* If you have a large {{ic|/home}} partition, it might be better to allow services that do not depend on {{ic|/home}} to start while {{ic|/home}} is being fsck'ed. This can be achieved by adding the following options to the {{ic|/etc/fstab}} entry of your {{ic|/home}} partition:
+
退出系统并停止电源:
  
  noauto,x-systemd.automount
+
  $ systemctl poweroff
  
This will fsck and mount {{ic|/home}} when it is first accessed, and the kernel will buffer all file access to {{ic|/home}} until it is ready.
+
待机:
  
* The same applies to remote filesystem mounts. If you want them to be mounted only upon access, you will need to use the {{ic|noauto,x-systemd.automount}} parameters. In addition, you can use the {{ic|1=x-systemd.device-timeout=#}} option to specify a timeout in case the network resource is not available.
+
$ systemctl suspend
  
* If you have encrypted filesystems with keyfiles, you can also add the {{ic|noauto}} parameter to the corresponding entries in {{ic|/etc/crypttab}}. Systemd will then not open the encrypted device on boot, but instead wait until it is actually accessed and then automatically open it with the specified keyfile before mounting it. This might save a few seconds on boot if you are using an encrypted RAID device for example, because systemd doesn't have to wait for the device to become available. For example:
+
休眠:
  
{{hc|/etc/crypttab|
+
$ systemctl hibernate
data /dev/md0 /root/key noauto}}
+
  
==== LVM ====
+
混合休眠模式(同时休眠到硬盘并待机):
  
If you have LVM volumes not activated via the [[Mkinitcpio|initramfs]], enable {{ic|lvm.service}} (provided by the {{pkg|lvm2}} package):
+
$ systemctl hybrid-sleep
  
# systemctl enable lvm
+
== 编写单元文件 ==
  
Similarly, if you have LVM on encrypted devices mounted later during boot (e.g. from {{ic|/etc/crypttab}}), enable {{ic|lvm-on-crypt.service}} (also provided by the {{pkg|lvm2}} package):
+
{{ic|systemd}} [http://www.freedesktop.org/software/systemd/man/systemd.unit.html 单元文件]的语法来源于 XDG桌面入口配置文件{{ic|.desktop}}文件,最初的源头则是Microsoft Windows的{{ic|.ini}}文件。单元文件可以从两个地方加载,优先级从低到高分别是:
  
# systemctl enable lvm-on-crypt
+
* {{ic|/usr/lib/systemd/system/}}: 软件包安装的单元
 +
* {{ic|/etc/systemd/system/}}: 系统管理员安装的单元
  
=== ACPI 电源管理 ===
+
* 当{{ic|systemd}}运行在[[systemd/User#How it works|用户模式]]下时,使用的加载路径是完全不同的。
systemd 能够处理某些电源相关的 [[Wikipedia:Advanced_Configuration_and_Power_Interface|ACPI]] 事件,通过 {{ic|/etc/systemd/logind.conf}} 的下列选项配置:
+
* systemd 单元名仅能包含 ASCII 字符, 下划线和点号. 其它字符需要用 C-style "\x2d" 替换. 参阅 {{ic|man systemd.unit}} {{ic|man systemd-escape}}.}}
* {{ic|HandlePowerKey}}:按下电源键后的动作
+
* {{ic|HandleSleepKey}}:按下挂起键后的动作
+
* {{ic|HandleHibernateKey}}: 按下休眠键后的动作
+
* {{ic|HandleLidSwitch}}:合上笔记本盖后待机
+
  
动作可以是 {{ic|ignore}}, {{ic|poweroff}}, {{ic|reboot}}, {{ic|halt}}, {{ic|suspend}}, {{ic|hibernate}} 或 {{ic|kexec}}.
+
单元文件的语法,可以参考系统已经安装的单元,也可以参考{{ic|man systemd.service}}中的[http://www.freedesktop.org/software/systemd/man/systemd.service.html#Examples EXAMPLES章节]。
  
系统默认设置为:
+
{{小贴士| 以 {{ic|#}} 开头的注释可能也能用在 unit-files 中, 但是只能在新行中使用。 不要在 ''systemd'' 的参数后面使用行末注释, 否则 unit 将会启动失败。}}
HandlePowerKey=poweroff
+
HandleSuspendKey=suspend
+
HandleHibernateKey=hibernate
+
HandleLidSwitch=suspend
+
  
如果不用图形界面,或者使用 [[i3 (简体中文)|i3]]、[[awesome (简体中文)|awesome]] 这样简单的桌面管理器时,systemd 可以替代 [[acpid (简体中文)|acpid]] 处理 ACPI 事件。
+
=== 处理依赖关系 ===
  
在当前版本的 systemd 中,这些 {{ic|Handle}} 选项将会被应用到整个系统当中,除非它们被别的程序——例如某个桌面环境中的电源管理器——给“阻止”(inhibited)。如果其它的程序没有阻止这些 {{ic|Handle}} ,你可能会先被 systemd 挂起你的系统,然后当系统被唤醒之后,电源管理器又会再次将系统挂起。
+
使用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=}} 选项没有制定,这两个单元将被并行启动。
  
{{注意|目前只有[[GNOME]] 和 [[KDE]] 支持 "inhibited" 命令。在其它的桌面管理器同样实现该功能之前,如果你想使用[[Xfce]], [[acpid]] 或者其它程序来管理 ACPI 事件,你需要把 {{ic|Handle}} 选项设置为 {{ic|ignore}} 。包含该功能的新版本还在开发当中。}}
+
依赖关系通常被用在服务(service)而不是[[#目标(target)|目标(target)]]上。例如, {{ic|network.target}} 一般会被某个配置网络接口的服务引入,所以,将自定义的单元排在该服务之后即可,因为 {{ic|network.target}} 已经启动。
  
{{Note|Systemd can also use other suspend backends (such as [[Uswsusp]] or [[TuxOnIce]]), in addition to the default ''kernel'' backend, in order to put the computer to sleep or hibernate.}}
+
=== 服务类型 ===
  
==== 休眠接口 ====
+
编写自定义的 service 文件时,可以选择几种不同的服务启动方式。启动方式可通过配置文件 {{ic|[Service]}} 段中的 {{ic|1=Type=}} 参数进行设置。
运行 {{ic|systemctl suspend}} 或 {{ic|systemctl hibernate}} 命令时,Systemd 不使用 [[pm-utils]] 进行系统休眠。所以 [[pm-utils]] 钩子和用户自定义钩子都不会运行。Systemd 提供了一个类似的机制,在事件发生时,运行 {{ic|/usr/lib/systemd/system-sleep/}} 中的所有可执行文件。运行时会传入两个参数:
+
* {{ic|pre}} 或 {{ic|post}},标示机器是关闭还是唤醒
+
* {{ic|suspend}} 或 {{ic|hibernate}},标示挂起还是睡眠
+
  
和 [[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|systemd-suspend.service}} 或 {{ic|systemd-hibernate.service}} 记录,可以通过 [[#systemd 日志|journal]] 查看:
+
{{ic|type}}的更多解释可以参考 [http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= systemd.service(5)]
# journalctl -b -u systemd-suspend
+
  
也可以使用 {{ic|sleep.target}}, {{ic|suspend.target}} {{ic|hibernate.target}} 设置要执行的钩子脚本,详情参阅 {{ic|man systemd.special}} 和 {{ic|man systemd-sleep}}
+
=== 修改现存单元文件 ===
 +
为了避免和 pacman 冲突,不应该直接编辑软件包提供的文件. 要更改由软件包提供的单元文件,先创建名为 {{ic|/etc/systemd/system/<单元名>.d/}} 的目录(如 {{ic|/etc/systemd/system/httpd.service.d/}}),然后放入 {{ic|*.conf}} 文件,其中可以添加或重置参数。这里设置的参数优先级高于原来的单元文件。例如,如果想添加一个额外的依赖,创建这么一个文件即可:
  
脚本示例:
+
{{hc|/etc/systemd/system/<unit>.d/customdependency.conf|2=
{{hc|/usr/lib/systemd/system-sleep/example.sh|
+
[Unit]
#!/bin/sh
+
Requires=<新依赖>
case $1/$2 in
+
After=<新依赖>}}
  pre/*)
+
    echo going to $2 ...
+
    ;;
+
  post/*)
+
    echo waking up from $2 ...
+
    ;;
+
esac}}
+
  
See {{ic|man 7 systemd.special}} and {{ic|man 8 systemd-sleep}} for more details
+
As another example, in order to replace the {{ic|ExecStart}} directive for a unit that is not of type {{ic|oneshot}}, create the following file:
  
=== 临时文件 ===
+
{{hc|/etc/systemd/system/''unit''.d/customexec.conf|2=
{{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/}} 目录中的同名配置。
+
[Service]
 
+
ExecStart=
临时文件通常和服务文件同时提供,以生成守护进程需要的文件和目录。例如 [[Samba (简体中文)|Samba]] 服务需要目录 {{ic|/var/run/samba}} 存在并设置正确的权限位,就象这样:
+
ExecStart=''new command''
{{hc|/usr/lib/tmpfiles.d/samba.conf|
+
D /var/run/samba 0755 root root
+
 
}}
 
}}
  
此外,临时文件还可以用来在开机时向特定文件写入某些内容。比如,要禁止系统从USB设备唤醒,利用旧的 {{ic|/etc/rc.local}} 可以用 {{ic|echo USBE > /proc/acpi/wakeup}},而现在可以这么做:
+
想知道为什么修改 {{ic|ExecStart}} 前必须将其置空,参见 ([https://bugzilla.redhat.com/show_bug.cgi?id=756787#c9]).
{{hc|/etc/tmpfiles.d/disable-usb-wake.conf|
+
 
w /proc/acpi/wakeup - - - - USBE
+
下面是自动重启服务的一个例子:
 +
 
 +
{{hc|/etc/systemd/system/''unit''.d/restart.conf|2=
 +
[Service]
 +
Restart=always
 +
RestartSec=30
 
}}
 
}}
推荐使用新方法,因为 systemd 并不原生支持 {{ic|/etc/rc.local}}。
 
  
详情参见 {{ic|man 4 tmpfiles.d}}。
+
然后运行以下命令使更改生效:
  
=== 单元(unit) ===
+
# systemctl daemon-reload
一个单元配置文件可以描述如下内容之一:系统服务、socket、系统设备、挂载点、交换分区/文件、启动目标(target)、文件系统路径、由 systemd 管理的计时器。文件格式受 .desktop 文件启发,而最初起源是 Windows 下的 .ini 文件。详情参见 {{ic|man systemd.unit}}。
+
# systemctl restart <单元>
  
详情参阅 {{ic|man 5 systemd.unit}}.
+
此外,把旧的单元文件从 {{ic|/usr/lib/systemd/system/}} 复制到 {{ic|/etc/systemd/system/}},然后进行修改,也可以达到同样效果。在 {{ic|/etc/systemd/system/}} 目录中的单元文件的优先级总是高于 {{ic|/usr/lib/systemd/system/}} 目录中的同名单元文件。注意,当 {{ic|/usr/lib/}} 中的单元文件因软件包升级变更时,{{ic|/etc/}} 中自定义的单元文件不会同步更新。此外,你还得执行 {{ic|systemctl reenable <unit>}},手动重新启用该单元。因此,建议使用前面一种利用 {{ic|*.conf}} 的方法。
  
== 从 initscripts 迁移到 systemd ==
+
{{小贴士|用 {{ic|systemd-delta}} 命令来查看哪些单元文件被覆盖、哪些被修改。系统维护的时候需要及时了解哪些单元已经有了更新。}}
  
=== Initscripts 模拟 ===
+
安装 {{Pkg|vim-systemd}} 软件包,可以使 unit 配置文件在 [[Vim]] 下支持语法高亮。
  
{{Pkg|initscripts}} 软件包提供了 systemd 和 Arch 传统配置的整合。When {{Pkg|initscripts}} are installed in parallel with systemd, with the system running on systemd, systemd will do the following:
+
== 目标(target) ==
 +
启动级别(runlevel)是一个旧的概念。现在,systemd 引入了一个和启动级别功能相似又不同的概念——目标(target)。不像数字表示的启动级别,每个''目标''都有名字和独特的功能,并且能同时启用多个。一些''目标''继承其他''目标''的服务,并启动新服务。systemd 提供了一些模仿 sysvinit 启动级别的''目标'',仍可以使用旧的 {{ic|telinit 启动级别}} 命令切换。
  
# Parse the {{ic|DAEMONS}} array of {{ic|/etc/rc.conf}} and start all listed daemons at boot
+
=== 获取当前目标 ===
# Execute {{ic|/etc/rc.local}} during boot
+
不要使用 {{ic|runlevel}} 命令了:
# Execute {{ic|/etc/rc.local.shutdown}} during shutdown
+
$ systemctl list-units --type=target
  
Initscripts emulation is simply meant as a transitional measure to ease users' move to systemd, and '''will eventually go away'''. Native systemd does not rely on {{ic|rc.conf}} centralised configuration, so it is recommended to use [[#Native configuration|native systemd configuration files]], which will take precedence over {{ic|/etc/rc.conf}}.
+
=== 创建新目标 ===
 +
在 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/}} 中的单元文件)。
  
{{Note|The recommended way to replace {{ic|/etc/rc.local}} is to write the custom service files for any things you want to run on the system startup. See the corresponding [[#Writing_custom_.service_files|section]].}}
+
=== 目标表 ===
 +
{| 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)
 +
|-
 +
|}
  
{{Note|If you disabled {{keypress|Ctrl+Alt+Del}} to reboot in {{ic|/etc/inittab}}, you will have to reconfigure this setting for systemd by running {{ic|systemctl mask ctrl-alt-del.target}} as root.}}
+
=== 切换启动级别/目标 ===
 +
systemd 中,启动级别通过“目标单元”访问。通过如下命令切换:
 +
# systemctl isolate graphical.target
 +
该命令对下次启动无影响。等价于{{ic|telinit 3}} {{ic|telinit 5}}
  
If you disabled {{keypress|Ctrl+Alt+Del}} to reboot in {{ic|/etc/inittab}}, you will have to reconfigure this setting for systemd by running {{ic|systemctl mask ctrl-alt-del.target}} as root.
+
=== 修改默认启动级别/目标 ===
 +
开机启动进的目标是 {{ic|default.target}},默认链接到 {{ic|graphical.target}} (大致相当于原来的启动级别5)。可以通过[[Kernel parameters (简体中文)|内核参数]]更改默认启动级别:
  
=== Moving away from the DAEMONS array ===
+
* {{ic|1=systemd.unit=multi-user.target}} (大致相当于级别3)
 +
* {{ic|1=systemd.unit=rescue.target}} (大致相当于级别1)
  
For a pure systemd setup, you should remove the {{ic|/etc/rc.conf}} file entirely and enable services only via {{ic|systemctl}}. For each {{ic|<service_name>}} in the {{ic|DAEMONS}} array in {{ic|/etc/rc.conf}}, run:
+
另一个方法是修改 {{ic|default.target}}。可以通过 {{ic|systemctl}} 修改它:
  
  # systemctl enable <service_name>
+
  # systemctl set-default multi-user.target
  
{{Tip|For a list of commonly used daemons with their initscripts and systemd equivalents, see [[Daemons List|this table]].}}
+
要覆盖已经设置的''default.target'',请使用 force:
 +
# systemctl set-default -f multi-user.target
  
If {{ic|<service_name>.service}} does not exist:
+
可以在 {{ic|systemctl}} 的输出中看到命令执行的效果:链接 {{ic|/etc/systemd/system/default.target}} 被创建,指向新的默认启动级别。
  
* Most probably, systemd uses a different name. For example, {{ic|cronie.service}} replaces the {{ic|crond}} init daemon; {{ic|alsa-store.service}} and {{ic|alsa-restore.service}} replace the {{ic|alsa}} init daemon. Another important instance is the {{ic|network}} daemon, which is replaced with another set of service files (see [[Configuring Network]] for more details.)
+
== 临时文件 ==
* Otherwise, a service file may not be available for systemd. In that case, you'll need to keep {{ic|rc.conf}} to start the service during boot up.
+
{{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/}} 目录中的同名配置。
  
{{Tip|You may look inside a package that contains daemon start scripts for service names. For instance:
+
临时文件通常和服务文件同时提供,以生成守护进程需要的文件和目录。例如 [[Samba (简体中文)|Samba]] 服务需要目录 {{ic|/run/samba}} 存在并设置正确的权限位,就象这样:
$ pacman -Ql cronie
+
{{hc|/usr/lib/tmpfiles.d/samba.conf|
[...]
+
D /run/samba 0755 root root
cronie /etc/rc.d/crond                            #Daemon initscript listed in the DAEMONS array (unused in a "pure" systemd configuration)
+
[...]
+
cronie /usr/lib/systemd/system/cronie.service    #Corresponding systemd daemon service
+
[...]
+
 
}}
 
}}
  
* Finally, some services do not need to be explicitly enabled by the user. For instance, {{ic|dbus.service}} will automatically be enabled when {{ic|dbus-core}} is installed. {{ic|alsa-store.service}} and {{ic|alsa-restore.service}} are also enabled automatically by systemd. Check the list of available services and their state using the {{ic|systemctl}} command like this: {{ic|systemctl status <service_name>}}.
+
此外,临时文件还可以用来在开机时向特定文件写入某些内容。比如,要禁止系统从USB设备唤醒,利用旧的 {{ic|/etc/rc.local}} 可以用 {{ic|echo USBE > /proc/acpi/wakeup}},而现在可以这么做:
 +
{{hc|/etc/tmpfiles.d/disable-usb-wake.conf|
 +
w /proc/acpi/wakeup - - - - USBE
 +
}}
  
== systemd 简单使用 ==
+
详情参见{{ic|systemd-tmpfiles(8)}} 和 {{ic|man 5 tmpfiles.d}}。
  
The main command used to introspect and control systemd is {{ic|systemctl}}. Some of its uses are examining the system state and managing the system and services. See {{ic|man 1 systemctl}} for more details.
+
{{注意|该方法不能向 {{ic|/sys}} 中的配置文件添加参数,因为 {{ic|systemd-tmpfiles-setup}} 有可能在相关模块加载前运行。这种情况下,需要首先通过 {{ic|modinfo <模块名>}} 确认需要的参数,并在 [[Kernel modules (简体中文)#选项|{{ic|/etc/modprobe.d}} 下的一个文件]]中设置改参数。另外,还可以使用 [[udev (简体中文)#udev规则|udev 规则]],在设备就绪时设置相应属性。}}
  
*{{ic|systemctl}}:控制 systemd 状态,包括服务的启动和停止。
+
== 定时器 ==
*{{ic|systemd-cgls}}:以树形递归显示指定 Linux 控制组(cgroup)的内容
+
定时器是以 ''.timer'' 为后缀的配置文件,记录由system的里面由时间触发的动作, 定时器可以替代 ''cron'' 的大部分功能。详情参阅 [[systemd/Timers (简体中文)]].
*{{ic|systemadm}}:控制 systemd 状态的图形前端(由 [[AUR (简体中文)|AUR]] 软件包 {{AUR|systemd-ui-git}} 提供)。
+
  
{{小贴士|在 {{ic|systemctl}} 参数中添加 {{ic|-H <用户名>@<主机名>}} 可以实现对其他机器的远程控制。该过程使用 [[SSH (简体中文)|SSH]] 链接。}}
+
== 日志 ==
 +
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}}。这意味着,系统重启后日志将丢失。
  
$ systemctl
+
{{Tip|如果 {{ic|/var/log/journal/}} 位于 [[btrfs]] 文件系统,应该考虑对这个目录禁用写入时复制,方法参阅[[Btrfs#Copy-On-Write (CoW)]].}}
  
以下命令等效:
+
=== 过滤输出 ===
  
$ systemctl list-units
+
{{ic|journalctl}}可以根据特定字段过滤输出。如果过滤的字段比较多,需要较长时间才能显示出来。
  
输出运行失败的单元:
+
示例:
  
$ systemctl --failed
+
显示本次启动后的所有日志:
  
所有可用的单元文件存放在 {{ic|/usr/lib/systemd/system/}} 和 {{ic|/etc/systemd/system/}} 目录(后者优先级更高)。
+
# journalctl -b
  
=== 使用单元 ===
+
不过,一般大家更关心的不是本次启动后的日志,而是上次启动时的(例如,刚刚系统崩溃了)。可以使用 {{ic|-b}} 参数:
一个单元可以是系统服务({{ic|.service}})、挂载点({{ic|.mount}})、sockets({{ic|.sockets}})。
+
* {{ic|journalctl -b -0}} 显示本次启动的信息
 +
* {{ic|journalctl -b -1}} 显示上次启动的信息
 +
* {{ic|journalctl -b -2}} 显示上上次启动的信息 {{ic|journalctl -b -2}}  
  
使用 {{ic|systemctl}} 控制单元时,通常需要使用单元文件的全名,包括扩展名(例如 {{ic|sshd.service}})。但是有些单元可以在{{ic|systemctl}}中使用简写方式。
+
* 显示从某个日期 ( 或时间 ) 开始的消息: {{bc|1=# journalctl --since="2012-10-30 18:17:16"}}
* 如果无后缀,sistemctl 默认后缀为{{ic|.service}}. 例如{{ic|netcfg}} {{ic|netcfg.service}} 是等价的。
+
* 显示从某个时间 ( 例如 20分钟前 ) 的消息: {{bc|1=# journalctl --since "20 min ago"}}
* 挂载点会自动转化为相应的{{ic|.mount}}单元。例如{{ic|/home}}等价于{{ic|home.mount}}
+
* 显示最新信息{{bc|# journalctl -f}}
* 设备会自动转化为相应的{{ic|.device}}单元,所以{{ic|/dev/sda2}}等价于{{ic|dev-sda2.device}}.
+
* 显示特定程序的所有消息: {{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}}
  
立即激活单元:
+
详情参阅{{ic|man journalctl}}、{{ic|man systemd.journal-fields}},以及 Lennert 的这篇[http://0pointer.de/blog/projects/journalctl.html 博文]。
  
# systemctl start <unit>
+
=== 日志大小限制 ===
  
立即停止单元:
+
如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果 {{ic|/var/log/journal}} 储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改配置文件指定最大限制。如限制日志最大 50MiB:
# systemctl stop <unit>
+
  
重启单元:
+
{{hc|/etc/systemd/journald.conf|2=
 
+
SystemMaxUse=50M
# systemctl restart <unit>
+
 
+
命令单元重新读取配置:
+
 
+
# systemctl reload <unit>
+
 
+
输出单元运行状态:
+
 
+
$ systemctl status <unit>
+
 
+
检查单元是否配置为自动启用:
+
$ systemctl is-enabled <unit>
+
 
+
开机自动激活单元:
+
 
+
# systemctl enable <unit>
+
+
{{注意|如果服务没有{{ic|Install}}段落,一般意味着应该通过其它服务自动调用它们。如果真的需要手动安装,可以直接连接服务,将 foo 替换为真实的服务名:
+
{{bc|# ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/}}
+
 
}}
 
}}
  
取消开机自动激活单元:
+
详情参见 {{ic|man journald.conf}}.
  
{{bc|# systemctl disable <unit>}}
+
=== 配合 syslog 使用 ===
 +
systemd 提供了 socket {{ic|/run/systemd/journal/syslog}},以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 {{ic|/dev/log}}([http://lwn.net/Articles/474968/ 官方说明])。Arch 软件仓库中的 {{pkg|syslog-ng}} 已经包含了需要的配置。
  
显示单元的手册页(必须由单元文件提供):
+
''systemd'' 216 开始,{{ic|journald.conf}} 使用 {{ic|no}} 转发socket . 为了使 ''syslog-ng'' 配合 ''journald'' , 你需要在 {{ic|/etc/systemd/journald.conf}}  中设置  {{ic|1=ForwardToSyslog=yes}} . 参阅 [[Syslog-ng#Overview]] 了解更多细节.
 +
 +
如果你选择使用 {{Pkg|rsyslog}} , 因为 [[rsyslog]] 从日志中 [http://lists.freedesktop.org/archives/systemd-devel/2014-August/022295.html#journald 直接] 传出消息,所以不再必要改变那个选项..
  
{{bc|$ systemctl help <unit>}}
+
设置开机启动 syslog-ng:
 +
  # systemctl enable syslog-ng
  
=== 电源管理 ===
+
[http://0pointer.de/blog/projects/ 这里]有一份很不错的 {{ic|journalctl}} 指南。
  
If you are in a local {{ic|systemd-logind}} user session and no other session is active, the following commands will work without root privileges. If not (for example, because another user is logged into a tty), systemd will automatically ask you for the root password.
+
=== 手动清理日志 ===
  
重启:
+
{{ic|/var/log/journal}} 存放着日志, {{ic|rm}} 应该能工作. 或者使用{{ic|journalctl}},
  
$ systemctl reboot
+
例如:
  
退出系统并停止电源(shut down and power-off):
+
* 清理日志使总大小小于 100M: {{bc|1=# journalctl --vacuum-size=100M}}
 +
* 清理最早两周前的日志. {{bc|1=# journalctl --vacuum-time=2weeks}}
  
$ systemctl poweroff
+
参阅 {{ic|man journalctl}} 获得更多信息.
  
退出系统并中断(shut down and halt):
+
=== Journald in conjunction with syslog ===
  
$ systemctl halt
+
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]).
  
待机:
+
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].
  
$ systemctl suspend
+
See [[Syslog-ng#Overview]] and [[Syslog-ng#syslog-ng and systemd journal]], or [[rsyslog]] respectively, for details on configuration.
  
休眠:
+
===转发 journald 到 /dev/tty12 ===
  
$ systemctl hibernate
+
建立一个 [[#Editing provided units|drop-in directory]] {{ic|/etc/systemd/journald.conf.d}} 然后在其中建立 {{ic|fw-tty12.conf}} :
  
== 启动桌面环境 ==
+
{{hc|1=/etc/systemd/journald.conf.d/fw-tty12.conf|2=
 +
[Journal]
 +
ForwardToConsole=yes
 +
TTYPath=/dev/tty12
 +
MaxLevelConsole=info
 +
}}
  
=== 使用登录管理器 ===
+
然后重新启动  systemd-journald.
  
通过启动[[Display Manager (简体中文)|登录管理器]](或称显示管理器),即可进行图形界面登录。目前,Arch 提供了 [[GDM (简体中文)|GDM]]、[[KDM (简体中文)|KDM]]、[[SLiM (简体中文)|SLiM]]、[[XDM (简体中文)|XDM]] 和 [[LXDM (简体中文)|LXDM]] 的 systemd 服务文件。以 KDM 为例,配置开机启动:
+
=== 查看特定位置的日志 ===
# systemctl enable kdm.service
+
有时你希望查看另一个系统上的日志.例如从 Live 环境修复现存的系统.
  
执行上述命令后,登录管理器应当能正常工作了。如果不是的话,很可能是因为你修改了{{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}}):
+
== 疑难解答 ==
 +
=== 寻找错误 ===
  
# rm /etc/systemd/system/default.target
+
这个例子中的失败的服务是 {{ic|systemd-modules-load}} :
  
=== Using systemd-logind ===
+
'''1.''' 通过 ''systemd'' 寻找启动失败的服务:
  
{{Note|As of 2012-10-30, [[ConsoleKit]] has been [https://www.archlinux.org/news/consolekit-replaced-by-logind/ replaced by systemd-logind] as the default mechanism to login to the DE.}}
+
{{hc|
 +
1=$ systemctl --state=failed|
 +
2=systemd-modules-load.service  loaded '''failed failed'''  Load Kernel Modules
 +
}}
  
In order to check the status of your user session, you can use {{ic|loginctl}}. All [[PolicyKit]] actions like suspending the system or mounting external drives will work out of the box.
+
'''2.''' 我们发现了启动失败的 {{ic|systemd-modules-load}} 服务. 我们想知道更多信息:
  
$ loginctl show-session $XDG_SESSION_ID
+
{{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: '''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''')
 +
}}
  
== Writing custom .service files ==
+
如果没列出 {{ic|Process ID}}, 通过 {{ic|systemctl}} 重新启动失败的服务 ( 例如 {{ic|systemctl restart systemd-modules-load}} )
  
=== Handling dependencies ===
+
'''3.''' 现在得到了 PID ,你就可以进一步探查错误的详细信息了.通过下列的命令收集日志,PID 参数是你刚刚得到的 {{ic|Process ID}} (例如 15630):
  
With systemd, dependencies can be resolved by designing the unit files correctly. The most typical case is that the unit {{ic|A}} requires the unit {{ic|B}} to be running before {{ic|A}} is started. In that case add {{ic|1=Requires=B}} and {{ic|1=After=B}} to the {{ic|[Unit]}} section of {{ic|A}}. If the dependency is optional, add {{ic|1=Wants=B}} and {{ic|1=After=B}} instead. Note that {{ic|1=Wants=}} and {{ic|1=Requires=}} do not imply {{ic|1=After=}}, meaning that if {{ic|1=After=}} is not specified, the two units will be started in parallel.
+
{{hc|1=$ journalctl -b _PID=15630|2=
 +
-- 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''''
 +
}}
  
Dependencies are typically placed on services and not on targets. For example, {{ic|network.target}} is pulled in by whatever service configures your network interfaces, therefore ordering your custom unit after it is sufficient since {{ic|network.target}} is started anyway.
+
'''4.''' 我们发现有些内核模块的配置文件不正确,因此在  {{ic|/etc/modules-load.d/}} 中检查一下:
  
=== Type ===
+
{{hc|$ 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
 +
...
 +
}}
  
There are several different start-up types to consider when writing a custom service file. This is set with the {{ic|1=Type=}} parameter in the {{ic|[Service]}} section. See {{ic|man systemd.service}} for a more detailed explanation.
+
'''5.''' 错误消息 {{ic|Failed to find module 'blacklist usblp'}} 也许和  {{ic|blacklist.conf}} 相关. 让我们注释掉第三步发现的错误的选项:
  
* {{ic|1=Type=simple}}: systemd considers the service to be started up immediately. The process must not fork. Do not use this type if other services need to be ordered on this service, unless it is socket activated.
+
{{hc|/etc/modules-load.d/blacklist.conf|
* {{ic|1=Type=forking}}: systemd considers the service started up once the process forks and the parent has exited. For classic daemons use this type unless you know that it is not necessary. You should specify {{ic|1=PIDFile=}} as well so systemd can keep track of the main process.
+
'''#''' blacklist usblp
* {{ic|1=Type=oneshot}}: This is useful for scripts that do a single job and then exit. You may want to set {{ic|1=RemainAfterExit=}} as well so that systemd still considers the service as active after the process has exited.
+
'''#''' install usblp /bin/false
* {{ic|1=Type=notify}}: Identical to {{ic|1=Type=simple}}, but with the stipulation that the daemon will send a signal to systemd when it is ready. The reference implementation for this notification is provided by {{ic|libsystemd-daemon.so}}.
+
}}
* {{ic|1=Type=dbus}}: The service is considered ready when the specified {{ic|BusName}} appears on DBus's system bus.
+
  
=== Replacing provided unit files ===
+
'''6.''' 最后重新启动 {{ic|systemd-modules-load}} 服务:
  
The unit files in {{ic|/etc/systemd/system/}} take precedence over the ones in {{ic|/usr/lib/systemd/system/}}.
+
$ systemctl start systemd-modules-load
To make your own version of a unit (which will not be destroyed by an upgrade), copy the old unit file from {{ic|/usr/lib/}} to {{ic|/etc/}} and make your changes there. Alternatively you can use {{ic|.include}} to parse an existing service file and then override or add new options. For example, if you simply want to add an additional dependency to a service file, you may use:
+
  
{{hc|/etc/systemd/system/<service-name>.service|2=
+
如果服务成功启动,不会有任何输出.如果你还是遇到了错误,回到步骤三,获得新的 PID 来跟踪日志并解决错误.
.include /usr/lib/systemd/system/<service-name>.service
+
  
[Unit]
+
可以像这样确认服务成功启动:
Requires=<new dependency>
+
After=<new dependency>}}
+
  
Then run the following for your changes to take effect:
+
{{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'''.
 +
}}
  
# systemctl reenable <unit>
+
参阅 [[#诊断启动问题]] 一节获得更多探查错误的方法.  
  # systemctl restart <unit>
+
  
{{Tip|You can use {{ic|systemd-delta}} to see which unit files have been overridden and what exactly has been changed.}}
+
=== 诊断启动问题 ===
  
=== Syntax highlighting for units within Vim ===
+
使用如下内核参数引导:
 +
{{ic|<nowiki>systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M</nowiki>}}
  
Syntax highlighting for systemd unit files within [[Vim]] can be enabled by installing {{AUR|vim-systemd}} from the [[Arch User Repository|AUR]].
+
更多有关调试的信息,参见[http://freedesktop.org/wiki/Software/systemd/Debugging 该文]
  
== 目标(target) ==
+
=== 诊断一个特定服务 ===
启动级别(runlevel)是一个旧的概念。现在,systemd 引入了一个和启动级别功能相似又不同的概念——目标(target)。不像数字表示的启动级别,每个''目标''都有名字和独特的功能,并且能同时启用多个。一些''目标''继承其他''目标''的服务,并启动新服务。systemd 提供了一些模仿 sysvinit 启动级别的''目标'',仍可以使用旧的 {{ic|telinit 启动级别}} 命令切换。
+
  
=== 获取当前目标 ===
+
如果某个 ''systemd'' 服务的工作状况不合你的预期因此你希望调试的话,设置 {{ic|SYSTEMD_LOG_LEVEL}} [[environment variable|环境变量]] 为 {{ic|debug}} . 例如以调试模式运行 ''systemd-networkd'' 服务:
不要使用 {{ic|runlevel}} 命令了:
+
$ systemctl list-units --type=target
+
  
=== 创建新目标 ===
+
# systemctl stop systemd-networkd
在 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_LOG_LEVEL=debug /lib/systemd/systemd-networkd
  
=== 目标表 ===
+
或者等价的,临时编辑系统单元文件,例如:
{| border="1"
+
!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)
+
|-
+
|}
+
  
=== 切换启动级别/目标 ===
+
{{hc|/lib/systemd/system/systemd-networkd.service|2=
systemd 中,启动级别通过“目标单元”访问。通过如下命令切换:
+
[Service]
# systemctl isolate graphical.target
+
...
该命令对下次启动无影响。等价于{{ic|telinit 3}} 或 {{ic|telinit 5}}
+
Environment=SYSTEMD_LOG_LEVEL=debug
 +
....
 +
}}
  
=== 修改默认启动级别/目标 ===
+
如果经常需要调试信息,以[[#修改现存单元文件|一般方法]]添加环境变量.
开机启动进的目标是 {{ic|default.target}},默认链接到 {{ic|graphical.target}} (大致相当于原来的启动级别5)。可以通过 [[kernel parameters]]更改默认启动级别:
+
* {{ic|1=systemd.unit=multi-user.target}} (大致相当于级别3)
+
* {{ic|1=systemd.unit=rescue.target}} (大致相当于级别1)
+
  
另一个方法是修改 {{ic|default.target}}。可以通过 {{ic|systemctl}} 修改它:
+
=== 关机/重启十分缓慢 ===
# systemctl enable multi-user.target
+
  
命令执行情况由 {{ic|systemctl}} 显示:链接 {{ic|/etc/systemd/system/default.target}} 被创建,指向新的默认启动级别。 该方法当且仅当目标配置文件中有以下内容时有效:
+
如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再尝试杀死它。请阅读[http://freedesktop.org/wiki/Software/systemd/Debugging#Shutdown_Completes_Eventually 这篇文章],确认你是否是该问题受害者。
[Install]
+
Alias=default.target
+
目前,{{ic|multi-user.target}}、{{ic|graphical.target}} 都包含这段内容。
+
  
== 日志 ==
+
=== 短时进程无日志记录 ===
自版本 38 起,systemd 提供了自己日志系统(logging system),称为 journal. 使用 systemd 日志,无需额外安装日志服务(syslog)。读取日志的命令:
+
# journalctl
+
  
By default (when {{ic|Storage&#61;}} is set to {{ic|auto}} in {{ic|/etc/systemd/journald.conf}}), the journal writes to {{ic|/var/log/journal/}}. If the directory {{ic|/var/log/journal/}} does not exist (e.g. if you or some program delete it), systemd will '''not''' create it automatically, but instead write its logs to {{ic|/run/systemd/journal}}. This means that logs will be lost on reboot.
+
{{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。
  
=== 过滤输出 ===
+
=== 禁止在程序崩溃时转储内存 ===
 +
要使用老的内核转储,创建下面文件:
 +
{{hc|/etc/sysctl.d/49-coredump.conf|2=<nowiki>
 +
kernel.core_pattern = core
 +
kernel.core_uses_pid = 0</nowiki>}}
  
{{ic|journalctl}}可以根据特殊字段过滤输出,例如:
+
然后运行:
 +
# /usr/lib/systemd/systemd-sysctl
  
Show all messages from this boot:
+
同样可能需要执行“unlimit”设置文件大小:
  # journalctl -b
+
  $ ulimit -c unlimited
  
显示新信息:
+
更多信息请参阅 [http://www.freedesktop.org/software/systemd/man/sysctl.d.html sysctl.d] 和 [https://www.kernel.org/doc/Documentation/sysctl/kernel.txt /proc/sys/kernel 文档]。
# journalctl -f
+
  
显示给定可执行文件的所有消息:
+
=== 启动的时间太长 ===
{{bc|# journalctl /usr/lib/systemd/systemd}}
+
  
显示指定过程的所有消息:
+
不少用户用了 {{ic|systemd-analyze}} 命令以后报告启动的时间比预计的要长,通常会说 {{ic|systemd-analyze}} 分析结果表示 [[NetworkManager]] 占据了太多的启动的时间.
{{bc|1=# journalctl _PID=1}}
+
  
显示指定单元的所有消息:
+
有些用户的问题是 {{ic|/var/log/journal}} 文件夹似乎过大.这也许也会对像{{ic|systemctl status}} 或 {{ic|journalctl}} 的命令有影响.一种解决方案是删除其中的文件 (但最好将它们备份到某处) 然后限制日志文件的大小.
# journalctl -u netcfg
+
  
详情参阅{{ic|man journalctl}}{{ic|systemd.journal-fields}}
+
=== systemd-tmpfiles-setup.service 在启动时启动失败 ===
 +
从 systemd 219 开始, {{ic|/usr/lib/tmpfiles.d/systemd.conf}} 指定 {{ic|/var/log/journal}} 的 ACL 属性和目录, 因此日志所在的文件系统上要启用ACL.
  
=== 日志大小限制 ===
+
参阅 [[Access Control Lists#Enabling ACL]] 获得如何包含 {{ic|/var/log/journal}} 启动 ACL 的详细信息.
  
如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果 {{ic|/var/log/journal}} 储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改 {{ic|/etc/systemd/journald.conf}} 中的 {{ic|SystemMaxUse}} 来指定该最大限制。如限制日志最大 50MiB:
+
=== 不能设定在开机时启动软链接到 /etc/systemd/system 的服务 ===
  
SystemMaxUse=50M
+
如果 {{ic|/etc/systemd/system/''foo''.service}} 是个符号链接, 运行 {{ic|systemctl enable ''foo''.service}} 时可能遇到这样的错误:
  
详情参见 {{ic|man journald.conf}}.
+
Failed to issue method call: No such file or directory
  
=== 配合 syslog 使用 ===
+
这是 systemd 的 [https://bugzilla.redhat.com/show_bug.cgi?id=955379#c14 设计选择] ,可以通过输入绝对路径来规避这个错误:
systemd 提供了 socket {{ic|/run/systemd/journal/syslog}},以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 {{ic|/dev/log}}(http://lwn.net/Articles/474968/ 官方说明)。以 Arch 源中的 syslog-ng 已经包含了需要的配置。
+
  
设置开机启动 syslog-ng:
+
# systemctl enable ''/absolute/path/foo''.service
  # systemctl enable syslog-ng
+
  
== 优化 ==
+
== 相关资源 ==
  
=== 启动过程分析 ===
 
systemd 提供了一个分析启动过程的工具 —— {{ic|systemd-analyze}}。可以用它看看哪些单元拖慢了开机过程,并据此进行优化。安装 {{Pkg|python2-dbus}}、{{Pkg|python2-cairo}} 软件包后该工具才能工作。
 
 
查看开机过程在内核/用户空间消耗的时间:
 
$ systemd-analyze
 
{{Tip|如果在 {{ic|/etc/mkinitcpio.conf}} 的 {{ic|HOOKS}} 数组添加 {{ic|timestamp}},并重新生成启动内存镜像(initramfs),{{ic|systemd-analyze}} 还可以显示处理该启动镜像花费的时间。}}
 
 
按照耗费时间顺序,输出启动每个单元耗费的时间:
 
$ systemd-analyze blame
 
 
生成类似于 [[Bootchart (简体中文)|bootchart]] 的开机过程图表:
 
$ systemd-analyze plot > plot.svg
 
 
==== 使用 bootchart ====
 
由于没有办法在内核参数设置两个 init,所以不能使用源里的 bootchart。不过,[[AUR (简体中文)|AUR]] 软件包 {{AUR|bootchart2}} 提供了一个的 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 的超级牛力只有在重启几次后才会显现。
 
 
=== Early start for services ===
 
One central feature of systemd is [[D-Bus]] and socket activation. This causes services to be started when they are first accessed and is generally a good thing. However, if you know that a service (like [[UPower]]) will always be started during boot, then the overall boot time might be reduced by starting it as early as possible. This can be achieved (if the service file is set up for it, which in most cases it is) by issuing:
 
 
# systemctl enable upower
 
 
This will cause systemd to start UPower as soon as possible, without causing races with the socket or D-Bus activation.
 
 
=== 精简输出信息 ===
 
修改启动加载器内核参数中的 {{ic|verbose}} 为 {{ic|quiet}} 即可。对于某些用户,特别是 SSD 用户,TTY 的龟速实际上成为了性能瓶颈,精简输出信息实际上有利于提高性能。
 
 
== 疑难解答 ==
 
=== 关机/重启十分缓慢 ===
 
如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再杀死它。
 
请阅读 Fedora wiki 上的[http://fedoraproject.org/wiki/How_to_debug_Systemd_problems#Diagnosing_shutdown_problems 文章],确认你是否是该问题受害者。
 
 
=== Disable warning bell ===
 
Add command {{ic|xset -b}} to the {{ic|.xinitrc}} file.
 
Discussion on [https://bbs.archlinux.org/viewtopic.php?pid=1148781 this] forum topic.
 
 
== 相关资源 ==
 
 
*[http://www.freedesktop.org/wiki/Software/systemd 官方网站]
 
*[http://www.freedesktop.org/wiki/Software/systemd 官方网站]
*[http://0pointer.de/public/systemd-man/ 手册页]
+
*[[Wikipedia:zh:systemd|维基百科上的介绍]]
 +
*[http://0pointer.de/public/systemd-man/ man 手册页]
 
*[http://freedesktop.org/wiki/Software/systemd/Optimizations systemd 优化]
 
*[http://freedesktop.org/wiki/Software/systemd/Optimizations systemd 优化]
 
*[http://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions 常见问题 FAQ]
 
*[http://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions 常见问题 FAQ]
 
*[http://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks 小技巧]
 
*[http://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks 小技巧]
 
*[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://en.gentoo-wiki.com/wiki/Systemd Gentoo Wiki 条目]
 
 
*[http://fedoraproject.org/wiki/Systemd Fedora 项目对 systemd 的介绍]
 
*[http://fedoraproject.org/wiki/Systemd Fedora 项目对 systemd 的介绍]
 
*[http://fedoraproject.org/wiki/How_to_debug_Systemd_problems 如何调试 systemd 故障]
 
*[http://fedoraproject.org/wiki/How_to_debug_Systemd_problems 如何调试 systemd 故障]
*[http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html Booting up: Tools and tips for systemd, a Linux init tool. In The H]
+
*''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 篇]科普文章
* [http://0pointer.de/blog/projects/systemd.html 开发者 Lennart 的博文]
+
*[http://0pointer.de/blog/projects/systemd.html Lennart 的博文]
* [http://0pointer.de/blog/projects/systemd-update.html 一篇更新报告]
+
*[http://0pointer.de/blog/projects/systemd-update.html 更新报告]
* [http://0pointer.de/blog/projects/systemd-update-2.html 另一篇更新报告]
+
*[http://0pointer.de/blog/projects/systemd-update-2.html 更新报告2]
* [http://0pointer.de/blog/projects/why.html 最新动态]
+
*[http://0pointer.de/blog/projects/systemd-update-3.html 更新报告3]
* [http://en.wikipedia.org/wiki/Systemd 维基百科页面]
+
*[http://0pointer.de/blog/projects/why.html 最新动态]
* [http://freedesktop.org/wiki/Software/systemd 项目主页]
+
*[https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet/zh Fedora Wiki 上的 SysVinit systemd 命令对比表]
* [http://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet Fedora's SysVinit to systemd cheatsheet]
+

Latest revision as of 12:01, 30 April 2016

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

摘自项目主页:

systemd 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本。systemd 的特性有:支持并行化任务;同时采用 socket 式与 D-Bus 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 cgroups 监视进程;支持快照和系统恢复;维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。

Note: Arch Linux 论坛的这篇帖子 详细的解释了 Arch Linux 迁移到 systemd 的原因.


systemd 基本工具

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

小贴士:
  • systemctl 参数中添加 -H <用户名>@<主机名> 可以实现对其他机器的远程控制。该过程使用 SSH连接。
  • systemadm 是 systemd 的官方图形前端。官方软件仓库 提供了稳定版本 systemd-ui
  • Plasma 用户可以安装 systemctl 图形前端 systemd-kcm。安装后可以在 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)。详情参阅 man 5 systemd.unit

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

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

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

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

立即激活单元:

# systemctl start <单元>

立即停止单元:

# systemctl stop <单元>

重启单元:

# systemctl restart <单元>

重新加载配置:

# systemctl reload <单元>

输出单元运行状态:

$ systemctl status <单元>

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

$ systemctl is-enabled <单元>

开机自动激活单元:

# systemctl enable <单元>

取消开机自动激活单元:

# 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文件。单元文件可以从两个地方加载,优先级从低到高分别是:

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

单元文件的语法,可以参考系统已经安装的单元,也可以参考man systemd.service中的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=idle: systemd会等待所有任务处理完成后,才开始执行idle类型的单元。其他行为和Type=simple 类似。

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

修改现存单元文件

为了避免和 pacman 冲突,不应该直接编辑软件包提供的文件. 要更改由软件包提供的单元文件,先创建名为 /etc/systemd/system/<单元名>.d/ 的目录(如 /etc/systemd/system/httpd.service.d/),然后放入 *.conf 文件,其中可以添加或重置参数。这里设置的参数优先级高于原来的单元文件。例如,如果想添加一个额外的依赖,创建这么一个文件即可:

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

As another example, in order to replace the ExecStart directive for a unit that is not of type oneshot, create the following file:

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

想知道为什么修改 ExecStart 前必须将其置空,参见 ([1]).

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

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

然后运行以下命令使更改生效:

# systemctl daemon-reload
# systemctl restart <单元>

此外,把旧的单元文件从 /usr/lib/systemd/system/ 复制到 /etc/systemd/system/,然后进行修改,也可以达到同样效果。在 /etc/systemd/system/ 目录中的单元文件的优先级总是高于 /usr/lib/systemd/system/ 目录中的同名单元文件。注意,当 /usr/lib/ 中的单元文件因软件包升级变更时,/etc/ 中自定义的单元文件不会同步更新。此外,你还得执行 systemctl reenable <unit>,手动重新启用该单元。因此,建议使用前面一种利用 *.conf 的方法。

小贴士: systemd-delta 命令来查看哪些单元文件被覆盖、哪些被修改。系统维护的时候需要及时了解哪些单元已经有了更新。

安装 vim-systemd 软件包,可以使 unit 配置文件在 Vim 下支持语法高亮。

目标(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

要覆盖已经设置的default.target,请使用 force:

# systemctl set-default -f multi-user.target

可以在 systemctl 的输出中看到命令执行的效果:链接 /etc/systemd/system/default.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)man 5 tmpfiles.d

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

定时器

定时器是以 .timer 为后缀的配置文件,记录由system的里面由时间触发的动作, 定时器可以替代 cron 的大部分功能。详情参阅 systemd/Timers (简体中文).

日志

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

# journalctl

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

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

过滤输出

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

示例:

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

# journalctl -b

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

  • journalctl -b -0 显示本次启动的信息
  • journalctl -b -1 显示上次启动的信息
  • journalctl -b -2 显示上上次启动的信息 journalctl -b -2
  • 显示从某个日期 ( 或时间 ) 开始的消息:
    # 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

详情参阅man journalctlman systemd.journal-fields,以及 Lennert 的这篇博文

日志大小限制

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

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

详情参见 man journald.conf.

配合 syslog 使用

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

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

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

设置开机启动 syslog-ng:

 # systemctl enable syslog-ng

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

手动清理日志

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

例如:

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

参阅 man journalctl 获得更多信息.

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 /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

疑难解答

寻找错误

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

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

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

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 服务:

# systemctl stop systemd-networkd
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd

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

/lib/systemd/system/systemd-networkd.service
[Service]
...
Environment=SYSTEMD_LOG_LEVEL=debug
....

如果经常需要调试信息,以一般方法添加环境变量.

关机/重启十分缓慢

如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。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 的详细信息.

不能设定在开机时启动软链接到 /etc/systemd/system 的服务

如果 /etc/systemd/system/foo.service 是个符号链接, 运行 systemctl enable foo.service 时可能遇到这样的错误:

Failed to issue method call: No such file or directory

这是 systemd 的 设计选择 ,可以通过输入绝对路径来规避这个错误:

# systemctl enable /absolute/path/foo.service

相关资源