Saber cuándo finaliza el apagado de qemu vm (iniciado a través de telnet usando QMP)

Saber cuándo finaliza el apagado de qemu vm (iniciado a través de telnet usando QMP)

Cuando inicio una máquina virtual qemu (Windows Server 2003) con

-qmp tcp:127.0.0.1:4444,server,nowait

Puedo apagarlo con el siguiente script

#!/bin/bash
telnet 127.0.0.1 4444 <<JSON 
{ "execute": "qmp_capabilities" } 
{ "execute": "system_powerdown" } 

JSON

Pero hay dos problemas:

  1. el script sale con $? = 1 y dice "Conexión cerrada por un host externo". ¿Puedo hacer que salga de forma limpia?

  2. El proceso de apagado ocurre de forma asincrónica. Entonces, el script regresa de inmediato, sin esperar a que la máquina virtual finalice el apagado. ¿Cómo puedo saber cuándo está hecho (sin buscar ps para qemu o algo como esto)?

El trasfondo es que quiero alojar una instalación de Windows Server 2003 dentro de una máquina virtual en un host Linux y quiero usar un UPS. En caso de un apagón, quiero apagar la VM y luego el host y, por supuesto, el host no debe iniciar el apagado hasta que la VM haya terminado.

Respuesta1

Es posible usar expect. Se emitirá un evento llamado "SHUTDOWN" cuando finalice la máquina virtual. Entonces, el siguiente script inicia el apagado y espera a que se complete:

#!/usr/bin/expect

set timeout -1

spawn telnet 127.0.0.1 4444

expect "QMP"
send "{ 'execute': 'qmp_capabilities' }\n"

expect "return"
send "{ 'execute': 'system_powerdown' }\n"

expect "SHUTDOWN"

Como ya obtuve votos negativos por mi pregunta y especialmente considerando la siguiente declaración

Si estás haciendo cosas como las anteriores, entonces todo lo demás probablemente sea un completo desastre que apenas funciona y se romperá si lo miras de manera incorrecta.

Tengo que decir otra cosa. Realmente no veo por qué hacer algo como esto es "probablemente un completo desastre", especialmente la máquina virtual en sí. Al iniciarlo a través de libvirt, se hace exactamente lo mismo en comparación con un script de shell que hace el trabajo. ¿Por qué debería "apenas funcionar"? Además, QMP ha sido diseñado y puesto a disposición a través de algo como telnet para que sea posible hacer "algo como esto" de esta manera, ¿no es así?

¿Y no es libvirt nada más que un contenedor para las interfaces de varias soluciones de virtualización para que uno pueda manejar múltiples instalaciones de máquinas virtuales ejecutadas por diferentes hipervisores de la misma manera? Entonces, ¿por qué debería usarlo cuando solo ejecuto una máquina virtual en un hipervisor?

Probablemente esté completamente equivocado aquí, pero al menos así es como se puede apagar una máquina virtual qemu usando un script (bash) y saber cuándo se hace de manera decente sin tener que usar libvirt.

Respuesta2

Encontré esto buscando apagar una VM sin libvirtd. En cuanto a por qué, libvirtd no se inicia debido a un dispositivo de intercambio fallido. Quería cerrar limpiamente las máquinas virtuales y no podía usar libvirt para guardar en el disco. Con lo anterior se me ocurrió

en /var/lib/libvirt/qemu

para calcetín en $(buscar | grep monitor); hacer printf "{ 'ejecutar': 'qmp_capabilities' }\n{ 'ejecutar': 'system_powerdown' }\n" | socat - CONEXIÓN UNIX:$calcetín; hecho

Esto es para UBUNTU. Entonces, en general, sí, normalmente usaría libvirt, pero sabía que era una interfaz para algún otro comando para cerrar. Saber lo que realmente estaba haciendo libvirt me permitió cerrar limpiamente las máquinas virtuales.

información relacionada