ia64/xen-unstable

view tools/hotplug/Linux/init.d/xendomains @ 19793:8018f09ef039

xendomains script: Small fix

From: Fabian Zimmermann <xen-users@z-technologies.de>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 18 10:26:28 2009 +0100 (2009-06-18)
parents cb8ece5d7647
children
line source
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
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
37 LOCKFILE=/var/lock/subsys/xendomains
38 XENDOM_CONFIG=/etc/sysconfig/xendomains
40 test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
41 if [ "$1" = "stop" ]; then exit 0;
42 else exit 6; fi; }
44 . $XENDOM_CONFIG
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
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
142 # Reset status of this service
143 rc_reset
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 }
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 }
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 }
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
193 [ -n "$name" -a -n "$id" ] && return 0 || return 1
194 }
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 }
213 start()
214 {
215 if [ -f $LOCKFILE ]; then
216 echo -e "xendomains already running (lockfile exists)"
217 return;
218 fi
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 XMR=`xm restore $dom 2>&1 1>/dev/null`
234 #xm restore $dom
235 if [ $? -ne 0 ]; then
236 echo -e "\nAn error occurred while restoring domain ${dom##*/}:\n$XMR"
237 rc_failed $?
238 echo -e '!'
239 else
240 # mv $dom ${dom%/*}/.${dom##*/}
241 rm $dom
242 fi
243 fi
244 fi
245 done
246 echo -e
247 fi
249 if contains_something "$XENDOMAINS_AUTO"
250 then
251 touch $LOCKFILE
252 echo -n "Starting auto Xen domains:"
253 # We expect config scripts for auto starting domains to be in
254 # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
256 # Create all domains with config files in XENDOMAINS_AUTO.
257 # TODO: We should record which domain name belongs
258 # so we have the option to selectively shut down / migrate later
259 # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
260 # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't
261 # restore correctly it requires administrative attention.
262 for dom in $XENDOMAINS_AUTO/*; do
263 echo -n " ${dom##*/}"
264 shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
265 echo $saved_domains | grep -w $shortdom > /dev/null
266 if [ $? -eq 0 ] || is_running $dom; then
267 echo -n "(skip)"
268 else
269 XMC=`xm create --quiet --defconfig $dom`
270 if [ $? -ne 0 ]; then
271 echo -e "\nAn error occurred while creating domain ${dom##*/}: $XMC\n"
272 rc_failed $?
273 echo -e '!'
274 else
275 usleep $XENDOMAINS_CREATE_USLEEP
276 fi
277 fi
278 done
279 fi
280 }
282 all_zombies()
283 {
284 name=;id=
285 while read LN; do
286 parseln "$LN" || continue
287 if test $id = 0; then continue; fi
288 if test "$state" != "-b---d" -a "$state" != "-----d"; then
289 return 1;
290 fi
291 done < <(xm list -l | grep '(\(domain\|domid\|name\)')
292 return 0
293 }
295 # Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
296 # if it has not exited by that time kill it, so the init script will
297 # succeed within a finite amount of time; if $2 is nonnull, it will
298 # kill the command as well as soon as no domain (except for zombies)
299 # are left (used for shutdown --all). Third parameter, if any, suppresses
300 # output of dots per working state (formatting issues)
301 watchdog_xm()
302 {
303 if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
304 exit
305 fi
307 usleep 20000
308 for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
309 # exit if xm save/migrate/shutdown is finished
310 PSAX=`ps axlw | grep "xm $1" | grep -v grep`
311 if test -z "$PSAX"; then exit; fi
312 if ! test -n "$3"; then echo -n '.'; fi
313 sleep 1
314 # go to kill immediately if there's only zombies left
315 if all_zombies && test -n "$2"; then break; fi
316 done
317 sleep 1
318 read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
319 # kill xm $1
320 kill $PSPID >/dev/null 2>&1
322 echo -e .
323 }
325 stop()
326 {
327 exec 3>&2 2> /dev/null
329 # Collect list of domains to shut down
330 if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
331 rdnames
332 fi
333 echo -n "Shutting down Xen domains:"
334 name=;id=
335 while read LN; do
336 parseln "$LN" || continue
337 if test $id = 0; then continue; fi
338 echo -n " $name"
339 if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
340 eval "
341 case \"\$name\" in
342 ($NAMES)
343 # nothing
344 ;;
345 (*)
346 echo -e '(skip)'
347 continue
348 ;;
349 esac
350 "
351 fi
352 # XENDOMAINS_SYSRQ chould be something like just "s"
353 # or "s e i u" or even "s e s i u o"
354 # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
355 if test -n "$XENDOMAINS_SYSRQ"; then
356 for sysrq in $XENDOMAINS_SYSRQ; do
357 echo -n "(SR-$sysrq)"
358 XMR=`xm sysrq $id $sysrq 2>&1 1>/dev/null`
359 if test $? -ne 0; then
360 echo -e "\nAn error occurred while doing sysrq on domain:\n$XMR\n"
361 rc_failed $?
362 echo -n '!'
363 fi
364 # usleep just ignores empty arg
365 usleep $XENDOMAINS_USLEEP
366 done
367 fi
368 if test "$state" = "-b---d" -o "$state" = "-----d"; then
369 echo -n "(zomb)"
370 continue
371 fi
372 if test -n "$XENDOMAINS_MIGRATE"; then
373 echo -n "(migr)"
374 watchdog_xm migrate &
375 WDOG_PID=$!
376 XMR=`xm migrate $id $XENDOMAINS_MIGRATE 2>&1 1>/dev/null`
377 if test $? -ne 0; then
378 echo -e "\nAn error occurred while migrating domain:\n$XMR\n"
379 rc_failed $?
380 echo -e '!'
382 kill $WDOG_PID >/dev/null 2>&1
383 else
384 kill $WDOG_PID >/dev/null 2>&1
386 echo -e .
387 usleep 1000
388 continue
389 fi
390 fi
391 if test -n "$XENDOMAINS_SAVE"; then
392 echo -n "(save)"
393 watchdog_xm save &
394 WDOG_PID=$!
395 mkdir -p "$XENDOMAINS_SAVE"
396 XMR=`xm save $id $XENDOMAINS_SAVE/$name 2>&1 1>/dev/null`
397 if test $? -ne 0; then
398 echo -e "\nAn error occurred while saving domain:\n$XMR\n"
399 rc_failed $?
400 echo -e '!'
401 kill $WDOG_PID >/dev/null 2>&1
402 else
403 kill $WDOG_PID >/dev/null 2>&1
404 echo -e .
405 usleep 1000
406 continue
407 fi
408 fi
409 if test -n "$XENDOMAINS_SHUTDOWN"; then
410 # XENDOMAINS_SHUTDOWN should be "--halt --wait"
411 echo -n "(shut)"
412 watchdog_xm shutdown &
413 WDOG_PID=$!
414 XMR=`xm shutdown $id $XENDOMAINS_SHUTDOWN 2>&1 1>/dev/null`
415 if test $? -ne 0; then
416 echo -e "\nAn error occurred while shutting down domain:\n$XMR\n"
417 rc_failed $?
418 echo -e '!'
419 fi
420 kill $WDOG_PID >/dev/null 2>&1
421 fi
422 done < <(xm list -l | grep '(\(domain\|domid\|name\)')
424 # NB. this shuts down ALL Xen domains (politely), not just the ones in
425 # AUTODIR/*
426 # This is because it's easier to do ;-) but arguably if this script is run
427 # on system shutdown then it's also the right thing to do.
428 if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
429 # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
430 echo -n " SHUTDOWN_ALL "
431 watchdog_xm shutdown 1 false &
432 WDOG_PID=$!
433 XMR=`xm shutdown $XENDOMAINS_SHUTDOWN_ALL 2>&1 1>/dev/null`
434 if test $? -ne 0; then
435 echo -e "\nAn error occurred while shutting down all domains: $XMR\n"
436 rc_failed $?
437 echo -e '!'
438 fi
439 kill $WDOG_PID >/dev/null 2>&1
440 fi
442 # Unconditionally delete lock file
443 rm -f $LOCKFILE
445 exec 2>&3
446 }
448 check_domain_up()
449 {
450 name=;id=
451 while read LN; do
452 parseln "$LN" || continue
453 if test $id = 0; then continue; fi
454 case $name in
455 ($1)
456 return 0
457 ;;
458 esac
459 done < <(xm list -l | grep '(\(domain\|domid\|name\)')
460 return 1
461 }
463 check_all_auto_domains_up()
464 {
465 if ! contains_something "$XENDOMAINS_AUTO"
466 then
467 return 0
468 fi
469 missing=
470 for nm in $XENDOMAINS_AUTO/*; do
471 rdname $nm
472 found=0
473 if check_domain_up "$NM"; then
474 echo -n " $name"
475 else
476 missing="$missing $NM"
477 fi
478 done
479 if test -n "$missing"; then
480 echo -n " MISS AUTO:$missing"
481 return 1
482 fi
483 return 0
484 }
486 check_all_saved_domains_up()
487 {
488 if ! contains_something "$XENDOMAINS_SAVE"
489 then
490 return 0
491 fi
492 missing=`/bin/ls $XENDOMAINS_SAVE`
493 echo -n " MISS SAVED: " $missing
494 return 1
495 }
497 # This does NOT necessarily restart all running domains: instead it
498 # stops all running domains and then boots all the domains specified in
499 # AUTODIR. If other domains have been started manually then they will
500 # not get restarted.
501 # Commented out to avoid confusion!
503 restart()
504 {
505 stop
506 start
507 }
509 reload()
510 {
511 restart
512 }
515 case "$1" in
516 start)
517 start
518 rc_status
519 if test -f $LOCKFILE; then rc_status -v; fi
520 ;;
522 stop)
523 stop
524 rc_status -v
525 ;;
527 restart)
528 restart
529 ;;
530 reload)
531 reload
532 ;;
534 status)
535 echo -n "Checking for xendomains:"
536 if test ! -f $LOCKFILE; then
537 rc_failed 3
538 else
539 check_all_auto_domains_up
540 rc_status
541 check_all_saved_domains_up
542 rc_status
543 fi
544 rc_status -v
545 ;;
547 *)
548 echo "Usage: $0 {start|stop|restart|reload|status}"
549 rc_failed 3
550 rc_status -v
551 ;;
552 esac
554 rc_exit