#!/bin/sh

# the following is the LSB init header see
# http://www.linux-foundation.org/spec//booksets/LSB-Core-generic/LSB-Core-generic.html#INITSCRCOMCONV
#
### BEGIN INIT INFO
# Provides:          libvirtdomains
# Required-Start:    $local_fs $remote_fs $network libvirtd
# Required-Stop:     $local_fs $remote_fs $network libvirtd
# Should-Start:      $null
# Should-Stop:       $null
# Default-Start:     3 5
# Default-Stop:      0 1 2 4 6
# Short-Description: daemon for libvirt virtualization API
# Description:       This is a daemon for managing QEMU guest instances
#                    and libvirt virtual networks
#                    See http://libvirt.org
### END INIT INFO


. /etc/rc.status
rc_reset

# read configuration
[ -f /etc/sysconfig/libvirtdomains ] && . /etc/sysconfig/libvirtdomains

# check kvm save directory
if [ ! -d $LIBVIRTDOMAINS_SAVE_DIR ]; then
	echo "directory $LIBVIRTDOMAINS_SAVE_DIR does not exists!"
	exit 1
fi

# =========================================================================
# check for running libvirtd
libvirtd_check() {
	rclibvirtd status > /dev/null || {
		echo -en "\n\t... libvirtd not running"
		rc_failed 3
		rc_status -v
		rc_exit
	}
}

# =========================================================================
# check if libvirtd is up and running
# (races on bootup)
libvirtd_running() {
	virsh version > /dev/null 2>&1
	RES=$?
	if [ $RES != 0 ]; then
		# race?
		echo -en "\n\twaiting for libvirtd to start "
		COUNTER="10"
		while [ $RES != 0 ] && [ $COUNTER -gt 0 ]; do
			echo -e "."
			COUNTER=$[$COUNTER-1]
			sleep 1s
			virsh version > /dev/null 2>&1
			RES=$?
		done
	fi
}

# =========================================================================
# number of running domains
libvirtd_domains() {
	DOM_COUNT=`virsh list | grep running | wc -l`
}

# =========================================================================
# try to gracefully shutdown all domains
domains_shutdown() {
	# number of running domains
	libvirtd_domains # DOM_COUNT

	# try to gracefully shutdown all domains
	if [ "$LIBVIRTDOMAINS_SHUTDOWN" = "yes" ] \
	    && [ "x$DOM_COUNT" != "x0" ]; then

		echo ""
		echo "shutdown of remaining domains ..."
		for VM in `virsh list | grep running | awk '{ print $1 }'`; do
			NAME="`virsh list | grep " ${VM} " | awk '{ print $2 }'`"
			echo -e "\tShutdown domain: ${NAME}"
			virsh shutdown $VM >/dev/null
			sleep 1s
		done

		if [ -n $LIBVIRTDOMAINS_SHUTDOWN_MAXWAIT ] ; then
			COUNTER="${LIBVIRTDOMAINS_SHUTDOWN_MAXWAIT}"
		else
			# default value
			COUNTER=100
		fi

		DOT=0
		libvirtd_domains # DOM_COUNT
		while [ $DOM_COUNT -gt 0 ] && [ $COUNTER -gt 0 ] ; do
			libvirtd_domains # DOM_COUNT
			sleep 1
			COUNTER=$[$COUNTER-1]
			DOT=$[$DOT-1]
			if [ $DOT -le 0 ] ; then
				echo -n "."
				DOT=3
			fi
		done

		libvirtd_domains # DOM_COUNT
		if [ "x$DOM_COUNT" != "x0" ] ; then
			echo -en "\n\tsome domains are still running - stopping nevertheless"
		fi

		echo ""
		echo -en "\t... finished"
	fi
}

# =========================================================================
# restore domains
domains_restore() {
	FILES_COUNT=`ls ${LIBVIRTDOMAINS_SAVE_DIR} | grep "\.libvirt$" | wc -l`
	if [ "x$FILES_COUNT" == "x0" ]; then
		# nothing to restore
		return
	fi

	echo ""
	echo "restoring domains ..."
	FILES=`ls ${LIBVIRTDOMAINS_SAVE_DIR} | grep "\.libvirt$"`
	# restore kvm domains
	for FILE in $FILES; do
		rc_reset
		echo -en "\tRestore domain from: $FILE"
		virsh restore ${LIBVIRTDOMAINS_SAVE_DIR}/${FILE} >/dev/null 2>&1
		RES=$?
		if [ $RES = 0 ]; then
			# success
			rm ${LIBVIRTDOMAINS_SAVE_DIR}/${FILE}
			rc_failed 0
		else
			# failure
			rc_failed 1
		fi
		rc_status -v
	done
	echo -en "\t... finished"
}

# =========================================================================
# save (selected) domains
domains_save() {
	echo ""
	echo "saving domains ..."

	for VM in `virsh list | grep running | awk '{ print $1 }'`; do
		NAME="`virsh list | grep " ${VM} " | awk '{ print $2 }'`"
		SAVE=`echo " ${LIBVIRTDOMAINS_SAVE_VM} " | grep " ${NAME} " | wc -l`
		if [ $SAVE != 0 ]; then
			echo -en "\tSave domain: ${NAME}"
			FILE="${LIBVIRTDOMAINS_SAVE_DIR}/${NAME}.libvirt"
			virsh save $VM $FILE >/dev/null 2>&1
			RES=$?
			if [ $RES = 0 ]; then
				# success
				rc_failed 0
			else
				# failure
				rc_failed 1
			fi
			rc_status -v
		fi
	done
	echo -en "\t... finished"
}

case "$1" in
    start)
        echo -n "Starting libvirtdomains "

	# check if libvirtd is running (check 1)
	libvirtd_check

	# check if libvirtd is running (check 2)
	libvirtd_running

	if [ $LIBVIRTDOMAINS_SAVE = "yes" ]; then
		# restore domains
		domains_restore
		rc_failed 0
	else
		# save / restore switched off
		rc_failed 5
	fi

	rc_status -v
        ;;
    stop)
        echo -n "Shutting down libvirtdomains "

	# check if libvirtd is running
	libvirtd_check

	if [ $LIBVIRTDOMAINS_SAVE = "yes" ] ; then
		# save domains
		domains_save
		rc_failed 0
	else
		# save / restore switched off
		rc_failed 5
	fi

	# shutdown all remaining domains
	domains_shutdown

	rc_status -v
        ;;
    *)
        echo "Usage: $0 {start|stop}"
	rc_failed 2
	rc_exit
        ;;
esac
rc_exit
