#!/bin/sh
### BEGIN INIT INFO
# Provides:          xen xend
# Required-Start:    $syslog $remote_fs xenstored
# Required-Stop:     $syslog $remote_fs xenstored
# X-Start-Before:    libvirt-bin
# X-Stop-After:      libvirt-bin
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Xen daemons
# Description:       Xen daemons
### END INIT INFO

. /lib/init/vars.sh
. /lib/lsb/init-functions

# Default variables

[ -r /etc/default/xen ] && . /etc/default/xen
[ -r /etc/default/xend ] && . /etc/default/xend

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC="Xen daemons"

ROOT=$(/usr/lib/xen-common/bin/xen-dir 2>/dev/null)
if [ $? -ne 0 ]; then
	log_warning_msg "Not running within Xen or no compatible utils"
	exit 0
fi
TOOLSTACK=$(/usr/lib/xen-common/bin/xen-toolstack 2>/dev/null)
if [ $? -ne 0 ]; then
	log_warning_msg "No usable Xen toolstack selected"
	exit 0
fi

[ -e "$ROOT"/bin/xend ] && XEND="$ROOT"/bin/xend
XENCONSOLED="$ROOT"/bin/xenconsoled
XENCONSOLED_PIDFILE="/var/run/xenconsoled.pid"
QEMU=/usr/bin/qemu-system-i386
QEMU_PIDFILE="/var/run/qemu-dom0.pid"
QEMU_ARGS="-xen-domid 0 -xen-attach -name dom0 -nographic -M xenpv -daemonize -monitor /dev/null -serial /dev/null -parallel /dev/null"

capability_check()
{
	[ -e "/proc/xen/capabilities" ] || return 1
	grep -q "control_d" /proc/xen/capabilities || return 1
	return 0
}

xend_start()
{
	if [ -z "$XEND" ] || [ "$(basename "$TOOLSTACK")" != xm ]; then
		return 0
	fi

	log_progress_msg "xend"
	xend_start_real
	return $?
}

xend_stop()
{
	if [ -z "$XEND" ] || [ "$(basename "$TOOLSTACK")" != xm ]; then
		return 0
	fi

	log_progress_msg "xend"
	xend_stop_real
	return $?
}

xend_restart()
{
	if [ -z "$XEND" ] || [ "$(basename "$TOOLSTACK")" != xm ]; then
		return 0
	fi

	log_progress_msg "xend"
	xend_stop_real
	case "$?" in
		0|1)
		xend_start_real
		case "$?" in
			0) ;;
			*) return 2 ;;
		esac
		;;
		*) return 2 ;;
	esac
	return 0
}

xend_start_real()
{
	$XEND status && return 1
	$XEND start || return 2

	i=0
	while [ $i -lt 10 ]; do
		$XEND status && return 0 || true
		i=$(($i + 1))
		sleep 1
	done
	return 2
}

xend_stop_real()
{
	log_progress_msg "xend"
	$XEND status || return 0
	$XEND stop || return 1
}

xenconsoled_start()
{
	log_progress_msg "xenconsoled"
	xenconsoled_start_real
	return $?
}

xenconsoled_stop()
{
	log_progress_msg "xenconsoled"
	xenconsoled_stop_real
	return $?
}

xenconsoled_restart()
{
	log_progress_msg "xenconsoled"
	xenconsoled_stop_real
	case "$?" in
		0|1)
		xenconsoled_start_real
		case "$?" in
			0) ;;
			*) return 2 ;;
		esac
		;;
		*) return 2 ;;
	esac
	return 0
}

xenconsoled_start_real()
{
	start-stop-daemon --start --quiet --pidfile "$XENCONSOLED_PIDFILE" --exec "$XENCONSOLED" --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile "$XENCONSOLED_PIDFILE" --exec "$XENCONSOLED" -- \
		$XENCONSOLED_ARGS --pid-file="$XENCONSOLED_PIDFILE" \
		|| return 2
}

