[Pkg-libvirt-maintainers] Bug#508604: Acknowledgement (Mechanism to automatically save and restore the state of virtual machines on host shutdown/start-up)

Tuomas Jormola tj at solitudo.net
Sat Dec 13 14:23:31 UTC 2008


Hi,

I tuned my script to be more intelligent. It now detects save/restore
conflict with Xen. Domain state file name is configurable. More robust
save and restore. Option to start QEMU/KVM virtual machines if no
restore file for the domain can be located, thus emulating libvirt
autostart feature, which must be switched off at libvirt level.

-- 
Tuomas Jormola <tj at solitudo.net>
-------------- next part --------------
#!/bin/sh
#
# This script automatically saves running VMs
# managed by libvirtd on stop and restores VMs on start
#
# (C) 2008 Tuomas Jormola <tj at solitudo.net>
#
### BEGIN INIT INFO
# Required-Start:    $network $local_fs
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: save and restore libvirtd managed VMs
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
domain_state_file_name_pattern=%n
enabled=false

. /lib/lsb/init-functions

if test -f /etc/default/libvirt-domain-state; then
	. /etc/default/libvirt-domain-state
fi

test "$enabled" = "true" || exit 0

xen_enabled=0
if test -f /etc/default/xendomains; then
	. /etc/default/xendomains
	if test -n "$XENDOMAINS_MIGRATE" || test "$XENDOMAINS_SAVE" = "true"; then
		xen_enabled=1
	fi
fi
if test $xen_enabled -eq 1; then
	log_warning_msg "Automatic domain state save and restore implemented by Xen"
	exit 1
fi
if test -z "$domain_state_file_directory"; then
	log_failure_msg "Domain save directory not defined"
	exit 1
fi
if ! test -d "$domain_state_file_directory"; then
	log_failure_msg "Domain save directory not found: $domain_state_file_directory"
	exit 1
fi
if test -z "$domain_state_file_name_pattern"; then
	log_failure_msg "Domain state file name pattern not defined"
	exit 1
fi
if echo $domain_state_file_name_pattern | grep -q '/'; then
	log_failure_msg "Domain state file name pattern must not contain slashes"
	exit 1
fi
if ! echo $domain_state_file_name_pattern | grep -q '%n'; then
	log_failure_msg "Domain state file name pattern must contain %n"
	exit 1
fi
if test -z "$libvirt_hypervisor_uri"; then
	log_failure_msg "libvirt hypervisor connection URI not defined"
	exit 1
fi
if test "$libvirt_hypervisor_uri" != "`virsh -q -c $libvirt_hypervisor_uri uri 2>/dev/null`"; then
	log_failure_msg "Failed to connect to libvirt hypervisor $libvirt_hypervisor_uri"
	exit 1
fi

run_virsh() {
	virsh -q -c $libvirt_hypervisor_uri $*
}

# Print full path to domain state file for the domain.
expand_domain_state_file() {
	test -n "$domain_name" || return
	domain_state_file_name=`echo $domain_state_file_name_pattern | sed "s/%n/$domain_name/g" 2>/dev/null`
	test -n "$domain_state_file_name" || return
	echo $domain_state_file_directory/$domain_state_file_name
}

check_domain_autostart() {
	virsh_output=`run_virsh dominfo $1 2>/dev/null`
	ret=$?
	if test $ret != 0; then
		return 2
	fi
	echo $virsh_output | grep -q 'Autostart: disable' 2>/dev/null
}

# Restore a domain from state file if the domain is shut down
# or start QEMU/KVM domain if enabled.
restore_domain() {
	case "$domain_status" in
		"shut off")
			domain_state_file=`expand_domain_state_file`
			if test -f $domain_state_file; then
				if run_virsh restore $domain_state_file >/dev/null 2>&1; then
					if test "$delete_restored_domain_state_files" = "true"; then
						rm -f $domain_state_file
					fi
					log_action_msg "$domain_name restored"
				else
					log_failure_msg "Failed to restore $domain_name from $domain_state_file"
				fi
			elif test "$start_qemu_domains_without_state_file" = "true" && test -f /etc/libvirt/qemu/$domain_name.xml; then
				if run_virsh start $domain_name >/dev/null 2>&1; then
					log_action_msg "$domain_name started (QEMU/KVM domain with no restore file)"
				else
					log_failure_msg "Failed to start QEMU/KVM domain $domain_name"
				fi
			else
				log_warning_msg "Restore file not found for $domain_name"
			fi
			;;
		"running") log_warning_msg "$domain_name already running"; return ;;
		*)         log_warning_msg "Unknown status for domain $domain_name: $domain_status"; return ;;
	esac
}

