systemd (简体中文)

https://wiki.archlinux.org/index.php?title=systemd_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&oldid=228354#.E5.AE.89.E8.A3.85

Revision as of 03:50, 13 October 2012 by Jobinson99 (talk | contribs) (→‎shell 短命令)
( diff) ← Older revision | Latest revision ( diff) | Newer revision → ( diff)

Template:Article summary startTemplate:Article summary textTemplate:Article summary headingTemplate:Article summary wikiTemplate:Article summary wikiTemplate:Article summary wiki - 开发者已经将 udev 整合到 systemd 中。Template:Article summary end

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

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

提示: Arch 的启动系统正在向 systemd 迁移,原因参见 该帖。

另见维基百科上的介绍。

Contents

  • 1 迁移前需注意
  • 2 安装
    • 2.1 纯 systemd 安装
    • 2.2 混合安装
    • 2.3 Supplementary information
  • 3 原生 systemd 配置文件
    • 3.1 主机名
    • 3.2 控制台字体和键盘布局
    • 3.3 本地化设置
    • 3.4 时区
    • 3.5 硬件时钟
    • 3.6 开机加载内核模块
    • 3.7 禁用内核模块
    • 3.8 临时文件
    • 3.9 挂载网络文件系统
    • 3.10 用 systemd 替代 acpid
    • 3.11 休眠接口
      • 3.11.1 示例
    • 3.12 单元(unit)
  • 4 systemd 命令
    • 4.1 分析系统状态
    • 4.2 使用单元
    • 4.3 电源管理
  • 5 启动级别(runlevel)/目标(target)
    • 5.1 获取当前启动级别/目标
    • 5.2 创建新目标
    • 5.3 目标表
    • 5.4 切换启动级别/目标
    • 5.5 修改默认启动级别/目标
  • 6 启动桌面环境
    • 6.1 使用登录管理器
    • 6.2 使用服务文件
  • 7 systemd 日志
    • 7.1 过滤输出
    • 7.2 日志大小限制
    • 7.3 配合传统日志服务(syslog)
  • 8 网络
    • 8.1 DHCP 动态获取 IP
    • 8.2 其他配置方式
  • 9 Arch 整合
    • 9.1 Initscripts 模拟
    • 9.2 rc.conf
    • 9.3 完全切换到原生 systemd
  • 10 自写服务进程 .service 文件
    • 10.1 依赖关系处理
    • 10.2 类型
    • 10.3 替换已有的文件
    • 10.4 Vim中的语法高亮
  • 11 常见问题
  • 12 优化
    • 12.1 启动过程分析
      • 12.1.1 【不建议】使用 bootchart
    • 12.2 shell 短命令
    • 12.3 精简输出信息
    • 12.4 尽早启动单元
    • 12.5 自动挂载
    • 12.6 启动速度优化
    • 12.7 用户会话
  • 13 疑难解答
    • 13.1 关机/重启十分缓慢
      • 13.1.1 SLiM 和 xfce-session
    • 13.2 If the CUPS service isn't starting on demand
    • 13.3 Disable warning bell
  • 14 相关资源

迁移前需注意

  • 最好先参照 rc.conf (简体中文) 按照最新格式配置 initscripts。完成后,基本上就没什么需要配置的了。
  • 阅读该站,了解 systemd。
  • systemd 自己有一套日志(journal)系统,用于代替 syslog。两者也可以共存,参见:#配合传统日志服务(syslog)。
  • 无需担心 systemd 替换 cronacpidxinetd 等的计划会造成麻烦。至少,目前来讲,继续使用这些服务不会出现问题。

安装

systemd 可以和 Arch 默认的启动系统(initscripts)共存,通过添加/删除内核参数init=/bin/systemd 切换。

纯 systemd 安装

  1. 从[core]仓库安装 systemd
  2. 在启动引导器添加内核参数init=/bin/systemd
  3. 创建systemd 配置文件.
  4. systemctl enable ... 启用服务,替换 rc.conf 中的 daemons。
  5. 重启并删除 init=... 项.
  6. 手动删除initscripts,然后安装systemd-sysvcompat.

