シャットダウンコマンドが発行された後、次のようなステータスメッセージが表示されることがあります。
A stop job is running for Session 1 of user xy
そして、システムはしばらくの間、または永遠に依存して永遠にハングします???
つまり、「ジョブの停止」とは正確には何ですか?
また、なぜそれがかかる時間を非常に正確に推定するのか、そして他の時間は永久に実行できるのですか?
systemdは、「ジョブ」のキューに関して内部的に動作します。各job(少し簡略化)は実行するアクションです:特定のユニットを停止、チェック、開始、または再起動します。
(たとえば)systemdにサービスユニットを開始するように指示すると、あらゆるユニット(サービスユニット、マウントユニット、デバイスユニット、およびユニットの要件と依存関係に従ってその目標を達成するために必要であり、ユニットの順序関係に従ってそれらを順序付け、解決し、(可能であれば)自己矛盾を修正し、(その最終ステップが成功した場合)場所それらをキューに入れます。
次に、エンキューされた「ジョブ」を実行しようとします。
ユーザーxyのセッション1で停止ジョブが実行されています
単位表示名はSession 1 of user xy
。これは(表示名から)sessionユニットであり、serviceユニットではありません。これは、systemdのlogind
プログラムとそのPAMプラグインによって維持されるユーザー空間ログインセッションの抽象化です。これは、(本質的には理論的には)そのユーザーがどこかで「ログインセッション」として実行しているすべてのプロセスのグループです。
それに対してエンキューされたジョブはstop
です。また、systemdのユーザーが誤ってセッションhangupとセッションshutdownを混同しているため、時間がかかる可能性があります。彼らは前者を破って後者を機能させ、それに応じてsystemdを変更して後者を破って前者を機能させます。 systemdの人々は、これらが2つの異なるものであることを実際に認識する必要があります。
ログインセッションで、SIGTERM
を無視するもの、またはSIGTERM
を見た後、終了に時間がかかるものがあります。皮肉なことに、前者は一部のジョブ制御シェルの長期にわたる動作です。これらの特定のジョブ制御シェルであるときにログインセッションリーダーを終了する正しい方法は、セッションがハングアップしたことを通知すると、すべてのtheirジョブ(内部のsystemdジョブとは異なる種類のジョブ)を実行して終了します。
実際に起こっていることは、systemdがSIGKILL
に頼るまでユニットのstopタイムアウトを待機していることです。もちろん、このタイムアウトはユニットごとに構成可能で、タイムアウトしないように設定できます。それゆえ、なぜ異なる行動を見ることができるのか。
これらのメッセージは、ジョブを開始および停止するinitシステムであるsystemdからのものです。ジョブはデーモンにすることもできますが、ディスクのマウントとマウント解除、/ tmpの削除、ブート全体での画面の明るさの保存と復元などの小さなタスクも実行できます。 systemctl list-units
はあなたにアイデアを与えます。 Systemdは「ユニット」と「ジョブ」を使用して、ほとんど同じことを意味します。
systemctl stop ...
のようにジョブが停止している場合、問題は、ジョブが完了するまで待機してから、失敗を宣言してSIGKILL
シグナルでジョブのプロセスを強制終了するまでの時間です。 SIGKILL
は、プロセスが正常に終了する機会を与えないため、必要がない限り、実際には使用しません。一部のプロセスでは、数秒で障害を宣言するのに十分な時間がかかる場合があります。データベースなどの他のプロセスでは、ジョブが完全に停止するために大量のネットワークおよびディスクI/Oが発生する可能性があるため、これらのユニットに完全にシャットダウンするために数分を与える場合があります。 。
シャットダウン時に表示されるのは、実行に時間がかかるsystemctl stop $UNIT_NAME
に相当します。 SIGKILLが発行されてシャットダウンが続行されるまでの経過秒数と最大待機時間を示すカウンターがあります。
長い遅延が予想される正当な理由がない限り、これは通常、ある種の誤動作を示しています。 DHCPサーバーがリリースに応答しないため、リリースアクションがタイムアウトする必要があるか、エラーが発生してデーモンが終了しない可能性があります。
一部のサービスがスタックし、systemdはそれが終了するのを待っています。 systemdはおそらく、かかる時間を正確に見積もっていません。時間(通常90秒)は、systemdが忍耐力を使い果たす前に待機する時間です。この投稿を参照してください: