Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
--- xendomains.org 2008-04-27 22:37:02.000000000 +0900 +++ virtdomains 2008-05-05 07:43:07.000000000 +0900 @@ -1,6 +1,6 @@ #!/bin/bash # -# /etc/init.d/xendomains +# /etc/init.d/virtdomains # Start / stop domains automatically when domain 0 boots / shuts down. # # chkconfig: 345 99 00 @@ -14,8 +14,12 @@ # Applications HOWTO" by Avi Alkalay # # +# Revised by T.Nonogaki, Stray Penguin +# +# Rev.0.1.2 +# ### BEGIN INIT INFO -# Provides: xendomains +# Provides: virtdomains # Required-Start: $syslog $remote_fs xend # Should-Start: # Required-Stop: $syslog $remote_fs xend @@ -34,8 +38,8 @@ exit 0 fi -LOCKFILE=/var/lock/subsys/xendomains -XENDOM_CONFIG=/etc/sysconfig/xendomains +LOCKFILE=/var/lock/subsys/virtdomains +XENDOM_CONFIG=/etc/sysconfig/virtdomains test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing"; if [ "$1" = "stop" ]; then exit 0; @@ -66,8 +70,10 @@ #echo -n " [${_SMSG[${_RC_RV}]}] " if test ${_RC_RV} = 0; then success " [${_SMSG[${_RC_RV}]}] " + echo else failure " [${_SMSG[${_RC_RV}]}] " + echo fi } elif test -e /lib/lsb/init-functions; then @@ -128,7 +134,7 @@ } fi -if ! which usleep >&/dev/null +if ! which usleep &>/dev/null then usleep() { @@ -159,8 +165,8 @@ # read name from xen config file rdname() { - NM=$(xm create --quiet --dryrun --defconfig "$1" | - sed -n 's/^.*(name \(.*\))$/\1/p') + NM=$(env LANG=C virsh dominfo ${1##*/} 2>/dev/null | + awk '/^Name:[[:space:]]+/ { print $2; exit; }') } rdnames() @@ -182,10 +188,21 @@ parseln() { - name=`echo "$1" | cut -c0-17` + local numf + name=`echo "$@" | cut -c0-17` name=${name%% *} - rest=`echo "$1" | cut -c18- ` - read id mem cpu vcpu state tm < <(echo "$rest") + rest=`echo "$@" | cut -c18-` + numf=`echo $rest | wc -w` + if [ $numf -eq 5 ]; then + read id mem vcpu state tm < <(echo "$rest") + elif [ $numf -eq 4 ]; then + read mem vcpu state tm < <(echo "$rest") + id="" + else + read mem vcpu tm < <(echo "$rest") + id="" + state="" + fi } is_running() @@ -194,20 +211,41 @@ RC=1 while read LN; do parseln "$LN" - if test $id = 0; then continue; fi + if [ "$id" = "0" -o -z "$id" ]; then continue; fi case $name in - ($NM) + $NM) RC=0 + break ;; esac - done < <(xm list | grep -v '^Name') + done < <(xm list | grep -Ev 'Name[[:space:]]+ID') + return $RC +} + +is_running_by_virsh() +{ + rdname $1 + RC=1 + while read LN; do + read id name state < <(echo "$LN") + if [ "$id" = "0" -o "$state" = "shut off" ]; then continue; fi + case $name in + $NM) + RC=0 + break + ;; + esac + done < <(env LANG=C virsh list --all 2>/dev/null | + grep -E '^ +' | grep -Ev '^ *Id +Name') return $RC } start() { - if [ -f $LOCKFILE ]; then - echo -n "xendomains already running (lockfile exists)" + local RETVAL + if [ -f $LOCKFILE ]; then + echo -n "virtdomains already running (lockfile exists)" + rc_failed return; fi @@ -215,111 +253,170 @@ if [ "$XENDOMAINS_RESTORE" = "true" ] && contains_something "$XENDOMAINS_SAVE" then - mkdir -p $(dirname "$LOCKFILE") - touch $LOCKFILE - echo -n "Restoring Xen domains:" + [ -d $(dirname "$LOCKFILE") ] || + mkdir -p $(dirname "$LOCKFILE") + echo -n "Restoring Xen domains: " saved_domains=`ls $XENDOMAINS_SAVE` for dom in $XENDOMAINS_SAVE/*; do - echo -n " ${dom##*/}" - xm restore $dom - if [ $? -ne 0 ]; then - rc_failed $? + echo -n "${dom##*/} " + xm restore $dom &>/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL echo -n '!' else + touch $LOCKFILE # mv $dom ${dom%/*}/.${dom##*/} rm $dom fi + echo -n ". " done - echo . + HAVE_SAVE=1 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 + # We expect files for auto starting domains to be in XENDOMAINS_AUTO + # - each file name must match that of the domain but file itself can + # be empty - # Create all domains with config files in XENDOMAINS_AUTO. + # Create all domains with named 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. + [ $HAVE_SAVE -eq 1 ] && echo + echo -n "Starting auto Xen domains: " 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 + dom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p') + echo -n "$dom" + echo $saved_domains | grep -w $dom >/dev/null + if [ $? -eq 0 ]; then + echo -n "(skip)" + elif is_running $dom && is_running_by_virsh $dom; then echo -n "(skip)" else - xm create --quiet --defconfig $dom - if [ $? -ne 0 ]; then - rc_failed $? + echo -n " " + xm start $dom &>/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL echo -n '!' else + touch $LOCKFILE usleep $XENDOMAINS_CREATE_USLEEP fi + HAVE_AUTO=1 fi + echo -n ". " done + [ $HAVE_AUTO -eq 1 ] || echo fi } +# Return TRUE if it seems only zombie domains (not in shutdown process) +# are left, FALSE if no domains left or found any shutting-down healthily. all_zombies() { while read LN; do parseln "$LN" - if test $id = 0; then continue; fi + if [ "$id" = "0" -o -z "$id" ]; then continue; fi if test "$state" != "-b---d" -a "$state" != "-----d"; then - return 1; + return 1 fi - done < <(xm list | grep -v '^Name') + done < <(xm list | grep -Ev 'Name[[:space:]]+ID') return 0 } -# Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish; +# Return TRUE if it seems only zombie domains (not in shutdown process) +# left, FALSE if no domains left or found any shutting-down healthily. +# FIXME: State obtained via virsh is not so strict as xm. +# Are these check conditions correct? +all_zombies_by_virsh() +{ + local all=0 + local zomb=0 + while read LN; do + read id name state < <(echo "$LN") + if [ "$id" = "0" -o "$state" = "shut off" ]; then continue; fi + : $((all++)) + if test "$state" = "no state"; then + : $((zomb++)) + fi + done < <(env LANG=C virsh list --all 2>/dev/null | + grep -E '^ +' | grep -Ev '^ *Id +Name') + [ $all -eq 0 ] && return 1 + [ $all -eq $zomb ] && return 0 + return 1 +} + +# Call syntax: watchdog_xm -c $act {-d $dom|-f} +# Wait for max $XENDOMAINS_STOP_MAXWAIT for `xm $dom $id' 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). +# succeed within a finite amount of time; if $force (-f) 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() { + local act dom + local force=0 if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then exit fi - usleep 20000 + while getopts "c:d:f" opt; do + case $opt in + c) + act=$OPTARG;; + d) + dom=$OPTARG;; + f) + force=1 + dom=$XENDOMAINS_SHUTDOWN_ALL;; + esac + done + shift $(($OPTIND -1)) + usleep 300000 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 + PSAX=`ps axlw | grep "xm $act $dom" | grep -v grep` + [ -z "$PSAX" ] && exit echo -n "."; sleep 1 # go to kill immediately if there's only zombies left - if all_zombies && test -n "$2"; then break; fi + if [ $force -eq 1 ]; then + #if all_zombies || all_zombies_by_virsh; then + if all_zombies; then + #echo "Domain $dom seems zombie" + break + fi + fi done sleep 1 read PSF PSUID PSPID PSPPID < <(echo "$PSAX") - # kill xm $1 - kill $PSPID >/dev/null 2>&1 + # kill `xm $act $dom' process + kill $PSPID &>/dev/null + exit } stop() { + local RETVAL # Collect list of domains to shut down if test "$XENDOMAINS_AUTO_ONLY" = "true"; then rdnames fi - echo -n "Shutting down Xen domains:" + echo -n "Shutting down Xen domains: " while read LN; do parseln "$LN" - if test $id = 0; then continue; fi - echo -n " $name" + if [ "$id" = "0" -o -z "$id" ]; then continue; fi + echo -n "$name" if test "$XENDOMAINS_AUTO_ONLY" = "true"; then case $name in - ($NAMES) + $NAMES) # nothing ;; - (*) - echo -n "(skip)" + *) + echo "(skip). " continue ;; esac @@ -330,9 +427,10 @@ 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 $? + xm sysrq $id $sysrq &>/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL echo -n '!' fi # usleep just ignores empty arg @@ -340,67 +438,78 @@ done fi if test "$state" = "-b---d" -o "$state" = "-----d"; then - echo -n "(zomb)" + echo -n "(zomb). " continue fi if test -n "$XENDOMAINS_MIGRATE"; then echo -n "(migr)" - watchdog_xm migrate & + watchdog_xm -c migrate -d $name & WDOG_PID=$! - xm migrate $id $XENDOMAINS_MIGRATE - if test $? -ne 0; then - rc_failed $? - echo -n '!' - kill $WDOG_PID >/dev/null 2>&1 + xm migrate $name $XENDOMAINS_MIGRATE &>/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL + echo -n '!. ' + kill $WDOG_PID &>/dev/null else - kill $WDOG_PID >/dev/null 2>&1 + #kill $WDOG_PID &>/dev/null + echo -n ". " continue fi fi if test -n "$XENDOMAINS_SAVE"; then echo -n "(save)" - watchdog_xm save & + watchdog_xm -c save -d $name & 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 + xm save $name ${XENDOMAINS_SAVE}/$name &>/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL + echo -n '!. ' + kill $WDOG_PID &>/dev/null else - kill $WDOG_PID >/dev/null 2>&1 + #kill $WDOG_PID &>/dev/null + echo -n ". " continue fi fi if test -n "$XENDOMAINS_SHUTDOWN"; then # XENDOMAINS_SHUTDOWN should be "--halt --wait" echo -n "(shut)" - watchdog_xm shutdown & + watchdog_xm -c shutdown -d $name & WDOG_PID=$! - xm shutdown $id $XENDOMAINS_SHUTDOWN - if test $? -ne 0; then - rc_failed $? + xm shutdown $name $XENDOMAINS_SHUTDOWN &>/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL echo -n '!' + kill $WDOG_PID &>/dev/null fi - kill $WDOG_PID >/dev/null 2>&1 + echo -n ". " fi - done < <(xm list | grep -v '^Name') + done < <(xm list | grep -Ev 'Name[[:space:]]+ID') # 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 '!' + if test -n "$XENDOMAINS_SHUTDOWN_ALL"; then + #if ! all_zombies && ! all_zombies_by_virsh; then + if ! all_zombies; then + # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait" + echo + echo -n "SHUTDOWN_ALL " + watchdog_xm -c shutdown -f & + WDOG_PID=$! + xm shutdown $XENDOMAINS_SHUTDOWN_ALL >/dev/null + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + rc_failed $RETVAL + echo -n '!' + kill $WDOG_PID >/dev/null 2>&1 + fi fi - kill $WDOG_PID >/dev/null 2>&1 fi # Unconditionally delete lock file @@ -411,13 +520,13 @@ { while read LN; do parseln "$LN" - if test $id = 0; then continue; fi + if [ "$id" = "0" -o -z "$id" ]; then continue; fi case $name in - ($1) + $1) return 0 ;; esac - done < <(xm list | grep -v "^Name") + done < <(xm list | grep -Ev 'Name[[:space:]]+ID') return 1 } @@ -464,7 +573,9 @@ restart() { stop + rc_status -v start + rc_status } reload() @@ -472,6 +583,8 @@ restart } +HAVE_SAVE=0 +HAVE_AUTO=0 case "$1" in start)