Yocto linux服务脚本问题

Yocto linux服务脚本问题

我写了一个 systemd 脚本mqtt.service,位于 /home/root目录中

这是我的mqtt.service脚本:

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
[Unit]
Description=mqtt

DefaultDependencies=no
After=xdk-daemon.service


[Service]

Restart=always
RestartSec=10
ExecStart=/bin/sh /home/root/mosquitto-1.4/mqtt_start.sh



[Install]

WantedBy=multi-user.target

这就是内容mqtt_start.sh

#!/bin/sh
/home/root/mosquitto-1.4/src/mosquitto -c /home/root/mosquitto-1.4/mosquitto.conf -d -p 1885 > /dev/null 2>&1

如果我粘贴该行:

/home/root/mosquitto-1.4/src/mosquitto -c /home/root/mosquitto-1.4/mosquitto.conf -d -p 1885

进入终端,mqtt代理正常启动但在这里我无法启动它

我做到了

$ systemctl enable /home/root/mqtt.service
$ systemctl status mqtt.service
● mqtt.service - mqtt
   Loaded: loaded (/home/root/mqtt.service; enabled)
   Active: failed (Result: resources) since Mon 2015-04-06 10:42:48 UTC; 24s ago
 Main PID: 677 (code=exited, status=0/SUCCESS)

Apr 06 10:42:39 edison sh[677]: 1428316959: Warning: Mosquitto should not be run as root/administrator.
Apr 06 10:42:48 edison systemd[1]: mqtt.service holdoff time over, scheduling restart.
Apr 06 10:42:48 edison systemd[1]: mqtt.service failed to schedule restart job: Unit mqtt.service failed to load: No such file or directory.
Apr 06 10:42:48 edison systemd[1]: Unit mqtt.service entered failed state.

让我知道我错在哪里。

编辑 :

重新启动后我做了:

systemctl 状态 mqtt.service和结果:

● mqtt.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)

答案1

您的 systemd 服务单元默认为,Type=simple但您的包装脚本正在使用该--daemon选项。这是准备协议不匹配。就绪协议不匹配会导致服务无法正确启动,或者(更常见)被 systemd(错误)诊断为失败。

后者正在这里发生。因为你对系统进行了过度设计,你的守护进程出现了不必要的分叉两次以上,而错误的进程是实际的守护进程。此外,您还不必要地在包装脚本中重复 systemd 服务单元功能。

完全摆脱包装器 shell 脚本,并像这样编写您的服务单元:

[单元]
描述=Mosquitto MQTT 代理
文档=man:mosquitto(8)
文档=man:mosquitto.conf(5)
ConditionPathExists=/home/root/mosquitto-1.4/mosquitto.conf
After=xdk-daemon.service

[服务]
ExecStart=/home/root/mosquitto-1.4/src/mosquitto -p 1885 -c /home/root/mosquitto-1.4/mosquitto.conf
ExecReload=/bin/kill -HUP $MAINPID
用户=蚊子
重新启动=失败时
重新启动秒=10

[安装]
WantedBy=多用户.target

请注意:

  • 您不需要该--daemon选项。经纪人已经被守护进程化当 systemd 运行它时。
  • 您不应该使用该--daemon选项。 Mosquitto 不会讲forking就绪协议,因为它是实际上还没有准备好分叉后退出。 (我们希望有一天人们能够编写这样的程序,这样他们就可以继承他们的监听套接字因此可以通过套接字激活。)
  • 您不需要在包装器脚本中摆弄标准输出和错误。 systemd 将处理守护进程的标准输出和错误。如果确实需要的话,它们可以在服务单元文件中进行配置,但这对于这个程序来说似乎根本没有必要。
  • 由于 systemd 可识别的正确进程现在是守护进程,systemctl reload mqtt.service现在可以向正确的位置发送信号并工作。
  • systemd 本身将以 user 身份调用代理mosquitto;因此,您需要确保存在具有该名称的用户帐户,并且具有必要的访问权限。请注意日志中的警告。
  • systemd 人员推荐on-failure作为重启策略always
  • DefaultDependencies除非是守护进程,否则不应设置为 false实际上可以运行在启动过程的早期和关闭过程的后期,对于大多数情况来说通常情况并非如此。默认服务单元依赖关系是合适的对于这种守护进程。

相关内容