Linux Systemd冲突似乎没有使用ExecStopPost

Linux Systemd冲突似乎没有使用ExecStopPost

A.服务

[Unit]
Description = A-service
Conflicts= B.service
After = network.target

[Service]
PermissionsStartOnly = true
PIDFile = /run/AB/ab.pid
User = root
WorkingDirectory = /root/AB_services
ExecStartPre = /bin/mkdir /run/AB
ExecStartPre = /bin/chown -R root:root /run/AB
ExecStart = /usr/bin/python test_A.py --pid /run/AB/ab.pid
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
ExecStopPost = /bin/rm -rf /run/AB
PrivateTmp = true

[Install]
WantedBy = multi-user.target

B、服务

[Unit]
Description = B-Service
Conflicts = A.service
After = network.target

[Service]
PermissionsStartOnly = true
PIDFile = /run/AB/ab.pid
User = root
WorkingDirectory = /root/AB_services
ExecStartPre = /bin/mkdir /run/AB
ExecStartPre = /bin/chown -R root:root /run/AB
ExecStart = /usr/bin/python test_B.py --pid /run/AB/ab.pid
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
ExecStopPost = /bin/rm -rf /run/AB
PrivateTmp = true

[Install]
WantedBy = multi-user.target

我最初启动了,A.service它成功启动了。但是,当我启动时B.service,我看到正在A.service结束。但它ExecStopPost似乎没有执行,因为我收到以下错误:

/bin/mkdir: cannot create directory ‘/run/AB’: File exists

ExecStopPost真的不行吗Conflicts??

谢谢。

答案1

您尚未指定这两项服务之间的任何排序限制。因此,正在发生的事情是在完成停止(并执行)之前B.service启动(并执行)。 的相关部分mkdirA.servicerm
systemd.unit 文档:

Conflicts=
请注意,此设置独立于 After= 和 Before= 排序依赖关系并与之正交。

 

解决方案是将其他服务添加到每个服务的After=列表中(添加到的列表A.service中,反之亦然)。 另请参阅相关部分B.serviceAfter=
文档:

Before=, After=
给定两台设备之间存在任何顺序相关性,如果一台设备关闭而另一台设备启动,则关闭顺序将先于启动顺序。在这种情况下,排序依赖项是 After= 还是 Before= 并不重要。关闭两者中的哪一个并不重要,只要关闭一个并启动另一个即可。在所有情况下,关闭都是在启动之前命令的。

After=^ 意味着您是否使用或并不重要Before=。他们都会完成同样的事情。

答案2

谢谢帕特里克对于这样一个解释性的答案并消除了我的一些疑虑。

谢谢想知道代表我进行测试。

作为帕特里克的回答提到,由于未定义的顺序,它可能会行为不当。B.service无法运行,mkdir因为该目录已经存在并且A.service尚未删除。

  1. 您可以为它们定义一个顺序。无论哪个先启动,它们都会按照您当前的要求表现相同。

  2. 或者,您可以pid为这两个服务创建单独的文件,然后ExecStopPost只需删除该pid文件而不是目录。

请记住,如果您遵循第二种方法,则ExecStartPre不需要。

仅供参考,在浏览了一些init.d脚本之后,我认为放置pid文件的最佳位置是/var/run/不创建任何额外的目录。仅当您的服务以 root 身份启动时,这才有效,因为该位置仅对 root 进行写保护。

相关内容