1、引言
在调试存储相关功能时遇到了一个问题:“设备重启,重启后RDMA功能不可用,导致存储无法下IO,功能异常”。分析如下:
(1)首先看日志发现如下打印:RDMA模块收到了一个设备异常的异步事件,它认为没有可用的RDMA网卡,立即处理此异步事件将RDMA链接全部断开,如下图。
(2)接着看了下RDMA的网卡到底是否存在,且工作正常?通过rdma link命令发现rdma网卡是link的,且是正常工作的,如下图。
(3)发现前后两次RDMA网卡的设备名称不一样,第一次是mlx5_2,第二次是mlx5_bond_0设备。此时就想到了mlx5_bond_0设备是mlx5_2执行bond操作得到的设备。
(4)那么这就能联想到是由于存储的业务进程A启动的很早,发现的rdma设备是mlx5_2。然后有一个bond业务进程B(假设有一个bond进程)在存储的业务进程A之后起来。B在加载的过程中刷配置,将mlx5_2的设备进行了bond操作,变成了mlx5_bond_0设备。由此导致的存储无法下IO,功能异常。
(5)现在面临的就是验证猜想,以及解决问题。就用到了systemctl和journalctl命令,找到A和B的加载时间,以及确定B是哪个server。查找过程如下:通过journalctl命令发现openibd设置mlx5_bond_0的日志,然后对比存储业务进程A(即下面的kvserver)启动时间,确实印证了上面的想法
(6)通过systemctl命令看下是否存在openibd这个service。确实存在。那么只需要修改kvserver的service文件即可解决问题,将kvserver放在openibd这个service后启动即可。
所以,由上面这个问题引出一些关于systemd相关工具命令。接下来开始systemd的基础工具之旅。
2、systemd简介
systemd是一个系统管理守护进程、工具和库的集合,用于取代System V初始进程。systemd进程作为设备启动的第一个进程,是所有进程的父进程。
root@centos-virtual-machine:~# ps -eaf | grep systemd
root 1 0.0 0.0 171516 9384 ? Ss 2022 18:11 /usr/lib/systemd/systemd --switched-root --system --deserialize 16
systemd的功能是用于集中管理和配置类UNIX系统。目前在Linux生态系统中,systemd被部署到了大多数的标准Linux发行版中,熟知的ubuntu和centos都已经采用systemd,只有为数不多的几个发行版尚未部署。
2.1 systemd的管理的系统资源--unit(单元)
下文中会用到一个unit的概念,举一个例子来说明下:我们常见的sshd进程是systemd通过/etc/systemd/system/multi-user.target.wants/sshd.service文件执行/usr/sbin/sshd命令运行的。这里的sshd.service就可以称为一个unit, 即简单来讲unit就是一个配置文件。常见的unit有以.sokcet、.mount、.service、.timer等等结尾的文件。同时,systemd 默认从目录/etc/systemd/system/读取unit配置文件。但是,/etc/systemd/system/里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的unit配置文件存放在/usr/这个目录。
这块简单以sshd.service文件简单介绍下unit文件:
[root@localhost multi-user.target.wants]# cat sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
......
[Install]
WantedBy=multi-user.target
如上所示分为三部分,解释如下:
(1)[Unit]区块通常是配置文件的第一个区块,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系。它的主要字段如下:
Description:简短描述
Documentation:文档地址
Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
Condition:当前 Unit 运行必须满足的条件,否则不会运行
Assert:当前 Unit 运行必须满足的条件,否则会报启动失败
(2)[Service]区块用来 service 的配置,只有 service 类型的 unit 才有这个部分。它的主要字段如下:
Type:定义启动时的进程行为。它有以下几种值。
Type=simple:默认值,执行ExecStart指定的命令,启动主进程
Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
Type=dbus:当前服务通过D-Bus启动
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
Type=idle:若有其他任务执行完毕,当前服务才会运行
ExecStart:启动当前服务的命令
ExecStartPre:启动当前服务之前执行的命令
ExecStartPost:启动当前服务之后执行的命令
ExecReload:重启当前服务时执行的命令
ExecStop:停止当前服务时执行的命令
ExecStopPost:停止当其服务之后执行的命令
RestartSec:自动重启当前服务间隔的秒数
Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数
Environment:指定环境变量
(3)[Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下:
WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
Alias:当前 Unit 可用于启动的别名
Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit
关于unit文件的编写通常情况下unit都会有[Unit]和[Intsall]两个部分,剩余的一个部分(有的类型没有)根据不同类型的unit,内容不相同。unit配置文件的编写可以参考官网手册英文版:https://www.freedesktop.org/software/systemd/man/systemd.unit.html ,中文版:
http://www.jinbuguo.com/systemd/systemd.unit.html
3、systemctl命令
systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器。基本的命令如下:
(1)systemctl --version,检查系统上是否安装了systemd以及当前安装的Systemd的版本是什么。
root@centos-virtual-machine:~# journalctl --version
systemd 249 (249.11-0ubuntu3.9)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified
root@centos-virtual-machine:~#
(2)systemctl 用于管理系统相关的命令:
- systemctl reboot:用于重启系统
- systemctl poweroff:用于关闭系统,直接关机
- systemctl halt:用于暂停CPU工作
- systemctl suspend:用于暂停系统工作(一般使用这个命令),suspend一般情况下是停止内存活动
- systemctl hibernate:用于将系统进入休眠状态,类似于windows系统的睡眠,重新唤起系统时间相对于suspend可能会是将长一点
- systemctl hybrid-sleep:用于将系统进入交互式休眠状态
(3)systemctl 用于管理unit的使能、关闭、加载、停止、重启等命令
- systemctl enable unit:使能unit,会建立/etc和/usr目录下的软链接,系统启动会自启动此unit
root@centos-virtual-machine:~# systemctl enable bluetooth
Synchronizing state of bluetooth.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable bluetooth
Created symlink /etc/systemd/system/dbus-org.bluez.service → /lib/systemd/system/bluetooth.service.
Created symlink /etc/systemd/system/bluetooth.target.wants/bluetooth.service → /lib/systemd/system/bluetooth.service.
root@centos-virtual-machine:~#
- systemctl disable unit:关闭unit,会删除/etc和/usr目录下的软连接,系统启动不会加载此unit
root@centos-virtual-machine:~# systemctl disable bluetooth
Synchronizing state of bluetooth.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable bluetooth
Removed /etc/systemd/system/bluetooth.target.wants/bluetooth.service.
Removed /etc/systemd/system/dbus-org.bluez.service.
root@centos-virtual-machine:~#
- systemctl start unit:系统启动后,命令启动一个unit
- systemctl stop unit:系统启动后,命令停止一个unit
- systemctl kill unit:系统启动后,用于终止一个unit。
- systemctl reload unit:系统启动后,命令重启一个unit
- systemctl restart unit:系统启动后,命令启动或者重启一个unit
- systemctl daemon-reload unit:系统启动后,用于在修改unit配置文件后,需要使用此命令重新加载unit配置,否则unit配置文件的修改不会生效。配合systemctl restart unit命令使用。
- systemctl mask unit:屏蔽unit无法在系统启动的时候自启动,和system disable unit不一样,mask是将/etc下的软连接指向/dev/null,如果要mask的unit已经链接了指定目标,此时是命令是无法执行成功的。
- systemctl unmask unit:恢复unit在系统启动的时候自启动流程。
(4)systemctl 用于查看unit的状态
- system status unit:这个命令能看到unit的状态,以及在加载失败的情况下,能看到一些简单的失败原因。
root@centos-virtual-machine:~# systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2023-06-03 14:01:47 CST; 7h ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 874 (sshd)
Tasks: 1 (limit: 4342)
Memory: 5.5M
CPU: 828ms
CGroup: /system.slice/ssh.service
└─874 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
6月 03 14:01:45 centos-virtual-machine systemd[1]: Starting OpenBSD Secure Shell server...
6月 03 14:01:46 centos-virtual-machine sshd[874]: Server listening on 0.0.0.0 port 22.
6月 03 14:01:46 centos-virtual-machine sshd[874]: Server listening on :: port 22.
6月 03 14:01:47 centos-virtual-machine systemd[1]: Started OpenBSD Secure Shell server.
6月 03 14:24:07 centos-virtual-machine sshd[1627]: Accepted password for zijin from 192.168.92.1 port 50906 ssh2
6月 03 14:24:07 centos-virtual-machine sshd[1627]: pam_unix(sshd:session): session opened for user zijin(uid=1001) by (uid=0)
6月 03 19:51:15 centos-virtual-machine sshd[2177]: Accepted password for zijin from 192.168.92.1 port 56077 ssh2
6月 03 19:51:15 centos-virtual-machine sshd[2177]: pam_unix(sshd:session): session opened for user zijin(uid=1001) by (uid=0)
root@centos-virtual-machine:~#
下面介绍systemctl三个查询状态的简单方法,主要可能在写脚本的时候方便使用。
- systemctl is-enable unit:用于查看unit是否使能,在系统启动的时候能否自启动。
root@centos-virtual-machine:~# systemctl is-enabled ssh
enabled
root@centos-virtual-machine:~# systemctl is-enabled bluetooth
disabled
root@centos-virtual-machine:~#
- systemctl is-active unit:用于查看unit的运行状态是否时active的
root@centos-virtual-machine:~# systemctl is-active sshd
active
root@centos-virtual-machine:~# systemctl is-active bluetouth
inactive
root@centos-virtual-machine:~#
- systemctl is-failed unit:用于查看unit是否运行失败
root@centos-virtual-machine:~# systemctl is-failed sshd
active
root@centos-virtual-machine:~# systemctl is-failed bluetouth
inactive
root@centos-virtual-machine:~# systemctl is-failed fwupd-refresh
failed
root@centos-virtual-machine:~#
(5)systemctl用于查看系统unit的命令
- systemctl list-unit-file:用于显示出所有的unit配置,配合--type==xxx(unit类型)使用是查看某种unit类型的配置,配合grep命令对于写脚本会友好点(见例子)。需要说明下,这个命令是看不出unit的状态的,需要使用查看状态的命令查看。
root@centos-virtual-machine:~# systemctl list-unit-files
UNIT FILE STATE VENDOR PRESET
proc-sys-fs-binfmt_misc.automount static -
proc-sys-fs-binfmt_misc.mount disabled disabled
run-vmblock\x2dfuse.mount enabled enabled
root@centos-virtual-machine:~# systemctl list-unit-files | grep e2scrub_all
e2scrub_all.service static -
e2scrub_all.timer enabled enabled
root@centos-virtual-machine:~# systemctl list-unit-files --type=timer | grep e2scrub_all
e2scrub_all.timer enabled enabled
root@centos-virtual-machine:~#
说明:
命令中显示STATE字段的状态,一般是下面几种:
enabled:已建立启动链接
disabled:没建立启动链接
static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖
masked:该配置文件被禁止建立启动链接
- systemctl list-units:用于查看当前系统正在运行的unit。
root@centos-virtual-machine:~# systemctl list-units
UNIT LOAD ACTIVE SUB DESCRIPTION >
proc-sys-fs-binfmt_misc.automount loaded active running Arbitrary Executable File Formats File Sys>
sys-devices-pci0000:00-0000:00:10.0-host32-target32:0:0-32:0:0:0-block-sda-sda1.device loaded active plugged VMware_Virtual_S 1
......
- systemctl --failed:查看所有运行失败的服务进程,如下fwupd-refresh运行失败
root@centos-virtual-machine:~# systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● fwupd-refresh.service loaded failed failed Refresh fwupd metadata and update motd
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.
root@centos-virtual-machine:~#
(6)systemcl 关于unit的其他命令
- systemctl cat unit:用于查看unit配置文件是什么
root@centos-virtual-machine:~# systemctl cat sshd
# /lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
......
[Service]
EnvironmentFile=-/etc/default/ssh
......
[Install]
WantedBy=multi-user.target
Alias=sshd.service
root@centos-virtual-machine:~#
- systemctl show unit:用于查看unit的所有配置详细信息
root@centos-virtual-machine:~# systemctl show unit
Restart=no
NotifyAccess=none
......
- systemctl list-dependencies unit:用于查看unit依赖unit是什么,配合--all呈现target类型的依赖,默认是不显示的。
root@centos-virtual-machine:~# systemctl list-dependencies sshd
sshd.service
● ├─-.mount
● ├─system.slice
● └─sysinit.target
● ├─apparmor.service
● ├─dev-hugepages.mount
● ├─dev-mqueue.mount
.....
4、journalctl命令
Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf。常用的命令如下:
- journalctl:查看所有的日志
- journalctl -k:查看内核日志,不显示应用日志,和dmesg显示的内容是一样的。
- journalctl -b:查看本次系统启动的日志
- journalctl -b num:查看系统前几次启动的日志,num表示启动的次数,0表示本次启动日志,1表示上次启动日志,通过journalctl --list-boot查看系统历次启动的日期
- journalctl --since/--until 查看指定时间开始的日志,例子如下:
- journalctl --since="2012-10-30 18:17:16"
- journalctl --since "20 min ago"
- journalctl --since yesterday
- journalctl --since "2015-01-10" --until "2015-01-11 03:00"
- journalctl --since 09:00 --until "1 hour ago"
- journalctl -nnum:查看最新的日志,num表示行数,不指定num时,默认查看最新10行日志
- journalctl -f:实时输出最新日志,类似于tail -f命令,都是显示实时输出的日志
- journalctl -uunit:查看指定unit的日志,配合--since和--until 查看某个unit的指定时间的日志,-u也可以一次指定多个unit。
- journalctl _PID=pid:查看指定pid的日志。
- journalctl -plog_level_num/log_level_str:查看指定日志级别以上的日志。共有8级0: emerg,1: alert,2: crit,3: err,4: warning,5: notice,6: info,7: debug。
- journalctl -t log_id:查看指定log_id的日志。
- journalctl --disk-usage:查看所有日志文件的总磁盘使用情况
- journalctl --vacuum-size:用于指定日志文件占据的最大空间
- journalctl --vacuum-time:用于指定日志文件保存多久
5、systemd相关的扩展命令
(1)systemd-analyze 查看系统的简要过程以及花费的时间
root@centos-virtual-machine:~# systemd-analyze
Startup finished in 19.415s (kernel) + 1min 32.709s (userspace) = 1min 52.125s
graphical.target reached after 1min 7.466s in userspace
root@centos-virtual-machine:~#
(2)systemd-analyze blame 显示每个unit在启动的时候花费的时间是多少。
root@centos-virtual-machine:~# systemd-analyze blame
35.594s plymouth-quit-wait.service
25.842s dev-loop2.device
25.568s dev-loop3.device
9.383s snap-firefox-2667.mount
......
(3)systemd-analyze critical-chain 显示启动时的关键过程
root@centos-virtual-machine:~# systemd-analyze critical-chain
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.
graphical.target @1min 7.466s
└─multi-user.target @1min 7.463s
└─plymouth-quit-wait.service @31.847s +35.594s
└─systemd-user-sessions.service @30.552s +353ms
......
(4)systemd-analyze critical-chain unit 显示单个unit启动的流程
root@centos-virtual-machine:~# systemd-analyze critical-chain sshd.service
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.
ssh.service +1.630s
└─network.target @29.631s
└─NetworkManager.service @26.049s +3.485s
└─dbus.service @25.960s
└─basic.target @25.697s
......
结语,以上就是本次systemd工具的简介,欢迎补充