如何告诉 systemctl 服务已启动

如何告诉 systemctl 服务已启动

mediation.service我有一个这样的服务单元文件:

[Unit]
Description=Mobile-IP Log dumper

[Service]
Type=forking
ExecStart=/opt/mediation/mediation start
ExecStopPost=/opt/mediation/mediation stop
ExecReload=/opt/mediation/mediation reload
PIDFile=/var/lib/mediation/syslog-ng.pid

现在假设有人直接使用/opt/mediation/mediation start而不是使用systemctl start mediation

在这种情况下systemctl status mediation将显示:

● mediation.service - Mobile-IP Log dumper
   Loaded: loaded (/etc/systemd/system/mediation.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Mon 2016-07-11 11:24:11 CEST; 8s ago
  Process: 14088 ExecStopPost=/opt/mediation/mediation stop (code=exited, status=0/SUCCESS)
  Process: 13482 ExecStart=/opt/mediation/mediation start (code=exited, status=0/SUCCESS)
 Main PID: 13746

是否有可能systemctl status mediation显示服务的正确状态(即正在运行)?看起来 systemctl 在检查状态时不会重新加载 PIDFile,因为在这种情况下所有信息都是可用的,并且正确的状态是已知的。

答案1

不,你不能这么做。

systemd 的服务跟踪主要基于 cgroups,因此进程不能除非它位于适当的 cgroup 内,否则将被视为其中的一部分mediation.service。(例如,用户登录与 sshd.service 分离的方式是:通过移动到另一个 cgroup。)它不太关心 PID 文件,尽管它确实使用它们进行额外的验证。

但即使手动将进程移至正确的 cgroup(通过 /sys/fs/cgroup/systemd),整个服务仍不会被视为“活跃”,除非它已启动通过systemd。


在 Debian 和其他仍然混合/etc/init.d使用脚本的发行版中,可以通过编辑常见的“LSB 函数”脚本来解决此问题,以便在手动调用时通过 systemctl 自动重新运行 initscript。

但至于启动守护进程直接地… 好吧,我想最好不要这么做?或者,制作一个类似的包装脚本,将手动启动重定向到 systemctl。

答案2

由于没有直接的解决方案,解决方法可能是将这样的行添加到脚本中。

if [[ ! `ps --no-headers -o args -p $PPID | grep systemd` ]] ; then 
   echo "You must start the application with 'systemctl start mediation'"
   exit 1
fi

这可以防止服务在 systemctl 之外启动。

相关内容