【问题标题】:Systemd - detect in ExecStopPost whether service exited without errorSystemd - 在 ExecStopPost 中检测服务是否无错误退出
【发布时间】:2016-07-15 21:09:18
【问题描述】:

我有一个应用程序在完成并正常退出后不应重新启动。在此应用程序完成其业务后,我想关闭实例(ec2)。我正在考虑使用带有选项的 systemd 单元文件来执行此操作

Restart=on-failure
ExecStopPost=/path/to/script.sh

应该在ExecStopPost 上运行的脚本:

#!/usr/bin/env bash

# sleep 1; adding sleep didn't help

# this always comes out deactivating
service_status=$(systemctl is-failed app-importer) 

# could also do the other way round and check for failed
if [ $service_status = "inactive" ] 
then
  echo "Service exited normally: $service_status . Shutting down..."
  #shutdown -t 5
else
  echo "Service did not exit normally - $service_status"
fi
exit 0

问题是,当 post stop 运行时,我似乎无法检测到服务是否正常结束,然后状态为deactivating,只有在我知道它是否进入failed 状态之后。

【问题讨论】:

    标签: linux systemd


    【解决方案1】:

    您的问题是 systemd 认为服务是 deactivating 直到 ExecPostStop 进程完成。睡觉并没有帮助,因为它只会等待更长的时间。 ExecPostStop 的想法是清理服务可能留下的任何东西,如临时文件、UNIX 套接字等。服务尚未完成,准备重新启动,直到清理完成。因此,如果您这样看,systemd 所做的确实是有意义的。

    您应该做的是检查您的脚本中的$SERVICE_RESULT$EXIT_CODE 和/或$EXIT_STATUS,它会告诉您服务是如何停止的。示例:

    #!/bin/sh
    echo running exec post script | logger
    systemctl is-failed foobar.service | logger
    echo $SERVICE_RESULT, $EXIT_CODE and $EXIT_STATUS | logger
    

    何时允许服务运行完成:

    Sep 17 05:58:14  systemd[1]: Started foobar.
    Sep 17 05:58:17  root[1663]: foobar service will now exit
    Sep 17 05:58:17  root[1669]: running exec post script
    Sep 17 05:58:17  root[1671]: deactivating
    Sep 17 05:58:17  root[1673]: success, exited and 0
    

    当服务在完成之前停止:

    Sep 17 05:57:22  systemd[1]: Started foobar.
    Sep 17 05:57:24  systemd[1]: Stopping foobar...
    Sep 17 05:57:24  root[1643]: running exec post script
    Sep 17 05:57:24  root[1645]: deactivating
    Sep 17 05:57:24  root[1647]: success, killed and TERM
    Sep 17 05:57:24  systemd[1]: Stopped foobar.
    

    【讨论】:

    • systemctl stop foobar.service and kill $(pidof foobar_app) 在 ExecStopPost 上都产生成功、终止和 TERM,并且 foobar 进入“非活动”或死亡状态。有没有办法区分 foobar 进入“失败”状态与 foobar 进入“非活动”状态? $SERVICE_RESULT, $EXIT_CODE and/or $EXIT_STATUS 在这里没有帮助。
    • 所以,如果服务正常完成,或者被 systemd 强制停止,但如果它因非被 systemd 停止以外的原因而失败,您不想做某事?
    • 我想特别处理服务故障(核心转储、EXIT_FAILURE、不可屏蔽信号等),同时应该允许用户发起的 SIGTERM。特别是,我想知道该服务是否会在 ExecStopPost 中重新启动。 $SERVICE_RESULT 被宣传为持有“start-limit-burst”,但即使在配置了限制突发间隔并且服务达到了突发限制之后,它也不会显示该值
    • 在您的情况下,您可以尝试将SuccessAction=reboot 添加到Unit 部分。如果服务完成并返回 0、通过 systemctl 停止、通过 TERM 终止,这将触发。如果服务被 SEGV 杀死或返回非零代码,则不会触发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2017-11-23
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    相关资源
    最近更新 更多