本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。
本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:
由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。
systemd-analyze — 分析与调试 systemd 系统管理器
systemd-analyze
[OPTIONS...] [time]
systemd-analyze
[OPTIONS...] blame
systemd-analyze
[OPTIONS...] critical-chain [UNIT
...]
systemd-analyze
[OPTIONS...] plot [> file.svg]
systemd-analyze
[OPTIONS...] dot [PATTERN
...] [> file.dot]
systemd-analyze
[OPTIONS...] dump
systemd-analyze
[OPTIONS...] cat-config NAME
|PATH
...
systemd-analyze
[OPTIONS...] unit-paths
systemd-analyze
[OPTIONS...] log-level [LEVEL
]
systemd-analyze
[OPTIONS...] log-target [TARGET
]
systemd-analyze
[OPTIONS...] syscall-filter [SET
…]
systemd-analyze
[OPTIONS...] verify [FILES
...]
systemd-analyze
[OPTIONS...] calendar SPECS
...
systemd-analyze
[OPTIONS...] service-watchdogs [BOOL
]
systemd-analyze
[OPTIONS...] timespan SPAN
...
systemd-analyze
[OPTIONS...] security UNIT
...
systemd-analyze 可以显示系统启动过程中的性能统计数据、 获取 systemd 系统管理器的状态与跟踪信息、 校验单元文件的正确性。 此外,还可以用于调试 systemd 系统管理器。
systemd-analyze time 可以显示如下时间: (1)在启动第一个用户态进程(init)之前,内核运行了多长时间; (2)在切换进入实际的根文件系统之前,initrd(initial RAM disk)运行了多长时间; (3)进入实际的根文件系统之后,用户空间启动完成花了多长时间。 注意, 上述时间只是简单的计算了系统启动过程中到达不同标记点的时间, 并没有计入各单元实际启动完成所花费的时间以及磁盘空闲的时间。
systemd-analyze blame
按照每个单元花费的启动时间从多到少的顺序,列出所有当前正处于活动(active)状态的单元。
这些信息有助于用户优化系统启动速度。
不过需要注意的是,这些信息也可能具有误导性,
因为花费较长时间启动的单元,有可能只是在等待另一个依赖单元完成启动。
注意,
systemd-analyze blame
Type=simple
服务的结果,
因为 systemd 认为这种服务是立即启动的,
所以无法测量初始化延迟。
systemd-analyze critical-chain
[UNIT…
]
为指定的单元(省略参数表示默认启动目标单元)以树状形式显示时间关键链(time-critical chain)。
"@"后面的时刻表示该单元的启动时刻;
"+"后面的时长表示该单元总计花了多长时间才完成启动。
不过需要注意的是,
这些信息也可能具有误导性,
因为花费较长时间启动的单元,
有可能只是在
等待另一个依赖单元完成启动。
systemd-analyze plot 输出一个 SVG 图像,详细显示每个单元的启动时刻, 并高亮显示每个单元总计花了多长时间才完成启动。
systemd-analyze dot
按照
GraphViz
dot(1)
格式输出单元间的依赖关系图。
在实践中,通常使用 systemd-analyze dot | dot
-Tsvg > systemd.svg 命令来最终生成描述单元间依赖关系的 SVG 图像。
除非使用了 --order
或
--require
选项限定仅显示特定类型的依赖关系,
否则将会显示所有的依赖关系。如果指定了至少一个
PATTERN
参数(例如
*.target
这样的 shell 匹配模式),
那么将会仅显示所有匹配这些模式的单元的直接依赖关系。
systemd-analyze dump 按照人类易读的格式输出全部单元的状态(一般都有几千数万行)。 因为它的输出格式经常在未通知的情况下发生变化, 所以切勿将此输出用于程序分析。
systemd-analyze cat-config
类似于 systemctl cat ,但用于显示配置文件。
此命令将会把配置文件与配置片段的内容显示在标准输出上,
并且遵守 systemd 配置目录与配置文件的优先级规则。
参数要么是
绝对路径(例如 /etc/systemd/logind.conf
或
/usr/lib/systemd/logind.conf
)、
要么是相对于前缀的相对路径(例如 systemd/logind.conf
)。
例 1. 显示 logind 的配置
$ systemd-analyze cat-config systemd/logind.conf # /etc/systemd/logind.conf ... [Login] NAutoVTs=8 ... # /usr/lib/systemd/logind.conf.d/20-test.conf ... some override from another package # /etc/systemd/logind.conf.d/50-override.conf ... some administrator override
systemd-analyze unit-paths 列出与单元相关的全部目录,
包括:单元文件目录、配置片段目录(.d
)、
依赖关系目录(.wants
与 .requires
)。
与 --user
一起使用时表示针对 systemd 用户实例。
与 --global
一起使用时表示针对 systemd 用户实例的全局配置。
注意,此命令输出的列表仅为编译在
systemd-analyze 中的路径,
它实际上并不与运行中的 systemd 进程通信。
systemctl [--user] [--global] show -p UnitPath --value
命令会列出运行中的 systemd 进程实际使用的路径列表, 但是会忽略空目录。
systemd-analyze log-level
打印出 systemd 守护进程当前的日志等级。
如果提供了可选的 LEVEL
参数,
那么表示将 systemd 守护进程的日志等级更改为 LEVEL
(可使用的值参见
--log-level=
选项(参见
systemd(1)))。
systemd-analyze log-target
打印出 systemd 守护进程当前的日志目标。
如果提供了可选的 TARGET
参数,
那么表示将 systemd 守护进程的日志目标更改为 TARGET
(可使用的值参见
--log-target=
选项(参见
systemd(1)))。
systemd-analyze syscall-filter [SET
…]
如果指定了至少一个 SET
参数,那么仅显示指定的集合所包含的系统调用列表;
否则显示全部系统调用集合的详情。注意,必须在 SET
参数中包含
"@
" 前缀。
systemd-analyze verify
校验指定的单元文件以及被指定的单元文件引用的其他单元文件的正确性,并显示发现的错误。
FILES
参数可以是单元文件的精确路径(带有上级目录),也可以仅仅是单元文件的名称(没有目录前缀)。
对于那些仅给出了文件名(没有目录前缀)的单元,
将会优先在其他已经给出精确路径的单元文件的所在目录中搜索,
如果没有找到,将会继续在常规的单元目录中搜索(详见
systemd.unit(5) 手册)。
可以使用 $SYSTEMD_UNIT_PATH
环境变量来更改默认的单元搜索目录。
systemd-analyze calendar 解析并标准化"日历事件",
计算出下一个过期时间。接受的参数与 OnCalendar=
选项(参见
systemd.timer(5) 手册)相同,
表达式语法遵守
systemd.time(7) 规范。
systemd-analyze service-watchdogs
显示 systemd 守护进程的服务单元运行时看门狗的当前状态。
如果提供了可选的布尔值参数,那么表示全局启用或禁用
服务单元运行时看门狗(WatchdogSec=
)与紧急操作(例如
OnFailure=
或 StartLimitAction=
)。参见
systemd.service(5) 手册。
注意,硬件看门狗不受该命令的影响。
systemd-analyze timespan 解析一个"时长",并以微秒为单位输出规格化后的等效值。 接受的参数表达式语法遵守 systemd.time(7) 规范。有单位的值将被解析为秒。
systemd-analyze security 分析一个或多个指定服务单元的安全性和沙箱设置。 如果指定了至少一个单元名称,那么将检查指定服务单元的安全设置并显示详细分析。 如果未指定单元名称,那么将检查所有当前已加载的长时间运行的服务单元, 并显示一个简洁的结果表格。 该命令检查各种安全相关的设置,根据每个设置的重要性分配一个"暴露级别"数值。 然后,为整个单元计算出一个总体暴露级别数值,这是一个 0.0…10.0 之间的估计值,表示该服务的暴露程度。 数值越大表示沙箱应用的越少(安全性越低)、数值越小表示沙箱应用的越多(安全性越高)。 注意,该命令只分析 systemd 本身实现的针对每个服务的安全特性, 并不会考虑服务代码本身应用的任何附加安全机制。不要误解这种方式计算的"暴露级别": 高"暴露级别"既不意味着服务代码本身没有有效的沙箱机制, 也不意味着服务实际上易受远程或本地攻击的影响。 但是,高"暴露级别"的服务确实有可能需要加强额外的安全与沙箱限制。 注意,许多单独的安全和沙箱设置是可以规避绕过的(除非与其他结合使用)。 例如,如果服务保留了创建或撤消挂载点的特权, 那么许多沙箱选项就可以由服务代码本身取消。 所以,每个服务应该尽可能使用最全面和最严格的沙箱与安全设置。 该工具会考虑某些设置组合之间的关系,但不是全部。 还要注意,这里分析的安全性和沙箱设置仅适用于服务代码本身执行的操作。 如果一个服务可以访问IPC系统(例如 D-Bus),那么它可能会请求其他不受相同限制的服务进行操作。 如果没有验证IPC访问策略, 那么任何全面的安全性和沙箱分析都是不完整的。
如果没指定任何命令,那么等价于使用 systemd-analyze time 命令。
可以识别的选项如下:
--system
¶操作 systemd 系统实例。 这是隐含的默认值。
--user
¶操作 systemd 用户实例。
--global
¶操作 systemd 用户实例的 全局配置。
--order
, --require
¶仅可与
dot 命令一起使用,
表示仅显示特定类型的依赖。
--order
表示仅显示
After=
与 Before=
依赖。
--require
表示仅显示
Requires=
,
Requisite=
,
Wants=
, Conflicts=
依赖。
如果这两个选项都没有使用,
那么表示显示所有依赖。
--from-pattern=
, --to-pattern=
¶仅可与
dot 命令一起使用,
用于筛选可以出现在依赖关系图中的单元。
这两个选项都接受一个符合
glob(7)
规范的 shell 匹配模式(例如
*.target
),
用于匹配单元的名称。
可以多次使用这两个选项, 以筛选 最终允许出现在依赖关系图中的单元, 多个选项的组合规则如下: 先将多个"from"选项视为一组(内部用"OR"逻辑连接)、 再将多个"to"选项视为一组(内部用"OR"逻辑连接), 最后再将"from"组与"to"组之间用"AND"逻辑连接。 最终计算出 可以出现在依赖关系图中的单元。
--fuzz=
timespan
¶仅可与
critical-chain 命令一起使用,
表示也显示那些比同一层次上最后一个单元完成启动的时间
提前了不足 timespan
时长的单元。
timespan
的默认单位是秒,
但是也可以
明确的设置单位后缀(例如"50ms")。
--man=no
¶不检查
Documentation=
中列出的手册页是否真实存在。
--generators
¶调用单元生成器(参见 systemd.generator(7) 手册)。 某些单元生成器需要超级用户权限,如果以普通用户身份调用, 那么将会导致报错或警告。
--root=PATH
¶用于 cat-files 命令,
在指定的根路径 PATH
下显示配置文件。
-H
, --host=
¶操作指定的远程主机。可以仅指定一个主机名(hostname),
也可以使用 "username@hostname
" 格式。
hostname 后面还可以加上
SSH监听端口(以冒号":
"分隔)与容器名(以正斜线"/
"分隔),
也就是形如 "hostname:port/container
" 的格式,
以表示直接连接到指定主机的指定容器内。
操作将通过SSH协议进行,以确保安全。
可以通过
machinectl -H
HOST
命令列出远程主机上的所有容器名称。IPv6地址必须放在方括号([])内。
-M
, --machine=
¶-h
, --help
¶--version
¶--no-pager
¶不将程序的输出内容管道(pipe)给分页程序。
例 2. 把所有名称以
"avahi-daemon
"开头的单元的依赖关系绘制成一张图
$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg $ eog avahi.svg
例 3. 把所有 target 单元之间的依赖关系绘制成一张图
$ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg $ eog targets.svg
目前可以检测如下错误:
未知的小节与配置指令(配置选项)
未找到 必须依赖的单元
未找到
Documentation=
中列出的手册页
未找到在例如 ExecStart=
等可执行指令中设置的
可执行文件(包括找到的文件不具备可执行权限)
例 4. 拼写错误的配置指令
$ cat ./user.slice [Unit] WhatIsThis=11 Documentation=man:nosuchfile(1) Requires=different.service [Service] Description=x $ systemd-analyze verify ./user.slice [./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit' [./user.slice:13] Unknown section 'Service'. Ignoring. Error: org.freedesktop.systemd1.LoadFailed: Unit different.service failed to load: No such file or directory. Failed to create user.slice/start: Invalid argument user.slice: man nosuchfile(1) command failed with code 16
例 5. 丢失了 service 单元
$ tail ./a.socket ./b.socket ==> ./a.socket <== [Socket] ListenStream=100 ==> ./b.socket <== [Socket] ListenStream=100 Accept=yes $ systemd-analyze verify ./a.socket ./b.socket Service a.service not loaded, a.socket cannot be started. Service b@0.service not loaded, b.socket cannot be started.
$SYSTEMD_PAGER
¶指定分页程序。仅在未指定 --no-pager
选项时有意义。
此变量会覆盖 $PAGER
的值。如果 $SYSTEMD_PAGER
与 $PAGER
都未设置,
那么将会依次尝试如下常见的分页程序:
less(1),
more(1),
如果最终仍未找到分页程序,那么将不使用分页。
将此变量设为空字符串或 "cat
" 等价于使用 --no-pager
选项。
$SYSTEMD_LESS
¶用于覆盖默认传递给 less
程序的命令行选项("FRSXMK
")。
如果 $SYSTEMD_LESS
的值不含 "K
" ,
并且使用 less 作为分页程序,那么
Ctrl+C 信号将会被忽略。
这将允许 less 自己处理
Ctrl+C 信号。
$SYSTEMD_LESSCHARSET
¶用于覆盖默认传递给 less 程序的字符集。
(如果终端兼容 UTF-8 ,那么默认值是 "utf-8
" )