
背景
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_daemon
systemd
foo_daemon
を介しての正常なシャットダウンを試みますSIGTERM
。- シャットダウン/終了が完了するまで最大 2 秒かかります
foo_daemon
。 foo_daemon
プロセスがまだ生きている場合は、強制シャットダウンを試みます(PIDがリサイクルされて間違ったPIDに対して問題が発生するSIGKILL
リスクはありません)。テストしているデバイスは、多数のプロセスを迅速に生成/分岐します。systemd
SIGKILL
そのため、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