2007-01-16 00:42:10 +01:00
|
|
|
#!/bin/bash
|
|
|
|
#
|
2007-05-23 01:45:46 +02:00
|
|
|
# xendomains Starts and stops Xen VMs
|
2007-01-16 00:42:10 +01:00
|
|
|
#
|
|
|
|
# chkconfig: 35 99 00
|
2007-05-23 01:45:46 +02:00
|
|
|
# description: Starts and stops Xen VMs
|
2007-01-16 00:42:10 +01:00
|
|
|
#
|
|
|
|
### BEGIN INIT INFO
|
|
|
|
# Provides: xendomains
|
|
|
|
# Required-Start: $syslog $remote_fs xend
|
|
|
|
# Should-Start:
|
|
|
|
# Required-Stop: $syslog $remote_fs xend
|
|
|
|
# Should-Stop:
|
|
|
|
# Default-Start: 3 5
|
|
|
|
# Default-Stop: 0 1 2 4 6
|
2007-05-23 01:45:46 +02:00
|
|
|
# Short-Description: Starts and stops Xen VMs
|
|
|
|
# Description: Starts and stops Xen VMs automatically when the
|
|
|
|
# host starts and stops.
|
2007-01-16 00:42:10 +01:00
|
|
|
### END INIT INFO
|
|
|
|
|
|
|
|
. /etc/rc.status
|
|
|
|
rc_reset
|
|
|
|
|
|
|
|
LOCKFILE=/var/lock/subsys/xendomains
|
|
|
|
XENDOM_CONFIG=/etc/sysconfig/xendomains
|
2007-05-23 01:45:46 +02:00
|
|
|
RETCODE_FILE=/tmp/xendomains.rc.$$
|
|
|
|
|
|
|
|
. "$XENDOM_CONFIG"
|
2007-01-16 00:42:10 +01:00
|
|
|
|
|
|
|
shopt -s dotglob nullglob
|
|
|
|
|
|
|
|
smart_term=1
|
|
|
|
if [ -z "$esc" ]; then
|
|
|
|
smart_term=0
|
|
|
|
rc_timer_on()
|
|
|
|
{
|
|
|
|
(trap "exit 0" TERM; sleep $1) & _rc_timer_pid=$!
|
|
|
|
}
|
|
|
|
rc_timer_off()
|
|
|
|
{
|
|
|
|
if [ -n "$_rc_timer_pid" ]; then
|
|
|
|
kill -TERM $_rc_timer_pid > /dev/null 2>&1
|
|
|
|
fi
|
|
|
|
unset _rc_timer_pid
|
|
|
|
}
|
|
|
|
fi
|
|
|
|
|
|
|
|
xendomains_abort()
|
|
|
|
{
|
|
|
|
echo -n "xendomains "
|
|
|
|
rc_failed $1
|
|
|
|
rc_status -v
|
|
|
|
rc_exit
|
|
|
|
}
|
|
|
|
|
2007-05-23 01:45:46 +02:00
|
|
|
check()
|
|
|
|
{
|
|
|
|
XEND=`ps ax | grep -w xend | grep -w python | awk '{ print $1 }'`
|
|
|
|
XEND=`echo $XEND`
|
|
|
|
|
|
|
|
if [ "$1" = status ]; then
|
|
|
|
if [ ! -e /proc/xen/capabilities ] || [ ! -r "$XENDOM_CONFIG" ] || [ -z "$XEND" ]; then
|
|
|
|
xendomains_abort 3
|
2007-01-16 00:42:10 +01:00
|
|
|
fi
|
2007-05-23 01:45:46 +02:00
|
|
|
else
|
|
|
|
if [ `id -u` != 0 ]; then
|
|
|
|
xendomains_abort 4
|
|
|
|
fi
|
|
|
|
if [ ! -e /proc/xen/capabilities ] || [ -z "$XEND" ] ||
|
|
|
|
! grep control_d /proc/xen/capabilities >/dev/null 2>&1; then
|
|
|
|
if [ "$1" = stop ] ||
|
|
|
|
[ "$1" = restart ]; then
|
|
|
|
xendomains_abort 0
|
|
|
|
else
|
|
|
|
xendomains_abort 6
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ ! -r "$XENDOM_CONFIG" ]; then
|
2007-01-16 00:42:10 +01:00
|
|
|
xendomains_abort 6
|
|
|
|
fi
|
|
|
|
fi
|
2007-05-23 01:45:46 +02:00
|
|
|
}
|
2007-01-16 00:42:10 +01:00
|
|
|
|
|
|
|
dir_contains_something()
|
|
|
|
{
|
|
|
|
[ -d "$1" ] || return 1
|
|
|
|
local dirfiles=( "$1"/* )
|
|
|
|
[ ${#dirfiles[@]} != 0 ]
|
|
|
|
}
|
|
|
|
|
|
|
|
get_name_from_cfg()
|
|
|
|
{
|
2007-05-23 01:45:46 +02:00
|
|
|
NM=`grep '^name[ ]*=' "$1" | sed -e 's/^name[ ]*=[ ]*['\''"]\([^'\''"]*\)['\''"].*$/\1/'`
|
2007-01-16 00:42:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
running_auto_names()
|
|
|
|
{
|
|
|
|
unset AUTONAMES[@]
|
|
|
|
if ! dir_contains_something "$XENDOMAINS_AUTO"; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
for dom in "$XENDOMAINS_AUTO"/*; do
|
|
|
|
get_name_from_cfg "$dom"
|
|
|
|
AUTONAMES+=("$NM")
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
parseln()
|
|
|
|
{
|
2007-02-11 11:48:10 +01:00
|
|
|
name=${1:0:$((${#1}-36))}
|
2007-01-16 00:42:10 +01:00
|
|
|
name=${name%% *}
|
2007-02-11 11:48:10 +01:00
|
|
|
rest="${1: -36}"
|
|
|
|
id=${rest:0:4}
|
|
|
|
id=`echo $id`
|
|
|
|
mem=${rest:4:6}
|
|
|
|
mem=`echo $mem`
|
|
|
|
vcpu=${rest:10:6}
|
|
|
|
vcpu=`echo $vcpu`
|
|
|
|
state=${rest:16:11}
|
|
|
|
state=`echo $state`
|
|
|
|
tm=${rest:27}
|
|
|
|
tm=`echo $tm`
|
2007-01-16 00:42:10 +01:00
|
|
|
}
|
|
|
|
|
2007-05-23 01:45:46 +02:00
|
|
|
xm_list()
|
|
|
|
{
|
|
|
|
TERM=vt100 xm list | grep -v '^Name *ID'
|
|
|
|
}
|
|
|
|
|
2007-01-16 00:42:10 +01:00
|
|
|
is_cfg_running()
|
|
|
|
{
|
|
|
|
get_name_from_cfg "$1"
|
|
|
|
while read LN; do
|
|
|
|
parseln "$LN"
|
2007-02-11 11:48:10 +01:00
|
|
|
[ "$id" = 0 ] && continue
|
|
|
|
if [ "$name" = "$NM" ]; then
|
|
|
|
[ -z "$state" ] && return 1
|
|
|
|
return 0
|
|
|
|
fi
|
2007-05-23 01:45:46 +02:00
|
|
|
done < <(xm_list)
|
2007-01-16 00:42:10 +01:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
start()
|
|
|
|
{
|
|
|
|
if [ -f "$LOCKFILE" ]; then
|
|
|
|
echo -n "xendomains already running (lockfile exists)"
|
|
|
|
rc_reset
|
|
|
|
rc_status -v
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
local printed=0
|
|
|
|
|
|
|
|
if [ "$XENDOMAINS_RESTORE" = "true" ] &&
|
|
|
|
dir_contains_something "$XENDOMAINS_SAVE"; then
|
|
|
|
mkdir -p $(dirname "$LOCKFILE")
|
|
|
|
touch "$LOCKFILE"
|
|
|
|
echo "Restoring saved Xen domains"
|
|
|
|
printed=1
|
|
|
|
for dom in "$XENDOMAINS_SAVE"/*; do
|
|
|
|
echo -n " ${dom##*/}: "
|
|
|
|
xm restore "$dom" >/dev/null 2>&1
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rc_failed
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
rm -f "$dom"
|
|
|
|
fi
|
|
|
|
rc_status -v
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
if dir_contains_something "$XENDOMAINS_AUTO"; then
|
|
|
|
touch "$LOCKFILE"
|
|
|
|
echo "Starting auto Xen domains"
|
|
|
|
printed=1
|
|
|
|
for dom in "$XENDOMAINS_AUTO"/*; do
|
|
|
|
echo -n " ${dom##*/}: "
|
|
|
|
if is_cfg_running "$dom"; then
|
|
|
|
rc_status -s
|
|
|
|
else
|
|
|
|
xm create --quiet --defconfig "$dom"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rc_failed
|
|
|
|
else
|
|
|
|
usleep $XENDOMAINS_CREATE_USLEEP
|
|
|
|
rc_reset
|
|
|
|
fi
|
|
|
|
rc_status -v
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $printed -eq 0 ]; then
|
|
|
|
echo -n "Starting xendomains"
|
|
|
|
rc_failed 6 # not configured
|
|
|
|
rc_status -v
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
is_zombie_state()
|
|
|
|
{
|
|
|
|
[ "$1" = "-b---d" ] || [ "$1" = "-----d" ]
|
|
|
|
}
|
|
|
|
|
|
|
|
any_non_zombies()
|
|
|
|
{
|
|
|
|
while read LN; do
|
|
|
|
parseln "$LN"
|
2007-02-11 11:48:10 +01:00
|
|
|
[ "$id" = 0 ] && continue
|
|
|
|
[ -z "$state" ] && continue
|
2007-01-16 00:42:10 +01:00
|
|
|
is_zombie_state "$state" || return 0
|
2007-05-23 01:45:46 +02:00
|
|
|
done < <(xm_list)
|
2007-01-16 00:42:10 +01:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
migrate_with_watchdog()
|
|
|
|
{
|
|
|
|
(xm migrate "$@" ; echo $? > "$RETCODE_FILE") >/dev/null 2>&1 &
|
|
|
|
watchdog_xm $!
|
|
|
|
}
|
|
|
|
|
|
|
|
save_with_watchdog()
|
|
|
|
{
|
|
|
|
(xm save "$@" ; echo $? > "$RETCODE_FILE") >/dev/null 2>&1 &
|
|
|
|
watchdog_xm $!
|
|
|
|
}
|
|
|
|
|
|
|
|
shutdown_with_watchdog()
|
|
|
|
{
|
|
|
|
(xm shutdown -w "$@" ; echo $? > "$RETCODE_FILE") >/dev/null 2>&1 &
|
|
|
|
watchdog_xm $!
|
|
|
|
}
|
|
|
|
|
|
|
|
get_return_code()
|
|
|
|
{
|
|
|
|
local RC=127
|
|
|
|
[ -r "$RETCODE_FILE" ] && RC=`head -c10 "$RETCODE_FILE"`
|
|
|
|
rm -f "$RETCODE_FILE"
|
|
|
|
return $RC
|
|
|
|
}
|
|
|
|
|
|
|
|
# $1: The PID to wait on.
|
|
|
|
watchdog_xm()
|
|
|
|
{
|
|
|
|
local col=$((COLUMNS-11))
|
|
|
|
if [ -z "$XENDOMAINS_STOP_MAXWAIT" ] || [ "$XENDOMAINS_STOP_MAXWAIT" = "0" ]; then
|
|
|
|
wait $1 >/dev/null 2>&1
|
|
|
|
get_return_code
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
rc_timer_on $XENDOMAINS_STOP_MAXWAIT $col
|
|
|
|
while true; do
|
|
|
|
# Prefer "jobs" over "ps": faster and no false positives
|
|
|
|
pid=`jobs -l | grep " $1 Running"`
|
|
|
|
if [ -z "$pid" ]; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
pid=`jobs -l | grep " $_rc_timer_pid Running"`
|
|
|
|
if [ -z "$pid" ]; then
|
|
|
|
disown $1 # To avoid the "Terminated..." message
|
|
|
|
kill $1 >/dev/null 2>&1
|
|
|
|
fi
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
rc_timer_off
|
|
|
|
if [ $smart_term -ne 0 ]; then
|
|
|
|
echo -en "\015${esc}[${col}C "
|
|
|
|
fi
|
|
|
|
get_return_code
|
|
|
|
}
|
|
|
|
|
|
|
|
stop()
|
|
|
|
{
|
|
|
|
echo "Shutting down Xen domains"
|
|
|
|
if [ "$XENDOMAINS_AUTO_ONLY" = "true" ]; then
|
|
|
|
running_auto_names
|
|
|
|
fi
|
|
|
|
local printed=0
|
|
|
|
while read LN; do
|
|
|
|
parseln "$LN"
|
2007-02-11 11:48:10 +01:00
|
|
|
[ "$id" = 0 ] && continue
|
|
|
|
[ -z "$state" ] && continue
|
2007-01-16 00:42:10 +01:00
|
|
|
printed=1
|
|
|
|
if [ "$XENDOMAINS_AUTO_ONLY" = "true" ]; then
|
|
|
|
is_auto_domain=0
|
2007-02-22 14:55:08 +01:00
|
|
|
for n in "${AUTONAMES[@]}"; do
|
2007-01-16 00:42:10 +01:00
|
|
|
if [ "$name" = "$n" ]; then
|
|
|
|
is_auto_domain=1
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
if [ $is_auto_domain -eq 0 ]; then
|
|
|
|
echo -n " $name: "
|
|
|
|
rc_status -s
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ -n "$XENDOMAINS_SYSRQ" ]; then
|
|
|
|
for sysrq in $XENDOMAINS_SYSRQ; do
|
|
|
|
echo -n " $name: "
|
|
|
|
echo -n "sending sysrq '$sysrq'... "
|
|
|
|
xm sysrq $id $sysrq
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rc_failed
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
fi
|
|
|
|
rc_status -v
|
|
|
|
# usleep just ignores empty arg
|
|
|
|
usleep $XENDOMAINS_USLEEP
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
if is_zombie_state "$state"; then
|
|
|
|
echo -n " $name: "
|
|
|
|
echo -n "destroying zombie... "
|
|
|
|
xm destroy $id
|
|
|
|
rc_reset
|
|
|
|
rc_status -v
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
# HVM domains currently can't migrate or save so don't even try.
|
|
|
|
hvm=0
|
|
|
|
vmpath=`xenstore-read /local/domain/$id/vm 2> /dev/null`
|
|
|
|
if [ $? = 0 ]; then
|
|
|
|
[ `xenstore-read "$vmpath/image/ostype" 2> /dev/null` = hvm ] && hvm=1
|
|
|
|
fi
|
|
|
|
if [ -n "$XENDOMAINS_MIGRATE" ]; then
|
|
|
|
echo -n " $name: "
|
|
|
|
echo -n "migrating... "
|
|
|
|
if [ $hvm != 0 ]; then
|
|
|
|
echo -n "(unsupported for fully virtualized)"
|
|
|
|
rc_status -s
|
|
|
|
else
|
|
|
|
migrate_with_watchdog $id "$XENDOMAINS_MIGRATE"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rc_failed
|
|
|
|
rc_status -v
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
rc_status -v
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ -n "$XENDOMAINS_SAVE" ]; then
|
|
|
|
echo -n " $name: "
|
|
|
|
echo -n "saving... "
|
|
|
|
if [ $hvm != 0 ]; then
|
|
|
|
echo -n "(unsupported for fully virtualized)"
|
|
|
|
rc_status -s
|
|
|
|
else
|
|
|
|
save_with_watchdog $id "$XENDOMAINS_SAVE/$name"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rm -f "$XENDOMAINS_SAVE/$name"
|
|
|
|
rc_failed
|
|
|
|
rc_status -v
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
rc_status -v
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ -n "$XENDOMAINS_SHUTDOWN" ]; then
|
|
|
|
echo -n " $name: "
|
|
|
|
echo -n "shutting down... "
|
|
|
|
shutdown_with_watchdog $id $XENDOMAINS_SHUTDOWN
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rc_failed
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
fi
|
|
|
|
rc_status -v
|
|
|
|
fi
|
2007-05-23 01:45:46 +02:00
|
|
|
done < <(xm_list)
|
2007-01-16 00:42:10 +01:00
|
|
|
|
|
|
|
if [ -n "$XENDOMAINS_SHUTDOWN_ALL" ] && any_non_zombies ; then
|
|
|
|
echo -n " others: shutting down... "
|
|
|
|
shutdown_with_watchdog $XENDOMAINS_SHUTDOWN_ALL
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
rc_failed
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
fi
|
|
|
|
rc_status -v
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $printed -eq 0 ]; then
|
|
|
|
echo -e "${rc_done_up}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Unconditionally delete lock file
|
|
|
|
rm -f "$LOCKFILE"
|
|
|
|
}
|
|
|
|
|
|
|
|
check_domain_up()
|
|
|
|
{
|
|
|
|
while read LN; do
|
|
|
|
parseln "$LN"
|
2007-02-11 11:48:10 +01:00
|
|
|
[ "$id" = 0 ] && continue
|
|
|
|
if [ "$name" = "$1" ]; then
|
|
|
|
[ -z "$state" ] && return 1
|
|
|
|
return 0
|
|
|
|
fi
|
2007-05-23 01:45:46 +02:00
|
|
|
done < <(xm_list)
|
2007-01-16 00:42:10 +01:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
check_all_domains_up()
|
|
|
|
{
|
2007-07-05 01:35:39 +02:00
|
|
|
any_auto=0
|
|
|
|
any_save=0
|
|
|
|
dir_contains_something "$XENDOMAINS_AUTO" && any_auto=1
|
|
|
|
dir_contains_something "$XENDOMAINS_SAVE" && any_save=1
|
|
|
|
if [ $any_auto -eq 0 ] && [ $any_save -eq 0 ]; then
|
2007-01-16 00:42:10 +01:00
|
|
|
rc_reset
|
|
|
|
rc_status -v
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
echo
|
2007-07-05 01:35:39 +02:00
|
|
|
if [ $any_auto -ne 0 ]; then
|
|
|
|
for nm in "$XENDOMAINS_AUTO"/*; do
|
|
|
|
get_name_from_cfg "$nm"
|
|
|
|
echo -n " $nm: "
|
|
|
|
if check_domain_up "$NM"; then
|
|
|
|
rc_reset
|
|
|
|
else
|
|
|
|
rc_failed 2
|
|
|
|
fi
|
|
|
|
rc_status -v
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
if [ $any_save -ne 0 ]; then
|
|
|
|
for nm in "$XENDOMAINS_SAVE"/*; do
|
|
|
|
echo -n " $nm: "
|
|
|
|
rc_failed 3
|
|
|
|
rc_status -v
|
|
|
|
done
|
|
|
|
fi
|
2007-01-16 00:42:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# This does NOT necessarily restart all running domains: instead it
|
|
|
|
# stops all running domains and then boots all the domains specified in
|
|
|
|
# AUTODIR. If other domains have been started manually then they will
|
|
|
|
# not get restarted.
|
|
|
|
restart()
|
|
|
|
{
|
|
|
|
"$0" stop
|
|
|
|
start
|
|
|
|
}
|
|
|
|
|
|
|
|
case "$1" in
|
|
|
|
start)
|
2007-05-23 01:45:46 +02:00
|
|
|
check $1
|
2007-01-16 00:42:10 +01:00
|
|
|
start
|
|
|
|
;;
|
|
|
|
|
|
|
|
stop)
|
2007-05-23 01:45:46 +02:00
|
|
|
check $1
|
2007-01-16 00:42:10 +01:00
|
|
|
stop
|
|
|
|
;;
|
|
|
|
|
|
|
|
restart|reload)
|
2007-05-23 01:45:46 +02:00
|
|
|
check $1
|
2007-01-16 00:42:10 +01:00
|
|
|
restart
|
|
|
|
;;
|
|
|
|
|
|
|
|
try-restart)
|
2007-05-23 01:45:46 +02:00
|
|
|
check $1
|
2007-01-16 00:42:10 +01:00
|
|
|
"$0" status
|
|
|
|
if [ $? = 0 ]; then
|
|
|
|
"$0" restart
|
|
|
|
else
|
|
|
|
rc_reset
|
|
|
|
rc_status -v
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
|
|
|
|
status)
|
2007-05-23 01:45:46 +02:00
|
|
|
check $1
|
2007-01-16 00:42:10 +01:00
|
|
|
echo -n "Checking status of Xen domains"
|
|
|
|
if [ ! -f "$LOCKFILE" ]; then
|
|
|
|
rc_failed 3
|
|
|
|
rc_status -v
|
|
|
|
else
|
|
|
|
check_all_domains_up
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
|
|
|
|
*)
|
|
|
|
echo "Usage: $0 {start|stop|restart|try-restart|reload|status}"
|
|
|
|
rc_failed 2
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
rc_exit
|