All of lore.kernel.org
 help / color / mirror / Atom feed
* xendomains init script
@ 2005-10-19  9:44 Kurt Garloff
  2005-10-26 17:11 ` Ewan Mellor
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Kurt Garloff @ 2005-10-19  9:44 UTC (permalink / raw)
  To: Xen development list


[-- Attachment #1.1.1: Type: text/plain, Size: 708 bytes --]

Hi,

I worked on the xendomains init script.

It now allows the user to configure what he wants to be done on
xendomains stop: sysrq, migrate, save, or shutdown.
For this to be safe, a timeout has been introduced (optional).
On start, saved domains may be restored, and not yet started
domains from the auto start dir will be started in addition.
status reports missing domains, restart and reload work as well.

The init script is somewhat SUSE-ish, but it should work on LSB
compliant and on RH based distros as well.

I would appreciate this to be put into tools/examples/init.d/

Signed-off-by: Kurt Garloff <garloff@suse.de>

Best,
-- 
Kurt Garloff, Director SUSE Labs, Novell Inc.

[-- Attachment #1.1.2: init.xendomains --]
[-- Type: text/plain, Size: 11013 bytes --]

#!/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

# 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 /lib/lsb/init-functions; then
	# LSB    
    	. /lib/lsb/init-functions
	echo_rc()
	{
	    if test ${_RC_RV} = 0; then
		log_success_msg "  [${_SMSG[${_RC_RV}]}] "
	    else
		log_failure_msg "  [${_SMSG[${_RC_RV}]}] "
	    fi
	}
    elif 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
	}
    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

# Reset status of this service
rc_reset

# read name from xen config file
rdname()
{
    NM=`grep '^name *=' $1 | sed -e 's/^name *= *"\([^"]*\)".*$/\1/' -e 's/%[id]/[0-9]*/g'`
}

rdnames()
{
    NAMES=
    if test ! -d $XENDOMAINS_AUTO -o `/bin/ls $XENDOMAINS_AUTO | wc -l` -eq 0; 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()
{
    name=`echo "$1" | cut -c0-17`
    name=${name%% *}
    rest=`echo "$1" | cut -c18- `
    read id mem cpu vcpu state tm < <(echo "$rest")
}

is_running()
{
    rdname $1
    RC=1
    while read LN; do
	parseln "$LN"
	if test $id = 0; then continue; fi
	case $name in 
	    ($NM)
		RC=0
		;;
	esac
    done < <(xm list | grep -v '^Name')
    return $RC
}

start() 
{
    if [ -f $LOCKFILE ]; then 
	echo -n "xendomains already running (lockfile exists)"
	return; 
    fi

    if test "$XENDOMAINS_RESTORE" = "true" -a -n "$XENDOMAINS_SAVE" \
	    -a -d $XENDOMAINS_SAVE -a `/bin/ls $XENDOMAINS_SAVE | wc -l` -gt 0; then

	touch $LOCKFILE
	echo -n "Restoring Xen domains:"
	for dom in $XENDOMAINS_SAVE/*; do
	    echo -n " ${dom##*/}"
	    xm restore $dom
	    if [ $? -ne 0 ]; then
		rc_failed $?
		echo -n '!'
	    else
		# mv $dom ${dom%/*}/.${dom##*/}
		rm $dom
	    fi
	done
    fi

    if test -n "$XENDOMAINS_AUTO" -a -d $XENDOMAINS_AUTO \
	    -a `/bin/ls $XENDOMAINS_AUTO | wc -l` -gt 0; 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
	for dom in $XENDOMAINS_AUTO/*; do
	    echo -n " ${dom##*/}"
	    if is_running $dom; then
		echo -n "(skip)"
	    else
		xm create --quiet --defconfig $dom
		if [ $? -ne 0 ]; then
		    rc_failed $?
		    echo -n '!'
		fi
	    fi
	done
    fi	
}

all_zombies()
{
    while read LN; do
	parseln "$LN"
	if test $id = 0; then continue; fi
	if test "$state" != "-b---d" -a "$state" != "-----d"; then
	    return 1;
	fi
    done < <(xm list | grep -v '^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).
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
	echo -n "."; 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
}

stop()
{
    # Collect list of domains to shut down
    if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
	rdnames
    fi
    echo -n "Shutting down Xen domains:"
    while read LN; do
	parseln "$LN"
	if test $id = 0; then continue; fi
	echo -n " $name"
	if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
	    case $name in
		($NAMES)
		    # nothing
		    ;;
		(*)
		    echo -n "(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)"
		xm sysrq $id $sysrq
		if test $? -ne 0; then
		    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=$!
	    xm migrate $id $XENDOMAINS_MIGRATE
	    if test $? -ne 0; then
		rc_failed $?
		echo -n '!'
		kill $WDOG_PID >/dev/null 2>&1
	    else
		kill $WDOG_PID >/dev/null 2>&1
		continue
	    fi
	fi
	if test -n "$XENDOMAINS_SAVE"; then
	    echo -n "(save)"
	    watchdog_xm save &
	    WDOG_PID=$!
	    xm save $id $XENDOMAINS_SAVE/$name
	    if test $? -ne 0; then
		rc_failed $?
		echo -n '!'
		kill $WDOG_PIG >/dev/null 2>&1
	    else
		kill $WDOG_PIG >/dev/null 2>&1
		continue
	    fi
	fi
	if test -n "$XENDOMAINS_SHUTDOWN"; then
	    # XENDOMAINS_SHUTDOWN should be "--halt --wait"
	    echo -n "(shut)"
	    watchdog_xm shutdown &
	    WDOG_PID=$!
	    xm shutdown $id $XENDOMAINS_SHUTDOWN
	    if test $? -ne 0; then
		rc_failed $?
		echo -n '!'
	    fi
	    kill $WDOG_PIG >/dev/null 2>&1
	fi
    done < <(xm list | grep -v '^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 &
	WDOG_PID=$!
	xm shutdown $XENDOMAINS_SHUTDOWN_ALL
	if test $? -ne 0; then
	    rc_failed $?
	    echo -n '!'
	fi
	kill $WDOG_PID >/dev/null 2>&1
    fi

    # Unconditionally delete lock file
    rm -f $LOCKFILE
}

check_domain_up()
{
    while read LN; do
	parseln "$LN"
	if test $id = 0; then continue; fi
	case $name in 
	    ($1)
		return 0
		;;
	esac
    done < <(xm list | grep -v "^Name")
    return 1
}

check_all_auto_domains_up()
{
    if test -z "$XENDOMAINS_AUTO" -o ! -d "$XENDOMAINS_AUTO" \
	    -o `/bin/ls $XENDOMAINS_AUTO | wc -l` -eq 0; 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 test -z "$XENDOMAINS_SAVE" -o ! -d "$XENDOMAINS_SAVE" \
	    -o `/bin/ls $XENDOMAINS_SAVE | wc -l` -eq 0; 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

[-- Attachment #1.1.3: sysconfig.xendomains --]
[-- Type: text/plain, Size: 4980 bytes --]

## Path: System/xen
## Description: xen domain start/stop on boot
## Type: string
## Default: 
#
# The xendomains script can send SysRq requests to domains on shutdown.
# If you don't want to MIGRATE, SAVE, or SHUTDOWN, this may be a possibility
# to do a quick and dirty shutdown ("s e i u o") or at least sync the disks
# of the domains ("s").
#
XENDOMAINS_SYSRQ=""

## Type: integer 
## Default: 100000
#
# If XENDOMAINS_SYSRQ is set, this variable determines how long to wait
# (in microseconds) after each SysRq, so the domain has a chance to react.
# If you want to a quick'n'dirty shutdown via SysRq, you may want to set
# it to a relatively high value (1200000).
#
XENDOMAINS_USLEEP=100000

## Type: string
## Default: ""
#
# Set this to a non-empty string if you want to migrate virtual machines
# on shutdown. The string will be passed to the xm migrate DOMID command
# as is: It should contain the target IP address of the physical machine
# to migrate to and optionally parameters like --live. Leave empty if
# you don't want to try virtual machine relocation on shutdown.
# If migration succeeds, neither SAVE nor SHUTDOWN will be executed for
# that domain.
#
XENDOMAINS_MIGRATE=""

## Type: string
## Default: /var/lib/xen/save
#
# Directory to save running domains to when the system (dom0) is
# shut down. Will also be used to restore domains from if # XENDOMAINS_RESTORE
# is set (see below). Leave empty to disable domain saving on shutdown 
# (e.g. because you rather shut domains down).
# If domain saving does succeed, SHUTDOWN will not be executed.
#
XENDOMAINS_SAVE=/var/lib/xen/save

## Type: string
## Default: "--halt --wait"
#
# If neither MIGRATE nor SAVE were enabled or if they failed, you can
# try to shut down a domain by sending it a shutdown request. To do this,
# set this to "--halt --wait". Omit the "--wait" flag to avoid waiting
# for the domain to be really down. Leave empty to skip domain shutdown.
#
XENDOMAINS_SHUTDOWN="--halt --wait"

## Type: string
## Default: "--all --halt --wait"
#
# After we have gone over all virtual machines (resp. all automatically
# started ones, see XENDOMAINS_AUTO_ONLY below) in a loop and sent SysRq,
# migrated, saved and/or shutdown according to the settings above, we
# might want to shutdown the virtual machines that are still running
# for some reason or another. To do this, set this variable to
# "--all --halt --wait", it will be passed to xm shutdown.
# Leave it empty not to do anything special here.
# (Note: This will hit all virtual machines, even if XENDOMAINS_AUTO_ONLY
# is set.)
# 
XENDOMAINS_SHUTDOWN_ALL="--all --halt --wait"

## Type: boolean
## Default: true
#
# This variable determines whether saved domains from XENDOMAINS_SAVE
# will be restored on system startup. 
#
XENDOMAINS_RESTORE=true

## Type: string
## Default: /etc/xen/auto
#
# This variable sets the directory where domains configurations
# are stored that should be started on system startup automatically.
# Leave empty if you don't want to start domains automatically
# (or just don't place any xen domain config files in that dir).
# Note that the script tries to be clever if both RESTORE and AUTO are 
# set: It will first restore saved domains and then only start domains
# in AUTO which are not running yet. 
# Note that the name matching is somewhat fuzzy.
#
XENDOMAINS_AUTO=/etc/xen/auto

## Type: boolean
## Default: false
# 
# If this variable is set to "true", only the domains started via config 
# files in XENDOMAINS_AUTO will be treated according to XENDOMAINS_SYSRQ,
# XENDOMAINS_MIGRATE, XENDOMAINS_SAVE, XENDMAINS_SHUTDOWN; otherwise
# all running domains will be. 
# Note that the name matching is somewhat fuzzy.
# 
XENDOMAINS_AUTO_ONLY=false

## Type: integer
## Default: 300
#
# On xendomains stop, a number of xm commands (xm migrate, save, shutdown,
# shutdown --all) may be executed. In the worst case, these commands may
# stall forever, which will prevent a successful shutdown of the machine.
# If this variable is non-zero, the script will set up a watchdog timer
# for every of these xm commands and time it out after the number of seconds
# specified by this variable.
# Note that SHUTDOWN_ALL will not be called if no virtual machines or only
# zombies are still running, so you don't need to enable this timeout just
# for the zombie case.
# The setting should be large enough to make sure that migrate/save/shutdown
# can succeed. If you do live migrations, keep in mind that live migration
# of a 1GB machine over Gigabit ethernet may actually take something like
# 100s (assuming that live migration uses 10% of the network # bandwidth).
# Depending on the virtual machine, a shutdown may also require a significant
# amount of time. So better setup this variable to a huge number and hope the
# watchdog never fires.
#
XENDOMAINS_STOP_MAXWAIT=300


[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread
* RE: xendomains init script
@ 2005-10-26 19:05 Ian Pratt
  2005-10-26 23:35 ` Chris Bainbridge
  0 siblings, 1 reply; 14+ messages in thread
