命令与用法
systemd列出所有服务及其状态
systemctl list-units --type=service
systemd概念
基础概念
systemd 是pid 为1的进程,即系统进所有用户进程的父进程。它使用cgroup/namespace等管理系统内的所有资源(因为它是所有进程的父 进程,所以它有权管)。
systemd管理的所有资源都是通过unit文件配置给systemd去启动的。这次资源分为很多种类型:
- automount:用于控制自动挂载文件系统,相当于 SysV-init 的 autofs 服务
- device:对于 /dev 目录下的设备,主要用于定义设备之间的依赖关系
- mount:定义系统结构层次中的一个挂载点,可以替代过去的 /etc/fstab 配置文件
- path:用于监控指定目录或文件的变化,并触发其它 Unit 运行
- scope:这种 Unit 文件不是用户创建的,而是 Systemd 运行时产生的,描述一些系统服务的分组信息
- service:封装守护进程的启动、停止、重启和重载操作,是最常见的一种 Unit 文件
- slice:用于表示一个 CGroup 的树,通常用户不会自己创建这样的 Unit 文件
- snapshot:用于表示一个由 systemctl snapshot 命令创建的 Systemd Units 运行状态快照
- socket:监控来自于系统或网络的数据消息,用于实现基于数据自动触发服务启动
- swap:定义一个用户做虚拟内存的交换分区
- target:用于对 Unit 文件进行逻辑分组,引导其它 Unit 的执行。它替代了 SysV-init 运行级别的作用,并提供更灵活的基于特定设备事件的启动方式。其实是一群unit 的集合,例如上面表格中谈到的multi-user.target 其实就是一堆服务的集合~也就是说, 选择执行multi-user.target 就是执行一堆其他.service 或/及.socket 之类的服务就是了!
- timer:用于配置在特定时间触发的任务,替代了 Crontab 的功能
这些配置可以对比Android的initrc文件和selinux配置去看,有很多相似之处。
/etc/systemd/system/:管理员依据主机系统的需求所建立的执行脚本,其实这个目录有点像以前/etc/rc.d/rc5.d/Sxx之类的功能。 /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先序要比/usr/lib/systemd/system/高! /usr/lib/systemd/system/:每个服务最主要的启动脚本设定,有点类似以前的/etc/init.d底下的档案;
可以先list,然后用show命令去看配置文件的具体内容和所有路径:
systemctl list-units --type=automount
输出:
UNIT LOAD ACTIVE SUB DESCRIPTION
proc-sys-fs-binfmt_misc.automount loaded active running Arbitrary Executable File Formats File System Automo>
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
1 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
systemctl show proc-sys-fs-binfmt_misc.automount
输出:
Where=/proc/sys/fs/binfmt_misc
DirectoryMode=0755
Result=success
TimeoutIdleUSec=0
Id=proc-sys-fs-binfmt_misc.automount
Names=proc-sys-fs-binfmt_misc.automount
WantedBy=sysinit.target
Before=systemd-binfmt.service proc-sys-fs-binfmt_misc.mount binfmt-support.service sysinit.target
After=-.mount
Triggers=proc-sys-fs-binfmt_misc.mount
RequiresMountsFor=/proc/sys/fs
Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html https://www.freedesktop.org/>
Description=Arbitrary Executable File Formats File System Automount Point
LoadState=loaded
ActiveState=active
FreezerState=running
SubState=running
FragmentPath=/lib/systemd/system/proc-sys-fs-binfmt_misc.automount
UnitFileState=static
UnitFilePreset=enabled
StateChangeTimestamp=Wed 2022-07-13 23:15:19 CST
StateChangeTimestampMonotonic=5507885
InactiveExitTimestamp=Wed 2022-07-13 23:15:18 CST
InactiveExitTimestampMonotonic=4937320
ActiveEnterTimestamp=Wed 2022-07-13 23:15:18 CST
ActiveEnterTimestampMonotonic=4937320
ActiveExitTimestampMonotonic=0
InactiveEnterTimestampMonotonic=0
CanStart=yes
CanStop=yes
CanReload=no
CanIsolate=no
CanFreeze=no
StopWhenUnneeded=no
RefuseManualStart=no
RefuseManualStop=no
AllowIsolate=no
DefaultDependencies=no
OnFailureJobMode=replace
IgnoreOnIsolate=yes
NeedDaemonReload=no
JobTimeoutUSec=infinity
JobRunningTimeoutUSec=infinity
JobTimeoutAction=none
ConditionResult=yes
AssertResult=yes
ConditionTimestamp=Wed 2022-07-13 23:15:18 CST
ConditionTimestampMonotonic=4937143
AssertTimestamp=Wed 2022-07-13 23:15:18 CST
AssertTimestampMonotonic=4937170
Transient=no
Perpetual=no
StartLimitIntervalUSec=10s
StartLimitBurst=5
StartLimitAction=none
FailureAction=none
SuccessAction=none
InvocationID=14d256d70b0c46b99617f285f347a1bb
CollectMode=inactive
上述命令打印的是运行时信息,实际去看它的配置文件没有这么复杂:
cat /lib/systemd/system/proc-sys-fs-binfmt_misc.automount
输出:
[Unit]
Description=Arbitrary Executable File Formats File System Automount Point
Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/binfmt_misc/
ConditionPathIsReadWrite=/proc/sys/
[Automount]
Where=/proc/sys/fs/binfmt_misc
systemd架构图
Service
systemctl list-units --type=service
输出:
UNIT LOAD ACTIVE SUB DESCRIPTION
accounts-daemon.service loaded active running Accounts Service
alsa-restore.service loaded active exited Save/Restore Sound Card State
apparmor.service loaded active exited Load AppArmor profiles
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
binfmt-support.service loaded active exited Enable support for additional exe>
bluetooth.service loaded active running Bluetooth service
cron.service loaded active running Regular background program proces>
dbus.service loaded active running D-Bus System Message Bus
gdm3.service loaded active exited LSB: GNOME Display Manager
haveged.service loaded active running Entropy Daemon based on the HAVEG>
ifupdown-pre.service loaded active exited Helper to synchronize boot up for>
kmod-static-nodes.service loaded active exited Create list of static device node>
lm-sensors.service loaded active exited Initialize hardware monitoring se>
lxc-net.service loaded active exited LXC network bridge setup
lxc.service loaded active exited LXC Container Initialization and >
lxcfs.service loaded active running FUSE filesystem for LXC
ModemManager.service loaded active running Modem Manager
networking.service loaded active exited Raise network interfaces
NetworkManager.service loaded active running Network Manager
● nvidia-persistenced.service loaded failed failed NVIDIA Persistence Daemon
packagekit.service loaded active running PackageKit Daemon
plymouth-quit-wait.service loaded active exited Hold until boot process finishes >
plymouth-quit.service loaded active exited Terminate Plymouth Boot Screen
plymouth-read-write.service loaded active exited Tell Plymouth To Write Out Runtim>
plymouth-start.service loaded active exited Show Plymouth Boot Screen
我们可以通过名字(去掉.service后缀)查看其中的一个:
systemctl cat dbus.service
# /lib/systemd/system/dbus.service
[Unit]
Description=D-Bus System Message Bus
Documentation=man:dbus-daemon(1)
Requires=dbus.socket
[Service]
ExecStart=/usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog->
ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.free>
OOMScoreAdjust=-900
lines 1-10/10 (END)
从配置文件我们可以知道如下信息:
想看查看这个服务的文档可以使用命令man 1 dbus-daemon
。 这个服务的启动依赖于dbus.socket这个socket资源的创建.
它的启动和reload命令分别是…。
socket
dbus.socket是另一个systemd管理的unit,我们可以看一下它的内容:
systemctl cat dbus.socket
输出:
# /lib/systemd/system/dbus.socket
[Unit]
Description=D-Bus System Message Bus Socket
[Socket]
ListenStream=/run/dbus/system_bus_socket
可以看到:
- 这个socket的路径是/run/dbus/system_bus_socket。
因为它的路径,显然它是一个unix domain socket。
ls /run/dbus/system_bus_socket -la
也可以通过show子命令来查看:
systemctl show dbus.socket
socket相关的systemd代码在这里:socket.c
入口
systemd启动后第一个查看的配置文件是/etc/systemd/system/default.target
,这个一个软链接,它指向的目标是可以get/set的。
get
default=$(systemctl get-default)
echo $default
systemctl cat $default
由于我的系统被我配置成了默认不进图形界面,所以它指向的是multi-user.target.
这时,我启动系统后进入命令行,需要手动运行sddm
或是lightdm
,才能进入图形界面。
如果想一启动就进入图形界面,需要设置default为graphical.target
。
set
systemctl set-default graphicl.target
graphical.target的内容是:
systemctl cat graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
可以看到它基本就是multi-user.target + display-manager.service。
systemctl cat display-manager.service
# /lib/systemd/system/lightdm.service
[Unit]
Description=Light Display Manager
Documentation=man:lightdm(1)
After=systemd-user-sessions.service
# replaces plymouth-quit since lightdm quits plymouth on its own
Conflicts=plymouth-quit.service
After=plymouth-quit.service
# lightdm takes responsibility for stopping plymouth, so if it fails
# for any reason, make sure plymouth still stops
OnFailure=plymouth-quit.service
[Service]
ExecStart=/usr/sbin/lightdm
Restart=always
BusName=org.freedesktop.DisplayManager
[Install]
Alias=display-manager.service
可以看到我的display-manager.service应该也是一个软链接,它指向lightdm.service。