mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Now the init script is called xencommons and, as the name suggests, it is a common script between xl and xend because it is used to start xenconsoled, xenstored and xenbackendd and the initialization of these three daemons has been removed from xend. The global xen_toolstack=xl/xend variable has been removed. Regarding the network setup, I made the vif scripts follow the same pattern as the other scripts in xen-backend: a new script called vif-setup is executed unconditionally. vif-setup is going to do the right thing depending on the value of the environmental variable "script" (same technique used before), defaulting to vif-bridge. In the common scenario the toolstack doesn't need to set the variable "script" because vif-bridge is going to be called anyway. There is no global network script to setup the network bridges with xl, so if you are using xl without xend, you need to manually configure the bridges using your distro network setup, or, if you are lazy, you can just add something like: /etc/xen/scripts/network-bridge start to your rc.local. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
560 lines
13 KiB
Bash
560 lines
13 KiB
Bash
#!/bin/bash
|
|
#
|
|
# /etc/init.d/xendomains
|
|
# Start / stop domains automatically when domain 0 boots / shuts down.
|
|
#
|
|
# chkconfig: 345 99 00
|
|
# description: Start / stop Xen domains.
|
|
#
|
|
# This script offers fairly basic functionality. It should work on Redhat
|
|
# but also on LSB-compliant SuSE releases and on Debian with the LSB package
|
|
# installed. (LSB is the Linux Standard Base)
|
|
#
|
|
# Based on the example in the "Designing High Quality Integrated Linux
|
|
# Applications HOWTO" by Avi Alkalay
|
|
# <http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/>
|
|
#
|
|
### BEGIN INIT INFO
|
|
# Provides: xendomains
|
|
# Required-Start: $syslog $remote_fs xend
|
|
# Should-Start:
|
|
# Required-Stop: $syslog $remote_fs xend
|
|
# Should-Stop:
|
|
# Default-Start: 3 4 5
|
|
# Default-Stop: 0 1 2 6
|
|
# Default-Enabled: yes
|
|
# Short-Description: Start/stop secondary xen domains
|
|
# Description: Start / stop domains automatically when domain 0
|
|
# boots / shuts down.
|
|
### END INIT INFO
|
|
|
|
if `xm list &> /dev/null`
|
|
then
|
|
exit 0
|
|
fi
|
|
|
|
# Correct exit code would probably be 5, but it's enough
|
|
# if xend complains if we're not running as privileged domain
|
|
if ! [ -e /proc/xen/privcmd ]; then
|
|
exit 0
|
|
fi
|
|
|
|
LOCKFILE=/var/lock/subsys/xendomains
|
|
XENDOM_CONFIG=/etc/sysconfig/xendomains
|
|
|
|
test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
|
|
if [ "$1" = "stop" ]; then exit 0;
|
|
else exit 6; fi; }
|
|
|
|
. $XENDOM_CONFIG
|
|
|
|
# Use the SUSE rc_ init script functions;
|
|
# emulate them on LSB, RH and other systems
|
|
if test -e /etc/rc.status; then
|
|
# SUSE rc script library
|
|
. /etc/rc.status
|
|
else
|
|
_cmd=$1
|
|
declare -a _SMSG
|
|
if test "${_cmd}" = "status"; then
|
|
_SMSG=(running dead dead unused unknown)
|
|
_RC_UNUSED=3
|
|
else
|
|
_SMSG=(done failed failed missed failed skipped unused failed failed)
|
|
_RC_UNUSED=6
|
|
fi
|
|
if test -e /etc/init.d/functions; then
|
|
# REDHAT
|
|
. /etc/init.d/functions
|
|
echo_rc()
|
|
{
|
|
#echo -n " [${_SMSG[${_RC_RV}]}] "
|
|
if test ${_RC_RV} = 0; then
|
|
success " [${_SMSG[${_RC_RV}]}] "
|
|
else
|
|
failure " [${_SMSG[${_RC_RV}]}] "
|
|
fi
|
|
}
|
|
elif test -e /lib/lsb/init-functions; then
|
|
# LSB
|
|
. /lib/lsb/init-functions
|
|
if alias log_success_msg >/dev/null 2>/dev/null; then
|
|
echo_rc()
|
|
{
|
|
echo " [${_SMSG[${_RC_RV}]}] "
|
|
}
|
|
else
|
|
echo_rc()
|
|
{
|
|
if test ${_RC_RV} = 0; then
|
|
log_success_msg " [${_SMSG[${_RC_RV}]}] "
|
|
else
|
|
log_failure_msg " [${_SMSG[${_RC_RV}]}] "
|
|
fi
|
|
}
|
|
fi
|
|
else
|
|
# emulate it
|
|
echo_rc()
|
|
{
|
|
echo " [${_SMSG[${_RC_RV}]}] "
|
|
}
|
|
fi
|
|
rc_reset() { _RC_RV=0; }
|
|
rc_failed()
|
|
{
|
|
if test -z "$1"; then
|
|
_RC_RV=1;
|
|
elif test "$1" != "0"; then
|
|
_RC_RV=$1;
|
|
fi
|
|
return ${_RC_RV}
|
|
}
|
|
rc_check()
|
|
{
|
|
return rc_failed $?
|
|
}
|
|
rc_status()
|
|
{
|
|
rc_failed $?
|
|
if test "$1" = "-r"; then _RC_RV=0; shift; fi
|
|
if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi
|
|
if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed 3; shift; fi
|
|
if test "$1" = "-v"; then echo_rc; shift; fi
|
|
if test "$1" = "-r"; then _RC_RV=0; shift; fi
|
|
return ${_RC_RV}
|
|
}
|
|
rc_exit() { exit ${_RC_RV}; }
|
|
rc_active()
|
|
{
|
|
if test -z "$RUNLEVEL"; then read RUNLEVEL REST < <(/sbin/runlevel); fi
|
|
if test -e /etc/init.d/S[0-9][0-9]${1}; then return 0; fi
|
|
return 1
|
|
}
|
|
fi
|
|
|
|
if ! which usleep >&/dev/null
|
|
then
|
|
usleep()
|
|
{
|
|
if [ -n "$1" ]
|
|
then
|
|
sleep $(( $1 / 1000000 ))
|
|
fi
|
|
}
|
|
fi
|
|
|
|
# Reset status of this service
|
|
rc_reset
|
|
|
|
##
|
|
# Returns 0 (success) if the given parameter names a directory, and that
|
|
# directory is not empty.
|
|
#
|
|
contains_something()
|
|
{
|
|
if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# read name from xen config file
|
|
rdname()
|
|
{
|
|
NM=$(xm create --quiet --dryrun --defconfig "$1" |
|
|
sed -n 's/^.*(name \(.*\))$/\1/p')
|
|
}
|
|
|
|
rdnames()
|
|
{
|
|
NAMES=
|
|
if ! contains_something "$XENDOMAINS_AUTO"
|
|
then
|
|
return
|
|
fi
|
|
for dom in $XENDOMAINS_AUTO/*; do
|
|
rdname $dom
|
|
if test -z $NAMES; then
|
|
NAMES=$NM;
|
|
else
|
|
NAMES="$NAMES|$NM"
|
|
fi
|
|
done
|
|
}
|
|
|
|
parseln()
|
|
{
|
|
if [[ "$1" =~ '(domain' ]]; then
|
|
name=;id=
|
|
else if [[ "$1" =~ '(name' ]]; then
|
|
name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/')
|
|
else if [[ "$1" =~ '(domid' ]]; then
|
|
id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/')
|
|
fi; fi; fi
|
|
|
|
[ -n "$name" -a -n "$id" ] && return 0 || return 1
|
|
}
|
|
|
|
is_running()
|
|
{
|
|
rdname $1
|
|
RC=1
|
|
name=;id=
|
|
while read LN; do
|
|
parseln "$LN" || continue
|
|
if test $id = 0; then continue; fi
|
|
case $name in
|
|
($NM)
|
|
RC=0
|
|
;;
|
|
esac
|
|
done < <(xm list -l | grep '(\(domain\|domid\|name\)')
|
|
return $RC
|
|
}
|
|
|
|
start()
|
|
{
|
|
if [ -f $LOCKFILE ]; then
|
|
echo -e "xendomains already running (lockfile exists)"
|
|
return;
|
|
fi
|
|
|
|
saved_domains=" "
|
|
if [ "$XENDOMAINS_RESTORE" = "true" ] &&
|
|
contains_something "$XENDOMAINS_SAVE"
|
|
then
|
|
mkdir -p $(dirname "$LOCKFILE")
|
|
touch $LOCKFILE
|
|
echo -n "Restoring Xen domains:"
|
|
saved_domains=`ls $XENDOMAINS_SAVE`
|
|
for dom in $XENDOMAINS_SAVE/*; do
|
|
if [ -f $dom ] ; then
|
|
HEADER=`head -c 16 $dom | head -n 1 2> /dev/null`
|
|
if [ $HEADER = "LinuxGuestRecord" ]; then
|
|
echo -n " ${dom##*/}"
|
|
XMR=`xm restore $dom 2>&1 1>/dev/null`
|
|
#xm restore $dom
|
|
if [ $? -ne 0 ]; then
|
|
echo -e "\nAn error occurred while restoring domain ${dom##*/}:\n$XMR"
|
|
rc_failed $?
|
|
echo -e '!'
|
|
else
|
|
# mv $dom ${dom%/*}/.${dom##*/}
|
|
rm $dom
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
echo -e
|
|
fi
|
|
|
|
if contains_something "$XENDOMAINS_AUTO"
|
|
then
|
|
touch $LOCKFILE
|
|
echo -n "Starting auto Xen domains:"
|
|
# We expect config scripts for auto starting domains to be in
|
|
# XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
|
|
|
|
# Create all domains with config files in XENDOMAINS_AUTO.
|
|
# TODO: We should record which domain name belongs
|
|
# so we have the option to selectively shut down / migrate later
|
|
# If a domain statefile from $XENDOMAINS_SAVE matches a domain name
|
|
# in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't
|
|
# restore correctly it requires administrative attention.
|
|
for dom in $XENDOMAINS_AUTO/*; do
|
|
echo -n " ${dom##*/}"
|
|
shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
|
|
echo $saved_domains | grep -w $shortdom > /dev/null
|
|
if [ $? -eq 0 ] || is_running $dom; then
|
|
echo -n "(skip)"
|
|
else
|
|
XMC=`xm create --quiet --defconfig $dom`
|
|
if [ $? -ne 0 ]; then
|
|
echo -e "\nAn error occurred while creating domain ${dom##*/}: $XMC\n"
|
|
rc_failed $?
|
|
echo -e '!'
|
|
else
|
|
usleep $XENDOMAINS_CREATE_USLEEP
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
all_zombies()
|
|
{
|
|
name=;id=
|
|
while read LN; do
|
|
parseln "$LN" || continue
|
|
if test $id = 0; then continue; fi
|
|
if test "$state" != "-b---d" -a "$state" != "-----d"; then
|
|
return 1;
|
|
fi
|
|
done < <(xm list -l | grep '(\(domain\|domid\|name\)')
|
|
return 0
|
|
}
|
|
|
|
# Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
|
|
# if it has not exited by that time kill it, so the init script will
|
|
# succeed within a finite amount of time; if $2 is nonnull, it will
|
|
# kill the command as well as soon as no domain (except for zombies)
|
|
# are left (used for shutdown --all). Third parameter, if any, suppresses
|
|
# output of dots per working state (formatting issues)
|
|
watchdog_xm()
|
|
{
|
|
if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
|
|
exit
|
|
fi
|
|
|
|
usleep 20000
|
|
for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
|
|
# exit if xm save/migrate/shutdown is finished
|
|
PSAX=`ps axlw | grep "xm $1" | grep -v grep`
|
|
if test -z "$PSAX"; then exit; fi
|
|
if ! test -n "$3"; then echo -n '.'; fi
|
|
sleep 1
|
|
# go to kill immediately if there's only zombies left
|
|
if all_zombies && test -n "$2"; then break; fi
|
|
done
|
|
sleep 1
|
|
read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
|
|
# kill xm $1
|
|
kill $PSPID >/dev/null 2>&1
|
|
|
|
echo -e .
|
|
}
|
|
|
|
stop()
|
|
{
|
|
exec 3>&2 2> /dev/null
|
|
|
|
# Collect list of domains to shut down
|
|
if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
|
|
rdnames
|
|
fi
|
|
echo -n "Shutting down Xen domains:"
|
|
name=;id=
|
|
while read LN; do
|
|
parseln "$LN" || continue
|
|
if test $id = 0; then continue; fi
|
|
echo -n " $name"
|
|
if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
|
|
eval "
|
|
case \"\$name\" in
|
|
($NAMES)
|
|
# nothing
|
|
;;
|
|
(*)
|
|
echo -e '(skip)'
|
|
continue
|
|
;;
|
|
esac
|
|
"
|
|
fi
|
|
# XENDOMAINS_SYSRQ chould be something like just "s"
|
|
# or "s e i u" or even "s e s i u o"
|
|
# for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
|
|
if test -n "$XENDOMAINS_SYSRQ"; then
|
|
for sysrq in $XENDOMAINS_SYSRQ; do
|
|
echo -n "(SR-$sysrq)"
|
|
XMR=`xm sysrq $id $sysrq 2>&1 1>/dev/null`
|
|
if test $? -ne 0; then
|
|
echo -e "\nAn error occurred while doing sysrq on domain:\n$XMR\n"
|
|
rc_failed $?
|
|
echo -n '!'
|
|
fi
|
|
# usleep just ignores empty arg
|
|
usleep $XENDOMAINS_USLEEP
|
|
done
|
|
fi
|
|
if test "$state" = "-b---d" -o "$state" = "-----d"; then
|
|
echo -n "(zomb)"
|
|
continue
|
|
fi
|
|
if test -n "$XENDOMAINS_MIGRATE"; then
|
|
echo -n "(migr)"
|
|
watchdog_xm migrate &
|
|
WDOG_PID=$!
|
|
XMR=`xm migrate $id $XENDOMAINS_MIGRATE 2>&1 1>/dev/null`
|
|
if test $? -ne 0; then
|
|
echo -e "\nAn error occurred while migrating domain:\n$XMR\n"
|
|
rc_failed $?
|
|
echo -e '!'
|
|
|
|
kill $WDOG_PID >/dev/null 2>&1
|
|
else
|
|
kill $WDOG_PID >/dev/null 2>&1
|
|
|
|
echo -e .
|
|
usleep 1000
|
|
continue
|
|
fi
|
|
fi
|
|
if test -n "$XENDOMAINS_SAVE"; then
|
|
echo -n "(save)"
|
|
watchdog_xm save &
|
|
WDOG_PID=$!
|
|
mkdir -p "$XENDOMAINS_SAVE"
|
|
XMR=`xm save $id $XENDOMAINS_SAVE/$name 2>&1 1>/dev/null`
|
|
if test $? -ne 0; then
|
|
echo -e "\nAn error occurred while saving domain:\n$XMR\n"
|
|
rc_failed $?
|
|
echo -e '!'
|
|
kill $WDOG_PID >/dev/null 2>&1
|
|
else
|
|
kill $WDOG_PID >/dev/null 2>&1
|
|
echo -e .
|
|
usleep 1000
|
|
continue
|
|
fi
|
|
fi
|
|
if test -n "$XENDOMAINS_SHUTDOWN"; then
|
|
# XENDOMAINS_SHUTDOWN should be "--halt --wait"
|
|
echo -n "(shut)"
|
|
watchdog_xm shutdown &
|
|
WDOG_PID=$!
|
|
XMR=`xm shutdown $id $XENDOMAINS_SHUTDOWN 2>&1 1>/dev/null`
|
|
if test $? -ne 0; then
|
|
echo -e "\nAn error occurred while shutting down domain:\n$XMR\n"
|
|
rc_failed $?
|
|
echo -e '!'
|
|
fi
|
|
kill $WDOG_PID >/dev/null 2>&1
|
|
fi
|
|
done < <(xm list -l | grep '(\(domain\|domid\|name\)')
|
|
|
|
# NB. this shuts down ALL Xen domains (politely), not just the ones in
|
|
# AUTODIR/*
|
|
# This is because it's easier to do ;-) but arguably if this script is run
|
|
# on system shutdown then it's also the right thing to do.
|
|
if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
|
|
# XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
|
|
echo -n " SHUTDOWN_ALL "
|
|
watchdog_xm shutdown 1 false &
|
|
WDOG_PID=$!
|
|
XMR=`xm shutdown $XENDOMAINS_SHUTDOWN_ALL 2>&1 1>/dev/null`
|
|
if test $? -ne 0; then
|
|
echo -e "\nAn error occurred while shutting down all domains: $XMR\n"
|
|
rc_failed $?
|
|
echo -e '!'
|
|
fi
|
|
kill $WDOG_PID >/dev/null 2>&1
|
|
fi
|
|
|
|
# Unconditionally delete lock file
|
|
rm -f $LOCKFILE
|
|
|
|
exec 2>&3
|
|
}
|
|
|
|
check_domain_up()
|
|
{
|
|
name=;id=
|
|
while read LN; do
|
|
parseln "$LN" || continue
|
|
if test $id = 0; then continue; fi
|
|
case $name in
|
|
($1)
|
|
return 0
|
|
;;
|
|
esac
|
|
done < <(xm list -l | grep '(\(domain\|domid\|name\)')
|
|
return 1
|
|
}
|
|
|
|
check_all_auto_domains_up()
|
|
{
|
|
if ! contains_something "$XENDOMAINS_AUTO"
|
|
then
|
|
return 0
|
|
fi
|
|
missing=
|
|
for nm in $XENDOMAINS_AUTO/*; do
|
|
rdname $nm
|
|
found=0
|
|
if check_domain_up "$NM"; then
|
|
echo -n " $name"
|
|
else
|
|
missing="$missing $NM"
|
|
fi
|
|
done
|
|
if test -n "$missing"; then
|
|
echo -n " MISS AUTO:$missing"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
check_all_saved_domains_up()
|
|
{
|
|
if ! contains_something "$XENDOMAINS_SAVE"
|
|
then
|
|
return 0
|
|
fi
|
|
missing=`/bin/ls $XENDOMAINS_SAVE`
|
|
echo -n " MISS SAVED: " $missing
|
|
return 1
|
|
}
|
|
|
|
# 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.
|
|
# Commented out to avoid confusion!
|
|
|
|
restart()
|
|
{
|
|
stop
|
|
start
|
|
}
|
|
|
|
reload()
|
|
{
|
|
restart
|
|
}
|
|
|
|
|
|
case "$1" in
|
|
start)
|
|
start
|
|
rc_status
|
|
if test -f $LOCKFILE; then rc_status -v; fi
|
|
;;
|
|
|
|
stop)
|
|
stop
|
|
rc_status -v
|
|
;;
|
|
|
|
restart)
|
|
restart
|
|
;;
|
|
reload)
|
|
reload
|
|
;;
|
|
|
|
status)
|
|
echo -n "Checking for xendomains:"
|
|
if test ! -f $LOCKFILE; then
|
|
rc_failed 3
|
|
else
|
|
check_all_auto_domains_up
|
|
rc_status
|
|
check_all_saved_domains_up
|
|
rc_status
|
|
fi
|
|
rc_status -v
|
|
;;
|
|
|
|
*)
|
|
echo "Usage: $0 {start|stop|restart|reload|status}"
|
|
rc_failed 3
|
|
rc_status -v
|
|
;;
|
|
esac
|
|
|
|
rc_exit
|