235 lines
5.3 KiB
Text
235 lines
5.3 KiB
Text
#!/sbin/openrc-run
|
|
|
|
description="Virtual Machine Management (libvirt) Guests"
|
|
|
|
depend() {
|
|
use libvirtd
|
|
}
|
|
|
|
# set the default to QEMU
|
|
[ -z "${LIBVIRT_URIS}" ] && LIBVIRT_URIS="qemu:///system"
|
|
|
|
# default to suspending the VM via managedsave
|
|
case "${LIBVIRT_SHUTDOWN}" in
|
|
managedsave|shutdown|destroy) ;;
|
|
*) LIBVIRT_SHUTDOWN="managedsave" ;;
|
|
esac
|
|
|
|
# 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
|
|
local hvuri=$1
|
|
shift
|
|
|
|
do_virsh "${hvuri}" list --uuid $@
|
|
}
|
|
|
|
libvirtd_dom_count() {
|
|
local hvuri=$1
|
|
shift
|
|
|
|
libvirtd_dom_list "${hvuri}" $@ | wc -l
|
|
}
|
|
|
|
libvirtd_net_list() {
|
|
# Only work with networks by their UUIDs
|
|
local hvuri=$1
|
|
shift
|
|
|
|
do_virsh "${hvuri}" net-list --uuid $@
|
|
}
|
|
|
|
libvirtd_net_count() {
|
|
local hvuri=$1
|
|
shift
|
|
|
|
libvirtd_net_list "${hvuri}" $@ | 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_as=
|
|
local dom_ids=
|
|
local uuid=
|
|
local dom_count=
|
|
|
|
[ "${persist}" = "--transient" ] && shutdown_type="shutdown"
|
|
[ -n "${counter}" ] || counter=500
|
|
|
|
einfo " Shutting down domain(s) ..."
|
|
|
|
# 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}"
|
|
# Get autostart state
|
|
dom_as=$(do_virsh ${uri} dominfo ${uuid} | \
|
|
awk '$1 == "Autostart:" { print $2 }')
|
|
|
|
if [ "${persist}" = "--persistent" ]; then
|
|
# Save our running state only if LIBVIRT_IGNORE_AUTOSTART != yes
|
|
if [ "x${LIBVIRT_IGNORE_AUTOSTART}" = "xyes" ] && \
|
|
[ ${dom_as} = "enabled" ]; then
|
|
:
|
|
else
|
|
echo "${uri} ${uuid}" >> ${gueststatefile}
|
|
fi
|
|
|
|
fi
|
|
|
|
# Now let's stop it
|
|
do_virsh "${uri}" ${shutdown_type} ${uuid} > /dev/null
|
|
|
|
done
|
|
|
|
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" ]; then
|
|
counter=$((${counter} - 1))
|
|
fi
|
|
printf "."
|
|
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 uuid=
|
|
local net_name=
|
|
|
|
if [ "${LIBVIRT_NET_SHUTDOWN}" != "no" ]; then
|
|
|
|
einfo " Shutting down network(s):"
|
|
for uuid 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 ${uuid} > /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
|
|
|
|
[ ! -e "${netstatefile}" ] && touch "${netstatefile}"
|
|
[ ! -e "${gueststatefile}" ] && touch "${gueststatefile}"
|
|
|
|
# if the user didn't want to start any guests up then respect their wish
|
|
[ "x${LIBVIRT_START}" = "xno" ] && return 0
|
|
|
|
# start networks
|
|
ebegin "Starting libvirt networks"
|
|
while read -r uri uuid
|
|
do
|
|
# ignore trash
|
|
[ -z "${uri}" ] || [ -z "${uuid}" ] && continue
|
|
|
|
name=$(do_virsh "${uri}" net-name ${uuid})
|
|
einfo " ${name}"
|
|
do_virsh "${uri}" net-start ${uuid} > /dev/null
|
|
done <"${netstatefile}"
|
|
eend 0
|
|
|
|
# start domains
|
|
ebegin "Starting libvirt domains"
|
|
while read -r uri uuid
|
|
do
|
|
# ignore trash
|
|
[ -z "${uri}" ] || [ -z "${uuid}" ] && continue
|
|
|
|
name=$(do_virsh "${uri}" domname ${uuid})
|
|
einfo " ${name}"
|
|
do_virsh "${uri}" start ${uuid} > /dev/null
|
|
done <"${gueststatefile}"
|
|
eend 0
|
|
}
|
|
|
|
stop() {
|
|
local counter=
|
|
local dom_name=
|
|
local net_name=
|
|
local dom_ids=
|
|
local uuid=
|
|
local dom_count=
|
|
|
|
rm -f "${gueststatefile}"
|
|
[ $? -ne 0 ] && eerror "Unable to save domain state"
|
|
rm -f "${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
|
|
}
|