KVM - The Linux Kernel-Based Virtual Machine
News, Blogs and Resources on the Linux (KVM) Kernel-Based Virtual Machine

stop script running vms using virsh

10 replies [Last post]
joern
User offline. Last seen 37 weeks 4 days ago. Offline
Joined: Sep 14 2008
Points: 0

Hi there,

don't know if something like this is already out there (hint ?),

wrote my own little script :

#!/bin/sh
TIMEOUT=60

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

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

echo kvmshutdown \: Timeout happend. Destroying VM $1

virsh destroy $1

return 1

}

# Here is the start of the main "program" :-)

virsh list|grep running|tr -s \ |cut -f3 -d\  > /tmp/runvm.lst

while read vm
do
  echo  $vm is running
  kvmshutdown $vm
  if [ "$?" -eq "0" ]
  then
    echo VM $vm normally shutdown
  else
    echo VM $vm destroyed !
  fi
done < /tmp/runvm.lst

 If you can improve the script : do it :-)

greetings

     joern

Anonymous
SSH shutdown

Well, I guess I'm going to mix your script with a middle step: a shutdown through ssh.
ACPI isn't working right with Windows, and it wouldn't guarantee a close of all software running. The XEN aproach doesn't help when you REALLY WANT to shutdown all ou restart all, so Suspend or Save Snapshot is not the answer to me.

So, I collaborate here my ssh shutdown (just use Cygwin with openssh installed, and .ssh/authorized_keys):
ssh windows_server 'shutdown /m WIN2003TS /s /t 60 /d p:0:0 /c "[SDEV Manut - SDEV]"'

Then I would wait a min for the shutdown, try again with a /f to force closing of all apps, then wait another min and finally destroy it.

Anonymous
Thank you for the script

Thank you very much for the script. It didn't work for me the way I wanted, and hence modified it a bit.

The challenges were
1. "virsh shutdown" didn't work for me well. So, I used SSH instead, as also was mentioned by Anonymous above.
2. The while loop, reading /tmp/runvm.lst was not taking multiple virtual machines correctly - it used to only shutdown one machine and exit. I couldn't figure out the problem, so I replaced it with a for loop.
3. Enabled logging also.

The updated code is available at http://exain.wordpress.com/2009/05/22/auto-shutdown-kvm-virtual-machines...

Thank you
Vivek Kapoor
http://exain.com

Anonymous
stop script running vms using virsh

hi Joern i have extended ur script ... since under KVM Windows vm's do not accept acpi-power-switch.

So I had to make a start-stop-script that saves and restores the vm.

And we need one start-stop-script per vm. I only done some initial testing.

Would be great if u or someone else could test all cases in the script.

 

cheers saman.behnam@opensoft24.com

