Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

When I start a qemu (Windows Server 2003) virtual machine with

-qmp tcp:127.0.0.1:4444,server,nowait

I can make it shutdown with the following script

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

JSON

But there are two problems:

  1. the script exits with $? = 1 and says "Connection closed by foreign host". Can I make it exit in a clean way?

  2. The shutdown process happens asynchronously. So, the script returns at once, not waiting for the vm to finish the shutdown. How do I know when it's done (without grepping ps for qemu or something like this)?

The background is I want to host a Windows Server 2003 installation inside a VM on a linux host and I want to use an UPS. In case of a blackout, I want to shutdown the VM and then the host – and of course, the host should start the shutdown not until the VM is done.

share|improve this question
2  
Why aren't you running your VMs with libvirt? It takes care of this for you. –  Michael Hampton Dec 27 '13 at 9:44
    
I want to keep the overhead as small as possible. Libvirt is an abstraction layer that I actually don't need – starting the VM via shell script is just fine. It's just this one case (that hopefully never will happen) where this would be a benefit, so I'm looking for a solution without it. –  Tobias Leupold Dec 27 '13 at 9:49
2  
I think you're making the overhead TOO small. libvirt is pretty lightweight already, and not to mention it makes doing everything else with your VMs much easier. –  Michael Hampton Dec 27 '13 at 9:50
    
Well, everthing else works just fine ;-) –  Tobias Leupold Dec 27 '13 at 9:51
2  
If you're doing stuff like the above, then everything else is probably a complete mess that only barely works, and will break if you look at it the wrong way. You really should be using libvirt. –  Michael Hampton Dec 27 '13 at 9:52

1 Answer 1

up vote 1 down vote accepted

It is possible using expect. An event called "SHUTDOWN" will be emitted when the vm is finished. So, the following script starts the shutdown and waits for it to 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"

As I got already downvotes for my question and especially considering the following statement

If you're doing stuff like the above, then everything else is probably a complete mess that only barely works, and will break if you look at it the wrong way.

I have to say another thing. I really don't see why doing something like this is "probably a complete mess", especially the vm itself. When launching it via libvirt, the very same thing is done compared to a shell script doing the job. Why should it "barely work"?! Additionally, QMP has been designed and made available through something like telnet to make it possible to do "something like this" in this way, isn't it?

And isn't libvirt nothing but a wrapper to the interfaces of several virtualization solutions so one can handle multiple vm installations run by different hypervisors in the same manner? So why should I use it when I only run one vm in one hypervisor?

Probably I'm completely wrong here, but at least, this is how one can shutdown a qemu virtual machine using a (bash) script and know when it's done in a decent way without having to use libvirt.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.