web-dev-qa-db-ja.com

カーネルパニックで失敗してQemuを終了させることはできますか?

Qemuを継続的インテグレーションパイプラインに追加して、さまざまなinitrdアーティファクトをテストしようとしています。このようにQemuを実行できることはすでに発見しました。

qemu-system-x86_64 \
    -machine q35 \
    -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly \
    -drive if=pflash,format=raw,file=OVMF_VARS.fd \
    -kernel vmlinuz-4.4.0-121-generic \
    -initrd my-initramfs.cpio.xz \
    -nographic

...initスクリプトでこれを行うと、qemu-system-x86_64がステータス0で終了します。

# poweroff -f

これは、initスクリプトが終了しないため機能します-poweroff -fを呼び出し、「永久に」スリープするか、Qemuが「パワーダウン」するまでスリープします。

ACPI: Preparing to enter system sleep state S5
reboot: Power down

set -eu経由でエラー時にinitを強制することで、exitスクリプトの問題を検出できるようにしたいと思います。 initスクリプトを(正しく)終了すると、カーネルパニックが発生しますが、qemu-system-x86_64プロセスが永久にハングします。

いつまでもハングアップしないようにするにはどうすればよいですか? QemuホストでQemuゲストのカーネルパニックを検出するにはどうすればよいですか?

さらなる解明:

私のアプリケーションの性質はセキュリティに敏感です。つまり、Linuxカーネルの構成/コンパイルは「許可」されていますが、カーネルパラメータの受け渡しは許可されていません。細かい点を述べるために、 CMDLINE_OVERRIDE が有効になっています。

6
rubicks

私は働いているものを持っています:

  • CONFIG_PVPANIC=yを使用してカーネルを構成(およびビルド)します。これにより、pvpanicデバイスのサポートがコンパイルされたカーネルが生成されます。
  • qemu-system-x86_64-device pvpanicオプションで呼び出します。これは、カーネルパニックをキャッチ(および終了)するようにQemuに指示します。

カーネルパニックによりqemu-system-x86_64は正常に終了します(ステータス0を返します)が、少なくともハングしていません。

私を正しい方向に向けてくれた@ dsstorefile1に感謝します。

参照:

3
rubicks

QEMU -no-reboot +カーネルCLI kernel.panic=-1

また、pvpanicと同様に0を返しますが、次の利点があります。

  • 何も再コンパイルする必要はなく、ブートパラメータのみ
  • armおよびaarch64 -M virtとx86で動作しますが、pvpanicはArch/x86の下にあるため、x86固有のようです

this setup でテストされています。

GDBpanicシンボルを追跡します

これに対処する別の方法は、panic関数のアドレスに到達したことを検出し、QEMUを終了することです。

https://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-で説明されているように、panicでGDBを確実に破壊できます。 qemu/33203642#33203642

しかし、TODO:QEMUをステータス1で終了させる方法は? quitをGDBからQEMUモニターに転送するGDB内からmonitor quitを使用すると、本当に近づきますが、ステータス0で終了しないので、完全には近づきません。

gem5 は、デフォルトでこの追跡をネイティブに実行します。

これは次の場所で発生します https://github.com/gem5/gem5/blob/1da285dfcc31b904afc27e440544d006aae25b38/src/Arch/arm/linux/system.cc#L7

たぶんQEMU開発者はこのテクニックからインスピレーションを得て、似たようなものを実装できます。