###############################################################

 #!/bin/sh
 
 
 # U need per VM a separate start-stop-script!
 VM_NAME="win0" # Name of ur guest VM
 VM_XML_FILE="/etc/libvirt/qemu/"$VM_NAME".xml" # XML config file of ur guest VM.
 TIMEOUT=300
 VM_SAVE_DIR="/kvm/tmp/vm_save_dir" # Directory for storing the guest VM save data..
 DEVNULL="/dev/null"
 #ACTION="shutdown"
 ACTION="save" # ACTION takes one argument, either "save" or "shutdown". In the "save" case it will save the VM and restore it while stopping or starting. In the "shtudown" case it will sutdown then VM and start it while stopping or starting.
 
 
 
 vmshutdown () {
         PID=$(ps ax|grep $VM_NAME|grep kvm|cut -c 1-6)
         ps --pid $PID > "$DEVNULL" 2>&1
         if [ "$?" -eq "1" ];  then
                 echo "VM "$VM_NAME" is not running!!! Exiting."
                 exit 1
         fi
         COUNT=0
         echo "kvmshutdown \: Shutting down "$VM_NAME" with pid $PID"
         virsh shutdown "$VM_NAME" && exit 0
         while [ "$COUNT" -lt "$TIMEOUT" ]; do
                 ps --pid $PID > "$DEVNULL" 2>&1
                 if [ "$?" -eq "1" ];  then
                         exit 0
                 fi
                 sleep 5
                 COUNT=$(($COUNT+5))
         done
         echo "kvmshutdown \: Timeout happend. Destroying VM "$VM_NAME""
         virsh destroy "$VM_NAME" && exit 1
 }
 
 vmstart () {
         PID=$(ps ax|grep $VM_NAME|grep kvm|cut -c 1-6)
         ps --pid $PID > "$DEVNULL" 2>&1
         if [ "$?" -eq "0" ];  then
                 echo "VM "$VM_NAME" is allready running!!! Exiting."
                 exit 1
         fi
         virsh start "$VM_XML_FILE" && exit 0
         exit 1
 }
 
 vmsave () {
         PID=$(ps ax|grep $VM_NAME|grep kvm|cut -c 1-6)
         ps --pid $PID > "$DEVNULL" 2>&1
         if [ "$?" -eq "1" ];  then
                 echo "VM "$VM_NAME" is not running!!! Exiting."
                 exit 1
         fi
         COUNT=0
         echo "vmsave \: Saving VM "$VM_NAME""
         if [ ! -d "$VM_SAVE_DIR" ]; then
                 echo "creating  "$VM_SAVE_DIR""
                 mkdir -p "$VM_SAVE_DIR"
         fi
         virsh save "$VM_NAME" "$VM_SAVE_DIR/$VM_NAME.kvm.save" && exit 0
         while [ "$COUNT" -lt "$TIMEOUT" ]; do
                 ps --pid $PID > "$DEVNULL" 2>&1
                 if [ "$?" -eq "1" ];  then
                         exit 0
                 fi
                 sleep 5
                 COUNT=$(($COUNT+5))
         done
         echo "vmsave \: Timeout happend. Destroying VM "$VM_NAME""
         virsh destroy "$VM_NAME"
         exit 1
 }
 
 vmrestore () {
         PID=$(ps ax|grep $VM_NAME|grep kvm|cut -c 1-6)
         ps --pid $PID > "$DEVNULL" 2>&1
         if [ "$?" -eq "0" ];  then
                 echo "VM "$VM_NAME" is allready running!!! Exiting."
                 exit 1
         fi
         if ! ls "$VM_SAVE_DIR"/"$VM_NAME".kvm.save > /dev/null 2>&1 ; then
                 echo "Restore file "$VM_NAME".kvm.save in "$VM_SAVE_DIR" not found! Starting VM!!!"
                 vmstart
                 exit 1
         fi
         cd "$VM_SAVE_DIR"
         echo "vmrestore \: Restoring VM "$VM_NAME""
         virsh restore "$VM_SAVE_DIR"/"$VM_NAME".kvm.save && rm -f "$VM_SAVE_DIR"/"$VM_NAME".kvm.save
         exit 0
 }
 
 
 # Here is the start of the main "program" :-)
 case "$1" in
         start)
                 case "$ACTION" in
                         save)
                                         vmrestore
                                         ;;
                         shutdown)
                                         vmstart
                                         ;;
                 esac
                 ;;
         stop)
                 case "$ACTION" in
                         save)
                                         vmsave
                                         ;;
                         shutdown)
                                         vmshutdown
                                         ;;
                 esac
                 ;;
 
         *)
                 N="$0"
                 echo "Usage: "$N" {start|stop}" >&2
                 exit 1
                 ;;
 esac
 exit 0

###############################################################

Anonymous
update: found some errors!

#!/bin/sh

# U need per VM a separate start-stop-script!
VM_NAME="lenny0" # Name of ur guest VM
TIMEOUT=300
VM_SAVE_DIR="/kvm/tmp/vm_save_dir" # Directory for storing the guest VM save data..
DEVNULL="/dev/null"
#ACTION="shutdown"
ACTION="save" # ACTION takes one argument, either "save" or "shutdown". In the "save" case it will save the VM and restore it while stopping or starting. In the "shtudown" case it will sutdown then VM and start it while stopping or starting.

