Wissen, wann ein QEMU-VM-Shutdown (eingeleitet über Telnet mit QMP) abgeschlossen ist

Wissen, wann ein QEMU-VM-Shutdown (eingeleitet über Telnet mit QMP) abgeschlossen ist

Wenn ich eine virtuelle QEMU-Maschine (Windows Server 2003) starte mit

-qmp tcp:127.0.0.1:4444,server,nowait

Ich kann es mit dem folgenden Skript herunterfahren

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

JSON

Es gibt jedoch zwei Probleme:

  1. Das Skript wird mit $? = 1 beendet und meldet „Verbindung vom fremden Host geschlossen“. Kann ich es auf saubere Weise beenden?

  2. Der Herunterfahrvorgang erfolgt asynchron. Das Skript kehrt also sofort zurück und wartet nicht, bis die VM das Herunterfahren abgeschlossen hat. Woher weiß ich, wann es fertig ist (ohne in ps nach qemu oder etwas Ähnlichem zu suchen)?

Der Hintergrund ist, dass ich eine Windows Server 2003-Installation in einer VM auf einem Linux-Host hosten möchte und eine USV verwenden möchte. Im Falle eines Stromausfalls möchte ich zuerst die VM und dann den Host herunterfahren – und natürlich sollte der Host erst mit dem Herunterfahren beginnen, wenn die VM fertig ist.

Antwort1

Dies ist mit expect möglich. Ein Ereignis namens „SHUTDOWN“ wird ausgegeben, wenn die VM fertig ist. Das folgende Skript startet also das Herunterfahren und wartet, bis es abgeschlossen ist:

#!/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"

Da ich bereits Downvotes für meine Frage erhalten habe und insbesondere unter Berücksichtigung der folgenden Aussage

Wenn Sie Dinge wie die oben beschriebenen tun, ist alles andere wahrscheinlich ein einziges Durcheinander, das kaum funktioniert und bei falscher Betrachtungsweise kaputtgeht.

Ich muss noch etwas sagen. Ich verstehe wirklich nicht, warum so etwas „wahrscheinlich ein komplettes Chaos“ ist, insbesondere die VM selbst. Wenn man sie über libvirt startet, passiert genau das Gleiche, als wenn ein Shell-Skript die Aufgabe erledigt. Warum sollte es „kaum funktionieren“?! Außerdem wurde QMP so konzipiert und über etwas wie Telnet verfügbar gemacht, dass es möglich ist, „so etwas“ auf diese Weise zu tun, oder nicht?

Und ist libvirt nicht nichts anderes als ein Wrapper für die Schnittstellen mehrerer Virtualisierungslösungen, sodass mehrere VM-Installationen, die von verschiedenen Hypervisoren ausgeführt werden, auf die gleiche Weise verwaltet werden können? Warum sollte ich es also verwenden, wenn ich nur eine VM in einem Hypervisor ausführe?

Wahrscheinlich liege ich hier völlig falsch, aber so kann man zumindest eine virtuelle QEMU-Maschine mithilfe eines (Bash-)Skripts ordnungsgemäß herunterfahren und weiß, wann dies abgeschlossen ist, ohne libvirt verwenden zu müssen.

Antwort2

Ich bin darauf gestoßen, als ich eine VM ohne libvirtd herunterfahren wollte. Der Grund dafür war, dass libvirtd aufgrund eines ausgefallenen Swap-Geräts nicht gestartet werden konnte. Ich wollte die VMs sauber herunterfahren und konnte libvirt nicht zum Speichern auf der Festplatte verwenden. Mit dem oben genannten kam ich auf

in /var/lib/libvirt/qemu

für sock in $(find | grep monitor); mache printf "{ 'execute': 'qmp_capabilities' }\n{ 'execute': 'system_powerdown' }\n" | socat - UNIX-CONNECT:$sock; fertig

Dies ist für UBUNTU. Also, ja, ich würde normalerweise libvirt verwenden, aber ich wusste, dass es eine Schnittstelle zu einem anderen Befehl zum Herunterfahren war. Da ich wusste, was libvirt tatsächlich tat, konnte ich die VMs sauber herunterfahren.

verwandte Informationen