Estou tentando adicionar o Qemu ao meu pipeline de integração contínua para testar vários initrd
artefatos. Já descobri que posso rodar o Qemu assim:
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
...e causar qemu-system-x86_64
a saída com status 0
se eu fizer isso no meu init
script:
# poweroff -f
Isso funciona porque o script init não sai - ele invoca poweroff -f
e dorme "para sempre" ou até que o Qemu faça um "Power Down":
ACPI: Preparing to enter system sleep state S5
reboot: Power down
Gostaria de poder detectar problemas no init
script forçando um exit
erro on via set -eu
. Sair do init
script (corretamente) causa pânico no kernel, mas o qemu-system-x86_64
processo trava para sempre.
Como posso evitar que fique pendurado para sempre? Como faço para que o host Qemu detecte um kernel panic no convidado Qemu?
Maior esclarecimento:
A natureza do meu aplicativo é sensível à segurança; ou seja, configurar/compilar o kernel linux é "permitido", mas passar parâmetros do kernel não. Para colocar um ponto fino nisso, CMDLINE_OVERRIDE
está habilitado.
QEMU
-no-reboot
+ CLI do kernelkernel.panic=-1
qemu-system-X -no-reboot
Opção QEMU CLI: faz QEMU sair quando o convidado tenta reiniciarkernel.panic=-1
parâmetro de inicialização do kernel: faz com que o Linux tente reiniciar imediatamente após um pânico: https://github.com/torvalds/linux/blob/v4.17/Documentation/admin-guide/kernel-parameters.txt#L2931Ele também retorna
0
comopvpanic
, mas tem as seguintes vantagens:-M virt
, bem como no x86, enquanto o pvpanic parece específico do x86, pois está sobarch/x86
Testado com esta configuração .
Rastrear o
panic
símbolo com GDBOutra maneira de fazer isso pode ser detectar quando o endereço da
panic
função é alcançado e, em seguida, tentar encerrar o QEMU.Você pode definitivamente quebrar o GDB
panic
conforme explicado em: https://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642Mas então TODO: como fazer o QEMU sair com status 1? Usar
monitor quit
, de dentro do GDB, que encaminhaquit
para o monitor QEMU do GDB, chega muito perto, mas não exatamente, pois não sai com status0
.gem5 faz esse rastreamento por padrão nativamente, o que é incrível.
Isso acontece em: https://github.com/gem5/gem5/blob/1da285dfcc31b904afc27e440544d006aae25b38/src/arch/arm/linux/system.cc#L73
Talvez os desenvolvedores do QEMU possam se inspirar nessa técnica e implementar algo semelhante.
Eu tenho algo que está funcionando:
CONFIG_PVPANIC=y
; isso produz um kernel com suporte compilado para opvpanic
dispositivo.qemu-system-x86_64
com a-device pvpanic
opção; isso instrui o Qemu a capturar (e sair) um kernel panic.Um kernel panic faz
qemu-system-x86_64
com que saia com sucesso (return status0
), mas pelo menos não está mais travando.Muito obrigado a @dsstorefile1 por me indicar a direção certa.
Referências: