mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
Init script for handling guests on shutdown/boot
Example output during shutdown: Running guests on default URI: console, rhel6-1, rhel5-64 Running guests on lxc:/// URI: lxc-shell Running guests on xen:/// URI: error: no hypervisor driver available for xen:/// error: failed to connect to the hypervisor Running guests on vbox+tcp://orkuz/system URI: no running guests. Suspending guests on default URI... Suspending console: done Suspending rhel6-1: done Suspending rhel5-64: done Suspending guests on lxc:/// URI... Suspending lxc-shell: error: Failed to save domain 9cba8bfb-56f4-6589-2d12-8a58c886dd3b state error: this function is not supported by the hypervisor: virDomainManagedSave Note, the "Suspending $guest: " shows progress during the suspend phase if domjobinfo gives meaningful output. Example output during boot: Resuming guests on default URI... Resuming guest rhel6-1: done Resuming guest rhel5-64: done Resuming guest console: done Resuming guests on lxc:/// URI... Resuming guest lxc-shell: already active Configuration used for generating the examples above: URIS='default lxc:/// xen:/// vbox+tcp://orkuz/system' The script uses /var/lib/libvirt/libvirt-guests files to note all active guest it should try to resume on next boot. It's content looks like: default 7f8b9d93-30e1-f0b9-47a7-cb408482654b 085b4c95-5da2-e8e1-712f-6ea6a4156af2 fb4d8360-5305-df3a-2da1-07d682891b8c lxc:/// 9cba8bfb-56f4-6589-2d12-8a58c886dd3b
This commit is contained in:
parent
e0037c2ee8
commit
66823690e4
@ -30,6 +30,8 @@ EXTRA_DIST = \
|
||||
libvirtd.uml.logrotate.in \
|
||||
test_libvirtd.aug \
|
||||
THREADING.txt \
|
||||
libvirt-guests.init.in \
|
||||
libvirt-guests.sysconf \
|
||||
$(AVAHI_SOURCES) \
|
||||
$(DAEMON_SOURCES)
|
||||
|
||||
@ -217,21 +219,27 @@ install-logrotate: $(LOGROTATE_CONFS)
|
||||
$(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
install-init: libvirtd.init
|
||||
install-init: libvirtd.init libvirt-guests.init
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d
|
||||
$(INSTALL_SCRIPT) libvirtd.init \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
$(INSTALL_SCRIPT) libvirt-guests.init \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
|
||||
$(INSTALL_SCRIPT) $(srcdir)/libvirtd.sysconf \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
$(INSTALL_SCRIPT) $(srcdir)/libvirt-guests.sysconf \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
|
||||
|
||||
uninstall-init:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
|
||||
|
||||
BUILT_SOURCES += libvirtd.init
|
||||
BUILT_SOURCES += libvirtd.init libvirt-guests.init
|
||||
|
||||
libvirtd.init: libvirtd.init.in
|
||||
%.init: %.init.in
|
||||
$(AM_V_GEN)sed \
|
||||
-e s!\@localstatedir\@!@localstatedir@!g \
|
||||
-e s!\@sbindir\@!@sbindir@!g \
|
||||
|
295
daemon/libvirt-guests.init.in
Normal file
295
daemon/libvirt-guests.init.in
Normal file
@ -0,0 +1,295 @@
|
||||
#!/bin/sh
|
||||
|
||||
# the following is the LSB init header
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: libvirt-guests
|
||||
# Required-Start: libvirtd
|
||||
# Required-Stop: libvirtd
|
||||
# Default-Start: 3 4 5
|
||||
# Short-Description: suspend/resume libvirt guests on shutdown/boot
|
||||
# Description: This is a script for suspending active libvirt guests
|
||||
# on shutdown and resuming them on next boot
|
||||
# See http://libvirt.org
|
||||
### END INIT INFO
|
||||
|
||||
# the following is chkconfig init header
|
||||
#
|
||||
# libvirt-guests: suspend/resume libvirt guests on shutdown/boot
|
||||
#
|
||||
# chkconfig: 345 98 02
|
||||
# description: This is a script for suspending active libvirt guests \
|
||||
# on shutdown and resuming them on next boot \
|
||||
# See http://libvirt.org
|
||||
#
|
||||
|
||||
sysconfdir=@sysconfdir@
|
||||
localstatedir=@localstatedir@
|
||||
|
||||
# Source function library.
|
||||
. "$sysconfdir"/rc.d/init.d/functions
|
||||
|
||||
URIS=default
|
||||
ON_BOOT=start
|
||||
ON_SHUTDOWN=suspend
|
||||
SHUTDOWN_TIMEOUT=0
|
||||
|
||||
test -f "$sysconfdir"/sysconfig/libvirt-guests && . "$sysconfdir"/sysconfig/libvirt-guests
|
||||
|
||||
LISTFILE="$localstatedir"/lib/libvirt/libvirt-guests
|
||||
|
||||
RETVAL=0
|
||||
|
||||
retval() {
|
||||
"$@"
|
||||
if [ $? -ne 0 ]; then
|
||||
RETVAL=1
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
run_virsh() {
|
||||
uri=$1
|
||||
shift
|
||||
|
||||
if [ "x$uri" = xdefault ]; then
|
||||
conn=
|
||||
else
|
||||
conn="-c $uri"
|
||||
fi
|
||||
|
||||
virsh $conn "$@"
|
||||
}
|
||||
|
||||
run_virsh_c() {
|
||||
( export LC_ALL=C; run_virsh "$@" )
|
||||
}
|
||||
|
||||
list_guests() {
|
||||
uri=$1
|
||||
|
||||
list=$(run_virsh_c $uri list)
|
||||
if [ $? -ne 0 ]; then
|
||||
RETVAL=1
|
||||
return 1
|
||||
fi
|
||||
|
||||
uuids=
|
||||
for id in $(echo "$list" | awk 'NR > 2 {print $1}'); do
|
||||
uuid=$(run_virsh_c $uri dominfo $id | awk '/^UUID:/{print $2}')
|
||||
if [ -z "$uuid" ]; then
|
||||
RETVAL=1
|
||||
return 1
|
||||
fi
|
||||
uuids="$uuids $uuid"
|
||||
done
|
||||
|
||||
echo $uuids
|
||||
}
|
||||
|
||||
guest_name() {
|
||||
uri=$1
|
||||
uuid=$2
|
||||
|
||||
name=$(run_virsh_c $uri dominfo $uuid 2>/dev/null | \
|
||||
awk '/^Name:/{print $2}')
|
||||
[ -n "$name" ] || name=$uuid
|
||||
|
||||
echo "$name"
|
||||
}
|
||||
|
||||
guest_is_on() {
|
||||
uri=$1
|
||||
uuid=$2
|
||||
|
||||
guest_running=false
|
||||
info=$(run_virsh_c $uri dominfo $uuid)
|
||||
if [ $? -ne 0 ]; then
|
||||
RETVAL=1
|
||||
return 1
|
||||
fi
|
||||
|
||||
id=$(echo "$info" | awk '/^Id:/{print $2}')
|
||||
|
||||
[ -n "$id" ] && [ "x$id" != x- ] && guest_running=true
|
||||
return 0
|
||||
}
|
||||
|
||||
start() {
|
||||
[ -f $LISTFILE ] || return 0
|
||||
|
||||
if [ "x$ON_BOOT" != xstart ]; then
|
||||
echo $"libvirt-guests is configured not to start any guests on boot"
|
||||
rm -f $LISTFILE
|
||||
return 0
|
||||
fi
|
||||
|
||||
while read uri list; do
|
||||
configured=false
|
||||
for confuri in $URIS; do
|
||||
if [ $confuri = $uri ]; then
|
||||
configured=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ! $configured; then
|
||||
echo $"Ignoring guests on $uri URI"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo $"Resuming guests on $uri URI..."
|
||||
for guest in $list; do
|
||||
name=$(guest_name $uri $guest)
|
||||
echo -n $"Resuming guest $name: "
|
||||
if guest_is_on $uri $guest; then
|
||||
if $guest_running; then
|
||||
echo $"already active"
|
||||
else
|
||||
retval run_virsh $uri start "$name" >/dev/null && \
|
||||
echo $"done"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done <$LISTFILE
|
||||
|
||||
rm -f $LISTFILE
|
||||
}
|
||||
|
||||
suspend_guest()
|
||||
{
|
||||
uri=$1
|
||||
guest=$2
|
||||
|
||||
name=$(guest_name $uri $guest)
|
||||
label=$"Suspending $name: "
|
||||
echo -n "$label"
|
||||
run_virsh $uri managedsave $guest >/dev/null &
|
||||
virsh_pid=$!
|
||||
while true; do
|
||||
sleep 1
|
||||
kill -0 $virsh_pid >&/dev/null || break
|
||||
progress=$(run_virsh_c $uri domjobinfo $guest 2>/dev/null | \
|
||||
awk '/^Data processed:/{print $3, $4}')
|
||||
if [ -n "$progress" ]; then
|
||||
printf '\r%s%12s ' "$label" "$progress"
|
||||
else
|
||||
printf '\r%s%-12s ' "$label" "..."
|
||||
fi
|
||||
done
|
||||
retval wait $virsh_pid && printf '\r%s%-12s\n' "$label" $"done"
|
||||
}
|
||||
|
||||
shutdown_guest()
|
||||
{
|
||||
uri=$1
|
||||
guest=$2
|
||||
|
||||
name=$(guest_name $uri $guest)
|
||||
label=$"Shutting down $name: "
|
||||
echo -n "$label"
|
||||
retval run_virsh $uri shutdown $guest >/dev/null || return
|
||||
timeout=$SHUTDOWN_TIMEOUT
|
||||
while [ $timeout -gt 0 ]; do
|
||||
sleep 1
|
||||
timeout=$[timeout - 1]
|
||||
guest_is_on $uri $guest || return
|
||||
$guest_running || break
|
||||
printf '\r%s%-12d ' "$label" $timeout
|
||||
done
|
||||
|
||||
if guest_is_on $uri $guest; then
|
||||
if $guest_running; then
|
||||
printf '\r%s%-12s\n' "$label" $"failed to shutdown in time"
|
||||
else
|
||||
printf '\r%s%-12s\n' "$label" $"done"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
# last stop was not followed by start
|
||||
[ -f $LISTFILE ] && return 0
|
||||
|
||||
suspending=true
|
||||
if [ "x$ON_SHUTDOWN" = xshutdown ]; then
|
||||
suspending=false
|
||||
if [ $SHUTDOWN_TIMEOUT -le 0 ]; then
|
||||
echo $"Shutdown action requested but SHUTDOWN_TIMEOUT was not set"
|
||||
RETVAL=6
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
: >$LISTFILE
|
||||
for uri in $URIS; do
|
||||
echo -n $"Running guests on $uri URI: "
|
||||
list=$(list_guests $uri)
|
||||
if [ $? -eq 0 ]; then
|
||||
empty=true
|
||||
for uuid in $list; do
|
||||
$empty || printf ", "
|
||||
echo -n $(guest_name $uri $uuid)
|
||||
empty=false
|
||||
done
|
||||
if $empty; then
|
||||
echo $"no running guests."
|
||||
else
|
||||
echo
|
||||
echo $uri $list >>$LISTFILE
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
while read uri list; do
|
||||
if $suspending; then
|
||||
echo $"Suspending guests on $uri URI..."
|
||||
else
|
||||
echo $"Shutting down guests on $uri URI..."
|
||||
fi
|
||||
|
||||
for guest in $list; do
|
||||
if $suspending; then
|
||||
suspend_guest $uri $guest
|
||||
else
|
||||
shutdown_guest $uri $guest
|
||||
fi
|
||||
done
|
||||
done <$LISTFILE
|
||||
}
|
||||
|
||||
gueststatus() {
|
||||
for uri in $URIS; do
|
||||
echo "* $uri URI:"
|
||||
retval run_virsh $uri list || echo
|
||||
done
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start|stop|gueststatus)
|
||||
$1
|
||||
;;
|
||||
restart)
|
||||
stop && start
|
||||
;;
|
||||
force-reload)
|
||||
;;
|
||||
status)
|
||||
if [ -f $LISTFILE ]; then
|
||||
RETVAL=3
|
||||
else
|
||||
RETVAL=0
|
||||
fi
|
||||
;;
|
||||
shutdown)
|
||||
ON_SHUTDOWN=shutdown
|
||||
stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart|force-reload|gueststatus|shutdown}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
24
daemon/libvirt-guests.sysconf
Normal file
24
daemon/libvirt-guests.sysconf
Normal file
@ -0,0 +1,24 @@
|
||||
# URIs to check for running guests
|
||||
# example: URIS='default xen:/// vbox+tcp://host/system lxc:///'
|
||||
#URIS=default
|
||||
|
||||
# action taken on host boot
|
||||
# - start all guests which were running on shutdown are started on boot
|
||||
# regardless on their autostart settings
|
||||
# - ignore libvirt-guests init script won't start any guest on boot, however,
|
||||
# guests marked as autostart will still be automatically started by
|
||||
# libvirtd
|
||||
#ON_BOOT=start
|
||||
|
||||
# action taken on host shutdown
|
||||
# - suspend all running guests are suspended using virsh managedsave
|
||||
# - shutdown all running guests are asked to shutdown. Please be careful with
|
||||
# this settings since there is no way to distinguish between a
|
||||
# guest which is stuck or ignores shutdown requests and a guest
|
||||
# which just needs a long time to shutdown. When setting
|
||||
# ON_SHUTDOWN=shutdown, you must also set SHUTDOWN_TIMEOUT to a
|
||||
# value suitable for your guests.
|
||||
#ON_SHUTDOWN=suspend
|
||||
|
||||
# number of seconds we're willing to wait for a guest to shut down
|
||||
#SHUTDOWN_TIMEOUT=0
|
@ -830,6 +830,10 @@ fi
|
||||
|
||||
%{_datadir}/libvirt/cpu_map.xml
|
||||
|
||||
%{_sysconfdir}/rc.d/init.d/libvirt-guests
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/libvirt-guests
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt
|
||||
|
||||
%if %{with_sasl}
|
||||
%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
|
||||
%endif
|
||||
|
Loading…
Reference in New Issue
Block a user