Auto shutdown KVM Virtual Machines on system shutdown

I have been  using KVM for virtualization for quite some time now, probably more than a year. Though the initial use was on the servers which were rarely shutdown, now I’ve started using it in my home envir0nment where frequent restarts or shutdowns are there. The challenge that I faced was to automatically shutdown the KVM virtual machines when the system was shutdown or restarted.

Thanks to Joern at linux-kvm.com, I was able to setup a script which does an auto shutdown of the Linux (basically any VM which has ssh available) machines. I am using it on Ubuntu 9.04 (Jaunty Jackalope) 64 Bit Desktop edition.

Steps

  1. Add the host file entries
  2. Make sure you are able to do ssh without entering any password from root into the VMs
  3. Put the script into the /etc/init.d directory.
  4. Test the script before rebooting the system
  5. Reboot the system to check if it worked

The Host File Entries

The VM should  have a static IP, and not through DHCP. The VM name should be added into the /etc/hosts file. If you have a VM named Crayon with IP Address 172.16.0.5, then add the entry in the host file like the following

172.16.0.5            Crayon

This is important as I’m doing it through ssh, so I need to ssh into the domain by its name.

Doing ssh into the VMs through root without password

This is out of the scope of this document. You can look at the “Passwordless ssh” post by Adam Monsen on linuxconfig.org

Just make sure, through the root login you are able to ssh into your VM without entering the password. Try it a few times.  You may need to set the root password through sudo passwd on your Ubuntu machine.

The Script

I have modified the script provided by Joern. I used ssh instead of “virsh shutdown domain” because “virsh shutdown” didn’t work at all for the Ubuntu 8.04 Server VM that I had, and for Ubuntu 9.04 Desktop VM it opened up the dialog where it asks what to do (Shutdown/Suspend/Restart etc.). It didn’t suit me well, thus I used the ssh method

Put the following script into /etc/init.d/shutdownvm

#!/bin/bash

# Original Author :
#    Joern http://www.linux-kvm.com/content/stop-script-running-vms-using-virsh
#
# Modified by : Vivek Kapoor http://exain.com
# Date: 22 May 2009

# Parameters you can modify :: START

TIMEOUT=90
LISTFILE=/root/runvm.lst
LOGFILE=/var/log/kvmshutdown.log
# Parameters you can modify :: STOP

PS=/bin/ps
SSH=/usr/bin/ssh
GREP=/bin/grep
CUT=/usr/bin/cut
VIRSH=/usr/bin/virsh
TR=/usr/bin/tr
CAT=/bin/cat
DATE=/bin/date

# Function to shutdown the virtual machine
kvmshutdown () {
COUNT=0
PID=$($PS ax|$GREP $1|$GREP kvm|$CUT -c 1-6)

echo kvmshutdown \: Shutting down $1 with pid $PID

#$VIRSH shutdown $1
$($SSH root@$1 halt)

while [ "$COUNT" -lt "$TIMEOUT" ]
do
 $PS --pid $PID
 if [ "$?" -eq "1" ]
 then
 return 0
 else
 sleep 5
 COUNT=$(($COUNT+5))
 fi
done

echo kvmshutdown \: Timeout happened. Destroying VM $1

$VIRSH destroy $1

return 1

}

# The program begins here

$VIRSH list 2>/dev/null|$GREP running|$TR -s \ |$CUT -f3 -d\  > $LISTFILE

VMN=`$CAT $LISTFILE`

for vm in $VMN
do
 echo "$vm" is running
 kvmshutdown "$vm"
 if [ "$?" -eq "0" ]
 then
 echo VM "$vm" normally shutdown
 echo `$DATE +%Y-%m-%d\ %H:%M:%S` VM $vm normally shutdown >> $LOGFILE
 else
 echo VM "$vm" destroyed !
 echo `$DATE +%Y-%m-%d\ %H:%M:%S` VM $vm destroyed >> $LOGFILE
 fi;
done

Now for some more activities so that it initializes on halt and reboot

  1. chmod 755 /etc/init.d/shutdownvm
  2. cd /etc/rc0.d
    ln -s ../init.d/shutdownvm K18shutdownvm
  3. cd /etc/rc6.d
    ln -s ../init.d/shutdownvm K18shutdownvm

I am using K18 as the kvm is having K20 value, and the above script should execute before kvm.

The beauty of the script by Joern is, it keeps on checking if the process has shutdown. So it will not wait for the complete Timeout value – in case the machine is shutdown earlier, it will proceed further. This I found to be great.

Testing the scripts

You may want to comment out “virsh destroy $1” in the script while you are testing it.

Using root, run the script /etc/init.d/shutdownvm

Keep on doing it as long as you don’t get the desired results. You probably would need to start your VMs a number of times to test it completely.

Reboot the system

Once you are satisfied that it is working as per your requirements, reboot the system. Prior to that you may want to uncomment the “virsh destroy $1” line in the script. While the system is rebooting, quickly try to shift to terminal 7 by pressing ALT+7. You should see the virtual machines being shutdown from there. If it doesn’t work successfully, you may need to do some more testing – probably the ssh connections are not getting established correctly as it is asking for password.

3 Responses to “Auto shutdown KVM Virtual Machines on system shutdown”

  1. joern Says:

    Try that one for the process id:

    PID=$(pgrep -f “(kvm|qemu).*name $1″)

    Greetings,

    joern

  2. Vivek Kapoor Says:

    Thank you. The script I’d copied from the link I’d mentioned in the post. However, the method by you is perhaps more elegant.

  3. Vivek Kapoor Says:

    Oh joern – I just checked. It was you who wrote the script :-) Thank you for that.

Leave a Reply