语境
我想只在启动完成A.service
后启动,并且是由相应的systemd路径单元激活的单元:。相关代码片段可以在下面找到。B.service
B.service
B.path
A.service
:
[Unit]
After=B.service
B.path
:
[Path]
PathExists=/some/path
[Install]
RequiredBy=A.service
问题
在启动过程中,我可以看到确实A.service
activate B.path
,然后在启动B.service
后被激活/some/path
,但问题是仍然在启动完成A.service
之前启动。B.service
通过检查日志日志,时间线如下所示:
T0
:A.service
已启动(然后失败,因为其设置取决于B.service
)B.path
已开始
T0
+X
秒:B.service
已开始
X
介于 3~6 之间,具体取决于启动期间路径何时存在。
文档
我检查了 systemd 文档Before=, After=
(关联)并发现了这个:
如果单元 foo.service 包含设置 Before=bar.service 并且两个单元都正在启动
这让我想知道是否是因为这个both units are being started
位。具体来说,B.service
只有在存在之后才启动/some/path
,可能是启动X
后几秒钟。A.service
但是,我不确定我对文档的理解是否正确,或者我实际上遗漏了其他内容。无论哪种方式,任何编写单元文件以实现我想要的目标的建议都会受到赞赏。谢谢!
答案1
鉴于省略了有问题的实际单元文件,有点难以回答,但您似乎误解了 Before=/After= 的含义;
在单元文件中使用“之前/之后”的含义是,在两个或多个单元之间做出优先级决定时,“之前/之后”条件将确定对单元执行操作的顺序。
在您的情况下,您有两个服务,其中一个服务A.service
依赖于第二个服务B.service
,但是您没有指定这两个服务具有依赖关系,仅指定它们的执行顺序如果他们有一个。
在这种情况下,听起来您还想设置Requisite=
,Requires=
或Wants=
onA.service
引用B.service
,如下A.Service
所示:
[Unit]
Requires=B.service
After=B.service
使用此配置,激活服务A.service
将需要激活B.service
,并且该After=
指令将确保在完成其自己的指令的执行之前A.service
不会开始执行其指令ExecStart=
B.service
ExecStart=
Requires=
并且Wants=
不仅会检查列出的单位是否已经激活,而且还会激活它们(如果尚未激活)
Requisite=
只会检查一个单元是否正在运行,如果没有,它定义的单元将立即失败
Before=
并且After=
仅指定同时调用时单元的激活顺序。这就是为什么您可以在当前配置中A.service
激活之前B.service
,因为它们当前没有同时激活,所以不应用排序依赖性。
也可以设置一个很好的覆盖Before=A.service
范围B.service
TLDR:您需要定义两个都 After=
也Requires=
。您“需要”Requires=
确保 if尚未运行,它将在运行B.service
时同时激活。A.service
您需要After=
指定何时A.service
和B.service
同时激活,这A.service
将延迟其执行,直到B.service
执行之后。