vmshutdown () {
if ! virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is not running!!! Exiting."
exit 1
fi
PID=$(ps ax|grep $VM_NAME|grep kvm|cut -c 1-6)
COUNT=0
echo "kvmshutdown \: Shutting down "$VM_NAME" with pid $PID"
virsh shutdown "$VM_NAME" && exit 0
while [ "$COUNT" -lt "$TIMEOUT" ]; do
ps --pid $PID > "$DEVNULL" 2>&1
if [ "$?" -eq "1" ]; then
exit 0
fi
sleep 5
COUNT=$(($COUNT+5))
done
echo "kvmshutdown \: Timeout happend. Destroying VM "$VM_NAME""
virsh destroy "$VM_NAME" && exit 1
}

vmstart () {
if virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is allready running!!! Exiting."
exit 1
fi
virsh start "$VM_NAME" && exit 0
exit 1
}

vmsave () {
if ! virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is not running!!! Exiting."
exit 1
fi
PID=$(ps ax|grep $VM_NAME|grep kvm|cut -c 1-6)
COUNT=0
echo "vmsave \: Saving VM "$VM_NAME""
if [ ! -d "$VM_SAVE_DIR" ]; then
echo "creating "$VM_SAVE_DIR""
mkdir -p "$VM_SAVE_DIR"
fi
virsh save "$VM_NAME" "$VM_SAVE_DIR/$VM_NAME.kvm.save" && exit 0
while [ "$COUNT" -lt "$TIMEOUT" ]; do
ps --pid $PID > "$DEVNULL" 2>&1
if [ "$?" -eq "1" ]; then
exit 0
fi
sleep 5
COUNT=$(($COUNT+5))
done
echo "vmsave \: Timeout happend. Destroying VM "$VM_NAME""
virsh destroy "$VM_NAME"
exit 1
}

vmrestore () {
if virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is allready running!!! Exiting."
exit 1
fi
if ! ls "$VM_SAVE_DIR"/"$VM_NAME".kvm.save > /dev/null 2>&1 ; then
echo "Restore file "$VM_NAME".kvm.save in "$VM_SAVE_DIR" not found! Starting VM!!!"
vmstart
exit 1
fi
cd "$VM_SAVE_DIR"
echo "vmrestore \: Restoring VM "$VM_NAME""
virsh restore "$VM_SAVE_DIR"/"$VM_NAME".kvm.save && rm -f "$VM_SAVE_DIR"/"$VM_NAME".kvm.save
exit 0
}

# Here is the start of the main "program" :-)
case "$1" in
start)
case "$ACTION" in
save)
vmrestore
;;
shutdown)
vmstart
;;
esac
;;
stop)
case "$ACTION" in
save)
vmsave
;;
shutdown)
vmshutdown
;;
esac
;;

*)
N="$0"
echo "Usage: "$N" {start|stop}" >&2
exit 1
;;
esac
exit 0

Anonymous
stop script running vms using virsh

Hi Joern
Hi there

I've done agian some modification to ur script, as I had the time now to check and the script. The TIMEOUT condition that u handle in ur script would never happen because ur script will wait till the process of stopping / saving the VM finishes. Thus if a VM hangs it will wait endless. Another funny thing is if I hade a VI editor open editing a "VM. xml"file the scirpt will see two pids (PID=$(ps ax|grep $1|grep kvm|cut -c 1-6). Its better to relay on the "virsh" command when checking VM state. Thus I wrote yet another "stop script running vms using virsh" Please check also here!

########################################################

#!/bin/sh

### BEGIN INIT INFO
# Provides: kvm-win0-rcs
# Required-Start: $kvm $libvirtd
# Required-Stop: $kvm $libvirtd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starting/Saving, Stopping/Restoring kvm-win0-rcs KVM guest.
# Description: Starting/Saving, Stopping/Restoring KVM guest "win0".
# kvm-win0-rcs KVM guest.
### END INIT INFO#

