Linuxカーネルのシャットダウンの内部はどのように機能しますか?

Linuxカーネルのシャットダウンの内部はどのように機能しますか?

私は、システムがシャットダウンしたときにユーザースペースとinitシステム(従来のinit sysV / upstart / systemd)がどのように機能するかを大まかに知っています。 (本質的に「やめて!」、「もうやめて」、「止めるには殺さなければならない」という連続的な命令が出て待っています…仕事が起きています。)

とにかく、カーネルでシステムシャットダウンがどのように機能するのかわかりません(そこで多くのことが起こっているに違いありません)。

カーネル文書を見てみました。https://www.kernel.org/doc/htmldocs/でも使用NSAの友達検索ツールまず、それがどのように機能するかを理解しましょう。

SE U+Lも検索してみましたが何もありませんね(無視したのですか?)

とにかく、この質問は少し難しいかもしれませんが、このQ&Aネットワークで答える価値があります。もっと多くの人がLinuxカーネルが終了したらどうなるか知りたいからです。

さらに、より詳細な説明へのリンクが変更されることがあります。

答えには、どのシステムコールと使用するカーネル信号を含めることができますか?

https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c x86で使用する再起動関連ファイルのようです(すでに終了直前ですね?)

たぶんここに見つかったスニペットがあるかもしれません。http://lxr.free-electrons.com/source/kernel/reboot.c#L176 説明を提供するために使用できます

176無効なkernel_power_off(無効)
177 {
178話
179 if(pm_power_off_prepare)
180 pm_power_off_prepare();
181話
182 syscore_shutdown();
183 pr_emerg("停電\n");
184話
[185章]
186}
187 EXPORT_SYMBOL_GPL(カーネルの電源を切る);

答え1

Linuxカーネルのしくみを理解するための主なリソースは次のとおりです。

  1. 文書
  2. Linux週間ニュース記事
  3. 源泉。わかりやすい複雑な獣です。LX、Linux相互参照。 LXR 亜種は以下で実行されます。lxr.linux.no他よりも優れていますが、しばしばダウンすることもあります。

この場合、ドキュメントやLWNで中心的に関連するコンテンツが見つからないため、LXRです。

userlandコードが最後にすることは呼び出しです。rebootシステムコール。 4つのパラメータが必要なので、LXRで検索するとSYSCALL_DEFINE4(reboot結果は次のようになります。kernel/reboot.c。発信者の権限とパラメータを確認した後、システムコールのエントリポイントは、再起動、緊密なループで停止、システムの電源を切るなどkernel_restart、いくつかの機能の1つを呼び出します。kernel_haltkernel_poweroffkernel_kexec新しいカーネルと交換(コンパイルされた場合)またはhibernate停電前にメモリをディスクに保存します。

kernel_restartkernel_haltそして kernel_power_offとても似ています:

  1. 渡すreboot_notifier_list、カーネルコンポーネントが使用できるフックのリスト。登録する電源が切れたらコードを実行します。この段階では、少数のドライバだけがコードを実行する必要があり、ほとんどは監視デバイスです。
  2. 設定system_state変える
  3. 障害を負う ユーザーモードヘルパー、ユーザーコードが起動しなくなりました。 (この段階でも既存のプロセスが存在する可能性があります。)
  4. 呼ぶdevice_shutdownシステム内のすべてのデバイスを解放または終了します。多くのドライバーがこの段階に閉じ込められます。
    この時点でまだマウントされているファイルシステムは、事実上強制的にアンマウントされます。システムコール呼び出し側は完全な削除を担当します。
  5. 電源オフの場合にのみ ACPI が設定されている場合、コードの実行が発生する可能性があります。ACPIエントリーの準備 状態S5(ソフト終了).
  6. マルチCPUコンピュータでは、どのCPUがシステムコールを呼び出したかに関係なく、すべてのCPUでコードを実行できます。migrate_to_reboot_cpu特定のCPUに切り替えると、スケジューラは他のCPUにコードをディスパッチできません。その後、1つのCPUのみが実行されます。
  7. syscore_shutdown通話shutdown方法登録されたsyscoreジョブ。私はこれが主に割り込みをディセーブルにすることだと思います。shutdownメソッドのあるフックはほとんどありません。
  8. 情報メッセージの録音 - 白鳥の歌。
  9. 最後に、以下を呼び出して、マシンに依存する方法でリラックスします。machine_restartmachine_haltまたはmachine_power_off

これ冬眠パスワード次の手順を実行します。

  1. 繰り返し電源管理フック
  2. ファイルシステムを同期します。
  3. すべてのユーザーパスワードを凍結する
  4. デバイスのホットプラグ防止
  5. スペースを交換するためにシステム状態をダンプします。
  6. すべてがうまくいけば休止状態ハードウェア。これには、、、、kernel_restartまたは一部のプラットフォームkernel_halt固有kernel_power_offのスリープメソッド呼び出しを含めることができます。

システムをシャットダウンする別の方法は次のとおりです。machine_emergency_restart。これは次のために発生します。魔法システムリクエストB。ボタンにはOさまざまな機能があります。呼ぶkernel_power_off

システムをシャットダウンしてシャットダウンすることもできます。パニックつまり、回復不能なエラーです。パニックはメッセージを記録し、システムの再起動を試みます(ハードウェア監視または緊急再起動を介して)。

答え2

これは単なる部分的な答えであり、より詳細で明確な他の答えを必ず招待します。

この答えの内容はkernel/reboot.c3.13 Linuxカーネルファイルからのものです(名前はshutdown.cではなく再起動.cなので、最初の推測ではないかもしれません)。

とにかく、基本的にシステムシャットダウンプロセスを表す3つの関数があります。

  • void kernel_halt(void)//システムが停止した状態で終了します。
  • void kernel_power_off(void)// シャットダウンでシャットダウン
  • void kernel_restart(char *cmd)//システムをシャットダウンして再起動します。

これらの機能は非常に簡単なので、ここに全体的に貼り付けることができます。このコードは、カーネルのシャットダウン中に実行された手順を最もよく示します。 (このレビューは私が書いたもので、100%理想的であるか正確ではないかもしれません。自信があるかどうかを直接確認してください。簡単です。一度試してください。

void kernel_halt(void)

無効なカーネルの停止
{
    //最初のステップ:
    // a) 再起動/終了時に実行するように登録された呼び出し関数/コールバック
    // b) system_sate を SYSTEM_HALT に設定します。
    // c)userspacetoolの対話を停止します。
    // d) device_shutdown() 関数呼び出し
    kernel_shutdown_prepare(SYSTEM_HALT);

    //ステップ2:マルチCPUシステムにはこれが必要だと思います。
    migration_to_reboot_cpu();

    // 3番目のステップ:
    // syscore_shutdown - 登録されているすべてのシステムコア終了コールバックを実行します。
    syscore_shutdown();

    // 4番目のメッセージ
    pr_emerg("システムが停止しました\n");
    kmsg_dump(KMSG_DUMP_HALT);

    // 5番目の呼び出しアーキテクチャ固有のCPU-halt-code
    machine_halt();
}

すべてはsys_rebootシステムコールを介して開始されますが、再起動だけでなくシャットダウンも考慮すると、とにかくシャットダウンプロセスに直接接続するわけではありません。

関連情報