Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
163 lines (137 sloc) 5.03 KB
#!/bin/bash
#
# This script will shutdown all running VMs in a Xen pool, all slave Xen
# hosts, and eventually the Xen pool master.
#
# Communication between Xen hosts is required for the sucessfull shutdown
# of all VMs/hosts; ensure that the network infrastructure between Xen
# hosts does not loose power before this script completes execution.
#
# This script will only run on the pool master though should be installed
# (along with NUT) on all Xen hosts in the case of a change in master.
#
main () {
# Script version number
version=1.0
# Seconds until VM clean shutdown times out (seconds until force shutdown initiated)
vm_shutdown_timeout=600
# Seconds until VM force shutdown times out (seconds until power reset initiated)
vm_forcedown_timeout=80
# Seconds to wait after initiating power reset on VM
vm_powerreset_timeout=60
# Seconds until slave host shutdown timeout (seconds until master gives up and shuts itself down)
xen_slave_timeout=240
# Log file location
log_file="/var/log/nut.log"
log_date "==============================================================================="
log_date "Powerdown event recieved from NUT master, initiating shutdown proceedure"
log_date "xen-shutdown.sh version $version"
log_date "==============================================================================="
# Get UUIDs of all running VMs
vm_uuids=( $(xe vm-list power-state=running is-control-domain=false --minimal | tr , "\n" ) )
# Shutdown each VM
for uuid in "${vm_uuids[@]}"; do
vm_name="$(xe vm-param-get uuid=$uuid param-name=name-label)"
log_date "Shutting down VM $vm_name (UUID: $uuid)"
xe vm-shutdown uuid=$uuid &
sleep 1
done
# Start timer for timeout
start_time=$SECONDS
# Loop until all VMs shutdown or timeout
sleep 10
while [ $(( SECONDS - start_time )) -lt $vm_shutdown_timeout ]; do
vm_uuids=( $(xe vm-list power-state=running is-control-domain=false --minimal | tr , "\n" ) )
if [ ${#vm_uuids[@]} -eq 0 ]; then
# If all VMs shutdown, shutdown hosts
shutdown_xenhosts
exit
else
log_date "Not all VMs shutdown, continuing to wait..."
sleep 10
fi
done
# Attempt to force shutdown any VMs still running after clean shutdown timeout
vm_uuids=( $(xe vm-list power-state=running is-control-domain=false --minimal | tr , "\n" ) )
for vm_uuid in "${vm_uuids[@]}"; do
vm_name="$(xe vm-param-get uuid=$vm_uuid param-name=name-label)"
log_date "Shutdown timeout, attempting to force down VM $vm_name (UUID: $vm_uuid)"
xe vm-shutdown uuid=$vm_uuid force=true &
sleep 1
done
sleep $vm_forcedown_timeout
# Initiate power reset on any VMs still running after clean and force shutdown timeout
vm_uuids=( $(xe vm-list power-state=running is-control-domain=false --minimal | tr , "\n" ) )
for vm_uuid in "${vm_uuids[@]}"; do
vm_name="$(xe vm-param-get uuid=$vm_uuid param-name=name-label)"
log_date "VM $vm_name (UUID: $vm_uuid) is still running, initiating power reset"
xe vm-reset-powerstate uuid=$vm_uuid force=true &
sleep 1
done
sleep $vm_powerreset_timeout
# Procede with shutting down hosts
shutdown_xenhosts
exit
}
shutdown_xenhosts () {
# Get UUID of all hosts
xen_uuids=( $(xe host-list --minimal | tr , "\n" ) )
# Get UUID of this host (master)
xen_master_uuid=$( cat /etc/xensource-inventory | grep -i installation_uuid | awk -F"'[[:blank:]]*" '{print $2}' )
# Get UUID of slave hosts
xen_slave_uuids=()
for uuid in ${xen_uuids[@]}; do
if [[ $uuid != $xen_master_uuid ]]; then
xen_slave_uuids+=($uuid)
fi
done
# Shutdown all slave hosts
for uuid in ${xen_slave_uuids[@]}; do
slave_name=$(xe host-param-get uuid=$uuid param-name=name-label)
log_date "Disabling slave host $slave_name (UUID: $uuid)"
xe host-disable uuid=$uuid
sleep 1
log_date "Shutting down slave host $slave_name (UUID: $uuid)"
xe host-shutdown uuid=$uuid &
sleep 1
done
# Start timer for timeout
start_time=$SECONDS
# Loop until all slave hosts do not respond to ping or timeout
sleep 10
for uuid in ${xen_slave_uuids[@]}; do
if [ $(( SECONDS - start_time )) -lt $xen_slave_timeout ]; then
while true; do
ping -c 1 $(xe host-param-get uuid=$uuid param-name=address) > /dev/null 2> /dev/null
# If slave replies to ping
if [ $? -eq 0 ]; then
log_date "Not all slave hosts shutdown, continuing to wait..."
sleep 10
continue
else
sleep 2
break
fi
done
else
log_date "Slave host shutdown timeout, proceeding with master host shutdown"
fi
done
# Shutdown master host
xen_master_name="$(xe host-param-get uuid=$xen_master_uuid param-name=name-label)"
log_date "Disabling master host $xen_master_name (UUID: $xen_master_uuid)"
xe host-disable uuid=$xen_master_uuid
sleep 1
log_date "Shutting down master host $xen_master_name (UUID: $xen_master_uuid)"
xe host-shutdown uuid=$xen_master_uuid
sleep 1
}
log_date () {
# logging function formatted to include a date
echo -e "$(date "+%Y/%m/%d %H:%M:%S"): $1" >> "$log_file" #2>&1
}
# Check that host has master role
role="$(more /etc/xensource/pool.conf)"
if [[ $role == *"master"* ]]; then
main
fi