混合安装

  1. 从[core]仓库安装 systemd
  2. 在启动引导器添加内核参数init=/bin/systemd
  3. 建议使用systemd 配置文件而不是 Arch 传统的配置文件。现在如果原生文件不存在,还能使用/etc/rc.conf配置变量,但是未来会停止支持 rc.conf.
  4. 建议安装 systemd-arch-units,该包提供了常用系统服务的 systemd 原生服务文件。
  5. 如果要同时使用 syslog 日志文件盒 systemd 日志,请参考后面的# 配合传统日志服务(syslog).

Supplementary information

Note: In a pure systemd installation, installing systemd-sysvcompat removes sysvinit, permits the export of LANG in /etc/locale.conf, and creates symlinks to halt, reboot, etc. You must manually remove initscripts to install systemd-sysvcompat [1].
Tip: If you have quiet in your kernel parameters, you should remove it for your first couple of systemd boots, to assist with identifying any issues during boot.
警告: udev 和很多其他系统软件要求 /usr 在启动早期就挂载。如果 /usr 和根目录不在同一分区,那么必须做一些额外设置。参见 mkinitcpio相关页面 以及 freedesktop.org的相关页面。

原生 systemd 配置文件

Note: You may need to create these files.

如果下列文件不存在,systemd 会从 /etc/rc.conf 读取相关配置。这只是一个临时解决方案,建议所有系统都使用 systemd 的配置文件,这也是目前 initscripts 推荐的配置方式。

提示: 某些文件可能需要手动创建。

主机名

设置主机名为“myhostname”:

/etc/hostname
myhostname

控制台字体和键盘布局

/etc/vconsole.conf 文件用来配置虚拟控制台,包括键盘映射和控制台字体:

/etc/vconsole.conf
KEYMAP=us
FONT=lat9w-16
FONT_MAP=8859-1_to_uni

详情参阅 控制台字体和Keymap.

本地化设置

更多内容参阅 man locale.conf

/etc/locale.conf
LANG=en_US.UTF-8
LC_COLLATE=C

时区

更多内容参阅 man 5 timezone

/etc/timezone
Asia/Shanghai
Note: This file does not obviate the need for /etc/localtime, which is a symbolic link to the desired time zone's zoneinfo file in /usr/share/zoneinfo/.

硬件时钟

systemd 默认识别硬件时钟为协调世界时(UTC),也推荐这样设置。处理夏令时有些麻烦,如果夏令时调整发生在关机时,下次启动时时间会出现问题(更多信息)。最新的内核直接从实时时钟芯片(RTC)读取时间,不使用 hwclock,内核把从 RTC 读取的时间当作 UTC 处理。所以如果硬件时间是地方时,系统启动一开始识别的时间是错误的,之后很快会进行矫正。这可能导致一些问题(尤其是时间倒退时)。

如果同时安装了 Windows 操作系统(默认使用地方时),那么一般 RTC 会被设置为地方时。Windows 其实也能处理 UTC,在注册表中设置下列DWORD键值为1即可:

HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal
警告: 在最新的 Windows 7、 Vista SP2 上,此设置会导致网络时间同步无法使用。而早期的版本中,此设置会导致系统 从睡眠、待机唤醒后出现故障。此外,Windows 还可能因此 无法处理夏令时调整。

如果不想因此弄乱 Windows,systemd 也可以接受本地时:

/etc/adjtime
 
0.0 0.0 0.0
0
LOCAL
注意: The other parameters are still needed but are ignored by systemd. (译者不理解……)
注意: 推荐使用 NTP服务来确保硬件时钟同步。

开机加载内核模块

systemd 读取 /etc/modules-load.d/ 中的配置,加载内核模块。配置文件名称通常为 /etc/modules-load.d/.conf。格式很简单,一行一个要读取的模块名,而空行以及第一个非空格字符为#;的行会被忽略,如:

/etc/modules-load.d/virtio-net.conf
# Load virtio-net.ko at boot
virtio-net

另见:Kernel modules (简体中文)#选项

禁用内核模块

禁用内核模块的方法和 Arch 默认的 initscripts 相同,因为该过程实际由 kmod 处理。参见:Kernel modules (简体中文)#黑名单。