# Please copy the init scripts of the KVM VM's in to "/etc/init.d" and then run! "for i in `cd /etc/init.d && ls kvm-*` ; do update-rc.d $i defaults 21 19 ; done"

# U need per VM a separate start-stop-script!
VM_NAME="win0" # Name of ur guest VM
TIMEOUT=300
VM_SAVE_DIR="/kvm/tmp/vm_save_dir" # Directory for storing the guest VM save data..
DEVNULL="/dev/null"
#ACTION="shutdown"
ACTION="save" # ACTION takes one argument, either "save" or "shutdown". In the "save" case it will save the VM and restore it while stopping or starting. In the "shtudown" case it will sutdown then VM and s
tart it while stopping or starting.

vmshutdown () {
if ! virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is not running!!! Exiting."
exit 1
fi
COUNT=0
echo "kvmshutdown \: Shutting down "$VM_NAME" with pid $PID"
virsh shutdown "$VM_NAME" &
while [ "$COUNT" -lt "$TIMEOUT" ]; do
if ! virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
exit 0
fi
sleep 5
COUNT=$(($COUNT+5))
done
echo "kvmshutdown \: Timeout happend. Destroying VM "$VM_NAME""
virsh destroy "$VM_NAME" && exit 1
}

vmstart () {
if virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is allready running!!! Exiting."
exit 1
fi
virsh start "$VM_NAME" && exit 0
exit 1
}

vmsave () {
if ! virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is not running!!! Exiting."
exit 1
fi
COUNT=0
echo "vmsave \: Saving VM "$VM_NAME""
if [ ! -d "$VM_SAVE_DIR" ]; then
echo "creating "$VM_SAVE_DIR""
mkdir -p "$VM_SAVE_DIR"
fi
virsh save "$VM_NAME" "$VM_SAVE_DIR/$VM_NAME.kvm.save" &
while [ "$COUNT" -lt "$TIMEOUT" ]; do
if ! virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
exit 0
fi
sleep 5
COUNT=$(($COUNT+5))
done
echo "vmsave \: Timeout happend. Destroying VM "$VM_NAME""
virsh destroy "$VM_NAME"
exit 1
}

vmrestore () {
if virsh list|grep running|grep -v grep|grep "$VM_NAME" > "$DEVNULL" 2>&1; then
echo "VM "$VM_NAME" is allready running!!! Exiting."
exit 1
fi
if ! ls "$VM_SAVE_DIR"/"$VM_NAME".kvm.save > /dev/null 2>&1 ; then
echo "Restore file "$VM_NAME".kvm.save in "$VM_SAVE_DIR" not found! Starting VM!!!"
vmstart
exit 1
fi
cd "$VM_SAVE_DIR"
echo "vmrestore \: Restoring VM "$VM_NAME""
virsh restore "$VM_SAVE_DIR"/"$VM_NAME".kvm.save && rm -f "$VM_SAVE_DIR"/"$VM_NAME".kvm.save
exit 0
}

# Here is the start of the main "program" :-)
case "$1" in
start)
case "$ACTION" in
save)
vmrestore
;;
shutdown)
vmstart
;;
esac
;;
stop)
case "$ACTION" in
save)
vmsave
;;
shutdown)
vmshutdown
;;
esac
;;

*)
N="$0"
echo "Usage: "$N" {start|stop}" >&2
exit 1
;;
esac
exit 0

########################################################

Please tell also if there is an official script for gracefully stopping / starting KVM VM's.

greets

saman

Anonymous
Non US-locales

I have added the line
unset LANG # Ensure english user interface for text tools

to ensure it also works for non english locales.

Jarl

Anonymous
Problems with samans proposal

Hi Samman.

I have tried your script, excelent work. However the script does not wait for libvirtd to start, it seems like the line # Required-Start: $kvm $libvirtd only ensures that kvm is started.

