![在 systemd 服务内启动 systemd 服务会导致死锁](https://linux22.com/image/109928/%E5%9C%A8%20systemd%20%E6%9C%8D%E5%8A%A1%E5%86%85%E5%90%AF%E5%8A%A8%20systemd%20%E6%9C%8D%E5%8A%A1%E4%BC%9A%E5%AF%BC%E8%87%B4%E6%AD%BB%E9%94%81.png)
first.service
我有一个调用 bash 脚本的systemd 服务(我们称之为)。
在该 bash 脚本中,我首先停止然后启动另一个服务systemctl
(例如systemctl start another.service
.
我注意到,当我在 shell 中执行脚本时,一切正常,并且another.service
被停止并稍后启动。
当我调用systemctl restart first.service
systemd 时,会正确停止“ another.service
”,但会继续启动它。
当我检查结果时,ps
它说两个 systemctl 调用都在工作,即systemctl restart first.service
和systemctl 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
,要么使用主进程的无限循环退出。