背景

背景

背景

systemd新しいサービス用のスクリプトを作成するように依頼されました。このサービスfoo_daemonは、時々「不良状態」になり、 経由では終了しませんSIGTERM(おそらくカスタム シグナル ハンドラーが原因)。開発者は、次の方法でサービスを開始/停止/再起動するように指示されるため、これは問題となります。

  • systemctl start foo_daemon.service
  • systemctl stop foo_daemon.service
  • systemctl restart foo_daemon.service

問題

foo_daemon場合によっては、状態が悪くなったために、次の方法で強制終了する必要があります。

  • systemctl kill -s KILL foo_daemon.service

質問

ユーザーがサービスを停止/再起動しようとするたびに、次の処理が実行されるようsystemdにスクリプトを設定するにはどうすればよいでしょうか。foo_daemonsystemd

  • foo_daemonを介しての正常なシャットダウンを試みますSIGTERM
  • シャットダウン/終了が完了するまで最大 2 秒かかりますfoo_daemon
  • foo_daemonプロセスがまだ生きている場合は、強制シャットダウンを試みます(PIDがリサイクルされて間違ったPIDに対して問題が発生するSIGKILLリスクはありません)。テストしているデバイスは、多数のプロセスを迅速に生成/分岐します。systemdSIGKILLそのため、PID のリサイクルが問題を引き起こすのではないかという、まれではあるが非常に現実的な懸念があります。
  • 実際には、PID のリサイクルについて心配しているだけであれば、リサイクルSIGKILLされた PID を強制終了することを気にせずに、プロセスの PID に対してスクリプトを発行するだけで問題ありません。

答え1

systemdはすでにこれをサポートしており、デフォルトで有効

カスタマイズしたいのはタイムアウトだけです。これは で行うことができますTimeoutStopSec=。例:

[Service]
TimeoutStopSec=2

ここで、systemd は SIGTERM を送信し、サービスが終了するまで 2 秒間待機し、終了しない場合は SIGKILL を送信します。

サービスが systemd に対応していない場合は、 で PID ファイルへのパスを指定する必要がある場合がありますPIDFile=

最後に、デーモンが多数のプロセスを生成するとおっしゃいました。この場合、設定するKillMode=control-groupと、systemd が cgroup 内のすべてのプロセスにシグナルを送信するようになります。

答え2

が必要だと誰も言及していないのでType=oneshot、タイムアウトの失敗により終了する完全な例を次に示します。

[Unit]
Description=timeout test

[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10

関連情報