I have cleaned up the script to have identical indentation for the init script comments:


### BEGIN INIT INFO
# Provides: kvm-rcs-YOUR_VM_NAME
# Required-Start: $kvm $libvirtd
# Required-Stop: $kvm $libvirtd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starting/Saving, Stopping/Restoring kvm-rcs- KVM guest.
# Description: Starting/Saving, Stopping/Restoring KVM guest.
### END INIT INFO#

This seem to have helped.

I have also made some other improvements, but somehow I don't feel this is the right place for developing a script together... Please let me know if you are interested.

Jarl

Anonymous
Correction.

I should have used the pre tag in stead of code tag. Here it goes.

### BEGIN INIT INFO
# Provides:          kvm-rcs-YOUR_VM_NAME
# Required-Start:    $kvm $libvirtd
# Required-Stop:     $kvm $libvirtd
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starting/Saving, Stopping/Restoring kvm-rcs- KVM guest.
# Description:       Starting/Saving, Stopping/Restoring KVM guest.
### END INIT INFO#
Saman Behnam (not verified)
new version stop script running vms using virsh

hi Jarl
hi there,
sorry for beeing away for so long. now i've updated the rc kvm scripts.
changes that i have made were:
- the script is now fully virsh libvirt and only virsh cli statements are used for vm management. so it's easy to adopt them to xen for example ...
- every domain has its own script and all the domain-scripts are invoked from one script called "kvm-domains" (similar to xen :) )
- i have implemented it now under centos but it should work in general also under debian and derivatives.
- i will also post how to make a centos kvm host wait for the domains to shutdown before shutting down itself.
here is the "kvm-domains" script:
###########################################################################################################
#!/bin/sh

### BEGIN INIT INFO
# Provides:          kvm-domains
# Default-Start:     3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/Stop kvm domains!
# Description:       Start/Stop kvm domains!
# kvm-domains.
### END INIT INFO#

# the following is chkconfig init header for Redhat/Suse ...
#
# kvm-domains:   Start/Stop kvm domains!
# chkconfig: 345 99 01
# description: Start/Stop kvm domains!
#

START_WAIT=3 # Time to wait between starting of the domains
STOP_WAIT=2 # Time to wait between shutdown of the domains
DEVNULL="/dev/null"
LIBVIRT="/etc/init.d/libvirtd"
KVM_RCS_DIR="/etc/init.d" # Directory where the startup scripts of the domains are located.
TIMEOUT=600 # Time to wait untill the KVM kernel modules are loaded and the libvirt daemon ist started
# and if of them fails within this time then we cancel the startup of the KVM domains.

start_kvm_libvirtd () {
    COUNT=0
    KVMINITFAIL=0
        while [ "$COUNT" -lt "$TIMEOUT" ]; do
                if ! lsmod|grep ^kvm_|grep -v grep > "$DEVNULL" 2>&1 || ! pgrep ^libvirtd > "$DEVNULL" 2>&1 ; then
                if ! lsmod|grep ^kvm_|grep -v grep > "$DEVNULL" 2>&1 ; then
                            if [ $(grep -c vmx /proc/cpuinfo) -ne 0 ]; then
                                    modprobe kvm-intel > "$DEVNULL" 2>&1
                            fi
                            if [ $(grep -c svm /proc/cpuinfo) -ne 0 ]; then
                                    modprobe kvm-amd > "$DEVNULL" 2>&1
                            fi
                            modprobe ksm > "$DEVNULL" 2>&1 # This is CentOS specific I think!
                fi
                ! pgrep ^libvirtd$ > "$DEVNULL" 2>&1 && "$LIBVIRT" start > "$DEVNULL" 2>&1
        fi
            if lsmod|grep ^kvm_|grep -v grep > "$DEVNULL" 2>&1 && pgrep ^libvirtd > "$DEVNULL" 2>&1 ; then
                COUNT="$TIMEOUT"
                KVMINITFAIL=1
            fi
        sleep 5
                COUNT=$(($COUNT+5))
    done
        if [ "$KVMINITFAIL" -eq 0 ] ; then
        echo "!!!!!!!!!!  Timeout happend inititalizing KVM. Exiting  !!!!!!!!!" && exit 1
    fi
}

