Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > media > main-testing > by-pkgid > 7564505c8b39bb85c995aba611b95a8a > files > 6

xen-3.3.0-7.2mdv2009.0.i586.rpm

#!/bin/bash
#
# chkconfig: 345 99 00
# description: Start / stop Xen domains.

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

source /etc/init.d/functions

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

##
# 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 -n "xendomains already running (lockfile exists)"
        return; 
    fi

    saved_domains=" "
    if [ "$XENDOMAINS_RESTORE" = "true" ] &&
       contains_something "$XENDOMAINS_SAVE"
    then
        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##*/}"
                    xm restore $dom
                    if [ $? -ne 0 ]; then
                        rc_failed $?
                        echo -n '!'
                    else
                        # mv $dom ${dom%/*}/.${dom##*/}
                        rm $dom
                    fi
                fi
            fi
        done
        echo .
    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
                xm create --quiet --defconfig $dom
                if [ $? -ne 0 ]; then
                    rc_failed $?
                    echo -n '!'
                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).
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:"
    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
            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=$!
            mkdir -p "$XENDOMAINS_SAVE"
            xm save $id $XENDOMAINS_SAVE/$name
            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_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_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 &
        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()
{
    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)
        echo -n "Starting xendomains"
        start
        rc=$?
        if [ $rc -eq 0 ]; then
            success "xendomains startup"
        else
            failure "xendomains startup"
        fi
        echo
        ;;
    stop)
        echo -n "Stopping xendomains"
        stop
        rc=$?
        if [ $rc -eq 0 ]; then
            success "xendomains shutdown"
        else
            failure "xendomains shutdown"
        fi
        echo
        ;;
    restart)
        restart
        ;;
    reload)
        reload
        ;;
    status)
        echo "Checking for xendomains:" 
        if [ -f $LOCKFILE ]; then 
            check_all_auto_domains_up
            check_all_saved_domains_up
        fi
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|status}"
        exit 1
        ;;
esac

exit $?