在 systemd 服务内启动 systemd 服务会导致死锁

在 systemd 服务内启动 systemd 服务会导致死锁

first.service我有一个调用 bash 脚本的systemd 服务(我们称之为)。

在该 bash 脚本中,我首先停止然后启动另一个服务systemctl(例如systemctl start another.service.

我注意到,当我在 shell 中执行脚本时,一切正常,并且another.service被停止并稍后启动。

当我调用systemctl restart first.servicesystemd 时,会正确停止“ another.service”,但会继续启动它。

当我检查结果时,ps它说两个 systemctl 调用都在工作,即systemctl restart first.servicesystemctl start another.service

我用的是systemd 230

这是已知的行为吗?我怎样才能解决这个问题?

有没有更好的方法来处理(重新)启动一个服务中的 systemd 服务?

编辑:我的first.service文件:

[Unit]
Description=First service
#Before=local-fs.target apache2.service rsyslog.service

[Service]
Type=oneshot
ExecStart=/usr/bin/test.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

我的another.service文件:

[Unit]
Description=Test service

[Service]
Type=oneshot
ExecStart=/bin/bash -c "while ( true  ) ; do { date ; echo 'It works!' ; sleep 10 ; } done"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

和我的 bash 脚本:

#!/bin/bash
echo stopping
systemctl stop another.service
echo "result of stop = $?"
echo starting
systemctl start another.service
echo "result of start = $?"
echo DONE

挂起后我得到以下输出ps

[piotr@/etc/systemd/system] $ ps -aux | grep systemctl
root      7801  0.0  0.0  27696  1336 pts/21   S+   16:06   0:00 systemctl restart first
root      7807  0.0  0.0  27696  1320 ?        S    16:06   0:00 systemctl start another.service
piotr     7915  0.0  0.0  15752   968 pts/22   S+   16:06   0:00 grep --color=auto systemctl

编辑2systemctl status:当我在另一个控制台中调用 时,我正在从这两种服务发布消息systemctl restart first

我还在 bash 脚本中添加了检查返回值。更新如上。

first.service

● first.service - First service
Loaded: loaded (/etc/systemd/system/first.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2017-04-19 16:34:43 CEST; 46s ago
Main PID: 12761 (test.sh)
CGroup: /system.slice/first.service
├─12761 /bin/bash /usr/bin/test.sh
└─12766 systemctl start another.service

Apr 19 16:34:43 piotr-ideapad systemd[1]: Starting First service...
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: stopping
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: result of stop = 0
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: starting

another.service

● another.service - Test service
Loaded: loaded (/etc/systemd/system/another.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2017-04-19 16:34:43 CEST; 1min 40s ago
Main PID: 12767 (bash)
CGroup: /system.slice/another.service
├─12767 /bin/bash -c while ( true   ) ; do { date ; echo 'It works!' ; sleep 10 ;  } done
└─13066 sleep 10

Apr 19 16:35:43 piotr-ideapad bash[12767]: Mi 19. Apr 16:35:43 CEST 2017
Apr 19 16:35:43 piotr-ideapad bash[12767]: It works!
Apr 19 16:35:53 piotr-ideapad bash[12767]: Mi 19. Apr 16:35:53 CEST 2017
Apr 19 16:35:53 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:03 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:03 CEST 2017
Apr 19 16:36:03 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:13 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:13 CEST 2017
Apr 19 16:36:13 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:23 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:23 CEST 2017
Apr 19 16:36:23 piotr-ideapad bash[12767]: It works!

编辑3:交换一些意见后,我将尝试重新表述该问题。

假设上面列出的我的进程都没有启用或启动。当我呼唤systemctl status他们时——他们loaded只是inactive
然后我打电话systemctl start first,这个终端命令没有完成。
如果我调用这些服务,我会得到它们systemctl status的状态,但我在终端中的执行仍然没有退出,并且它无限期地挂起。Active:activating (start)systemctl start first

我认为这两个进程都已排队,并且systemctl start another在我的 bash 脚本中等待systemctl start first它自己完成之前完成,这里我们遇到了死锁。

答案1

看似僵局的Type=oneshot指令实际上正如宣传的那样起作用。可以通过直接运行以下命令来触发“挂起” another.service

systemctl start another

一旦取消,人们可以检查journalctl发现它根本没有“挂起”,而是按预期运行无限循环。在 中man systemd.service,我们找到以下文档Type=oneshot

oneshot 的行为与 simple 类似;然而,预计该进程必须在 systemd 启动后续单元之前退出。

换句话说,您编写了一个无限循环,然后指示 systemd 等待它完成后再继续。

您要么需要使用不同的Type=, like Type=simple,要么使用主进程的无限循环退出。

相关内容