# Here comes the main program!

case "$1" in

    start)
        start_kvm_libvirtd
        COUNTER=0
                COUNT=2 # How many times should we try to bring up the KVM domains. I experienced a bug in libvritd,
        # and had to start saved domains twice to get them up!!!!! You can leave this at default!
        DOMCOUNTER=0
        while [ "$COUNTER" -lt "$COUNT" ] ; do
            cd "$KVM_RCS_DIR"
            for i in `ls kvm*rcs` ; do
                "$KVM_RCS_DIR"/"$i" start
                DOMCOUNTER=$(($DOMCOUNTER+1))
                sleep "$START_WAIT"
            done
            if [ `virsh list|grep running|wc -l` -eq $DOMCOUNTER ] ; then
            echo "All KVM domains started sucessfully" && exit 0
            fi
            COUNTER=$(($COUNTER+1))
        done
        echo "One or more KVM domains failed starting!!!" && exit 1
    ;;
    stop)
        start_kvm_libvirtd
        cd "$KVM_RCS_DIR"
        for i in `ls kvm*rcs` ; do
            "$KVM_RCS_DIR"/"$i" stop
            sleep "$STOP_WAIT"
        done
        while virsh list|grep running|grep -v grep ; do
            sleep 5
        done
        exit 0
    ;;
    status)
        virsh list
    ;;
    *)
            echo $"Usage: "$0" {start|stop|status}"
            exit 1
esac

exit 0
###########################################################################################################
Here is an example domain script
###########################################################################################################
#!/bin/sh

# Start/Stop script for KVM-QEMU domains. This scipt is invoked by the "kvm-domains" script!
VM_NAME="win0" # Name of your KVM domain. Check also the "virsh list" command.
TIMEOUT=300 # Time to wait while shutting down or saving! When gracefull shutdown or saving of the domain hangs we will kill the domain after 5 minutes.
VM_SAVE_DIR="/kvm/tmp/vm_save_dir" # Directory for storing the domain save data..
DEVNULL="/dev/null"
#ACTION="shutdown"
ACTION="save" # ACTION takes one argument, either "save" or "shutdown". In the "save" case it will save the domain when stopping and restore it when starting. In the "shtudown" case it will shutdown the domain when stopping and start it when starting.

vmshutdown () {
    if ! virsh dominfo $VM_NAME|grep State|grep "running"|grep -v grep > "$DEVNULL" 2>&1; then
        echo "VM "$VM_NAME" is not running!!! Exiting" && exit 1
    fi
    virsh shutdown "$VM_NAME" && echo "Shutting down "$VM_NAME"!"
    COUNT=0
    while [ "$COUNT" -lt "$TIMEOUT" ]; do
        if ! virsh dominfo $VM_NAME|grep State|grep "running"|grep -v grep > "$DEVNULL" 2>&1; then
            exit 0
        fi
        sleep 5
        COUNT=$(($COUNT+5))
    done
    echo "!!!!!!!!!!  Coult not shutdown. Timeout happend. Destroying VM "$VM_NAME"  !!!!!!!!!"
    echo "!!!!!!!!!!  Please check why we could not shutdown  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    virsh destroy "$VM_NAME" &
    exit 1
}

vmstart () {
    if virsh dominfo $VM_NAME|grep State|grep "running"|grep -v grep > "$DEVNULL" 2>&1; then
                echo "VM "$VM_NAME" is allready running!!! Exiting" && exit 1
        fi
    virsh start "$VM_NAME"&
    exit 0
}

