系统:之后=

系统:之后=

语境

我想只在启动完成A.service后启动,并且是由相应的systemd路径单元激活的单元:。相关代码片段可以在下面找到。B.serviceB.serviceB.path

A.service:

[Unit]
After=B.service

B.path:

[Path]
PathExists=/some/path

[Install]
RequiredBy=A.service

问题

在启动过程中,我可以看到确实A.serviceactivate 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.serviceExecStart=

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.serviceB.service同时激活,这A.service将延迟其执行,直到B.service执行之后。

相关内容