# Save a domain to state file if domain is running and if libvirt
# is not starting the domain
save_domain() {
	if test "$domain_status" != "running"; then
		log_warning_msg "$domain_name is not running"
		return
	fi
	check_domain_autostart $domain_name
	ret=$?
	case "$ret" in
		0) true ;;
		1) log_warning_msg "libvirtd autostart enabled for $domain_name"; return ;;
		2) log_failure_msg "Failed to get autostart status for $domain_name"; return ;;
		*) log_failure_msg "Unknown return code when checking autostart status for $domain_name"; return ;;
	esac
	domain_state_file=`expand_domain_state_file`
	if run_virsh save $domain_id $domain_state_file >/dev/null 2>&1; then
		log_action_msg "$domain_name saved"
	else
		log_failure_msg "Failed to save $domain_name as $domain_state_file"
	fi
}

print_domain_status() {
	log_action_msg "$domain_name: $domain_status"
}

# Generate list of all domains on the hypervisor and launch
# the callback function for each domain.
iterate_domains() {
	callback=$1
	run_virsh list --all 2>/dev/null | grep -v ^Connecting | \
	while read domain_id domain_name domain_status; do
		eval "$callback"
	done
}

case "$1" in
	start)
		log_action_begin_msg "Restoring virtual machines"
		iterate_domains restore_domain
		log_action_end_msg 0
		;;
	  stop)
		log_action_begin_msg "Saving virtual machines"
		iterate_domains save_domain
		log_action_end_msg 0
		;;
	  status)
		log_action_begin_msg "Checking status of virtual machines"
		iterate_domains print_domain_status
		log_action_end_msg 0
		;;
	  *)
		N=/etc/init.d/libvirt-domain-state
		echo "Usage: $N {start|stop|status}" >&2
		exit 1
		;;
esac

exit 0
-------------- next part --------------
# Provide support for storing virtual machine state on hypervisor host shutdown
# and restore on hypervisor host start-up. In order to support this, please
# note that you must configure each virtual machine so that the libvirt
# autostart feature is disabled. Also if you're using Xen, the built-in
# save/restore mechanism must be disabled.

# Directory where to save virtual machine state files. This directory
# needs to be created manually. Be sure that there's enough free disk
# space available! You will need at least the combied amount of physical
# memory and swap space allocated to all virtual machines plus some room
# for overhead. For instance, if you are running two virtual machines
# each configured to use 1GB of memory and 2GB of swap, you should
# reserve more than 6GB of space in the file system holding this
# directory. This setting is required.
#domain_state_file_directory=/var/lib/libvirt/domain-state-files

# File name pattern for state files where the virtual machine's state is saved.
# The pattern must contain string "%n" which is replaced with the name of each
# virtual machine. Default file name consists of just the virtual machine name,
# i.e. the pattern is "%n".
#domain_state_file_name_pattern=%n.state

# libvirt URI of the hypervisor.
# See http://libvirt.org/remote.html#Remote_URI_reference
# This setting is required.
#libvirt_hypervisor_uri=qemu:///system

# Uncommenting this setting will destroy each virtual machine state file
# after successful restore. Disabled by default, i.e. restore is performed
# but state files are left intact.
#delete_restored_domain_state_files=true

# If this setting is enabled, during the hypervisor host machine start-up the
# script will start each QEMU/KVM virtual machine that is found on the system
# for which no state file can be found. Effectively this emulates the libvirt
# auto-start feature, but in more smart manner. If state file is found, the
# virtual machine will be restored, and if not, new instance of the virtual
# machine is started. The net effect is that all QEMU/KVM machines will
# automatically be running when the hypervisor has finished booting.
#start_qemu_domains_without_state_file=true

# Uncomment this to actually enable automatic saving and restoring
# of the virtual machines.
#enabled=true


More information about the Pkg-libvirt-maintainers mailing list