# qemu: Herunterfahren per Script/telnet

## l3u

Hallo :-)

Wenn ich eine virtuelle qemu-Maschine mit

```
-qmp tcp:127.0.0.1:4444,server,nowait
```

starte, dann kann ich sie mit

```
telnet 127.0.0.1 4444 <<JSON

{ "execute": "qmp_capabilities" }

{ "execute": "system_powerdown" }

JSON
```

(also per Script) herunterfahren. Allerdings funktioniert die Kommunikation asynchron, also wird der Befehl sofort beendet, und nicht erst, wenn die Maschine heruntergefahren ist. Abgesehen davon sagt telnet auch „Connection closed by foreign host.“ und $? ist nicht 0.

Jetzt hierzu zwei Fragen:

1. Kann ich den telnet-Aufruf so gestalten, dass das Script „normal“ beendet wird, also $? hinterher 0 ist?

2. Wie finde ich heraus, wann die virtuelle Maschine fertig heruntergefahren ist? Bzw. kann ich das evtl. in den telnet-Aufruf packen, dass der Befehl eben nicht asynchron ausgeführt werden soll, so dass das Script erst dann zurückkommt, wenn die Maschine auch heruntergefahren ist?

Der Hintergrund ist, dass ein Server mit einer unterbrechungsfreien Stromversorgung im Ausfall-Fall erstmal die virtuelle Maschine herunterfahren soll, die er hostet und dann sich selbst – was natürlich sinnvollerweise erst dann angestoßen werden sollte, wenn die VM vollständig heruntergefahren ist.

Vielen Dank für die Antworten schonmal :-)

----------

## l3u

Es geht mit expect:

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

----------

## m_neutron

danke, der Thread hat mir sehr geholfen mit dem QMP-Interface 

warm zu werden  :Wink: 

benutze jetzt dieses stop script mit netcat und fuser [timeout]:

```

#!/bin/sh

#do a local telnet job to stop some vm

GUEST=vm.qcow2

IMAGE=/home/vms/win10ding

LOGGFILE=${IMAGE}/${GUEST}_kvm_start.log

CTRPORT=4444

ENCE="nc -i 1 -q 1 -t"

echo "sending powerdown signal to $GUEST..."

echo "`date`: sending powerdown signal to GUEST..." >> $LOGGFILE

#echo -e "\nsystem_powerdown\n" | $ENCE 127.0.0.1 $CTRPORT 

echo -e "{ \"execute\": \"qmp_capabilities\" } \n { \"execute\": \"system_powerdown\" }" | $ENCE 127.0.0.1 $CTRPORT

echo "waiting for $GUEST at $IMAGE to shutdown..."

echo "`date`: waiting for $GUEST to shutdown..." >> $LOGGFILE

for (( c=1; c<=300; c++ ))

do

   if  timeout 2 fuser -s $IMAGE/$GUEST

   then

   sleep 2

   echo -n "."

   echo -n ".">> $LOGGFILE

   else

   echo done

   echo -e "`date`:shutdown comleted\n\n" >> $LOGGFILE

   exit 0

   fi

done

echo "timeout: check $GUEST VM" >> $LOGGFILE

exit 1

```

----------

## l3u

Danke für die Blumen ;-) Mit expect spart man sich die Warteschleife … und ich denke mal, dass das auch genau für so einen Fall gedacht ist. Aber geht natürlich auch so.

----------

## toralf

/me hätte schwören können, daß es für Telnet eigentlich keine Anwendungsfälle mehr gibt - außer mal schnell 'nen lokalen Port testen - aber man lernt nie aus.

----------

## l3u

Braucht man schon immer mal wieder ;-)

----------

