#!/bin/bash # # /etc/init.d/xendomains # Start / stop domains automatically when domain 0 boots / shuts down. # # chkconfig: 345 99 00 # description: Start / stop Xen domains. # # Re-written from scratch by Steven Haigh for EL6 as stock # script has a lot of problems. May work on other distros, YMMV. # ### BEGIN INIT INFO # Provides: xendomains # Required-Start: $syslog $remote_fs xenstored xenconsoled # Should-Start: xend # Required-Stop: $syslog $remote_fs xenstored xenconsoled # Should-Stop: xend # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start/stop secondary xen domains # Description: Start / stop domains automatically when domain 0 # boots / shuts down. ### END INIT INFO ## Check if Xend is running, if so, use xm, else xl. XEND=`pidof -x xend` if [ $? -eq 0 ]; then CMD=`which xm` else CMD=`which xl` fi ## Check to see if we're running as Dom0. If so, the following file should ## exist. if ! [ -e /proc/xen/privcmd ]; then echo "Not running as Domain0. Exiting..." exit 0 fi ## Load the xendomains options, bailing if we can't. if [ -r /etc/sysconfig/xendomains ]; then . /etc/sysconfig/xendomains else echo "/etc/sysconfig/xendomains not found or unreadable. This is an issue. Exiting..." exit 0 fi if [ -d /var/lock/subsys ]; then LOCKFILE=/var/lock/subsys/xendomains else LOCKFILE=/var/lock/xendomains fi ## Source function library. . /etc/init.d/functions get_domu_name() { DOMU_NAME=$(awk '/^name/ {print $3}' $1) } watchdog() { ## Launch a command and wait until the timeout before killing forcefully. for WAIT in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do RESULT=`ps -p $PID` if [ $? -eq 1 ]; then success; echo break fi echo -n "." sleep 1 done RESULT=`ps -p $PID` if [ $? -eq 0 ]; then warning; echo kill $PID fi echo } start() { touch $LOCKFILE ## Check to see if we should restore saved DomUs on start ## Also check if the restore directory actually exists. if [ "$XENDOMAINS_RESTORE" = "true" ] && [ -d $XENDOMAINS_SAVE ] && [ -n "$XENDOMAINS_SAVE" ]; then for DOMU in $XENDOMAINS_SAVE/*; do if [ -r $DOMU ]; then HEADER=`head -c 16 $DOMU | head -n 1 2> /dev/null` if [ "$HEADER" = "LinuxGuestRecord" ] || [ "$HEADER" = "Xen saved domain" ]; then echo -n "Restoring Xen Domain ${DOMU##*/}" RESULT=`$CMD restore $DOMU 2>&1 1>/dev/null` if [ $? -ne 0 ]; then failure; echo else success; echo fi rm -f "$DOMU" fi fi done fi ## Check to see if our autostart directory exists and is actually set. if [ -d $XENDOMAINS_AUTO ] && [ -n $XENDOMAINS_AUTO ]; then ## Start each domain in our autostart directory. for DOMU in $XENDOMAINS_AUTO/*; do get_domu_name $DOMU echo -n $"Starting Xen auto domain $DOMU_NAME: " ## Check if domain is already running. RESULT=`$CMD list $DOMU_NAME >& /dev/null` if [ $? -eq 0 ] && [ $? -ne 2 ]; then ## DomU is already running. echo -n " (Skipped - Already running)" else ## Start the DomU... RESULT=`$CMD create $DOMU >& /dev/null` if [ $? -eq 0 ]; then usleep $XENDOMAINS_CREATE_USLEEP success; echo else failure; echo fi fi done fi return 0 } stop() { ## Check to see if we should send a SysRq to the DomUs if [ -n "$XENDOMAINS_SYSRQ" ]; then IFS=$'\n' echo -n "Sending SYSRQs to Xen Domains:" for DOMU in `$CMD list | tail -n +3 | sort`; do unset IFS DOMU_NAME=`echo "$DOMU" | awk '{ print $1 }'` for sysrq in $XENDOMAINS_SYSRQ; do $CMD sysrq $DOMU_NAME $sysrq echo -n "." done done success; echo fi ## Check to see if we should migrate running domains... if [ -n "$XENDOMAINS_MIGRATE" ]; then ## We should be doing a migrate. We don't really do much, just pass the ## values to XM/XL - if it fails, save or shutdown can have a go. IFS=$'\n' for DOMU in `$CMD list | tail -n +3 | sort`; do unset IFS DOMU_NAME=`echo "$DOMU" | awk '{ print $1 }'` echo -n "Migrating Xen domain $DOMU_NAME: " $CMD migrate $DOMU_NAME $XENDOMAINS_MIGRATE 2>&1 1>/dev/null & PID=$! watchdog done fi ## Check to see if we are to save domains... if [ -d $XENDOMAINS_SAVE ] && [ -n "$XENDOMAINS_SAVE" ]; then ## Cycle through the domains running and do what we need to do. IFS=$'\n' for DOMU in `$CMD list | tail -n +3 | sort`; do unset IFS DOMU_NAME=`echo "$DOMU" | awk '{ print $1 }'` ## Now we set our ionice to lower than realtime as we don't want the ## system to become unresponsive while saving a DomU. It still may ## need to fulfil requests from other DomUs etc. ionice -c 2 -n 7 -p $$ echo -n "Saving Xen Domain $DOMU_NAME: " $CMD save $DOMU_NAME $XENDOMAINS_SAVE/$DOMU_NAME > /dev/null 2>&1 & PID=$! watchdog done fi ## Shut down the remaining domains... if [ -n "$XENDOMAINS_SHUTDOWN" ]; then if [ "$CMD" = `which xm` ]; then echo -n "Sending shutdown to all DomUs: " $CMD shutdown --all success; echo else IFS=$'\n' for DOMU in `$CMD list | tail -n +3 | sort`; do unset IFS DOMU_NAME=`echo "$DOMU" | awk '{ print $1 }'` echo -n "Sending shutdown to DomU $DOMU_NAME:" $CMD shutdown -F "$DOMU_NAME" success; echo done fi echo "Waiting for all DomUs to complete shutdown" for WAIT in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do echo -n "." ## Check to see how many guests are still running. NUM_DOMU=$((`$CMD list | wc -l`-2)) if [ $NUM_DOMU -eq "0" ]; then success; echo break fi sleep 1 done ## Look for stray DomUs NUM_DOMU=$((`$CMD list | wc -l`-2)) if [ $NUM_DOMU -ne "0" ]; then ## Forcefully close any remaining DomUs warning; echo IFS=$'\n' for DOMU in `$CMD list | tail -n +3 | sort`; do unset IFS DOMU_NAME=`echo "$DOMU" | awk '{ print $1 }'` ID=`echo "$DOMU" | awk '{ print $2 }'` if [ -n "$ID" ]; then echo -n "Forcefully destroying $DOMU_NAME:" $CMD destroy $DOMU_NAME 2>&1 1>/dev/null & success; echo fi done fi fi rm -f $LOCKFILE return 0 } status() { ## We've already passed the test to see if Xen Dom0 is running, so here ## we check the number of lines returned from a list command and minus ## 2 from it (Header + Domain-0) and also some memory stats. NUM_DOMU=$((`$CMD list | wc -l`-2)) MEM_FREE=`$CMD info | grep free_memory | cut -f2 -d":"` MEM_TOTAL=`$CMD info | grep total_memory | cut -f2 -d":"` echo "Xen running with $NUM_DOMU DomUs. $MEM_FREE MB of$MEM_TOTAL MB free." return 0 } case "$1" in start) start RETVAL=$? ;; stop) stop RETVAL=$? ;; status) status RETVAL=$? ;; restart) stop start ;; esac