3 # xendomains Start / stop domains automatically when domain 0 boots / shuts down.
6 # description: Start / stop Xen domains.
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)
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/>
17 . /etc/rc.d/init.d/functions
20 $CMD list >/dev/null 2>/dev/null || CMD=xl
21 $CMD list >/dev/null 2>/dev/null || exit 0
23 [ -e /proc/xen/privcmd ] || exit 0
25 if [ -r /etc/sysconfig/xendomains ]; then
26 . /etc/sysconfig/xendomains
28 echo "/etc/sysconfig/xendomains does not exist"
29 if [ "$1" = "stop" ]; then
37 # Returns 0 (success) if the given parameter names a directory, and that
38 # directory is not empty.
40 contains_something() {
41 if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]; then
48 # read name from xen config file
50 NM=$($CMD create --quiet --dryrun --defconfig "$1" 2>&1 | sed -n 's/^.*\(name \(.*\)\)\|\("name": "\([^"]*\)",\?\)$/\2\4/p')
56 if ! contains_something "$XENDOMAINS_AUTO"; then
59 for dom in $XENDOMAINS_AUTO/*; do
61 if test -z $NAMES; then
70 if [[ "$1" = *"(domain"* ]]; then
72 elif [[ "$1" = *"\"domid\"":* ]]; then
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/')
82 [ -n "$name" -a -n "$id" ] && return 0 || return 1
88 $CMD list -l | grep '[("]\(domain\|domid\|name\)' | \
90 parseln "$LN" || continue
91 [ $id = 0 ] && continue
102 if [ -f /var/lock/subsys/xendomains ]; then
103 echo -e "xendomains already running (lockfile exists)"
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`
120 if [ $? -ne 0 ]; then
121 echo -e "\nAn error occurred while restoring domain ${dom##*/}:\n$XMR"
124 # mv $dom ${dom%/*}/.${dom##*/}
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
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
152 XMC=`$CMD create --quiet --defconfig $dom`
153 if [ $? -ne 0 ]; then
154 echo -e "\nAn error occurred while creating domain ${dom##*/}: $XMC\n"
157 usleep $XENDOMAINS_CREATE_USLEEP
166 $CMD list -l | grep '[("]\(domain\|domid\|name\)' | \
168 parseln "$LN" || continue
169 if test $id = 0; then continue; fi
170 if test "$state" != "-b---d" -a "$state" != "-----d"; then
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)
184 if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
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
195 # go to kill immediately if there's only zombies left
196 if all_zombies && test -n "$2"; then break; fi
199 PSPID=$($PSAX | awk '{ print $3 }')
201 kill $PSPID >/dev/null 2>&1
207 # Collect list of domains to shut down
208 if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
211 echo -n "Shutting down Xen domains:"
213 $CMD list -l | grep '[("]\(domain\|domid\|name\)' | \
215 parseln "$LN" || continue
216 if test $id = 0; then continue; fi
218 if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
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"
242 # usleep just ignores empty arg
243 usleep $XENDOMAINS_USLEEP
246 if test "$state" = "-b---d" -o "$state" = "-----d"; then
250 if test -n "$XENDOMAINS_MIGRATE"; then
252 watchdog_xencmd migrate &
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"
259 kill $WDOG_PID >/dev/null 2>&1
261 kill $WDOG_PID >/dev/null 2>&1
268 if test -n "$XENDOMAINS_SAVE"; then
270 watchdog_xencmd save &
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"
277 kill $WDOG_PID >/dev/null 2>&1
279 kill $WDOG_PID >/dev/null 2>&1
285 if test -n "$XENDOMAINS_SHUTDOWN"; then
286 # XENDOMAINS_SHUTDOWN should be "--halt --wait"
288 watchdog_xencmd shutdown &
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"
295 kill $WDOG_PID >/dev/null 2>&1
299 # NB. this shuts down ALL Xen domains (politely), not just the ones in
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 &
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"
313 kill $WDOG_PID >/dev/null 2>&1
316 # Unconditionally delete lock file
317 rm -f /var/lock/subsys/xendomains
325 $CMD list -l | grep '[("]\(domain\|domid\|name\)' | \
327 parseln "$LN" || continue
328 if test $id = 0; then continue; fi
329 if [ "$name" = "$1" ] ; then
336 check_all_auto_domains_up()
338 if ! contains_something "$XENDOMAINS_AUTO"; then
342 for nm in $XENDOMAINS_AUTO/*; do
345 if [ -n "$(check_domain_up "$NM")" ] ; then
348 missing="$missing $NM"
351 if test -n "$missing"; then
352 echo -n " MISS AUTO:$missing"
358 check_all_saved_domains_up()
360 if ! contains_something "$XENDOMAINS_SAVE"; then
363 missing=`/bin/ls $XENDOMAINS_SAVE`
364 echo -n " MISS SAVED: " $missing
369 # See how we were called.
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
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
394 msg_usage "$0 {start|stop|restart|reload|status}"