我知道以下线程,并且据说是对它的回答。除了答案不是一般意义上的答案。它说明了某个特定情况下的问题,但不是一般情况下的问题。
我的问题是:有没有办法以通用方式调试订购周期?例如:是否有一个命令来描述循环以及什么将一个单元与另一个单元联系起来?
例如,我有以下内容journalctl -b(请忽略日期,我的系统没有可与之同步时间的 RTC):
Jan 01 00:00:07 host0 systemd[1]: Found ordering cycle on sysinit.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on local-fs.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on cvol.service/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on basic.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on sockets.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on dbus.socket/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on sysinit.target/start
Jan 01 00:00:07 host0 systemd[1]: Breaking ordering cycle by deleting job local-fs.target/start
Jan 01 00:00:07 host0 systemd[1]: Job local-fs.target/start deleted to break ordering cycle starting with sysinit.target/start
Run Code Online (Sandbox Code Playgroud)
其中 cvol.service (被引入并打破循环的那个)是:
[Unit]
Description=Mount Crypto Volume
After=boot.mount
Before=local-fs.target
[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/usr/bin/cryptsetup open /dev/*** cvol --key-file /boot/***
[Install]
WantedBy=home.mount
WantedBy=root.mount
WantedBy=usr-local.mount
Run Code Online (Sandbox Code Playgroud)
根据 journalctl,cvol.service 需要 basic.service,但它没有,至少不是很明显。是否有一个命令可以演示此链接的来源?一般来说,是否有一个命令可以找到循环并显示循环中每个链接的来源?
Evg*_*gin 27
您可以用可视化的命令周期systemd-analyze verify,systemd-analyze dot和GraphViz的 dot工具:
systemd-analyze verify default.target |&
perl -lne 'print $1 if m{Found.*?on\s+([^/]+)}' |
xargs --no-run-if-empty systemd-analyze dot |
dot -Tsvg >cycle.svg
Run Code Online (Sandbox Code Playgroud)
您应该会看到如下内容:
在这里你可以看到循环: c.service->b.service->a.service->c.service
Color legend:
black = Requires
dark blue = Requisite
dark grey = Wants
red = Conflicts
green = After
Run Code Online (Sandbox Code Playgroud)
链接:
int*_*lfx 26
是否有一个命令可以演示此链接的来源?
您可以做的最接近的是systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.service,它将显示给定单元的结果(有效)依赖项列表。
是否有一个命令可以找到循环并显示循环中每个链接的来源?
据我所知,没有这样的命令。实际上 systemd 没有提供任何帮助调试订购周期(叹气)。
根据 journalctl,cvol.service 需要 basic.service,但它没有,至少不是很明显。
首先,要求依赖(Wants=,Requires=,BindsTo=等等)是独立的顺序依赖(的Before=和After=)。你在这里看到的是一个排序依赖循环,即它与其他无关Wants=。
其次,在某些类型的单元之间创建了许多“默认依赖关系”。它们由部分中的DefaultDependencies=指令控制[Unit](默认情况下启用)。
特别是,除非显式禁用此指令,否则任何.service-type 单元都会获得隐式Requires=basic.target和After=basic.target依赖项,这正是您所看到的。这记录在systemd.service(5) 中。
步骤1:对default.target运行验证命令
systemd-analyze verify default.target
Run Code Online (Sandbox Code Playgroud)
步骤 2:观察“systemd 通过删除作业打破排序周期”消息中提到的服务或目标,并显示其完整的依赖项列表
systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After <service or target name mentioned in the "breaking cycle" message>
Run Code Online (Sandbox Code Playgroud)
步骤 3:查看服务或目标文件中通常定义的“after”和“before”组
/lib/systemd/system
Run Code Online (Sandbox Code Playgroud)
并找到已知是连续的但按出站顺序排列的服务或目标。
例子:
dbus.service
Run Code Online (Sandbox Code Playgroud)
通常标记为“之后”
multi-user.target
Run Code Online (Sandbox Code Playgroud)
但“之前”
sockets.target
Run Code Online (Sandbox Code Playgroud)
通过调用可以轻松观察到这种依赖性
systemctl list-dependencies default.target
Run Code Online (Sandbox Code Playgroud)
但是如果文件
/lib/systemd/system/dbus.service
Run Code Online (Sandbox Code Playgroud)
包含如下行:
Before=multi-user.target
Run Code Online (Sandbox Code Playgroud)
或者
After=sockets.target
Run Code Online (Sandbox Code Playgroud)
或两者同时,意味着 dbus.service 被定义为出站,并导致 systemd 无限循环。
治疗方法很简单 - 将“之后”一词改为“之前”,如有必要,反之亦然。
| 归档时间: |
|
| 查看次数: |
24015 次 |
| 最近记录: |