systemd 服务将手动启动,但不会在启动时启动?

systemd 服务将手动启动,但不会在启动时启动?

我已经编写了一个 systemd 服务来在我的 Raspberry Pi 上启动 groundcontrol。

[Unit]
Description=Groundcontrol status monitor

[Service]
ExecStart=/opt/groundcontrol/groundcontrol/start.sh
Type=forking

[Install]
WantedBy=multi-user.target  

我使用脚本是因为除非从 bin 目录启动,否则 groundcontrol 将无法正常工作。以下是脚本:

cd /opt/groundcontrol/groundcontrol
./groundcontrol &

当我手动启动它时,它运行正常,但是当我启动我的 Pi 并运行时,systemctl它说它失败了。systemctl status groundcontrol.service打印

groundcontrol.service - Groundcontrol status monitor
   Loaded: loaded (/etc/systemd/system/groundcontrol.service; enabled)
   Active: failed (Result: exit-code) since Wed 1969-12-31 17:00:14 MST; 43 years 11 months ago
  Process: 111 ExecStart=/opt/groundcontrol/groundcontrol/start.sh (code=exited, status=0/SUCCESS)
 Main PID: 116 (code=exited, status=2)

Dec 31 17:00:11 waldo systemd[1]: Starting Groundcontrol status monitor...
Dec 31 17:00:12 waldo systemd[1]: Started Groundcontrol status monitor.
Dec 31 17:00:14 waldo systemd[1]: groundcontrol.service: main process exited, code=exited, status=2/INVALIDARGUMENT
Dec 31 17:00:14 waldo systemd[1]: Unit groundcontrol.service entered failed state. 

当我手动运行它时状态是

groundcontrol.service - Groundcontrol status monitor
   Loaded: loaded (/etc/systemd/system/groundcontrol.service; enabled)
   Active: active (running) since Thu 2013-12-26 15:38:02 MST; 1s ago
  Process: 296 ExecStart=/opt/groundcontrol/groundcontrol/start.sh (code=exited, status=0/SUCCESS)
 Main PID: 297 (groundcontrol)
   CGroup: /system.slice/groundcontrol.service
           `-297 ./groundcontrol

Dec 26 15:38:02 waldo systemd[1]: Started Groundcontrol status monitor. 

groundcontrol 提供了一个 System V init 脚本,但我不知道如何将它与 systemd 一起使用 - 这可能吗?它会比我的服务更好吗?如果不行,我该如何修复此服务?谢谢。

答案1

日志显示:

main process exited, code=exited, status=2/INVALIDARGUMENT

这意味着问题出在groundcontrol它自身;它返回了状态 2(某种故障)。

通常这个特定的问题——服务仅在启动时失败——是由服务启动引起的太早了,即当它需要一些系统尚未发现的硬件设备时。(请记住,在现代 Linux 系统中,几乎所有设备都是动态发现的;它说“哦,我有所有设备,让我们开始初始化。”)

解决方案是重写程序以使用 libudev 并动态添加设备。

解决方法是在特定设备之后对服务进行排序(但我不知道它需要哪个设备,所以我无法给出完整的答案),或者使用 Wants= + After= 来等待,systemd-udev-settle.service直到 udev 处理完第一批“新设备”事件。


.sh另外,为什么你要为 cd 到目录这个唯一目的而编写一个单独的脚本? WorkingDirectory=+Type=simple就足够了。(这&也是不必要的,因为 systemd 本身(作为服务管理器)在“后台”运行一切。)

相关内容