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