From: Ian Pratt @ 2005-10-26 19:05 UTC (permalink / raw)
  To: Kurt Garloff, Ewan Mellor; +Cc: Xen development list

> I think about adding one more feature to the script:
> XENDOMAINS_MEMSET0=xxx
> would make the script issue xm mem-set 0 xxx on xendomains 
> start and restore the old mem allocation of dom0 on xendomains stop.
> 
> Unless someone tells me it's not worth doing ...

You know about dom0-min-mem in xend-config.sxp, right? It's a related
feature, but I don't object to adding the one you're requesting.

Ian

^ permalink raw reply	[flat|nested] 14+ messages in thread
* RE: xendomains init script
@ 2005-10-27 14:15 Ian Pratt
  2005-10-27 15:16 ` Chris Bainbridge
  0 siblings, 1 reply; 14+ messages in thread
From: Ian Pratt @ 2005-10-27 14:15 UTC (permalink / raw)
  To: Chris Bainbridge, Xen development list

 
> Here's another feature... I'm not sure if anyone else will 
> need this, but we had a requirement to log all console 
> output, and to have console windows available at all time and 
> potentially multiplexed between users. I solved it by having 
> each xen domain start up in a persistent window inside a 
> screen session.

We've been thinking about having an option to fork off a 'screen'
session when creating a vm.

It would be good if you could write a few notes to describe what the
runes you use to start screen are, and whether you think it makes sense
to integrate this with 'xm'?

Thanks,
Ian

 
> My (gentoo) xendomains start() and stop() currently look like:
> 
> start() {
>         einfo "Starting ${AUTODIR} Xen domains"
>         if [[ ${SCREEN} == "yes" ]]; then
>                 screen -d -m -S xen -t xen-cbc0
>                 screen -r xen -X zombie dr
>                 logrotate -f /usr/share/xen/xen-consoles-logrotate
>                 screen -r xen -X logfile /var/log/xen-consoles/%t
>                 screen -r xen -X logfile flush 1
>                 screen -r xen -X deflog on
>         fi
>         # Create all domains with config files in AUTODIR.
>         for dom in $(ls ${AUTODIR}/* 2>/dev/null); do
>                 name=$(get_domname ${dom})
>                 if ! is_running ${name} ; then
>                         ebegin "  Starting domain ${name}"
>                         if [[ ${SCREEN} == "yes" ]]; then
>                                 screen -r xen -X screen -t 
> ${name} xm create ${dom} -c
>                         else
>                                 xm create --quiet ${dom}
>                         fi
>                         eend $?
>                 else
>                         einfo "  Not Starting domain ${name} 
> - allready running"
>                 fi
>         done

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2007-02-28 17:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-19  9:44 xendomains init script Kurt Garloff
2005-10-26 17:11 ` Ewan Mellor
2005-10-26 17:27   ` Kurt Garloff
2006-03-30  3:57 ` Florian Kirstein
2006-03-30  4:09 ` Florian Kirstein
2006-03-30 21:21   ` Daniel Veillard
2006-03-31  4:27     ` Florian Kirstein
2007-02-28  5:20       ` Florian Kirstein
2007-02-28 14:51         ` Keir Fraser
2007-02-28 17:26           ` Florian Kirstein
  -- strict thread matches above, loose matches on Subject: below --
2005-10-26 19:05 Ian Pratt
2005-10-26 23:35 ` Chris Bainbridge
2005-10-27 14:15 Ian Pratt
2005-10-27 15:16 ` Chris Bainbridge

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.