临时文件

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

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

/usr/lib/tmpfiles.d/samba.conf
D /var/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 并不原生支持 /etc/rc.local

详情参见 man tmpfiles.d

挂载网络文件系统

/etc/fstab 中设定的网络文件系统(如 NFS、Samba)无需配置即可正常工作,systemd 将确保网络文件系统在网络链接就绪后挂载。

也可以使用自动挂载功能,使得网络文件系统仅在访问时挂载。添加 x-systemd.device-timeout=超时时间/etc/fstab 部分即可。

详情参见 man systemd.mount

用 systemd 替代 acpid

systemd 能够处理某些电源相关的 ACPI 事件,通过 /etc/systemd/logind.conf 的下列选项配置:

  • HandlePowerKey:按下电源键后关机
  • HandleSleepKey:按下键盘Sleep键后待机
  • HandleLidSwitch:合上笔记本盖后待机

当选项设置为 no-session 时,事件仅在无用户登录时才会触发。设置为 any-session 时,仅在单用户会话时触发。详情参见 man logind.conf

不应在 GNOME、Xfce 这类能处理 ACPI 事件的桌面环境中使用上述选项。但如果不用图形界面,或者使用 i3、awesome 这样简单的桌面环境时,该功能可以替代 acpid 处理 ACPI 事件。

休眠接口

运行 systemctl suspendsystemctl hibernate 命令时,Systemd 不使用pm-utils进行系统休眠。所以pm-utils钩子和用户自定义钩子都不会运行。Systemd 提供了一个类似的机制,在事件发生时,运行/usr/lib/systemd/system-sleep/中的所有可执行文件。运行时会传入两个参数:

  • prepost,标示机器是关闭还是唤醒
  • suspendhibernate,标示使用的休眠方式

和pm-utils不通,systemd会并行执行脚本,不是按顺序执行。

脚本输出通过systemd-suspend.servicesystemd-hibernate.service记录,可以通过journal查看。

也可以使用 sleep.target, suspend.targethibernate.target 设置要执行的钩子脚本,详情参阅man systemd.specialman systemd-sleep

示例

/usr/lib/systemd/system-sleep/example.sh
case "$1" in
  pre )
    echo going to $2 ...
    ;;
  post )
    echo waking up from $2 ...
    ;;
esac

单元(unit)

一个单元配置文件可以描述如下内容之一:系统服务、socket、系统设备、挂载点、交换分区/文件、启动目标(target)、文件系统路径、由 systemd 管理的计时器。文件格式受 .desktop 文件启发,而最初起源是 Windows 下的 .ini 文件。详情参见 man systemd.unit

systemd 命令

  • systemctl:控制 systemd 状态,包括服务的启动和停止。
  • systemd-cgls:以树形递归显示指定 Linux 控制组(cgroup)的内容
  • systemadm:控制 systemd 状态的图形前端(由 AUR 软件包 systemd-ui-gitAUR 提供)。

详情参见上述工具的 man 手册页。

提示: systemctl 参数中添加 -H <用户名>@<主机名> 可以实现对其他机器的远程控制。该过程使用 SSH 链接。

分析系统状态

输出激活的单元:

$ systemctl

以下命令等效:

$ systemctl list-units

输出运行失败的单元:

$ systemctl --failed

所有可用的单元文件存放在 /usr/lib/systemd/system//etc/systemd/system/ 目录(后者优先级更高)。

使用单元

一个单元可以是系统服务(.service)、挂载点(.mount)、sockets(.sockets)。

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

  • 如果无后缀,sistemctl 默认后缀为.service. 例如netcfgnetcfg.service 是等价的。
    Note: This currently does not work with the commands enable and disable.
  • 挂载点会自动转化为相应的.mount单元。例如/home等价于home.mount
  • 设备会自动转化为相应的.device单元,所以/dev/sda2等价于dev-sda2.device.

立即激活单元:

# systemctl start 

立即停止单元:

# systemctl stop 

重启单元:

# systemctl restart 

命令单元重新读取配置:

# systemctl reload 

输出单元运行状态:

$ systemctl status 

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

$ systemctl is-enabled 

开机自动激活单元:

# systemctl enable 
注意: 如果服务没有安装段落,一般意味着应该通过其它服务自动调用它们。如果真的需要手动安装,可以直接连接服务,将 foo 替换为真实的服务名:
# ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/

取消开机自动激活单元:

# systemctl disable 

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

$ systemctl help 

电源管理

当系统中仅有一个ConsoleKit本地用户会话时,执行下列命令无需 root 权限。否则,systemd 会要求输入 root 密码。

重启:

$ systemctl reboot

退出系统并停止电源(shut down and power-off):

$ systemctl poweroff

退出系统并中断(shut down and halt):

$ systemctl halt

待机:

$ systemctl suspend

休眠:

$ systemctl hibernate

启动级别(runlevel)/目标(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)。可以通过内核参数(grub 菜单 kernel 行)更改默认启动级别:

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

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

# systemctl enable multi-user.target

命令执行情况由 systemctl 显示:链接 /etc/systemd/system/default.target 被创建,指向新的默认启动级别。 该方法当且仅当目标配置文件中有以下内容时有效:

[Install]
Alias=default.target

目前,multi-user.targetgraphical.target 都包含这段内容。

启动桌面环境

使用登录管理器

通过启动登录管理器(或称显示管理器),即可进行图形界面登录。目前,Arch 提供了 GDM、KDM、SLiM、XDM 和 LXDM 的 systemd 服务文件。以 KDM 为例,配置开机启动:

# systemctl enable kdm.service

执行上述命令后,登录管理器应当能正常工作了。如果不是的话,很可能是因为你修改了default.target。默认情况应当如下:

# ls -l /etc/systemd/system/default.target
/etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target

删除被修改的 default.target,systemd 会自动使用默认配置(即 graphical.target):

# rm /etc/systemd/system/default.target

使用服务文件

注意: 使用此方法的话,用户无法创建 PAM 会话。因此,ConsoleKit(赋予用户关机、操作声音设备等权限的程序)无法正常工作。更好的方案,参见: Automatic_login_to_virtual_console#With_systemd。

这个方法不需要登录管理器,直接启动了X。方法是创建一个新的服务文件:

/etc/systemd/system/graphical.target.wants/xinit.service
[Unit]
Description=Direct login to X
After=systemd-user-sessions.service

[Service]
ExecStart=/bin/su  -l -c "/bin/bash --login -c xinit"

[Install]
WantedBy=graphical.target

systemd 日志

自版本 38 起,systemd 提供了自己日志系统(logging system),称为 journal(还是日志的意思)。

使用 systemd 日志,无需额外安装日志服务(syslog)。读取日志的命令:

# journalctl

日志记录在虚拟文件系统内(/run/systemd/journal),所以重启后就会消失。要保留的话,需手动创建目录 /var/log/journal/

# mkdir /var/log/journal/

过滤输出

journalctl可以根据特殊字段过滤输出,例如:

显示给定可执行文件的所有消息:

# journalctl /usr/lib/systemd/systemd

显示指定过程的所有消息:

# journalctl _PID=1

显示指定单元的所有消息:

# journalctl _SYSTEMD_UNIT=netcfg.service

详情参阅man journalctlsystemd.journal-fields

日志大小限制

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

SystemMaxUse=50M

详情参见 man journald.conf.

配合传统日志服务(syslog)

systemd 提供了 socket /run/systemd/journal/syslog,以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 /dev/log(http://lwn.net/Articles/474968/ 官方说明)。以 Arch 原先默认的 syslog-ng 服务为例,修改 /etc/syslog-ng/syslog-ng.conf 的 source 部分:

source src {
    unix-dgram("/run/systemd/journal/syslog");
    internal();
    file("/proc/kmsg");
};

设置开机启动 syslog-ng:

# systemctl enable syslog-ng.service

网络

DHCP 动态获取 IP

如果使用 DHCP 动态获取 IP,可以使用 dhcpcd 软件包提供的 [email protected]。例如,为 eth0 启用 DHCP:

# systemctl start [email protected]

设置开机自动配置:

 # systemctl enable [email protected]

其他配置方式

对于静态IP、无线网络或其他上网方式,建议使用 netcfg 或 NetworkManager,两者都提供了 systemd 服务文件。

Note: 如果使用 NetworkManager,启用 NetworkManager-wait-online.service 服务可以让单元依赖于 network.target等待网络连接建立才启动。

如果使用静态IP,又不想用额外的工具,可以手动创建一个服务。

Arch 整合

Initscripts 模拟

initscripts 软件包提供了 systemd 和 Arch 传统配置的整合。这种模拟方便用户向 systemd 的转换。/etc/inittab 彻底废弃。

If you disabled Template:Keypress to reboot in /etc/inittab, you will have to reconfigure this setting for systemd by running systemctl mask ctrl-alt-del.target as root.

rc.conf

/etc/rc.conf 中的部分设置仍然可用。不过还是使用原生 systemd 配置代替为好。

支持的变量:

  • LOCALE
  • KEYMAP
  • CONSOLEFONT
  • CONSOLEMAP
  • HOSTNAME
  • DAEMONS

不支持的变量,以及替代的 systemd 设置:

  • TIMEZONE:自行建立软链接 /etc/localtime,指向对应的时区文件(比如 /usr/share/zoneinfo/Asia/Shanghai)。
  • HARDWARECLOCK:参见#硬件时钟。
  • USELVM:使用 lvm2 提供的 lvm.service 代替。
  • USECOLOR
  • MODULES

完全切换到原生 systemd

注意: 这是推荐的方法,这样系统不再需要 rc.conf,而是使用原生 systemd 配置文件。

按照 Systemd 原生配置文件的介绍,将/etc/rc.conf中的段落替换为相应的配置文件:

配置内容 配置文件 /etc/rc.conf段落
Hostname /etc/hostname

/etc/hosts

NETWORKING
终端字体和键盘映射 /etc/vconsole.conf LOCALIZATION
Locale /etc/locale.conf

/etc/locale.gen

LOCALIZATION
时区 /etc/timezone

/etc/localtime

LOCALIZATION
硬件时钟 /etc/adjtime LOCALIZATION
内核模块 /etc/modules-load.d/ HARDWARE
Daemons /etc/rc.conf DAEMONS
有线网络 /etc/rc.conf NETWORKING

因为历史原因,/etc/rc.conf中的DAEMONS段落依然与 systemd 兼容,可以用来在开机时启动服务。你可以选择删除/etc/rc.conf文件并完全通过 systemd 启动服务。对每个 DAEMONS 中的服务名,执行:

# systemctl enable .service
Tip: 服务的对应列表位于 这里。

如果服务名 .service 不存在:

  • systemd 可能还没有提供相应的服务文件,这时只能通过rc.conf启动服务。
  • systemd 中服务名可能有变化:
    • cronie.service 替代了crond
    • alsa-store.servicealsa-restore.service 替代了 alsa
    • network被几个服务文件替代,详情参阅网络部分。
  • systemd 会自动处理这些服务的启动顺序。
  • 有些服务不需要用户明确启用,例如只要安装了dbus-coredbus.service就会自动启动。可以通过systemctl命令检查服务的启动状态。
Tip: 可以检查软件包提供的文件,看看服务使用哪个启动脚本。例如:
$ pacman -Ql cronie
[...]
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
[...]

自写服务进程 .service 文件

依赖关系处理

With systemd dependencies can be resolved by designing the unit files correctly. The most typical case is that the unit A requires the unit B to be running before A is started. In that case add Requires=B and After=B to the [Unit] section of A. If the dependency is optional, add Wants=B and After=B instead. Note that Wants= and Requires= do not imply After=, meaning that if After= is not specified, the two units will be started in parallel.

Dependencies are typically placed on services and not on targets. For example, network.target is pulled in by whatever service configures your network interfaces, therefore ordering your custom unit after it is sufficient since network.target is started anyway.

类型

There are several different start-up types to consider when writing a custom service file. This is set with the Type= parameter in the [Service] section. See man systemd.service for a more detailed explanation.

  • Type=simple: systemd considers the daemon 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.
  • Type=forking: systemd considers the daemon 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, as most daemons use double-forking to signal that they are ready. You should specify PIDFile= as well so systemd can keep track of the main process.
  • Type=oneshot: This is useful for scripts that do a single job and then exit. You may want to set RemainAfterExit= as well so that systemd still considers the service as active after the process has exited.
  • Type=notify: Identical to Type=simple, but with the stipulation that the daemon will send a signal to systemd when it is ready. This requires systemd-specific code provided by libsystemd-daemon.so.
  • Type=dbus: The daemon is considered ready when the specified BusName appears on DBus's system bus.

替换已有的文件

The unit files in /etc/systemd/system/ take precedence over the ones in /usr/lib/systemd/system/.To make your own version of a unit (which will not be destroyed by an upgrade), copy the old unit file from /usr/lib/ to /etc/ and make your changes there. Alternatively you can use .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:

/etc/systemd/system/.service
.include /usr/lib/systemd/system/.service

[Unit]
Requires=
After=

Then run the following for your changes to take effect:

# systemctl reenable 
# systemctl restart 
Tip: You can use systemd-delta to see which unit files have been overridden and what exactly has been changed.

Vim中的语法高亮

Syntax highlighting for systemd unit files within Vim can be enabled by installing vim-systemdAUR from the AUR.

常见问题

最新的已知问题,参见:TODO。

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

优化

启动过程分析

systemd 提供了一个分析启动过程的工具 —— systemd-analyze。可以用它看看哪些单元拖慢了开机过程,并据此进行优化。安装 python2-dbuspython2-cairo 软件包后该工具才能工作。

查看开机过程在内核/用户空间消耗的时间:

$ systemd-analyze

Template:技巧

按照耗费时间顺序,输出启动每个单元耗费的时间:

$ systemd-analyze blame

生成类似于 bootchart 的开机过程图表:

$ systemd-analyze plot > plot.svg

【不建议】使用 bootchart

由于没有办法在内核参数设置两个 init,所以不能使用源里的 bootchart。不过,AUR 软件包 bootchart2AUR 提供了一个的 systemd 服务,安装后启用即可:

# systemctl enable bootchart.service

详情参阅 bootchart 文档。

shell 短命令

systemd 的管理命令都死长死长的,可以向 ~/.bashrc 添加下面的内容,简化命令以保护键盘:

# 简化systemd命令,例如sudo systemctl stop xxx.service 简化后变成 0.stop xxx
if ! systemd-notify --booted;
then  # 兼容不用 systemd 的情况
    0.start() {
        sudo rc.d start $1
    }

    0.restart() {
        sudo rc.d restart $1
    }

    0.stop() {
        sudo rc.d stop $1
    }
else
# start systemd service
# 运行一个守护进程
    0.start() {
        sudo systemctl start $1.service
    }
# restart systemd service
# 重启一个守护进程
    0.restart() {
        sudo systemctl restart $1.service
    }
# stop systemd service
# 关闭一个守护进程
    0.stop() {
        sudo systemctl stop $1.service
    }
# enable systemd service
# 启用一个守护进程
    0.enable() {
        sudo systemctl enable $1.service
    }
# disable a systemd service
# 停用一个守护进程
    0.disable() {
        sudo systemctl disable $1.service
    }
# show the status of a service
# 查看一个守护进程状态
    0.status() {
        systemctl status $1.service
    }
# reload a service configuration
# 重新加载一个守护进程的配置文件
    0.reload() {
        sudo systemctl reload $1.service
    }
# list all running service
# 列出所有运行中的守护进程
    0.list() {
        systemctl
    }
# list all failed service
# 列出所有运行失败的守护进程
    0.failed () {
        systemctl --failed
    }
# list all systemd available unit files
# 列出所有可用的进程文件
    0.list-files() {
        systemctl list-unit-files
    }
# check the log
# 查看系统日志
    0.log() {
        sudo journalctl
    }
# show wants
# 列出某个目标所需要的进程
    0.wants() {
        systemctl show -p "Wants" $1.target
    }
# analyze the system
# 查看启动进程所耗时间
    0.analyze() {
        systemd-analyze $1
    }
fi

精简输出信息

修改启动加载器内核参数中的 verbosequiet 即可。对于某些用户,特别是 SSD 用户,TTY 的龟速实际上成为了性能瓶颈,精简输出信息实际上有利于提高性能。

尽早启动单元

systemd 的一个重要特性是 dbus 总线式和 socket 式任务激活,即服务仅在第一次被使用时才启动,通常来说这样是很有好处的。不过,某些服务(比如 console-kit)开机时肯定是要启动的,早点启动反而节约时间(只是有些服务支持这样做):

# systemctl enable console-kit-daemon.service

这样 systemd 就会尽早启动 console-kit,而不必等待激活。

自动挂载

默认情况下,多数服务的启动必须等待磁盘检查和挂载所有文件系统。如果你的 /home 分区很大,最好还是让不需要这个分区的服务先启动,/home 在一边慢慢检查。添加下列内容到 /etc/fstab 对应行的 options 列即可:

noauto,x-systemd.automount

这样,只有 /home 第一次被访问时才会检查和挂载。内核会负责缓冲所有对 /home 的 I/O 操作,直到分区就绪。

如果使用带有密码文件的加密文件系统,也可以在 /etc/crypttab 中的相应项添加 noauto 参数。这样,systemd 不会在开机时就挂载加密文件系统,而要等待首次访问后再使用特定密码文件挂载。如果使用加密的 RAID 设备,这样或许可以节约几秒开机时间。例如:

/etc/crypttab
data /dev/md0 /root/key noauto

启动速度优化

systemd 自己实现了一个 readahead,可以用来提高开机效率。不过,效果会因内核版本和硬件情况而不同(极端的还会变慢)。开启 readahead:

# systemctl enable systemd-readahead-collect.service systemd-readahead-replay.service

要知道,readahead 的超级牛力只有在重启几次后才会显现。

用户会话

systemd 可以将用户会话划分进不同的 cgroups。添加 session optional pam_systemd.so/etc/pam.d/ 中相关文件(例如,控制 tty 登录的 login,控制远程登录的 sshd,控制需要密码的 KDM 登录的 kde,控制 KDM 自动登录的 kde-np)。

操作前:

$ systemd-cgls systemd:/system/[email protected]
systemd:/system/[email protected]:
├ tty5
│ └ 904 /sbin/agetty tty5 38400
├ tty2
│ ├ 13312 /bin/login --
│ └ 15765 -zsh
[…]

操作后:

$ systemd-cgls systemd:/user/example/
systemd:/user/example/:
├ 4
│ ├   902 /bin/login --
│ └ 16016 -zsh
[…]

进一步,可以完全用 systemd 替代 ConsoleKit。不过,必须手动从 ABS 重新编译 polkit,添加 systemd 支持(--enable-systemd)。这样,即使不用 ConsoleKit,用户也有自动挂载U盘之类的权限了。DBus 自 1.6.0 版本就支持 systemd,无需从 git 重新编译。

疑难解答

关机/重启十分缓慢

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

SLiM 和 xfce-session

目前,已知会导致关机缓慢的一种情况是,Xfce 配合 SLiM:使用 xfce-session 关机/重启会导致 slim.service 卡死,直到半分钟后 systemd 杀死它。一个解决方案是,使用修改版 slim.service:

/etc/systemd/system/slim.service
[Unit]
Description=SLiM Simple Login Manager
After=systemd-user-sessions.service

[Service]
Type=forking
PIDFile=/var/lock/slim.lock
ExecStart=/usr/bin/slim -d
ExecStop=/bin/kill -9 $MAINPID
ExecStopPost=/bin/rm /var/lock/slim.lock

[Install]
WantedBy=graphical.target

这样关机时 SLiM 就会被 SIGKILL 信号终止。由于 lock 文件也已并移除了,不会导致下次开机出现故障。

If the CUPS service isn't starting on demand

I found on my machine, even after running "systemctl enable cups.service", cups would never work until I manually issued "systemctl start cups.service". To remedy this you can manually symlink the cups service so its automatically started at boot:
# sudo ln -s '/usr/lib/systemd/system/cups.service' '/etc/systemd/system/multi-user.target.wants/cups.service'

Disable warning bell

Add command xset -b to the .xinitrc file.Discussion on this forum topic.



你可能感兴趣的:(linux)