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

From ArchWiki
Jump to: navigation, search
(安装)
(原生 systemd 配置文件)
Line 54: Line 54:
  
 
== 原生 systemd 配置文件 ==
 
== 原生 systemd 配置文件 ==
{{注意|可能需要手动创建文件,将权限设置为 644,属于 root:root.}}
+
{{注意|可能需要手动创建某些文件。所有文件的权限都是644,属主 root,属组 root。}}
如果下列文件不存在,{{Pkg|systemd}} 会从 {{ic|/etc/rc.conf}} 读取相关配置。这只是一个临时解决方案,建议所有系统都使用 systemd 的配置文件,这也是目前 initscripts 推荐的配置方式。
+
{{注意|某些文件可能需要手动创建。}}
+
  
 
=== 主机名 ===
 
=== 主机名 ===
主机名通过文件{{ic|/etc/hostname}}进行配置。该文件不应包含系统的域名(如果有)。使用如下命令设置主机名:
+
主机名通过文件 {{ic|/etc/hostname}} 进行配置。该文件不应包含系统的域名(如果有)。使用如下命令设置主机名:
 
  # hostnamectl set-hostname '''myhostname'''
 
  # hostnamectl set-hostname '''myhostname'''
  
更多细节请查看{{ic|man 5 hostname}}和{{ic|man 1 hostnamectl}}。
+
详情参见 {{ic|man 5 hostname}} 和 {{ic|man 1 hostnamectl}}。
  
示例文件:
+
文件示例:
 
{{hc|/etc/hostname|
 
{{hc|/etc/hostname|
 
myhostname
 
myhostname
 
}}
 
}}
  
=== 本地化设置 ===
+
=== 本地化设置(locale) ===
The default system locale is configured in {{ic|/etc/locale.conf}}. To set the default locale, do:
+
系统默认 locale 记录在 {{ic|/etc/locale.conf}} 文件中。通过如下命令配置:
  # localectl set-locale LANG="de_DE.utf8"
+
  # localectl set-locale LANG="zh_CN.utf8"
  
{{注意|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}}.}}
+
{{注意|设置默认locale前,请确保已经生成该locale。方法是:在 {{ic|/etc/locale.gen}} 中启用对应locale,然后以root权限执行 {{ic|locale-gen}}}}
  
See {{ic|man 1 localectl}} and {{ic|man 5 locale.conf}} for details.
+
详情参见 {{ic|man 1 localectl}} {{ic|man 5 locale.conf}}
  
详情请参阅[[Locale]]。
+
* 另参阅 [[Locale (简体中文)]]。
  
示例文件:
+
文件示例:
 
