source: trunk/packages/xen-common/xen-common/debian/xen-utils-common.xendomains.init @ 77

Last change on this file since 77 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 9.3 KB
Line 
1#!/bin/bash
2### BEGIN INIT INFO
3# Provides:          xendomains
4# Required-Start:    $syslog $remote_fs xend
5# Should-Start:
6# Required-Stop:     $syslog $remote_fs xend
7# Should-Stop:
8# Default-Start:     2 3 4 5
9# Default-Stop:      S 0 1 6
10# Default-Enabled:   yes
11# Short-Description: Start/stop secondary xen domains
12# Description:       Start / stop domains automatically when domain 0
13#                    boots / shuts down.
14### END INIT INFO
15
16PATH=/usr/lib/xen-common/bin:/sbin:/bin:/usr/sbin:/usr/bin
17VERSION=$(xen-utils-version -q 2>/dev/null || true)
18ROOT=/usr/lib/xen-$VERSION
19
20test "$VERSION" || exit 0
21test -e /proc/xen/privcmd || exit 0
22grep -q "control_d" /proc/xen/capabilities || exit 0
23
24LOCKFILE=/var/lock/xendomains
25XENDOM_CONFIG=/etc/default/xendomains
26
27test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
28        if [ "$1" = "stop" ]; then exit 0;
29        else exit 6; fi; }
30
31. $XENDOM_CONFIG
32
33_cmd=$1
34declare -a _SMSG
35if test "${_cmd}" = "status"; then
36    _SMSG=(running dead dead unused unknown)
37    _RC_UNUSED=3
38else
39    _SMSG=(done failed failed missed failed skipped unused failed failed)
40    _RC_UNUSED=6
41fi
42. /lib/lsb/init-functions
43echo_rc()
44{
45    if test ${_RC_RV} = 0; then
46        log_success_msg "  [${_SMSG[${_RC_RV}]}] "
47    else
48        log_failure_msg "  [${_SMSG[${_RC_RV}]}] "
49    fi
50}
51rc_reset() { _RC_RV=0; }
52rc_failed()
53{
54    if test -z "$1"; then
55        _RC_RV=1;
56    elif test "$1" != "0"; then
57        _RC_RV=$1;
58    fi
59    return ${_RC_RV}
60}
61rc_check()
62{
63    return rc_failed $?
64}       
65rc_status()
66{
67    rc_failed $?
68    if test "$1" = "-r"; then _RC_RV=0; shift; fi
69    if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi
70    if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed 3; shift; fi
71    if test "$1" = "-v"; then echo_rc; shift; fi
72    if test "$1" = "-r"; then _RC_RV=0; shift; fi
73    return ${_RC_RV}
74}
75rc_exit() { exit ${_RC_RV}; }
76
77if ! which usleep >&/dev/null
78then
79  usleep()
80  {
81    if [ -n "$1" ]
82    then
83      sleep $(( $1 / 1000000 ))
84    fi
85  }
86fi
87
88# Reset status of this service
89rc_reset
90
91##
92# Returns 0 (success) if the given parameter names a directory, and that
93# directory is not empty.
94#
95contains_something()
96{
97  if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]
98  then
99    return 0
100  else
101    return 1
102  fi
103}
104
105# read name from xen config file
106rdname()
107{
108    NM=$(xm create --quiet --dryrun --defconfig "$1" |
109         sed -n 's/^.*(name \(.*\))$/\1/p')
110}
111
112rdnames()
113{
114    NAMES=
115    if ! contains_something "$XENDOMAINS_AUTO"
116    then
117        return
118    fi
119    for dom in $XENDOMAINS_AUTO/*; do
120        rdname $dom
121        if test -z $NAMES; then
122            NAMES=$NM;
123        else
124            NAMES="$NAMES|$NM"
125        fi
126    done
127}
128
129parseln()
130{
131    name=`echo $1 | cut -d\  -f1`
132    name=${name%% *}
133    rest=`echo $1 | cut -d\  -f2-`
134    read id mem cpu vcpu state tm < <(echo "$rest")
135}
136
137is_running()
138{
139    rdname $1
140    RC=1
141    while read LN; do
142        parseln "$LN"
143        if test $id = 0; then continue; fi
144        case $name in
145            ($NM)
146                RC=0
147                ;;
148        esac
149    done < <(xm list | tail -n +2)
150    return $RC
151}
152
153start() 
154{
155    if [ -f $LOCKFILE ]; then
156        echo -n "xendomains already running (lockfile exists)"
157        return;
158    fi
159
160    if [ "$XENDOMAINS_RESTORE" = "true" ] &&
161       contains_something "$XENDOMAINS_SAVE"
162    then
163        mkdir -p $(dirname "$LOCKFILE")
164        touch $LOCKFILE
165        echo -n "Restoring Xen domains:"
166        for dom in $XENDOMAINS_SAVE/*; do
167            echo -n " ${dom##*/}"
168            xm restore $dom
169            if [ $? -ne 0 ]; then
170                rc_failed $?
171                echo -n '!'
172            else
173                # mv $dom ${dom%/*}/.${dom##*/}
174                rm $dom
175            fi
176        done
177        echo .
178    fi
179
180    if contains_something "$XENDOMAINS_AUTO"
181    then
182        touch $LOCKFILE
183        echo -n "Starting auto Xen domains:"
184        # We expect config scripts for auto starting domains to be in
185        # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
186
187        # Create all domains with config files in XENDOMAINS_AUTO.
188        # TODO: We should record which domain name belongs
189        # so we have the option to selectively shut down / migrate later
190        for dom in $XENDOMAINS_AUTO/*; do
191            echo -n " ${dom##*/}"
192            if is_running $dom; then
193                echo -n "(skip)"
194            else
195                xm create --quiet --defconfig $dom
196                if [ $? -ne 0 ]; then
197                    rc_failed $?
198                    echo -n '!'
199                else
200                    usleep $XENDOMAINS_CREATE_USLEEP
201                fi
202            fi
203        done
204    fi 
205}
206
207all_zombies()
208{
209    while read LN; do
210        parseln "$LN"
211        if test $id = 0; then continue; fi
212        if test "$state" != "-b---d" -a "$state" != "-----d"; then
213            return 1;
214        fi
215    done < <(xm list | tail -n +2)
216    return 0
217}
218
219# Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
220# if it has not exited by that time kill it, so the init script will
221# succeed within a finite amount of time; if $2 is nonnull, it will
222# kill the command as well as soon as no domain (except for zombies)
223# are left (used for shutdown --all).
224watchdog_xm()
225{
226    if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
227        exit
228    fi
229    usleep 20000
230    for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
231        # exit if xm save/migrate/shutdown is finished
232        PSAX=`ps axlw | grep "xm $1" | grep -v grep`
233        if test -z "$PSAX"; then exit; fi
234        echo -n "."; sleep 1
235        # go to kill immediately if there's only zombies left
236        if all_zombies && test -n "$2"; then break; fi
237    done
238    sleep 1
239    read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
240    # kill xm $1
241    kill $PSPID >/dev/null 2>&1
242}
243
244stop()
245{
246    # Collect list of domains to shut down
247    if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
248        rdnames
249    fi
250    echo -n "Shutting down Xen domains:"
251    while read LN; do
252        parseln "$LN"
253        if test $id = 0; then continue; fi
254        echo -n " $name"
255        if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
256            case $name in
257                ($NAMES)
258                    # nothing
259                    ;;
260                (*)
261                    echo -n "(skip)"
262                    continue
263                    ;;
264            esac
265        fi
266        # XENDOMAINS_SYSRQ chould be something like just "s"
267        # or "s e i u" or even "s e s i u o"
268        # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
269        if test -n "$XENDOMAINS_SYSRQ"; then
270            for sysrq in $XENDOMAINS_SYSRQ; do
271                echo -n "(SR-$sysrq)"
272                xm sysrq $id $sysrq
273                if test $? -ne 0; then
274                    rc_failed $?
275                    echo -n '!'
276                fi
277                # usleep just ignores empty arg
278                usleep $XENDOMAINS_USLEEP
279            done
280        fi
281        if test "$state" = "-b---d" -o "$state" = "-----d"; then
282            echo -n "(zomb)"
283            continue
284        fi
285        if test -n "$XENDOMAINS_MIGRATE"; then
286            echo -n "(migr)"
287            watchdog_xm migrate &
288            WDOG_PID=$!
289            xm migrate $id $XENDOMAINS_MIGRATE
290            if test $? -ne 0; then
291                rc_failed $?
292                echo -n '!'
293                kill $WDOG_PID >/dev/null 2>&1
294            else
295                kill $WDOG_PID >/dev/null 2>&1
296                continue
297            fi
298        fi
299        if test -n "$XENDOMAINS_SAVE"; then
300            echo -n "(save)"
301            watchdog_xm save &
302            WDOG_PID=$!
303            mkdir -p "$XENDOMAINS_SAVE"
304            xm save $id $XENDOMAINS_SAVE/$name
305            if test $? -ne 0; then
306                rc_failed $?
307                echo -n '!'
308                kill $WDOG_PIG >/dev/null 2>&1
309            else
310                kill $WDOG_PIG >/dev/null 2>&1
311                continue
312            fi
313        fi
314        if test -n "$XENDOMAINS_SHUTDOWN"; then
315            # XENDOMAINS_SHUTDOWN should be "--halt --wait"
316            echo -n "(shut)"
317            watchdog_xm shutdown &
318            WDOG_PID=$!
319            xm shutdown $id $XENDOMAINS_SHUTDOWN
320            if test $? -ne 0; then
321                rc_failed $?
322                echo -n '!'
323            fi
324            kill $WDOG_PIG >/dev/null 2>&1
325        fi
326    done < <(xm list | tail -n +2)
327
328    # NB. this shuts down ALL Xen domains (politely), not just the ones in
329    # AUTODIR/*
330    # This is because it's easier to do ;-) but arguably if this script is run
331    # on system shutdown then it's also the right thing to do.
332    if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
333        # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
334        echo -n " SHUTDOWN_ALL "
335        watchdog_xm shutdown 1 &
336        WDOG_PID=$!
337        xm shutdown $XENDOMAINS_SHUTDOWN_ALL
338        if test $? -ne 0; then
339            rc_failed $?
340            echo -n '!'
341        fi
342        kill $WDOG_PID >/dev/null 2>&1
343    fi
344
345    # Unconditionally delete lock file
346    rm -f $LOCKFILE
347}
348
349check_domain_up()
350{
351    while read LN; do
352        parseln "$LN"
353        if test $id = 0; then continue; fi
354        case $name in
355            ($1)
356                return 0
357                ;;
358        esac
359    done < <(xm list | tail -n +2)
360    return 1
361}
362
363check_all_auto_domains_up()
364{
365    if ! contains_something "$XENDOMAINS_AUTO"
366    then
367      return 0
368    fi
369    missing=
370    for nm in $XENDOMAINS_AUTO/*; do
371        rdname $nm
372        found=0
373        if check_domain_up "$NM"; then
374            echo -n " $name"
375        else
376            missing="$missing $NM"
377        fi
378    done
379    if test -n "$missing"; then
380        echo -n " MISS AUTO:$missing"
381        return 1
382    fi
383    return 0
384}
385
386check_all_saved_domains_up()
387{
388    if ! contains_something "$XENDOMAINS_SAVE" 
389    then
390      return 0
391    fi
392    missing=`/bin/ls $XENDOMAINS_SAVE`
393    echo -n " MISS SAVED: " $missing
394    return 1
395}
396
397# This does NOT necessarily restart all running domains: instead it
398# stops all running domains and then boots all the domains specified in
399# AUTODIR.  If other domains have been started manually then they will
400# not get restarted.
401# Commented out to avoid confusion!
402
403restart()
404{
405    stop
406    start
407}
408
409reload()
410{
411    restart
412}
413
414
415case "$1" in
416    start)
417        start
418        rc_status
419        if test -f $LOCKFILE; then rc_status -v; fi
420        ;;
421
422    stop)
423        stop
424        rc_status -v
425        ;;
426
427    restart)
428        restart
429        ;;
430    force-reload|reload)
431        reload
432        ;;
433
434    status)
435        echo -n "Checking for xendomains:" 
436        if test ! -f $LOCKFILE; then
437            rc_failed 3
438        else
439            check_all_auto_domains_up
440            rc_status
441            check_all_saved_domains_up
442            rc_status
443        fi
444        rc_status -v
445        ;;
446
447    *)
448        echo "Usage: $0 {start|stop|restart|reload|force-reload|status}"
449        rc_failed 3
450        rc_status -v
451        ;;
452esac
453
454rc_exit
Note: See TracBrowser for help on using the repository browser.