ia64/xen-unstable

view tools/examples/init.d/xendomains @ 14185:d2646466e0a7

Fix init.d/xendomains startup script so log_error and log_success
will also work on redhat-based distributions before RHEL 5. See
discussion "xendomains init script" about a year ago on xen-devel.

Signed-off-by: Florian Kirstein <ray@ray.net>
author kfraser@localhost.localdomain
date Wed Feb 28 18:06:56 2007 +0000 (2007-02-28)
parents a330509abb20
children 865c4ae59be3
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 name=`echo "$1" | cut -c0-17`
186 name=${name%% *}
187 rest=`echo "$1" | cut -c18- `
188 read id mem cpu vcpu state tm < <(echo "$rest")
189 }
191 is_running()
192 {
193 rdname $1
194 RC=1
195 while read LN; do
196 parseln "$LN"
197 if test $id = 0; then continue; fi
198 case $name in
199 ($NM)
200 RC=0
201 ;;
202 esac
203 done < <(xm list | grep -v '^Name')
204 return $RC
205 }
207 start()
208 {
209 if [ -f $LOCKFILE ]; then
210 echo -n "xendomains already running (lockfile exists)"
211 return;
212 fi
214 saved_domains=" "
215 if [ "$XENDOMAINS_RESTORE" = "true" ] &&
216 contains_something "$XENDOMAINS_SAVE"
217 then
218 mkdir -p $(dirname "$LOCKFILE")
219 touch $LOCKFILE
220 echo -n "Restoring Xen domains:"
221 saved_domains=`ls $XENDOMAINS_SAVE`
222 for dom in $XENDOMAINS_SAVE/*; do
223 echo -n " ${dom##*/}"
224 xm restore $dom
225 if [ $? -ne 0 ]; then
226 rc_failed $?
227 echo -n '!'
228 else
229 # mv $dom ${dom%/*}/.${dom##*/}
230 rm $dom
231 fi
232 done
233 echo .
234 fi
236 if contains_something "$XENDOMAINS_AUTO"
237 then
238 touch $LOCKFILE
239 echo -n "Starting auto Xen domains:"
240 # We expect config scripts for auto starting domains to be in
241 # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
243 # Create all domains with config files in XENDOMAINS_AUTO.
244 # TODO: We should record which domain name belongs
245 # so we have the option to selectively shut down / migrate later
246 # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
247 # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't
248 # restore correctly it requires administrative attention.
249 for dom in $XENDOMAINS_AUTO/*; do
250 echo -n " ${dom##*/}"
251 shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
252 echo $saved_domains | grep -w $shortdom > /dev/null
253 if [ $? -eq 0 ] || is_running $dom; then
254 echo -n "(skip)"
255 else
256 xm create --quiet --defconfig $dom
257 if [ $? -ne 0 ]; then
258 rc_failed $?
259 echo -n '!'
260 else
261 usleep $XENDOMAINS_CREATE_USLEEP
262 fi
263 fi
264 done
265 fi
266 }
268 all_zombies()
269 {
270 while read LN; do
271 parseln "$LN"
272 if test $id = 0; then continue; fi
273 if test "$state" != "-b---d" -a "$state" != "-----d"; then
274 return 1;
275 fi
276 done < <(xm list | grep -v '^Name')
277 return 0
278 }
280 # Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
281 # if it has not exited by that time kill it, so the init script will
282 # succeed within a finite amount of time; if $2 is nonnull, it will
283 # kill the command as well as soon as no domain (except for zombies)
284 # are left (used for shutdown --all).
285 watchdog_xm()
286 {
287 if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
288 exit
289 fi
290 usleep 20000
291 for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
292 # exit if xm save/migrate/shutdown is finished
293 PSAX=`ps axlw | grep "xm $1" | grep -v grep`
294 if test -z "$PSAX"; then exit; fi
295 echo -n "."; sleep 1
296 # go to kill immediately if there's only zombies left
297 if all_zombies && test -n "$2"; then break; fi
298 done
299 sleep 1
300 read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
301 # kill xm $1
302 kill $PSPID >/dev/null 2>&1
303 }
305 stop()
306 {
307 # Collect list of domains to shut down
308 if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
309 rdnames
310 fi
311 echo -n "Shutting down Xen domains:"
312 while read LN; do
313 parseln "$LN"
314 if test $id = 0; then continue; fi
315 echo -n " $name"
316 if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
317 case $name in
318 ($NAMES)
319 # nothing
320 ;;
321 (*)
322 echo -n "(skip)"
323 continue
324 ;;
325 esac
326 fi
327 # XENDOMAINS_SYSRQ chould be something like just "s"
328 # or "s e i u" or even "s e s i u o"
329 # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
330 if test -n "$XENDOMAINS_SYSRQ"; then
331 for sysrq in $XENDOMAINS_SYSRQ; do
332 echo -n "(SR-$sysrq)"
333 xm sysrq $id $sysrq
334 if test $? -ne 0; then
335 rc_failed $?
336 echo -n '!'
337 fi
338 # usleep just ignores empty arg
339 usleep $XENDOMAINS_USLEEP
340 done
341 fi
342 if test "$state" = "-b---d" -o "$state" = "-----d"; then
343 echo -n "(zomb)"
344 continue
345 fi
346 if test -n "$XENDOMAINS_MIGRATE"; then
347 echo -n "(migr)"
348 watchdog_xm migrate &
349 WDOG_PID=$!
350 xm migrate $id $XENDOMAINS_MIGRATE
351 if test $? -ne 0; then
352 rc_failed $?
353 echo -n '!'
354 kill $WDOG_PID >/dev/null 2>&1
355 else
356 kill $WDOG_PID >/dev/null 2>&1
357 continue
358 fi
359 fi
360 if test -n "$XENDOMAINS_SAVE"; then
361 echo -n "(save)"
362 watchdog_xm save &
363 WDOG_PID=$!
364 mkdir -p "$XENDOMAINS_SAVE"
365 xm save $id $XENDOMAINS_SAVE/$name
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_SHUTDOWN"; then
376 # XENDOMAINS_SHUTDOWN should be "--halt --wait"
377 echo -n "(shut)"
378 watchdog_xm shutdown &
379 WDOG_PID=$!
380 xm shutdown $id $XENDOMAINS_SHUTDOWN
381 if test $? -ne 0; then
382 rc_failed $?
383 echo -n '!'
384 fi
385 kill $WDOG_PID >/dev/null 2>&1
386 fi
387 done < <(xm list | grep -v '^Name')
389 # NB. this shuts down ALL Xen domains (politely), not just the ones in
390 # AUTODIR/*
391 # This is because it's easier to do ;-) but arguably if this script is run
392 # on system shutdown then it's also the right thing to do.
393 if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
394 # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
395 echo -n " SHUTDOWN_ALL "
396 watchdog_xm shutdown 1 &
397 WDOG_PID=$!
398 xm shutdown $XENDOMAINS_SHUTDOWN_ALL
399 if test $? -ne 0; then
400 rc_failed $?
401 echo -n '!'
402 fi
403 kill $WDOG_PID >/dev/null 2>&1
404 fi
406 # Unconditionally delete lock file
407 rm -f $LOCKFILE
408 }
410 check_domain_up()
411 {
412 while read LN; do
413 parseln "$LN"
414 if test $id = 0; then continue; fi
415 case $name in
416 ($1)
417 return 0
418 ;;
419 esac
420 done < <(xm list | grep -v "^Name")
421 return 1
422 }
424 check_all_auto_domains_up()
425 {
426 if ! contains_something "$XENDOMAINS_AUTO"
427 then
428 return 0
429 fi
430 missing=
431 for nm in $XENDOMAINS_AUTO/*; do
432 rdname $nm
433 found=0
434 if check_domain_up "$NM"; then
435 echo -n " $name"
436 else
437 missing="$missing $NM"
438 fi
439 done
440 if test -n "$missing"; then
441 echo -n " MISS AUTO:$missing"
442 return 1
443 fi
444 return 0
445 }
447 check_all_saved_domains_up()
448 {
449 if ! contains_something "$XENDOMAINS_SAVE"
450 then
451 return 0
452 fi
453 missing=`/bin/ls $XENDOMAINS_SAVE`
454 echo -n " MISS SAVED: " $missing
455 return 1
456 }
458 # This does NOT necessarily restart all running domains: instead it
459 # stops all running domains and then boots all the domains specified in
460 # AUTODIR. If other domains have been started manually then they will
461 # not get restarted.
462 # Commented out to avoid confusion!
464 restart()
465 {
466 stop
467 start
468 }
470 reload()
471 {
472 restart
473 }
476 case "$1" in
477 start)
478 start
479 rc_status
480 if test -f $LOCKFILE; then rc_status -v; fi
481 ;;
483 stop)
484 stop
485 rc_status -v
486 ;;
488 restart)
489 restart
490 ;;
491 reload)
492 reload
493 ;;
495 status)
496 echo -n "Checking for xendomains:"
497 if test ! -f $LOCKFILE; then
498 rc_failed 3
499 else
500 check_all_auto_domains_up
501 rc_status
502 check_all_saved_domains_up
503 rc_status
504 fi
505 rc_status -v
506 ;;
508 *)
509 echo "Usage: $0 {start|stop|restart|reload|status}"
510 rc_failed 3
511 rc_status -v
512 ;;
513 esac
515 rc_exit