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

From ArchWiki
Jump to: navigation, search
m
m
Line 7: Line 7:
 
[[it:Systemd]]
 
[[it:Systemd]]
 
[[ru:Systemd]]
 
[[ru:Systemd]]
[[zh-CN:Systemd]]
 
 
{{Article summary start}}
 
{{Article summary start}}
 
{{Article summary text|'''systemd''' 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本(init scripts)。systemd的特性有:支持积极并行化任务;同时采用 socket 式与 [[D-Bus (简体中文)|D-Bus]] 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 [[cgroups (简体中文)|cgroups]] 监视进程;支持快照和系统恢复;维护挂载点;各服务间基于依赖关系进行精密控制。systemd 完全可以替代 Arch 默认的 sysvinit 启动系统。}}
 
{{Article summary text|'''systemd''' 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本(init scripts)。systemd的特性有:支持积极并行化任务;同时采用 socket 式与 [[D-Bus (简体中文)|D-Bus]] 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 [[cgroups (简体中文)|cgroups]] 监视进程;支持快照和系统恢复;维护挂载点;各服务间基于依赖关系进行精密控制。systemd 完全可以替代 Arch 默认的 sysvinit 启动系统。}}

Revision as of 11:10, 15 July 2012

Template:Article summary start Template:Article summary text Template:Article summary heading Template:Article summary wiki Template:Article summary end

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

systemd 的详细介绍参见:

安装

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

  1. 从[core]仓库安装 systemd
  2. 在启动引导器添加内核参数(grub 菜单 kernel 行)init=/bin/systemd
  3. (可选)如果希望完全使用 systemd,可以移除 initscripts 并安装 systemd-sysvcompat。删除 sysvinit 后,由该包提供一些基本命令(initreboot 等)的链接。之后,可以删除上一步添加的内核参数。
  4. 建议安装 systemd-arch-units,该包提供了常用系统服务的 systemd 原生服务文件。
  5. 启用原来 rc.conf 中配置的自启动服务,systemd 无法完全兼容该文件。
警告: udev 和很多其他系统软件要求 /usr 在启动早期就挂载。如果 /usr 和根目录不在同一分区,那么必须做一些额外设置。参见 mkinitcpio相关页面 以及 freedesktop.org的相关页面

原生 systemd 配置文件

如果下列文件不存在,systemd 会从 /etc/rc.conf 读取相关配置。

小贴士: 某些文件可能需要手动创建。

主机名

设置主机名为“myhostname”:

/etc/hostname
myhostname

控制台和键盘布局

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

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

Locale

更多内容参阅 man locale.conf

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

时区

更多内容参阅 man 5 timezone

/etc/timezone
Asia/Shanghai
注意: 设置该文件后仍需配置 /etc/localtime

硬件时钟

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/<program>.conf。格式很简单,一行一个要读取的模块名,而空行以及第一个非空格字符为#;的行会被忽略,如:

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

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

禁用内核模块

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

临时文件

/etc/tmpfiles.d/ 中的文件描述了 systemd-tmpfiles 如何创建、清理、删除临时文件和目录,这些文件和目录通常存放在 /run/tmp 中。配置文件名称为 /etc/tmpfiles.d/<program>.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 中设定的网络文件系统(如 NFSSamba)无需配置即可正常工作,systemd 将确保网络文件系统在网络链接就绪后挂载。

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

详情参见 man systemd.mount

用 systemd 替代 acpid

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

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

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

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

