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