Saber quando um desligamento do qemu vm (iniciado via telnet usando QMP) é concluído

Saber quando um desligamento do qemu vm (iniciado via telnet usando QMP) é concluído

Quando inicio uma máquina virtual qemu (Windows Server 2003) com

-qmp tcp:127.0.0.1:4444,server,nowait

Posso desligá-lo com o seguinte script

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

JSON

Mas existem dois problemas:

  1. o script sai com $? = 1 e diz "Conexão fechada por host estrangeiro". Posso sair de forma limpa?

  2. O processo de desligamento acontece de forma assíncrona. Assim, o script retorna de uma vez, sem esperar que a VM termine o desligamento. Como posso saber quando está pronto (sem usar o grep ps para qemu ou algo assim)?

O pano de fundo é que desejo hospedar uma instalação do Windows Server 2003 dentro de uma VM em um host Linux e quero usar um UPS. No caso de um blecaute, quero desligar a VM e depois o host – e, claro, o host não deve iniciar o desligamento até que a VM seja concluída.

Responder1

É possível usar expect. Um evento chamado "SHUTDOWN" será emitido quando a VM terminar. Portanto, o script a seguir inicia o desligamento e aguarda sua conclusão:

#!/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 já recebi votos negativos para minha pergunta e especialmente considerando a seguinte afirmação

Se você estiver fazendo coisas como as acima, então todo o resto provavelmente será uma bagunça completa que mal funciona e irá quebrar se você olhar da maneira errada.

Eu tenho que dizer outra coisa. Eu realmente não vejo por que fazer algo assim é "provavelmente uma bagunça completa", especialmente a própria VM. Ao iniciá-lo via libvirt, a mesma coisa é feita em comparação com um script shell fazendo o trabalho. Por que deveria “mal funcionar”?! Além disso, o QMP foi projetado e disponibilizado através de algo como telnet para tornar possível fazer "algo assim" dessa forma, não é?

E o libvirt não é nada além de um wrapper para as interfaces de várias soluções de virtualização para que se possa lidar com múltiplas instalações de VM executadas por diferentes hipervisores da mesma maneira? Então, por que devo usá-lo quando executo apenas uma VM em um hipervisor?

Provavelmente estou completamente errado aqui, mas pelo menos é assim que se pode desligar uma máquina virtual qemu usando um script (bash) e saber quando isso é feito de maneira decente, sem ter que usar o libvirt.

Responder2

Me deparei com isso tentando desligar uma VM sem libvirtd. Quanto ao motivo, o libvirtd não foi iniciado devido a uma falha no dispositivo de troca. Eu queria desligar as VMs de maneira limpa e não pude usar o libvirt para salvar no disco. Com o acima eu descobri

em /var/lib/libvirt/qemu

para meia em $(find | grep monitor); faça printf "{ 'executar': 'qmp_capabilities' }\n{ 'executar': 'system_powerdown' }\n" | socat - UNIX-CONNECT:$sock; feito

Isto é para o UBUNTU. Então, no geral, sim, eu normalmente usaria o libvirt, mas sabia que era uma interface para algum outro comando ser desligado. Saber o que o libvirt estava realmente fazendo me permitiu desligar as VMs de maneira limpa.

informação relacionada