单元(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 控制单元时,必须使用单元文件的全名,包括扩展名(例如 netcfg.service)。详情参见 man systemd.unit

立即激活单元:

# systemctl start <unit>

立即停止单元:

# systemctl stop <unit>

重启单元:

# systemctl restart <unit>

命令单元重新读取配置:

# systemctl reload <unit>

输出单元运行状态:

$ systemctl status <unit>

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

$ systemctl is-enabled <unit>

开机自动激活单元:

# systemctl enable <unit>

取消开机自动激活单元:

# systemctl disable <unit>

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

$ systemctl help <unit>

电源管理

当系统中仅有一个本地用户会话时,执行下列命令无需 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

该命令对下次启动无影响。

修改默认启动级别/目标

开机启动进的目标是 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 提供了 GDMKDMSLiMXDMLXDM 的 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

如果使用 /etc/locale.conf 配置了 locale,那么还需要添加以下项到 /etc/environment

/etc/environment
LANG=en_US.utf8

使用服务文件

注意: 使用此方法的话,用户无法创建 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 <username> -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/

日志大小限制

如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 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/loghttp://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

systemd 的日志服务默认也会从 /proc/kmsg 读取内核信息,这就做了和传统日志服务相同的事(systemd-devel 相关帖子)。可以修改 /etc/systemd/journald.conf 来关闭 systemd 日志的这一功能:

ImportKernel=no

网络

DHCP 动态获取 IP

如果使用 DHCP 动态获取 IP,可以使用 systemd-arch-units 软件包提供的 dhcpcd@.service。例如,为 eth0 启用 DHCP:

# systemctl start dhcpcd@eth0.service

设置开机自动配置:

# systemctl enable dhcpcd@.service

注意,这样只会启用 eth0 的自动配置。如果还要配置其他链接,需要手动创建软连接:

# ln -s '/usr/lib/systemd/system/dhcpcd@.service' '/etc/systemd/system/multi-user.target.wants/dhcpcd@eth1.service'

其他配置方式

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

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

Arch 整合

initscripts-systemd 软件包提供了 systemd 和 Arch 传统配置的整合。该包包含了模拟 Arch 原启动脚本的单元文件和脚本,可用于从 sysVinit 过渡。

/etc/inittab 彻底废弃。

启用 rc-local.servicerc-local-shutdown.service 后,/etc/rc.local/etc/rc.local.shutdown 在分别在开关机时执行。

警告: 不推荐使用该软件包。比如,arch-load-modules.servicearch-daemons.target 在以后就会被移除。尽量使用 systemd 原生配置。

如果不需要某些单元,可以禁用掉:

# systemctl disable <unitfile>

以后会逐渐移除这个包的大多数功能,因为其他东西(udev/systemd/内核)将代为行使这些功能。

rc.conf

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

支持的变量:

  • LOCALE
  • KEYMAP
  • CONSOLEFONT
  • CONSOLEMAP
  • HOSTNAME
  • MODULES
  • DAEMONS:仍按顺序,支持禁用服务。如果有同名的 systemd 服务,此设置优先。可以通过 systemctl disable arch-daemons.target 关闭。

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

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

下面对 Arch 整合相关的单元一一做简要说明,并介绍 systemd 的替代方案。

rc-local.service / rc-local-shutdown.service

分别在开关机时执行 /etc/rc.local/etc/rc.local.shutdown

arch-daemons.target

处理 /etc/rc.conf 中的 DAEMONS 数组,启动服务。如果有同名 systemd 单元,启动相应单元,否则使用 /etc/rc.d/ 中的脚本。

替代方案:使用 systemd-arch-units 软件包提供的 systemd 单元。

arch-modules-load.service

根据 /etc/rc.conf 创建要加载的模块列表 /etc/modules-load.d/rc.conf,供 systemd 处理。

替代方案:在 /etc/modules-load.d/ 创建 *.conf,写入要加载的模块。

FAQ

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

Template:FAQ

Template:FAQ

Template:FAQ Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

Template:FAQ

优化

systemd-analyze

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

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

systemd-analyze
小贴士: 如果在 /etc/mkinitcpio.confHOOKS 数组添加 timestamp,并重新生成内存盘(initramfs),systemd-analyze 还可以显示处理内存盘花费的时间。

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

systemd-analyze blame

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

systemd-analyze plot > plot.svg

使用 bootchart

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

# systemctl enable bootchart.service

详情参阅 bootchart 文档

shell 短命令

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

if ! systemd-notify --booted; then  # 兼容不用 systemd 的情况
  start() {
    sudo rc.d start $1
  }

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

  stop() {
    sudo rc.d stop $1
  }
else
  start() {
    sudo systemctl start $1.service
  }

  restart() {
    sudo systemctl restart $1.service
  }

  stop() {
    sudo systemctl stop $1.service
  }

  enable() {
    sudo systemctl enable $1.service
  }

  status() {
    sudo systemctl status $1.service
  }

  disable() {
    sudo systemctl disable $1.service
  }
fi

精简输出信息

在 GRUB 修改内核参数(kernel 行)中的 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

readahead

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/getty@.service
systemd:/system/getty@.service:
├ 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 文件也已并移除了,不会导致下次开机出现故障。

相关资源