xenconsoled_stop_real()
{
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$XENCONSOLED_PIDFILE" --name xenconsoled
	RETVAL="$?"
	[ "$RETVAL" = 2 ] && return 2
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec "$XENCONSOLED"
	[ "$?" = 2 ] && return 2
	rm -f $XENCONSOLED_PIDFILE
	return "$RETVAL"
}

qemu_start()
{
	[ -x $QEMU ] || return 0
	log_progress_msg "qemu"
	qemu_start_real
	return $?
}

qemu_stop()
{
	[ -x $QEMU ] || return 0
	log_progress_msg "qemu"
	qemu_stop_real
	return $?
}

qemu_restart()
{
	[ -x $QEMU ] || return 0
	log_progress_msg "qemu"
	qemu_stop_real
	case "$?" in
		0|1)
		qemu_start_real
		case "$?" in
			0) ;;
			*) return 2 ;;
		esac
		;;
		*) return 2 ;;
	esac
	return 0
}

qemu_start_real()
{
	start-stop-daemon --start --quiet --pidfile "$QEMU_PIDFILE" \
		--exec "$QEMU" --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile "$QEMU_PIDFILE" \
		--exec "$QEMU" -- $QEMU_ARGS -pidfile "$QEMU_PIDFILE" \
		|| return 2
}

qemu_stop_real()
{
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$QEMU_PIDFILE" --exec "$QEMU"
	RETVAL="$?"
	[ "$RETVAL" = 2 ] && return 2
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec "$QEMU"
	[ "$?" = 2 ] && return 2
	rm -f $QEMU_PIDFILE
	return "$RETVAL"
}

init_dom0()
{
	log_progress_msg "init-dom0"
	if [ -e $ROOT/bin/xen-init-dom0 ] ; then
	    $ROOT/bin/xen-init-dom0 > /dev/null
	else
	    xenstore-write "/local/domain/0/name" "Domain-0"
	    xenstore-write "/local/domain/0/domid" "0"
	fi
}

case "$1" in
  start)
	log_daemon_msg "Starting $DESC"
	capability_check
	case "$?" in
		0) ;;
		*) log_end_msg 255; exit ;;
	esac
	xenconsoled_start
	case "$?" in
		0|1) ;;
		*) log_end_msg 1; exit ;;
	esac
	xend_start
	case "$?" in
		0|1) ;;
		*) log_end_msg 1; exit ;;
	esac
	qemu_start
	case "$?" in
		0|1) ;;
		*) log_end_msg 1; exit ;;
	esac
	init_dom0
	case "$?" in
		0|1) ;;
		*) log_end_msg 1; exit ;;
	esac
	log_end_msg 0
	;;
  stop)
	capability_check
	case "$?" in
		0) ;;
		*) exit ;;
	esac
	log_daemon_msg "Stopping $DESC"
	ret=0
	qemu_stop
	case "$?" in
		0|1) ;;
		*) ret=1 ;;
	esac
	xend_stop
	case "$?" in
		0|1) ;;
		*) ret=1 ;;
	esac
	xenconsoled_stop
	case "$?" in
		0|1) ;;
		*) ret=1 ;;
	esac
	log_end_msg $ret
	;;
  restart|force-reload)
	capability_check
	case "$?" in
		0) ;;
		*) exit ;;
	esac
	log_daemon_msg "Restarting $DESC"
	ret=0
	qemu_restart
	case "$?" in
		0|1) ;;
		*) ret=1 ;;
	esac
	xend_restart
	case "$?" in
		0|1) ;;
		*) ret=1 ;;
	esac
	xenconsoled_restart
	case "$?" in
		0|1) ;;
		*) ret=1 ;;
	esac
	log_end_msg $ret
	;;
  *)
	echo "Usage: $0 {start|stop|restart|force-reload}" >&2
	exit 3
	;;
esac

exit 0
