~ubuntu-branches/ubuntu/trusty/xen-common/trusty

« back to all changes in this revision

Viewing changes to tools/examples/init.d/xendomains

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2009-11-22 16:51:53 UTC
  • mfrom: (5.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20091122165153-d36l98kbx8a930h2
Tags: 3.4.2-2
* Redefine Xen version tests to allow detection of bare metal.
  (closes: #556859)
* Support oldstyle Xen kernel without xenfs. (closes: #557151)
* Use debhelper compat level 7.
* Remove oldstable-only conflicts.
* Add wrapper for xenpm.

Show diffs side-by-side

added added

removed removed

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