]> git.pld-linux.org Git - packages/xen.git/blob - xendomains.init
- rel 3
[packages/xen.git] / xendomains.init
1 #!/bin/sh
2 #
3 # xendomains            Start / stop domains automatically when domain 0 boots / shuts down.
4 #
5 # chkconfig:            345 99 00
6 # description:          Start / stop Xen domains.
7 #
8 # This script offers fairly basic functionality.  It should work on Redhat
9 # but also on LSB-compliant SuSE releases and on Debian with the LSB package
10 # installed.  (LSB is the Linux Standard Base)
11 #
12 # Based on the example in the "Designing High Quality Integrated Linux
13 # Applications HOWTO" by Avi Alkalay
14 # <http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/>
15 #
16 ### BEGIN INIT INFO
17 # Provides:          xendomains
18 # Required-Start:    $syslog $remote_fs xenstored xenconsoled
19 # Should-Start:      xend
20 # Required-Stop:     $syslog $remote_fs xenstored xenconsoled
21 # Should-Stop:       xend
22 # Default-Start:     2 3 4 5
23 # Default-Stop:      0 1 6
24 # Short-Description: Start/stop secondary xen domains
25 # Description:       Start / stop domains automatically when domain 0 
26 #                    boots / shuts down.
27 ### END INIT INFO
28
29 . /etc/rc.d/init.d/functions
30
31 CMD=xm
32 $CMD list >/dev/null 2>/dev/null || CMD=xl
33 $CMD list >/dev/null 2>/dev/null || exit 0
34
35 [ -e /proc/xen/privcmd ] || exit 0
36
37 if [ -r /etc/sysconfig/xendomains ]; then
38         . /etc/sysconfig/xendomains
39 else
40         echo "/etc/sysconfig/xendomains does not exist"
41         if [ "$1" = "stop" ]; then
42                 exit 0
43         else
44                 exit 6
45         fi
46 fi
47
48 ##
49 # Returns 0 (success) if the given parameter names a directory, and that
50 # directory is not empty.
51 #
52 contains_something() {
53   if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]; then
54         return 0
55   else
56         return 1
57   fi
58 }
59
60 # read name from xen config file
61 rdname() {
62         NM=$($CMD create --quiet --dryrun --defconfig "$1" | sed -n 's/^.*(name \(.*\))$/\1/p')
63 }
64
65 rdnames() {
66     NAMES=
67     if ! contains_something "$XENDOMAINS_AUTO"; then 
68         return
69     fi
70     for dom in $XENDOMAINS_AUTO/*; do
71         rdname $dom
72         if test -z $NAMES; then 
73             NAMES=$NM; 
74         else
75             NAMES="$NAMES|$NM"
76         fi
77     done
78 }
79
80 parseln() {
81     if [[ "$1" = "*(domain*" ]]; then
82         name=;id=
83     elif [[ "$1" = "*(name*" ]]; then
84         name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/')
85     elif [[ "$1" = "*(domid*" ]]; then
86         id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/')
87     fi
88     [ -n "$name" -a -n "$id" ] && return 0 || return 1
89 }
90
91 is_running() {
92     rdname $1
93     name=;id=
94     $CMD list -l | grep '(\(domain\|domid\|name\)' | \
95     while read LN; do
96         parseln "$LN" || continue
97         [ $id = 0 ] && continue
98         case $name in 
99             ($NM)
100                 return 0
101                 ;;
102         esac
103     done
104     return 1
105 }
106
107 start() {
108     if [ -f /var/lock/subsys/xendomains ]; then 
109         echo -e "xendomains already running (lockfile exists)"
110         return 
111     fi
112
113     saved_domains=" "
114     if [ "$XENDOMAINS_RESTORE" = "true" ] && contains_something "$XENDOMAINS_SAVE"; then
115         mkdir -p $(dirname "/var/lock/subsys/xendomains")
116         touch /var/lock/subsys/xendomains
117         echo -n "Restoring Xen domains:"
118         saved_domains=`ls $XENDOMAINS_SAVE`
119         for dom in $XENDOMAINS_SAVE/*; do
120             if [ -f $dom ] ; then
121                 HEADER=`head -c 16 $dom | head -n 1 2> /dev/null`
122                 if [ $HEADER = "LinuxGuestRecord" ]; then
123                     echo -n " ${dom##*/}"
124                     XMR=`$CMD restore $dom 2>&1 1>/dev/null`
125                     #$CMD restore $dom
126                     if [ $? -ne 0 ]; then
127                         echo -e "\nAn error occurred while restoring domain ${dom##*/}:\n$XMR"
128                         echo -e '!'
129                     else
130                         # mv $dom ${dom%/*}/.${dom##*/}
131                         rm $dom
132                     fi
133                 fi
134             fi
135         done
136         echo -e
137     fi
138
139     if contains_something "$XENDOMAINS_AUTO" ; then
140         touch /var/lock/subsys/xendomains
141         echo -n "Starting auto Xen domains:"
142         # We expect config scripts for auto starting domains to be in
143         # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
144
145         # Create all domains with config files in XENDOMAINS_AUTO.
146         # TODO: We should record which domain name belongs 
147         # so we have the option to selectively shut down / migrate later
148         # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
149         # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't 
150         # restore correctly it requires administrative attention.
151         for dom in $XENDOMAINS_AUTO/*; do
152             echo -n " ${dom##*/}"
153             shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
154             echo $saved_domains | grep -w $shortdom > /dev/null
155             if [ $? -eq 0 ] || is_running $dom; then
156                 echo -n "(skip)"
157             else
158                 XMC=`$CMD create --quiet --defconfig $dom`
159                 if [ $? -ne 0 ]; then
160                     echo -e "\nAn error occurred while creating domain ${dom##*/}: $XMC\n"
161                     echo -e '!'
162                 else
163                     usleep $XENDOMAINS_CREATE_USLEEP
164                 fi
165             fi
166         done
167     fi
168 }
169
170 all_zombies() {
171     name=;id=
172     $CMD list -l | grep '(\(domain\|domid\|name\)' | \
173     while read LN; do
174         parseln "$LN" || continue
175         if test $id = 0; then continue; fi
176         if test "$state" != "-b---d" -a "$state" != "-----d"; then
177             return 1;
178         fi
179     done
180     return 0
181 }
182
183 # Wait for max $XENDOMAINS_STOP_MAXWAIT for $CMD $1 to finish;
184 # if it has not exited by that time kill it, so the init script will
185 # succeed within a finite amount of time; if $2 is nonnull, it will
186 # kill the command as well as soon as no domain (except for zombies)
187 # are left (used for shutdown --all). Third parameter, if any, suppresses
188 # output of dots per working state (formatting issues)
189 watchdog_xencmd() {
190     if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
191         exit
192     fi
193
194     usleep 20000
195     for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
196         # exit if $CMD save/migrate/shutdown is finished
197         PSAX=`ps axlw | grep "$CMD $1" | grep -v grep`
198         if test -z "$PSAX"; then exit; fi
199         if ! test -n "$3"; then echo -n '.'; fi
200         sleep 1
201         # go to kill immediately if there's only zombies left
202         if all_zombies && test -n "$2"; then break; fi
203     done
204     sleep 1
205     PSPID=$($PSAX | awk '{ print $3 }')
206     # kill $CMD $1
207     kill $PSPID >/dev/null 2>&1
208     
209     echo -e .
210 }
211
212 stop() {
213     # Collect list of domains to shut down
214     if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
215         rdnames
216     fi
217     echo -n "Shutting down Xen domains:"
218     name=;id=
219     $CMD list -l | grep '(\(domain\|domid\|name\)' | \
220     while read LN; do
221         parseln "$LN" || continue
222         if test $id = 0; then continue; fi
223         echo -n " $name"
224         if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
225             eval "
226             case \"\$name\" in
227                 ($NAMES)
228                     # nothing
229                     ;;
230                 (*)
231                     echo -e '(skip)'
232                     continue
233                     ;;
234             esac
235             "
236         fi
237         # XENDOMAINS_SYSRQ chould be something like just "s" 
238         # or "s e i u" or even "s e s i u o"
239         # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
240         if test -n "$XENDOMAINS_SYSRQ"; then
241             for sysrq in $XENDOMAINS_SYSRQ; do
242                 echo -n "(SR-$sysrq)"
243                 XMR=`$CMD sysrq $id $sysrq 2>&1 1>/dev/null`
244                 if test $? -ne 0; then
245                     echo -e "\nAn error occurred while doing sysrq on domain:\n$XMR\n"
246                     echo -n '!'
247                 fi
248                 # usleep just ignores empty arg
249                 usleep $XENDOMAINS_USLEEP
250             done
251         fi
252         if test "$state" = "-b---d" -o "$state" = "-----d"; then
253             echo -n "(zomb)"
254             continue
255         fi
256         if test -n "$XENDOMAINS_MIGRATE"; then
257             echo -n "(migr)"
258             watchdog_xencmd migrate &
259             WDOG_PID=$!
260             XMR=`$CMD migrate $id $XENDOMAINS_MIGRATE 2>&1 1>/dev/null`
261             if test $? -ne 0; then
262                 echo -e "\nAn error occurred while migrating domain:\n$XMR\n"
263                 echo -e '!'
264
265                 kill $WDOG_PID >/dev/null 2>&1
266             else
267                 kill $WDOG_PID >/dev/null 2>&1
268                 
269                 echo -e .
270                 usleep 1000
271                 continue
272             fi
273         fi
274         if test -n "$XENDOMAINS_SAVE"; then
275             echo -n "(save)"
276             watchdog_xencmd save &
277             WDOG_PID=$!
278             mkdir -p "$XENDOMAINS_SAVE"
279             XMR=`$CMD save $id $XENDOMAINS_SAVE/$name 2>&1 1>/dev/null`
280             if test $? -ne 0; then
281                 echo -e "\nAn error occurred while saving domain:\n$XMR\n"
282                 echo -e '!'
283                 kill $WDOG_PID >/dev/null 2>&1
284             else
285                 kill $WDOG_PID >/dev/null 2>&1
286                 echo -e .
287                 usleep 1000
288                 continue
289             fi
290         fi
291         if test -n "$XENDOMAINS_SHUTDOWN"; then
292             # XENDOMAINS_SHUTDOWN should be "--halt --wait"
293             echo -n "(shut)"
294             watchdog_xencmd shutdown &
295             WDOG_PID=$!
296             XMR=`$CMD shutdown $id $XENDOMAINS_SHUTDOWN 2>&1 1>/dev/null`
297             if test $? -ne 0; then
298                 echo -e "\nAn error occurred while shutting down domain:\n$XMR\n"
299                 echo -e '!'
300             fi
301             kill $WDOG_PID >/dev/null 2>&1
302         fi
303     done
304
305     # NB. this shuts down ALL Xen domains (politely), not just the ones in
306     # AUTODIR/*
307     # This is because it's easier to do ;-) but arguably if this script is run
308     # on system shutdown then it's also the right thing to do.
309     if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
310         # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
311         echo -n " SHUTDOWN_ALL "
312         watchdog_xencmd shutdown 1 false &
313         WDOG_PID=$!
314         XMR=`$CMD shutdown $XENDOMAINS_SHUTDOWN_ALL 2>&1 1>/dev/null`
315         if test $? -ne 0; then
316             echo -e "\nAn error occurred while shutting down all domains: $XMR\n"
317             echo -e '!'
318         fi
319         kill $WDOG_PID >/dev/null 2>&1
320     fi
321
322     # Unconditionally delete lock file
323     rm -f /var/lock/subsys/xendomains
324 }
325
326 check_domain_up()
327 {
328     name=;id=
329     $CMD list -l | grep '(\(domain\|domid\|name\)' | \
330     while read LN; do
331         parseln "$LN" || continue
332         if test $id = 0; then continue; fi
333         case $name in 
334             ($1)
335                 return 0
336                 ;;
337         esac
338     done
339     return 1
340 }
341
342 check_all_auto_domains_up()
343 {
344     if ! contains_something "$XENDOMAINS_AUTO"; then
345       return 0
346     fi
347     missing=
348     for nm in $XENDOMAINS_AUTO/*; do
349         rdname $nm
350         found=0
351         if check_domain_up "$NM"; then 
352             echo -n " $name"
353         else 
354             missing="$missing $NM"
355         fi
356     done
357     if test -n "$missing"; then
358         echo -n " MISS AUTO:$missing"
359         return 1
360     fi
361     return 0
362 }
363
364 check_all_saved_domains_up()
365 {
366     if ! contains_something "$XENDOMAINS_SAVE"; then
367       return 0
368     fi
369     missing=`/bin/ls $XENDOMAINS_SAVE`
370     echo -n " MISS SAVED: " $missing
371     return 1
372 }
373
374 RETVAL=0
375 # See how we were called.
376 case "$1" in
377     start)
378         start
379         ;;
380     stop)
381         stop
382         ;;
383     restart|reload)
384 # This does NOT necessarily restart all running domains: instead it
385 # stops all running domains and then boots all the domains specified in
386 # AUTODIR.  If other domains have been started manually then they will
387 # not get restarted.
388     stop
389     start
390         ;;
391     status)
392         if [ -f /var/lock/subsys/xendomains; then
393             echo -n "Checking for xendomains:" 
394             check_all_auto_domains_up
395             check_all_saved_domains_up
396         fi
397         ;;
398     *)
399         msg_usage "$0 {start|stop|restart|reload|status}"
400         ;;
401 esac
402
403 exit $RETVAL
This page took 0.110834 seconds and 3 git commands to generate.