【问题标题】:How to run a specific program before systemd's watchdog stops a service如何在 systemd 的看门狗停止服务之前运行特定程序
【发布时间】:2018-10-17 17:04:37
【问题描述】:

我有一个由 systemd 运行的程序,其服务文件如下:

[Unit]
Description=...

[Service]
Type=notify
ExecStart=/usr/sbin/myprogram
WatchdogSec=1
KillMode=process
KillSignal=SIGTERM
Restart=always

它定期向看门狗发送相应的信号。有时,程序似乎挂起并被看门狗终止,然后重新启动。在看门狗终止它之前,我想通过执行命令或运行其他脚本(例如运行gdb -p <PID> --batch -ex 'thread apply all backtrace')从程​​序中捕获一些信息。我该怎么做?

【问题讨论】:

    标签: systemd watchdog


    【解决方案1】:

    ExecStop= 添加到您的服务中。

    [Service]
    ExecStart=....
    ExecStop=/path/to/SomeOtherProgram
    ....
    

    根据systemd手册,如果ExecStop选项可用,它会先运行,然后如果ExecStart下的进程在此之后仍然可用,它将运行KillMode

    执行停止= 要执行的命令以停止通过以下方式启动的服务 执行开始=。此参数采用多个命令行,遵循 与上述 ExecStart= 描述的方案相同。使用此设置是 可选的。该选项中配置的命令运行后, 暗示该服务已停止,并且任何剩余的进程 它根据 KillMode= 设置终止(请参阅 systemd.kill(5))。如果未指定此选项,则流程为 通过在服务时发送 KillSignal= 中指定的信号来终止 请求停止。说明符和环境变量替换是 支持(包括 $MAINPID,见上文)。

    编辑

    正如下面的评论,此解决方案可能不适用于service 文件中的Watchdog 选项。

    【讨论】:

    • 这应该会有所帮助,但我不喜欢这种方法有两点:1) 当服务被故意停止时,它也会执行ExecStop= 命令,例如在部署期间。 2)如果我理解正确,这会覆盖默认的停止命令。因此服务不会停止,除非设置 TimeoutStopSec= 触发 SIGKILL 或使用原始停止命令(我不知道)添加另一个 ExecStop= 或创建报价中描述的条件的其他内容。不过,我会试一试。您还有其他解决方案吗?
    • 不,您不需要任何额外的属性。 ExecStop= 停止另一个脚本,并且在它停止之后,如果 systemd 仍然找到从 ExecStart= 开始的 process-id,它将使用 KillSignal=SIGTERM 调用 KillMode=process。如果没有ExecStop=,无论如何它都会做同样的事情。
    • 不幸的是,事实证明这并没有像我们预期的那样工作。 systemd 看门狗终止服务后运行ExecStop= 命令(首先发送SIGABRT,然后在90 秒后超时时发送SIGTERM)。我想我不能在这里使用任何 systemd 机制,但必须在内部处理 SIGABRT 并从服务内收集信息。
    • 好的,tbh,我确实测试了它,但没有 Watchdog 并且它确实终止了进程...Watchdog 可能覆盖了结构。
    猜你喜欢
    • 2019-03-15
    • 1970-01-01
    • 2021-01-04
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多