{{hc|/etc/locale.conf|<nowiki>
 
{{hc|/etc/locale.conf|<nowiki>
 
LANG=en_US.utf8
 
LANG=en_US.utf8
Line 85: Line 83:
  
 
=== 虚拟控制台 ===
 
=== 虚拟控制台 ===
{{ic|/etc/vconsole.conf}} 文件用来配置虚拟控制台,包括键盘映射和控制台字体:
+
{{ic|/etc/vconsole.conf}} 文件用来配置虚拟控制台,包括键盘布局和控制台字体:
 
{{hc|/etc/vconsole.conf|<nowiki>
 
{{hc|/etc/vconsole.conf|<nowiki>
 
KEYMAP=us
 
KEYMAP=us
Line 91: Line 89:
 
FONT_MAP=8859-1_to_uni</nowiki>}}
 
FONT_MAP=8859-1_to_uni</nowiki>}}
  
{{注意|{{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.}}
+
{{注意|{{ic|{{Pkg|systemd}}-194}} 默认使用内核字体和键盘布局,因此以后不必在上述文件中留下空的 {{ic|1=KEYMAP=}} {{ic|1=FONT=}} 设置。}}
  
Another way to set the keyboard mapping (keymap) is doing:
+
还可以通过命令设置键盘布局:
 
  # localectl set-keymap de
 
  # localectl set-keymap de
  
This has the advantage that it will also set the same keymap for use in X11.
+
该方法的优点是设置可以应用于X11:
See {{ic|man 1 localectl}} and {{ic|man 5 vconsole.conf}} for details.
+
详情参见 {{ic|man 1 localectl}} {{ic|man 5 vconsole.conf}}
  
详情参阅 [[Fonts#Console_fonts|控制台字体]]和[[KEYMAP#Keyboard_layouts|Keymap]].
+
* 另参阅 [[Fonts (简体中文)#控制台字体|控制台字体]] 和 [[KEYMAP (简体中文)#键盘布局|键盘布局]]
  
 
=== 时区 ===
 
=== 时区 ===
Line 110: Line 108:
 
手动创建链接也行:
 
手动创建链接也行:
 
  # ln -sf ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime
 
  # ln -sf ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime
 +
 +
旧的配置文件 {{ic|/etc/timezone}} 已经没用了,可以安全删除。
  
 
=== 硬件时钟 ===
 
=== 硬件时钟 ===

Revision as of 02:44, 31 December 2012

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

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

摘自项目主页:

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

注意: 这个帖子详细解释了 Arch 向 systemd 迁移的原因。

另见维基百科上的介绍

迁移前需考虑

  • 阅读该站,了解 systemd。
  • systemd 自己有一套日志(journal)系统,用于代替 syslog。两者也可以共存,参见后面的日志部分
  • 虽然 systemd 可以替换 cronacpidxinetd 等的部分功能。至少目前还可以继续使用这些服务,无需立即切换。
  • 交互式 initscripts 启动脚本在 systemd 中无法工作。例如 netcfg-menu 无法在启动时显示。

安装

注意: 2012-10-13版安装介质开始,安装程序已经默认安装systemdsystemd-sysvcompat
注意: 如果是在 VPS 中使用 Arch,请先阅读:Virtual_Private_Server#Moving_your_VPS_from_initscripts_to_systemd

本部分帮助还在使用sysvinitinitscripts 的用户迁移到systemd.

  1. 官方软件仓库安装 systemd 并添加内核参数init=/usr/lib/systemd/systemd
  2. systemctl enable daemonname 启用 /etc/rc.conf 中的守护进程。从 /etc/rc.conf 到 systemd 服务的转换可以参考:守护进程列表Services
  3. 重启系统,执行命令 cat /proc/1/comm,如果返回systemd,表示 systemd 已经正常启动。
  4. 确认主机名已经正确设置:hostnamectl set-hostname myhostname
  5. 删除 initscriptssysvinit,并安装systemd-sysvcompat.
  6. 可选,删除init=/usr/lib/systemd/systemd内核参数,现在已经不需要它了,systemd-sysvcompat提供了默认的 init.

附加信息

  • 如果内核参数中有 quiet,可以先删除它以便调试。
  • 使用 Systemd 的时候无需将用户加入optical, audio, scanner用户组。加入这些组反而会有问题,例如audio组会导致程序阻塞软件混声。每个 PAM 登录都拥有一个 logind 会话,它通过POSIX ACLs,赋予本地会话以声音设备访问权限、通过udisks挂载和卸载移动设备的权限等。
注意: 对于使用 startx -- vt7 进入X环境的用户,由于 logind 会话无法应用于X环境,用户必须加入这些组。
  • 如果卸载 initscriptsrc.conf 将不再有效。如果曾在其中设置了静态网络,或还未迁移到systemd的系统服务,请根据该节配置。
  • 如果 fstab 中有 LVM 设备,首次启动时会因为等待超时进入急救控制台。输入管理员密码,执行 systemctl enable lvm 启用相关服务,重启即可。

原生 systemd 配置文件

注意: 可能需要手动创建某些文件。所有文件的权限都是644,属主 root,属组 root。

主机名

主机名通过文件 /etc/hostname 进行配置。该文件不应包含系统的域名(如果有)。使用如下命令设置主机名:

# hostnamectl set-hostname myhostname

详情参见 man 5 hostnameman 1 hostnamectl

文件示例:

/etc/hostname
myhostname

本地化设置(locale)

系统默认 locale 记录在 /etc/locale.conf 文件中。通过如下命令配置:

# localectl set-locale LANG="zh_CN.utf8"
注意: 设置默认locale前,请确保已经生成该locale。方法是:在 /etc/locale.gen 中启用对应locale,然后以root权限执行 locale-gen

详情参见 man 1 localectlman 5 locale.conf

文件示例:

/etc/locale.conf
LANG=en_US.utf8

虚拟控制台

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

/etc/vconsole.conf
KEYMAP=us
FONT=lat9w-16
FONT_MAP=8859-1_to_uni
注意: systemd-194 默认使用内核字体和键盘布局,因此以后不必在上述文件中留下空的 KEYMAP=FONT= 设置。

还可以通过命令设置键盘布局:

# localectl set-keymap de

该方法的优点是设置可以应用于X11: 详情参见 man 1 localectlman 5 vconsole.conf

时区

时区可通过创建适当的/etc/localtime符号链接来进行配置,该链接需指向目录/usr/share/zoneinfo/下的一个zoneinfo文件。也可执行以下命令直接完成这一操作:

# timedatectl set-timezone Asia/Shanghai

更多细节参见man 1 timedatectlman 5 localtimeman 7 archlinux

手动创建链接也行:

# ln -sf ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime

旧的配置文件 /etc/timezone 已经没用了,可以安全删除。

硬件时钟

systemd 默认识别硬件时钟为协调世界时(UTC)。

小贴士: 推荐使用NTP服务来确保硬件时钟同步。

Hardware clock in localtime

If you want to change the hardware clock to use local time (STRONGLY DISCOURAGED) do:

# timedatectl set-local-rtc true

If you want to revert to the hardware clock being in UTC, do:

# timedatectl set-local-rtc false

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

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

HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

详情参阅Time.

内核模块

目前,所有必要模块的加载均由 udev 自动完成。所以,如果不需要使用任何额外的模块,就没有必要在任何配置文件中添加启动时加载的模块。但是,有些情况下可能需要在系统启动时加载某个额外的模块,或者将某个模块列入黑名单以便使系统正常运行。

开机加载

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

另见man 5 modules-load.d

禁用内核模块

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

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

详情参见 man systemd.mount

Filesystem mounts

The default setup will automatically fsck and mount filesystems before starting services that need them to be mounted./etc/fstab 中设定的网络文件系统(如 NFSSamba)无需配置即可正常工作,systemd 将确保网络文件系统在网络链接就绪后挂载。/etc/fstab中设置的本地和远程文件系统应该能够正常工作。

See man 5 systemd.mount for details.

自动挂载

  • 如果你的 /home 分区较大,在开机校验(fsck)/home分区时, 最好别设置其他服务去依赖 /home 后启动. 你可以把下面这参数添加到 /etc/fstab 文件中 /home 的参数部分来实现:
noauto,x-systemd.automount

这时/home分区在获得访问权限后会自动校验和挂载, 并且内核会缓存所有的文件操作直到/home分区准备完成,这可以最大限度的提升系统启动的速度响应.

  • 挂载远程文件系统也是同理. 如果你仅想在需要的时候才挂载, 也可以给参数添加noauto,x-systemd.automount. 另外,你可以设置x-systemd.device-timeout=#参数的超时选项以防止网络资源不能访问的时候浪费时间.
  • 如果你的加密文件系统需要密钥, 你就需要添加noauto参数到 /etc/crypttab 文件中的对应位置. Systemd开机的时候就不会打开这个加密设备, 但是会一直等到用对应密钥获得访问权限后才自动挂载. 比如在使用加密RAID设备的时候可以节省一定的时间,因为systemd不得不等到设备可用后才能访问. 例如:
/etc/crypttab
data /dev/md0 /root/key noauto

LVM

If you have LVM volumes not activated via the initramfs, enable the lvm-monitoring service, which is provided by the lvm2 package:

# systemctl enable lvm-monitoring

Similarly, if you have LVM on encrypted devices mounted later during boot (e.g. from /etc/crypttab), enable the lvm-on-crypt service, which is also provided by the lvm2 package:

# systemctl enable lvm-on-crypt

ACPI 电源管理

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

  • HandlePowerKey:按下电源键后的动作
  • HandleSleepKey:按下挂起键后的动作
  • HandleHibernateKey: 按下休眠键后的动作
  • HandleLidSwitch:合上笔记本盖后待机

动作可以是 ignore, poweroff, reboot, halt, suspend, hibernatekexec.

系统默认设置为:

HandlePowerKey=poweroff
HandleSuspendKey=suspend
HandleHibernateKey=hibernate
HandleLidSwitch=suspend

如果不用图形界面,或者使用 i3awesome 这样简单的桌面管理器时,systemd 可以替代 acpid 处理 ACPI 事件。

注意: Systemd cannot handle AC and Battery ACPI events, so if you use Laptop Mode Tools or other similar tools acpid is still required.

在当前版本的 systemd 中,这些 Handle 选项将会被应用到整个系统当中,除非它们被别的程序——例如某个桌面环境中的电源管理器——给“阻止”(inhibited)。如果其它的程序没有阻止这些 Handle ,你可能会先被 systemd 挂起你的系统,然后当系统被唤醒之后,电源管理器又会再次将系统挂起。

注意: 目前只有GNOMEKDE 支持 "inhibited" 命令。在其它的桌面管理器同样实现该功能之前,如果你想使用Xfce, acpid 或者其它程序来管理 ACPI 事件,你需要把 Handle 选项设置为 ignore 。包含该功能的新版本还在开发当中。
注意: 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.

Sleep hooks

Systemd does not use pm-utils to put the machine to sleep when using systemctl suspend, systemctl hibernate or systemctl hybrid-sleep; pm-utils hooks, including any custom hooks, will not be run. However, systemd provides two similar mechanisms to run custom scripts on these events.

Suspend/resume service files

Service files can be hooked into suspend.target, hibernate.target and sleep.target to execute actions before or after suspend/hibernate. Separate files should be created for user actions and root/system actions. To activate the user service files, # systemctl enable suspend@<user> && systemctl enable resume@<user>. Examples:

/etc/systemd/system/suspend@.service
[Unit]
Description=User suspend actions
Before=sleep.target

[Service]
User=%I
Type=forking
Environment=DISPLAY=:0
ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ; /usr/bin/mysql -e 'slave stop'
ExecStart=/usr/bin/sflock

[Install]
WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit]
Description=User resume actions
After=suspend.target

[Service]
User=%I
Type=simple
ExecStartPre=/usr/local/bin/ssh-connect.sh
ExecStart=/usr/bin/mysql -e 'slave start'

[Install]
WantedBy=suspend.target

For root/system actions (activate with # systemctl enable root-suspend):

/etc/systemd/system/root-resume.service
[Unit]
Description=Local system resume actions
After=suspend.target

[Service]
Type=simple
ExecStart=/usr/bin/systemctl restart mnt-media.automount

[Install]
WantedBy=suspend.target
/etc/systemd/system/root-suspend.service
[Unit]
Description=Local system suspend actions
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/pkill sshfs

[Install]
WantedBy=sleep.target

A couple of handy hints about these service files (more in man systemd.service):

  • If Type=OneShot then you can use multiple ExecStart= lines. Otherwise only one ExecStart line is allowed. You can add more commands with either ExecStartPre or by separating commands with a semicolon (see the first example above -- note the spaces before and after the semicolon...these are required!).
  • A command prefixed with '-' will cause a non-zero exit status to be ignored and treated as a successful command.
  • The best place to find errors when troubleshooting these service files is of course with journalctl.
Hooks in /usr/lib/systemd/system-sleep

Systemd runs all executables in /usr/lib/systemd/system-sleep/, passing two arguments to each of them:

  • Argument 1: either pre or post, depending on whether the machine is going to sleep or waking up
  • Argument 2: suspend, hibernate or hybrid-sleep, depending on which is being invoked

In contrast to pm-utils, systemd will run these scripts concurrently and not one after another.

The output of any custom script will be logged by systemd-suspend.service, systemd-hibernate.service or systemd-hybrid-sleep.service. You can see its output in systemd's journal:

# journalctl -b -u systemd-suspend

Note that you can also use sleep.target, suspend.target, hibernate.target or hybrid-sleep.target to hook units into the sleep state logic instead of using custom scripts.

An example of a custom sleep script:

/usr/lib/systemd/system-sleep/example.sh
#!/bin/sh
case $1/$2 in
  pre/*)
    echo "Going to $2..."
    ;;
  post/*)
    echo "Waking up from $2..."
    ;;
esac

See man 7 systemd.special and man 8 systemd-sleep for more details.

临时文件

/usr/lib/tmpfiles.d//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 4 tmpfiles.d

单元(unit)

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

详情参阅 man 5 systemd.unit.

从 initscripts 迁移到 systemd

Initscripts 模拟

initscripts 软件包提供了 systemd 和 Arch 传统配置的整合。当同时安装了initscripts和systemd时,若以systemd启动系统,systemd将执行以下操作:

  1. 解析/etc/rc.conf中的DAEMONS数组,并在系统启动时,启动所有列出的守护进程
  2. 在启动过程中执行/etc/rc.local
  3. 在系统关闭过程中执行/etc/rc.local.shutdown

Initscripts模拟仅仅是作为用户迁移到systemd时的过渡措施,这一方案最终将不再可行。原生的systemd并不依赖于rc.conf文件的集中式配置,因此推荐使用原生的systemd配置文件。原生systemd配置文件比/etc/rc.conf具有更高优先级。

注意: 替换/etc/rc.local的推荐方式是针对系统启动时要运行的程序编写自定义的service文件,详见相关章节.
注意: 如果你在/etc/inittab中禁用了以Template:Keypress重启系统,则需要以root执行systemctl mask ctrl-alt-del.target以使其对systemd重新生效。

不使用 DAEMONS 列表

如果是要用纯 systemd 环境, 你可以删除 /etc/rc.conf 文件, 并且只通过 systemctl 命令来启动服务. 对于每个 DAEMONS 里面的 <service_name> 服务名. 用以下命令设置成自动启动:

# systemctl enabel <service_name>
小贴士: For a list of commonly used daemons with their initscripts and systemd equivalents, see this table.

如果提示 <service_name>.service 不存在:

  • 那很有可能是 systemd 用了不同的服务名. 比如 crond 服务 替换成 cronie.service; alsa 服务替换成了 alsa-store.servicealsa-restore.service 两个服务, 还有一个重要的情况是 network 服务也替换成另外一个服务文件 (到这里 Configuring_Network_(简体中文) 看详细的变化)
  • 另外, 有些 .service 文件 systemd 可能无法使用, 这样的话, 你就还得继续用 rc.conf 来开机自动启动你的服务.
小贴士: 你可以用下面这个命令来查看已安装的程序包都包含了哪些镜像启动的服务文件:
$ 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
[...]
  • 有些 services 服务是不需要用户一个个去明确的设置成开机自动启动. 比如 dbus.service 会由于依赖关系而跟着 dbus-core 自动启动. 而 alsa-store.servicealsa-restore.service 也会由 systemd 自动启动. 你可以用 systemctl status <service_name> 命令来查看各个可用的服务跟它们的运行状态.

systemd 简单使用

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

  • systemctl:控制 systemd 状态,包括服务的启动和停止。
  • systemd-cgls:以树形递归显示指定 Linux 控制组(cgroup)的内容
  • systemadm:控制 systemd 状态的图形前端(由 AUR 软件包 systemd-ui-gitAUR 提供)。
小贴士: systemctl 参数中添加 -H <用户名>@<主机名> 可以实现对其他机器的远程控制。该过程使用 SSH 链接。
注意: systemadm is the official graphical frontend for systemctl. It is provided by the systemd-ui-gitAUR package from the AUR.

分析系统状态

输出激活的单元:

$ 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 是等价的。
  • 挂载点会自动转化为相应的.mount单元。例如/home等价于home.mount
  • 设备会自动转化为相应的.device单元,所以/dev/sda2等价于dev-sda2.device.

立即激活单元:

# systemctl start <unit>

立即停止单元:

# systemctl stop <unit>

重启单元:

# systemctl restart <unit>

命令单元重新读取配置:

# systemctl reload <unit>

输出单元运行状态:

$ systemctl status <unit>

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

$ systemctl is-enabled <unit>

开机自动激活单元:

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

取消开机自动激活单元:

# systemctl disable <unit>}}

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

# systemctl help <unit>

Reload systemd, scanning for new or changed units:

# systemctl daemon-reload

电源管理

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

重启:

$ systemctl reboot

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

$ systemctl poweroff

待机:

$ systemctl suspend

休眠:

$ systemctl hibernate

混合休眠模式:

$ systemctl hybrid-sleep

启动桌面环境

使用登录管理器

通过启动登录管理器(或称显示管理器),即可进行图形界面登录。目前,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

Using systemd-logind

注意: 自 2012-10-30 起, ConsoleKit 已被 systemd-logind 取代 ,作为登录到桌面环境的默认方式。

可使用 loginctl 来查看用户会话的状态。所有 PolicyKit 操作,如挂起系统、挂载外部驱动器都直接可用。

$ loginctl show-session $XDG_SESSION_ID

自己编写 .service 文件

参见:Systemd/Services

处理依赖关系

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

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

启动类型(Type)

编写自定义的service文件时,可以选择几种不同的service启动方式。启动方式可通过配置文件 [Service] 段中的 Type= 参数进行设置。具体的参数说明请参阅 man systemd.service

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

Replacing provided unit files

目录 /etc/systemd/system/ 中的unit配置文件比 /usr/lib/systemd/system/ 目录下的文件拥有更高优先级。 若需要定制某个unit的启动(使配置不受软件包更新的影响),请将现有的unit配置文件从 /usr/lib/ 复制到 /etc/ 目录下,并在此目录中修改。或者,可以使用 .include 来解析一个现有的配置文件,并覆盖原选项或添加新选项。例如,若想要某个service的配置文件中添加额外依赖关系,可以编写:

/etc/systemd/system/<service-name>.service
.include /usr/lib/systemd/system/<service-name>.service

[Unit]
Requires=<new dependency>
After=<new dependency>

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

# systemctl reenable <unit>
# systemctl restart <unit>
小贴士: 可以用 systemd-delta 命令来查看哪些unit文件被覆盖、哪些被修改。

As the provided unit files will be updated from time to time, use systemd-delta for system maintenance.

对 unit 文件的 vim 语法高亮支持

可从 官方仓库 安装 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)。可以通过 kernel parameters更改默认启动级别:

  • 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 都包含这段内容。

日志

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

# journalctl

默认情况下(当 Storage= 在文件 /etc/systemd/journald.conf 中被设置为 auto),日志记录将被写入 /var/log/journal/。若目录 /var/log/journal/ 不存在(例如,被用户或某个程序删除),systemd将不会自动创建它,而是将日志记录写入 /run/systemd/journal。这意味着,系统重启后日志将丢失。

过滤输出

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

Show all messages from this boot:

# journalctl -b

显示新信息:

# journalctl -f

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

# journalctl /usr/lib/systemd/systemd

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

# journalctl _PID=1

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

# journalctl -u netcfg

详情参阅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/loghttp://lwn.net/Articles/474968/ 官方说明)。以 Arch 源中的 syslog-ng 已经包含了需要的配置。

设置开机启动 syslog-ng:

 # systemctl enable syslog-ng

优化

参阅Improve Boot Performance.

启动过程分析

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

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

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

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

$ systemd-analyze blame

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

$ systemd-analyze plot > plot.svg

使用 bootchart

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

# systemctl enable bootchart.service

详情参阅 bootchart 文档

预读

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

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

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

疑难解答

关机/重启十分缓慢

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

"Error: No space left on device" when trying to start/restart a service

Note: I don't know if this is a proper solution, but it seems to have worked for me (I didn't use the same value as they said to, however).

See this link: CrashPlan Support

Thanks to Fedora Forum for pointing me to this site.

Short lived processes don't seem to log any output

If systemctl -u foounit.service doesn't show any output for a short lived service, look at the PID instead. For example, if systemd-modules-load.service fails, and systemctl status systemd-modules-load shows that it ran as PID 123, then you might be able to see output in the journal for that PID, i.e. journalctl -b _PID=123. Metadata fields for the journal such as _SYSTEMD_UNIT and _COMM are collected asynchronously and rely on the /proc directory for the process existing. Fixing this requires fixing the kernel to provide this data via a socket connection, similar to SCM_CREDENTIALS.

相关资源