vmsave () {
    if ! virsh dominfo $VM_NAME|grep State|grep "running"|grep -v grep > "$DEVNULL" 2>&1; then
                echo "VM "$VM_NAME" is not running!!! Exiting" && exit 1
        fi
    if [ ! -d "$VM_SAVE_DIR" ]; then
        echo "creating  "$VM_SAVE_DIR""
        mkdir -p "$VM_SAVE_DIR"
    fi

    virsh save "$VM_NAME" "$VM_SAVE_DIR/$VM_NAME.kvm.save" &
    echo "Saving VM "$VM_NAME""
    COUNT=0
    while [ "$COUNT" -lt "$TIMEOUT" ]; do
        if ! virsh dominfo $VM_NAME|grep State|grep "running"|grep -v grep > "$DEVNULL" 2>&1; then   
            echo "Last saved at `date`" > "$VM_SAVE_DIR"/"$VM_NAME".kvm.save.log
            exit 0
        fi
        sleep 5
        COUNT=$(($COUNT+5))
    done
    echo "!!!!!!!!!!  Coult not save. Timeout happend. Destroying VM "$VM_NAME"  !!!!!!!!!"
        echo "!!!!!!!!!!  Please check why we could not save  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    virsh destroy "$VM_NAME" &
    exit 1
}

vmrestore () {
    if virsh dominfo $VM_NAME|grep State|grep "running"|grep -v grep > "$DEVNULL" 2>&1; then
        echo "VM "$VM_NAME" is allready running!!! Exiting" && exit 1
        fi
    if ! ls "$VM_SAVE_DIR"/"$VM_NAME".kvm.save > "$DEVNULL" 2>&1 ; then
        echo "Restore file "$VM_NAME".kvm.save in "$VM_SAVE_DIR" not found! Starting VM!!!"
        vmstart &
        exit 1
    fi
    echo "Restoring VM "$VM_NAME"" && cd "$VM_SAVE_DIR"
    virsh restore "$VM_SAVE_DIR"/"$VM_NAME".kvm.save && \
    rm -f "$VM_SAVE_DIR"/"$VM_NAME".kvm.save && \
    echo "Last restored at `date`" > "$VM_SAVE_DIR"/"$VM_NAME".kvm.restore.log
    exit 0
}

# Here is the start of the main "program" :-)
case "$1" in
    start)
        case "$ACTION" in
            save)
                    vmrestore
                    ;;
            shutdown)
                    vmstart
                    ;;
        esac
        ;;
    stop)
        case "$ACTION" in
            save)
                    vmsave
                    ;;
            shutdown)
                    vmshutdown
                    ;;
        esac
        ;;
   
    *)
        N="$0"
        echo "Usage: "$N" {start|stop}" >&2
        exit 1
        ;;
esac
exit 0
###########################################################################################################
to make a centos kvm host wait for the domains to shutdown before shutting down itself, i had to edit my "/etc/inittab"
(under debian this was working without to edit "/etc/inittab")
so my centos inittab looks like this now  :
###########################################################################################################
#
# inittab       This file describes how the INIT process should set up
#               the system in a certain run-level.
#
# Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
#               Modified for RHS Linux by Marc Ewing and Donnie Barnes
#

# Default runlevel. The runlevels used by RHS are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:

# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit

17:0:wait:/etc/init.d/kvm-domains stop
l0:0:wait:/etc/rc.d/rc 0
18:1:wait:/etc/init.d/kvm-domains stop
l1:1:wait:/etc/rc.d/rc 1
19:6:wait:/etc/init.d/kvm-domains stop
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
20:6:wait:/etc/init.d/kvm-domains stop
l6:6:wait:/etc/rc.d/rc 6

# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now

# When our UPS tells us power has failed, assume we have a few minutes
# of power left.  Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"

# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"

# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6

# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon
###########################################################################################################
tip: when u invoke the virt-manager on a centos host via ssh and x-forwarding then use absolute paths :)
cheers
Saman
 

Saman (not verified)
new version stop script running vms using virsh

system is Centos 5.4

Post new comment

The content of this field is kept private and will not be shown publicly.