#!/sbin/runscript description="Virtual Machine Management (libvirt) Guests" depend() { need libvirtd } # set the default to QEMU [ -z ${LIBVIRT_URIS} ] && LIBVIRT_URIS="qemu" # default to suspending the VM via managedsave [ -z ${LIBVIRT_SHUTDOWN} ] && LIBVIRT_SHUTDOWN="suspend" # default to 500 seconds [ -z ${LIBVIRT_MAXWAIT} ] && LIBVIRT_MAXWAIT=500 gueststatefile="/var/lib/libvirt/libvirt-guests.state" netstatefile="/var/lib/libvirt/libvirt-net.state" do_virsh() { local hvuri=$1 shift # if unset, default to qemu [ -z ${hvuri} ] && hvuri="qemu:///system" # if only qemu was supplied then correct the value [ "xqemu" = x${hvuri} ] && hvuri="qemu:///system" # Silence errors because virsh always throws an error about # not finding the hypervisor version when connecting to libvirtd # lastly strip the blank line at the end LC_ALL=C virsh -c ${hvuri} "$@" 2>/dev/null | head -n -1 } libvirtd_dom_list() { # Only work with domains by their UUIDs do_virsh "$1" list --uuid $2 } libvirtd_dom_count() { libvirtd_dom_list "$1" $2 | wc -l } libvirtd_net_list() { # Only work with networks by their UUIDs do_virsh "$1" net-list --uuid $2 } libvirtd_net_count() { libvirtd_net_list "$1" $2 | wc -l } libvirtd_dom_stop() { # stops all persistent or transient domains for a given URI # $1 - uri # $2 - persisent/transient local uri=$1 local persist=$2 local shutdown_type=${LIBVIRT_SHUTDOWN} local counter=${LIBVIRT_MAXWAIT} local dom_name= local dom_ids= local uuid= local dom_count= [ "${persist}" = "--persistent" ] && shutdown_type="shutdown" [ -n "${counter}" ] || counter=500 # grab all persistent or transient domains running dom_ids=$(libvirtd_dom_list ${uri} ${persist}) for uuid in ${dom_ids}; do # Get the name dom_name=$(do_virsh ${uri} domname ${uuid}) einfo " ${dom_name}" if [ "${persist}" = "--persistent" ]; then # Save our running state echo "${uri} ${uuid}" >> ${gueststatefile} fi # Now let's stop it do_virsh "${uri}" ${shutdown_type} ${uuid} > /dev/null done einfo " Waiting ${counter} seconds while domains shutdown ..." dom_count="$(libvirtd_dom_count ${uri} ${persist})" while [ ${dom_count} -gt 0 ] && [ ${counter} -gt 0 ] ; do dom_count="$(libvirtd_dom_count ${uri} ${persist})" sleep 1 if [ "${shutdown_type}" = "shutdown" ]; counter=$((${counter} - 1)) fi echo -n "." done if [ "${shutdown_type}" = "shutdown" ]; then # grab all domains still running dom_ids=$(libvirtd_dom_list ${uri} ${persist}) for uuid in ${dom_ids}; do dom_name=$(do_virsh ${uri} domname ${uuid}) eerror " ${dom_name} forcibly stopped" do_virsh "${uri}" destroy ${uuid} > /dev/null done fi } libvirtd_net_stop() { # stops all persistent or transient domains for a given URI # $1 - uri # $2 - persisent/transient local uri=$1 local persist=$2 local net_id= local net_name= if [ "${LIBVIRT_NET_SHUTDOWN}" != "no" ]; then einfo " Shutting down network(s):" for net_id in $(libvirtd_net_list ${uri} ${persist}); do net_name=$(do_virsh ${uri} net-name ${uuid}) einfo " ${net_name}" if [ "${persist}" = "--persistent" ]; then # Save our running state echo "${uri} ${uuid}" >> ${netstatefile} fi # Actually stop the network do_virsh qemu net-destroy ${net_name} > /dev/null done fi } start() { local uri= local uuid= local name= for uri in ${LIBVIRT_URIS}; do do_virsh "${uri}" connect if [ $? -ne 0 ]; then eerror "Failed to connect to '${uri}'. Domains may not start." fi done # start networks einfo "Starting libvirt networks" while read -r line do read -r uri uuid <<<"${line}" name=$(do_virsh "${uri}" net-name ${uuid}) einfo " ${name}" do_virsh "${uri}" net-start ${uuid} done <"${netstatefile}" einfo "Done starting libvirt networks" # start domains einfo "Starting libvirt domains" while read -r line do read -r uri uuid <<<"${line}" name=$(do_virsh "${uri}" domname ${uuid}) einfo " ${name}" do_virsh "${uri}" start ${uuid} done <"${gueststatefile}" einfo "Done starting libvirt domains" } stop() { local counter= local dom_name= local net_name= local dom_ids= local uuid= local dom_count= echo "" > "${gueststatefile}" [ $? -ne 0 ] && eerror "Unable to save domain state" echo "" > "${netstatefile}" [ $? -ne 0 ] && eerror "Unable to save net state" for uri in ${LIBVIRT_URIS}; do einfo "Stopping libvirt domains and networks for ${uri}" libvirtd_dom_stop "${uri}" "--persistent" libvirtd_dom_stop "${uri}" "--transient" libvirtd_net_stop "${uri}" "--persistent" libvirtd_net_stop "${uri}" "--transient" einfo "Done stopping domains and networks for ${uri}" done }