Port-xen archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Improved xendomains script



I've greatly improved the initial "xendomains" script I had posted
two weeks ago.  The attached script now allows for per-domain hook
scripts that are run before a domain is created, and after a domain
is stopped.  Also, to prevent the xendomains rc.d script from hanging
during system shutdown, I've modified the "stop" action -- instead of
waiting for all the domains to stop, we now use a poll/timeout loop
to check that all the domains are stopped.

The reason I added the poll/timeout is because on my 3.0_BETA machine,
some guest domains seem to get stuck in the "s" (shutdown) state and
never seem to get removed from the xend's domain list, so an:

        xm shutdown --halt --wait --all

was waiting forever and never returning.  I'm told that this was fixed
in -current, so I guess some pullups to the netbsd-3 branch are missing.
If anyone knows any more information about this issue, please let me
know.

I personally use the hook scripts to bind and unbind cgd(4) devices
that are used by each domain.  It's possible to run cgdconfig directly
from the domain configuration file since it's just a Python script,
but then it's not possible to enter passphrases.  Running cgdconfig
via the xendomains script doesn't have this problem.

I've added a giant comment block at the top of the xendomains script
to describe the variables that may be set in /etc/rc.conf.  Some
version of this script will eventually become part of the pkgsrc
sysutils/xentools20 package, so if you have any suggested improvements
or fixes, I'd love to hear them.

        Cheers,

        -- Johnny Lam <jlam%pkgsrc.org@localhost>
#!/bin/sh
#
# $NetBSD$
#
# PROVIDE: xendomains
# REQUIRE: xend
# KEYWORD: shutdown
#
# xendomains            This required variable is a whitespace-separated
#                       list of domains, e.g., xendomains="dom1 dom2 dom3".
#
# xendomains_config     This optional variable is a format string that
#                       represents the path to the configuration file for
#                       each domain.  "%s" is substituted with the name of
#                       the domain.  The default is "/usr/pkg/etc/xen/%s".
#
# xendomains_prehook    This optional variable is a format string that
#                       represents the command to run, if it exists, before
#                       starting each domain.  "%s" is substituted with the
#                       name of the domain.  The default is
#                       "/usr/pkg/etc/xen/%s-pre".
#
# xendomains_posthook   This optional variable is a format string that
#                       represents the command to run, if it exists, after
#                       stopping each domain.  "%s" is substituted with the
#                       name of the domain.  The default is
#                       "/usr/pkg/etc/xen/%s-post".
#

. /etc/rc.subr

name="xendomains"
ctl_command="/usr/pkg/sbin/xm"
start_cmd="xendomains_start"
stop_cmd="xendomains_stop"
list_cmd="xendomains_list"
extra_commands="list"

xendomains_start()
{
        [ -n "$xendomains" ] || return

        echo "Starting xen domains."
        for domain in $xendomains; do
                case "$domain" in
                "")     continue ;;
                esac

                # Start off by running the pre-hook script if it's present.
                if [ -n "${xendomains_prehook}" ]; then
                        cmdline=`printf "${xendomains_prehook}" $domain`
                        cmd="${cmdline%% *}"
                        if [ -x "$cmd" ]; then
                                $cmdline || echo "Pre-hook \`\`$cmdline'' 
failed... skipping $domain."
                                continue
                        fi
                fi

                # Ask xend to create the domain.
                if [ -n "${xendomains_config}" ]; then
                        file=`printf "${xendomains_config}" $domain`
                        if [ -f "$file" ]; then
                                ${ctl_command} create "$file"
                        fi
                fi
        done
}

xendomains_list() {
        # Output a whitespace-separated list of live guest domains.
        ${ctl_command} list | awk '
                (FNR <= 2) { next }
                ($5 !~ /s/) { s = s " " $1 }
                END { sub(" *", "", s); print s }'
}

xendomains_stop()
{
        # Determine an appropriate timeout waiting for all domains to
        # stop -- always wait at least 60s, and add 5s per active domain.
        #
        numdomains=$(xendomains_list | awk '{ print NF }')
        [ $numdomains -gt 0 ] || return
        timeout=$((60 + numdomains * 5))

        # Ask xend to stop every domain, and poll xend every 10s up to the
        # timeout period to check if all the domains are stopped.  We
        # consider a domain in the "s" (shutdown) state to be stopped.
        #
        echo "Stopping xen domains."
        ${ctl_command} shutdown --halt --all
        while [ $timeout -gt 0 ]; do
                livedomains=$(xendomains_list)
                [ -n "$livedomains" ] || break
                timeout=$((timeout - 10))
                sleep 10
        done
        livedomains=$(xendomains_list)
        if [ -n "$livedomains" ]; then
                echo "Failed to stop: $livedomains"
        else
                echo "All domains stopped."
        fi

        # Finish off by running the post-hook script if it's present.
        for domain in $xendomains; do
                case "$domain" in
                "")     continue ;;
                esac
                if [ -n "${xendomains_posthook}" ]; then
                        cmdline=`printf "${xendomains_posthook}" $domain`
                        cmd="${cmdline%% *}"
                        if [ -x "$cmd" ]; then
                                $cmdline || echo "Post-hook \`\`$cmdline'' 
failed."
                        fi
                fi
        done
}

load_rc_config $name

: ${xendomains_config="/usr/pkg/etc/xen/%s"}
: ${xendomains_prehook="/usr/pkg/etc/xen/%s-pre"}
: ${xendomains_posthook="/usr/pkg/etc/xen/%s-post"}

run_rc_command "$1"


Home | Main Index | Thread Index | Old Index