[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH v2] tools: Only install guests init script if --with-init=script=redhat



On 10/21/2012 04:45 PM, Cole Robinson wrote:
> Most of this deals with moving the libvirt-guests.sh script which
> does all the work to /usr/libexec, so it can be shared by both
> systemd and traditional init. Previously systemd depended on
> the script being in /etc/init.d
> 
> Required to fix https://bugzilla.redhat.com/show_bug.cgi?id=789747
> ---
> 

Ping on this too. I'd like to get this in before cutting 0.10.2 maint release.
Though this has a bit more going on so if anyone thinks it's risky I'm happy
to hold off.

Thanks,
Cole


> v2:
>     Break out common functionality, move to /usr/libexec/libvirt-guests.sh
> 
>  .gitignore                      |   1 +
>  libvirt.spec.in                 |   6 +-
>  po/POTFILES.in                  |   2 +-
>  tools/Makefile.am               |  18 +-
>  tools/libvirt-guests.init.in    |  27 ++
>  tools/libvirt-guests.init.sh    | 597 ----------------------------------------
>  tools/libvirt-guests.service.in |   4 +-
>  tools/libvirt-guests.sh.in      | 573 ++++++++++++++++++++++++++++++++++++++
>  8 files changed, 620 insertions(+), 608 deletions(-)
>  create mode 100644 tools/libvirt-guests.init.in
>  delete mode 100644 tools/libvirt-guests.init.sh
>  create mode 100644 tools/libvirt-guests.sh.in
> 
> diff --git a/.gitignore b/.gitignore
> index 804eda4..1f1b26f 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -177,6 +177,7 @@
>  /tools/*.[18]
>  /tools/libvirt-guests.init
>  /tools/libvirt-guests.service
> +/tools/libvirt-guests.sh
>  /tools/virsh
>  /tools/virsh-*-edit.c
>  /tools/virt-*-validate
> diff --git a/libvirt.spec.in b/libvirt.spec.in
> index ebebfab..d701977 100644
> --- a/libvirt.spec.in
> +++ b/libvirt.spec.in
> @@ -1380,8 +1380,6 @@ rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.uml
>  mv $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-%{version} \
>     $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-docs-%{version}
>  
> -sed -i -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/libvirt-guests
> -
>  %if %{with_dtrace}
>  %ifarch %{power64} s390x x86_64 ia64 alpha sparc64
>  mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes.stp \
> @@ -1600,10 +1598,13 @@ fi
>  
>  %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/nwfilter/
>  
> +%attr(0755, root, root) %{_libexecdir}/libvirt-guests.sh
>  %if %{with_systemd}
>  %{_unitdir}/libvirtd.service
> +%{_unitdir}/libvirt-guests.service
>  %else
>  %{_sysconfdir}/rc.d/init.d/libvirtd
> +%{_sysconfdir}/rc.d/init.d/libvirt-guests
>  %endif
>  %doc daemon/libvirtd.upstart
>  %config(noreplace) %{_sysconfdir}/sysconfig/libvirtd
> @@ -1865,7 +1866,6 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd
>  
>  %{_datadir}/libvirt/cpu_map.xml
>  
> -%{_sysconfdir}/rc.d/init.d/libvirt-guests
>  %if %{with_systemd}
>  %{_unitdir}/libvirt-guests.service
>  %endif
> diff --git a/po/POTFILES.in b/po/POTFILES.in
> index 9768528..cbf5bc6 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -190,7 +190,7 @@ src/xenapi/xenapi_utils.c
>  src/xenxs/xen_sxpr.c
>  src/xenxs/xen_xm.c
>  tools/console.c
> -tools/libvirt-guests.init.sh
> +tools/libvirt-guests.sh.in
>  tools/virsh.c
>  tools/virsh-domain-monitor.c
>  tools/virsh-domain.c
> diff --git a/tools/Makefile.am b/tools/Makefile.am
> index 0d7822d..281f010 100644
> --- a/tools/Makefile.am
> +++ b/tools/Makefile.am
> @@ -41,6 +41,7 @@ DISTCLEANFILES =
>  
>  bin_SCRIPTS = virt-xml-validate virt-pki-validate
>  bin_PROGRAMS = virsh virt-host-validate
> +libexec_SCRIPTS = libvirt-guests.sh
>  
>  if HAVE_SANLOCK
>  sbin_SCRIPTS = virt-sanlock-cleanup
> @@ -177,7 +178,7 @@ uninstall-sysconfig:
>  	rm -f $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
>  	rmdir $(DESTDIR)$(sysconfdir)/sysconfig ||:
>  
> -EXTRA_DIST += libvirt-guests.init.sh
> +EXTRA_DIST += libvirt-guests.sh.in libvirt-guests.init.in
>  
>  install-initscript: libvirt-guests.init
>  	$(MKDIR_P) $(DESTDIR)$(sysconfdir)/rc.d/init.d
> @@ -198,7 +199,7 @@ install-init:
>  uninstall-init:
>  endif # LIBVIRT_INIT_SCRIPT_RED_HAT
>  
> -libvirt-guests.init: libvirt-guests.init.sh $(top_builddir)/config.status
> +libvirt-guests.sh: libvirt-guests.sh.in $(top_builddir)/config.status
>  	$(AM_V_GEN)sed					\
>  	    -e 's!\ PACKAGE\@!$(PACKAGE)!g'		\
>  	    -e 's!\ bindir\@!$(bindir)!g'		\
> @@ -209,20 +210,26 @@ libvirt-guests.init: libvirt-guests.init.sh $(top_builddir)/config.status
>  	    < $< > $ -t &&				\
>  	    chmod a+x $ -t &&				\
>  	    mv $ -t $@
> +BUILT_SOURCES += libvirt-guests.sh
>  
> +libvirt-guests.init: libvirt-guests.init.in libvirt-guests.sh
> +	$(AM_V_GEN)sed \
> +		-e 's!\ libexecdir\@!$(libexecdir)!g' \
> +	< $< > $ -t && \
> +	chmod a+x $ -t && \
> +	mv $ -t $@
>  
>  
>  EXTRA_DIST += libvirt-guests.service.in
> -
>  SYSTEMD_UNIT_DIR = /lib/systemd/system
>  
>  if LIBVIRT_INIT_SCRIPT_SYSTEMD
> -install-systemd: libvirt-guests.service install-initscript install-sysconfig
> +install-systemd: libvirt-guests.service install-sysconfig libvirt-guests.sh
>  	$(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR)
>  	$(INSTALL_DATA) libvirt-guests.service \
>  	  $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirt-guests.service
>  
> -uninstall-systemd: uninstall-initscript uninstall-sysconfig
> +uninstall-systemd: uninstall-sysconfig
>  	rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirt-guests.service
>  	rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) ||:
>  
> @@ -241,6 +248,7 @@ libvirt-guests.service: libvirt-guests.service.in $(top_builddir)/config.status
>  	    -e 's!\ localstatedir\@!$(localstatedir)!g'	\
>  	    -e 's!\ sbindir\@!$(sbindir)!g'		\
>  	    -e 's!\ sysconfdir\@!$(sysconfdir)!g'	\
> +	    -e 's!\ libexecdir\@!$(libexecdir)!g'	\
>  	    < $< > $ -t &&				\
>  	    chmod a+x $ -t &&				\
>  	    mv $ -t $@
> diff --git a/tools/libvirt-guests.init.in b/tools/libvirt-guests.init.in
> new file mode 100644
> index 0000000..5f9a60e
> --- /dev/null
> +++ b/tools/libvirt-guests.init.in
> @@ -0,0 +1,27 @@
> +#!/bin/sh
> +
> +# the following is the LSB init header
> +#
> +### BEGIN INIT INFO
> +# Provides: libvirt-guests
> +# Required-Start: libvirtd
> +# Required-Stop: libvirtd
> +# Default-Start: 2 3 4 5
> +# Default-Stop: 0 1 6
> +# 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 99 01
> +# description:  This is a script for suspending active libvirt guests \
> +#               on shutdown and resuming them on next boot \
> +#               See http://libvirt.org
> +#
> +
> +exec @libexecdir@/libvirt-guests.sh "$@"
> diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh
> deleted file mode 100644
> index 99ef331..0000000
> --- a/tools/libvirt-guests.init.sh
> +++ /dev/null
> @@ -1,597 +0,0 @@
> -#!/bin/sh
> -
> -# the following is the LSB init header
> -#
> -### BEGIN INIT INFO
> -# Provides: libvirt-guests
> -# Required-Start: libvirtd
> -# Required-Stop: libvirtd
> -# Default-Start: 2 3 4 5
> -# Default-Stop: 0 1 6
> -# 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 99 01
> -# 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@"
> -libvirtd="@sbindir@"/libvirtd
> -
> -# Source function library.
> -test ! -r "$sysconfdir"/rc.d/init.d/functions ||
> -    . "$sysconfdir"/rc.d/init.d/functions
> -
> -# Source gettext library.
> -# Make sure this file is recognized as having translations: _("dummy")
> -. "@bindir@"/gettext.sh
> -
> -export TEXTDOMAIN="@PACKAGE@" TEXTDOMAINDIR="@localedir@"
> -
> -URIS=default
> -ON_BOOT=start
> -ON_SHUTDOWN=suspend
> -SHUTDOWN_TIMEOUT=300
> -PARALLEL_SHUTDOWN=0
> -START_DELAY=0
> -BYPASS_CACHE=0
> -
> -test -f "$sysconfdir"/sysconfig/libvirt-guests &&
> -    . "$sysconfdir"/sysconfig/libvirt-guests
> -
> -LISTFILE="$localstatedir"/lib/libvirt/libvirt-guests
> -VAR_SUBSYS_LIBVIRT_GUESTS="$localstatedir"/lock/subsys/libvirt-guests
> -
> -RETVAL=0
> -
> -# retval COMMAND ARGUMENTS...
> -# run command with arguments and convert non-zero return value to 1 and set
> -# the global return variable
> -retval() {
> -    "$@"
> -    if [ $? -ne 0 ]; then
> -        RETVAL=1
> -        return 1
> -    else
> -        return 0
> -    fi
> -}
> -
> -# run_virsh URI ARGUMENTS...
> -# start virsh and let it execute ARGUMENTS on URI
> -# If URI is "default" virsh is called without the "-c" argument
> -# (using libvirt's default connection)
> -run_virsh() {
> -    uri=$1
> -    shift
> -
> -    if [ "x$uri" = xdefault ]; then
> -        virsh "$@" </dev/null
> -    else
> -        virsh -c "$uri" "$@" </dev/null
> -    fi
> -}
> -
> -# run_virsh_c URI ARGUMENTS
> -# Same as "run_virsh" but the "C" locale is used instead of
> -# the system's locale.
> -run_virsh_c() {
> -    ( export LC_ALL=C; run_virsh "$@" )
> -}
> -
> -# test_connect URI
> -# check if URI is reachable
> -test_connect()
> -{
> -    uri=$1
> -
> -    run_virsh "$uri" connect 2>/dev/null
> -    if [ $? -ne 0 ]; then
> -        eval_gettext "Can't connect to \$uri. Skipping."
> -        echo
> -        return 1
> -    fi
> -}
> -
> -# list_guests URI PERSISTENT
> -# List running guests on URI.
> -# PERSISTENT argument options:
> -# --persistent: list only persistent guests
> -# --transient: list only transient guests
> -# [none]: list both persistent and transient guests
> -list_guests() {
> -    uri=$1
> -    persistent=$2
> -
> -    list=$(run_virsh_c "$uri" list --uuid $persistent)
> -    if [ $? -ne 0 ]; then
> -        RETVAL=1
> -        return 1
> -    fi
> -
> -    echo $list
> -}
> -
> -# guest_name URI UUID
> -# return name of guest UUID on URI
> -guest_name() {
> -    uri=$1
> -    uuid=$2
> -
> -    run_virsh "$uri" domname "$uuid" 2>/dev/null
> -}
> -
> -# guest_is_on URI UUID
> -# check if guest UUID on URI is running
> -# Result is returned by variable "guest_running"
> -guest_is_on() {
> -    uri=$1
> -    uuid=$2
> -
> -    guest_running=false
> -    id=$(run_virsh "$uri" domid "$uuid")
> -    if [ $? -ne 0 ]; then
> -        RETVAL=1
> -        return 1
> -    fi
> -
> -    [ -n "$id" ] && [ "x$id" != x- ] && guest_running=true
> -    return 0
> -}
> -
> -# started
> -# Create the startup lock file
> -started() {
> -    touch "$VAR_SUBSYS_LIBVIRT_GUESTS"
> -}
> -
> -# start
> -# Start or resume the guests
> -start() {
> -    [ -f "$LISTFILE" ] || { started; return 0; }
> -
> -    if [ "x$ON_BOOT" != xstart ]; then
> -        gettext "libvirt-guests is configured not to start any guests on boot"
> -        echo
> -        rm -f "$LISTFILE"
> -        started
> -        return 0
> -    fi
> -
> -    isfirst=true
> -    bypass=
> -    test "x$BYPASS_CACHE" = x0 || bypass=--bypass-cache
> -    while read uri list; do
> -        configured=false
> -        set -f
> -        for confuri in $URIS; do
> -            set +f
> -            if [ "x$confuri" = "x$uri" ]; then
> -                configured=true
> -                break
> -            fi
> -        done
> -        set +f
> -        if ! "$configured"; then
> -            eval_gettext "Ignoring guests on \$uri URI"; echo
> -            continue
> -        fi
> -
> -        test_connect "$uri" || continue
> -
> -        eval_gettext "Resuming guests on \$uri URI..."; echo
> -        for guest in $list; do
> -            name=$(guest_name "$uri" "$guest")
> -            eval_gettext "Resuming guest \$name: "
> -            if guest_is_on "$uri" "$guest"; then
> -                if "$guest_running"; then
> -                    gettext "already active"; echo
> -                else
> -                    if "$isfirst"; then
> -                        isfirst=false
> -                    else
> -                        sleep $START_DELAY
> -                    fi
> -                    retval run_virsh "$uri" start $bypass "$name" \
> -                        >/dev/null && \
> -                    gettext "done"; echo
> -                fi
> -            fi
> -        done
> -    done <"$LISTFILE"
> -
> -    rm -f "$LISTFILE"
> -    started
> -}
> -
> -# suspend_guest URI GUEST
> -# Do a managed save on a GUEST on URI. This function returns after the guest
> -# was saved.
> -suspend_guest()
> -{
> -    uri=$1
> -    guest=$2
> -
> -    name=$(guest_name "$uri" "$guest")
> -    label=$(eval_gettext "Suspending \$name: ")
> -    bypass=
> -    slept=0
> -    test "x$BYPASS_CACHE" = x0 || bypass=--bypass-cache
> -    printf '%s...\n' "$label"
> -    run_virsh "$uri" managedsave $bypass "$guest" >/dev/null &
> -    virsh_pid=$!
> -    while true; do
> -        sleep 1
> -        kill -0 "$virsh_pid" >/dev/null 2>&1 || break
> -
> -        slept=$(($slept + 1))
> -        if [ $(($slept % 5)) -eq 0 ]; then
> -            progress=$(run_virsh_c "$uri" domjobinfo "$guest" 2>/dev/null | \
> -                    awk '/^Data processed:/{print $3, $4}')
> -            if [ -n "$progress" ]; then
> -                printf '%s%s\n' "$label" "$progress"
> -            else
> -                printf '%s%s\n' "$label" "..."
> -            fi
> -        fi
> -    done
> -    retval wait "$virsh_pid" && printf '%s%s\n' "$label" "$(gettext "done")"
> -}
> -
> -# shutdown_guest URI GUEST
> -# Start a ACPI shutdown of GUEST on URI. This function return after the quest
> -# was successfully shutdown or the timeout defined by $SHUTDOWN_TIMEOUT expires.
> -shutdown_guest()
> -{
> -    uri=$1
> -    guest=$2
> -
> -    name=$(guest_name "$uri" "$guest")
> -    eval_gettext "Starting shutdown on guest: \$name"
> -    echo
> -    retval run_virsh "$uri" shutdown "$guest" >/dev/null || return
> -    timeout=$SHUTDOWN_TIMEOUT
> -    check_timeout=false
> -    if [ $timeout -gt 0 ]; then
> -        check_timeout=true
> -        format=$(eval_gettext "Waiting for guest %s to shut down, %d seconds left\n")
> -    else
> -        slept=0
> -        format=$(eval_gettext "Waiting for guest %s to shut down\n")
> -    fi
> -    while ! $check_timeout || [ "$timeout" -gt 0 ]; do
> -        sleep 1
> -        guest_is_on "$uri" "$guest" || return
> -        "$guest_running" || break
> -
> -        if $check_timeout; then
> -            if [ $(($timeout % 5)) -eq 0 ]; then
> -                printf "$format" "$name" "$timeout"
> -            fi
> -            timeout=$(($timeout - 1))
> -        else
> -            slept=$(($slept + 1))
> -            if [ $(($slept % 5)) -eq 0 ]; then
> -                printf "$format" "$name"
> -            fi
> -        fi
> -    done
> -
> -    if guest_is_on "$uri" "$guest"; then
> -        if "$guest_running"; then
> -            eval_gettext "Shutdown of guest \$name failed to complete in time."
> -        else
> -            eval_gettext "Shutdown of guest \$name complete."
> -        fi
> -    fi
> -}
> -
> -# shutdown_guest_async URI GUEST
> -# Start a ACPI shutdown of GUEST on URI. This function returns after the command
> -# was issued to libvirt to allow parallel shutdown.
> -shutdown_guest_async()
> -{
> -    uri=$1
> -    guest=$2
> -
> -    name=$(guest_name "$uri" "$guest")
> -    eval_gettext "Starting shutdown on guest: \$name"
> -    echo
> -    retval run_virsh "$uri" shutdown "$guest" > /dev/null
> -}
> -
> -# guest_count GUEST_LIST
> -# Returns number of guests in GUEST_LIST
> -guest_count()
> -{
> -    set -- $1
> -    echo $#
> -}
> -
> -# check_guests_shutdown URI GUESTS
> -# check if shutdown is complete on guests in "GUESTS" and returns only
> -# guests that are still shutting down
> -check_guests_shutdown()
> -{
> -    uri=$1
> -    guests=$2
> -
> -    guests_up=
> -    for guest in $guests; do
> -        if ! guest_is_on "$uri" "$guest" >/dev/null 2>&1; then
> -            eval_gettext "Failed to determine state of guest: \$guest. Not tracking it anymore."
> -            echo
> -            continue
> -        fi
> -        if "$guest_running"; then
> -            guests_up="$guests_up $guest"
> -        fi
> -    done
> -    echo "$guests_up"
> -}
> -
> -# print_guests_shutdown URI BEFORE AFTER
> -# Checks for differences in the lists BEFORE and AFTER and prints
> -# a shutdown complete notice for guests that have finished
> -print_guests_shutdown()
> -{
> -    uri=$1
> -    before=$2
> -    after=$3
> -
> -    for guest in $before; do
> -        case " $after " in
> -            *" $guest "*) continue;;
> -        esac
> -
> -        name=$(guest_name "$uri" "$guest")
> -        eval_gettext "Shutdown of guest \$name complete."
> -        echo
> -    done
> -}
> -
> -# shutdown_guests_parallel URI GUESTS
> -# Shutdown guests GUESTS on machine URI in parallel
> -shutdown_guests_parallel()
> -{
> -    uri=$1
> -    guests=$2
> -
> -    on_shutdown=
> -    check_timeout=false
> -    timeout=$SHUTDOWN_TIMEOUT
> -    if [ $timeout -gt 0 ]; then
> -        check_timeout=true
> -        format=$(eval_gettext "Waiting for %d guests to shut down, %d seconds left\n")
> -    else
> -        slept=0
> -        format=$(eval_gettext "Waiting for %d guests to shut down\n")
> -    fi
> -    while [ -n "$on_shutdown" ] || [ -n "$guests" ]; do
> -        while [ -n "$guests" ] &&
> -              [ $(guest_count "$on_shutdown") -lt "$PARALLEL_SHUTDOWN" ]; do
> -            set -- $guests
> -            guest=$1
> -            shift
> -            guests=$*
> -            shutdown_guest_async "$uri" "$guest"
> -            on_shutdown="$on_shutdown $guest"
> -        done
> -        sleep 1
> -
> -        set -- $guests
> -        guestcount=$#
> -        set -- $on_shutdown
> -        shutdowncount=$#
> -
> -        if $check_timeout; then
> -            if [ $(($timeout % 5)) -eq 0 ]; then
> -                printf "$format" $(($guestcount + $shutdowncount)) "$timeout"
> -            fi
> -            timeout=$(($timeout - 1))
> -            if [ $timeout -le 0 ]; then
> -                eval_gettext "Timeout expired while shutting down domains"; echo
> -                RETVAL=1
> -                return
> -            fi
> -        else
> -            slept=$(($slept + 1))
> -            if [ $(($slept % 5)) -eq 0 ]; then
> -                printf "$format" $(($guestcount + $shutdowncount))
> -            fi
> -        fi
> -
> -        on_shutdown_prev=$on_shutdown
> -        on_shutdown=$(check_guests_shutdown "$uri" "$on_shutdown")
> -        print_guests_shutdown "$uri" "$on_shutdown_prev" "$on_shutdown"
> -    done
> -}
> -
> -# stop
> -# Shutdown or save guests on the configured uris
> -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 -lt 0 ]; then
> -            gettext "SHUTDOWN_TIMEOUT must be equal or greater than 0"
> -            echo
> -            RETVAL=6
> -            return
> -        fi
> -    fi
> -
> -    : >"$LISTFILE"
> -    set -f
> -    for uri in $URIS; do
> -        set +f
> -
> -        test_connect "$uri" || continue
> -
> -        eval_gettext "Running guests on \$uri URI: "
> -
> -        list=$(list_guests "$uri")
> -        if [ $? -eq 0 ]; then
> -            empty=true
> -            for uuid in $list; do
> -                "$empty" || printf ", "
> -                printf %s "$(guest_name "$uri" "$uuid")"
> -                empty=false
> -            done
> -
> -            if "$empty"; then
> -                gettext "no running guests."
> -            fi
> -            echo
> -        fi
> -
> -        if "$suspending"; then
> -            transient=$(list_guests "$uri" "--transient")
> -            if [ $? -eq 0 ]; then
> -                empty=true
> -                for uuid in $transient; do
> -                    if "$empty"; then
> -                        eval_gettext "Not suspending transient guests on URI: \$uri: "
> -                        empty=false
> -                    else
> -                        printf ", "
> -                    fi
> -                    printf %s "$(guest_name "$uri" "$uuid")"
> -                done
> -                echo
> -                # reload domain list to contain only persistent guests
> -                list=$(list_guests "$uri" "--persistent")
> -                if [ $? -ne 0 ]; then
> -                    eval_gettext "Failed to list persistent guests on \$uri"
> -                    echo
> -                    RETVAL=1
> -                    set +f
> -                    return
> -                fi
> -            else
> -                gettext "Failed to list transient guests"
> -                echo
> -                RETVAL=1
> -                set +f
> -                return
> -            fi
> -        fi
> -
> -        if [ -n "$list" ]; then
> -            echo "$uri" "$list" >>"$LISTFILE"
> -        fi
> -    done
> -    set +f
> -
> -    if [ -s "$LISTFILE" ]; then
> -        while read uri list; do
> -            if "$suspending"; then
> -                eval_gettext "Suspending guests on \$uri URI..."; echo
> -            else
> -                eval_gettext "Shutting down guests on \$uri URI..."; echo
> -            fi
> -
> -            if [ "$PARALLEL_SHUTDOWN" -gt 1 ] &&
> -               ! "$suspending"; then
> -                shutdown_guests_parallel "$uri" "$list"
> -            else
> -                for guest in $list; do
> -                    if "$suspending"; then
> -                        suspend_guest "$uri" "$guest"
> -                    else
> -                        shutdown_guest "$uri" "$guest"
> -                    fi
> -                done
> -            fi
> -        done <"$LISTFILE"
> -    else
> -        rm -f "$LISTFILE"
> -    fi
> -
> -    rm -f "$VAR_SUBSYS_LIBVIRT_GUESTS"
> -}
> -
> -# gueststatus
> -# List status of guests
> -gueststatus() {
> -    set -f
> -    for uri in $URIS; do
> -        set +f
> -        echo "* $uri URI:"
> -        retval run_virsh "$uri" list || echo
> -    done
> -    set +f
> -}
> -
> -# rh_status
> -# Display current status: whether saved state exists, and whether start
> -# has been executed.  We cannot use status() from the functions library,
> -# since there is no external daemon process matching this init script.
> -rh_status() {
> -    if [ -f "$LISTFILE" ]; then
> -        gettext "stopped, with saved guests"; echo
> -        RETVAL=3
> -    else
> -        if [ -f "$VAR_SUBSYS_LIBVIRT_GUESTS" ]; then
> -            gettext "started"; echo
> -        else
> -            gettext "stopped, with no saved guests"; echo
> -        fi
> -        RETVAL=0
> -    fi
> -}
> -
> -# usage [val]
> -# Display usage string, then exit with VAL (defaults to 2).
> -usage() {
> -    program_name=$0
> -    eval_gettext "Usage: \$program_name {start|stop|status|restart|"\
> -"condrestart|try-restart|reload|force-reload|gueststatus|shutdown}"; echo
> -    exit ${1-2}
> -}
> -
> -# See how we were called.
> -if test $# != 1; then
> -    usage
> -fi
> -case "$1" in
> -    --help)
> -        usage 0
> -        ;;
> -    start|stop|gueststatus)
> -        "$1"
> -        ;;
> -    restart)
> -        stop && start
> -        ;;
> -    condrestart|try-restart)
> -        [ -f "$VAR_SUBSYS_LIBVIRT_GUESTS" ] && stop && start
> -        ;;
> -    reload|force-reload)
> -        # Nothing to do; we reread configuration on each invocation
> -        ;;
> -    status)
> -        rh_status
> -        ;;
> -    shutdown)
> -        ON_SHUTDOWN=shutdown
> -        stop
> -        ;;
> -    *)
> -        usage
> -        ;;
> -esac
> -exit $RETVAL
> diff --git a/tools/libvirt-guests.service.in b/tools/libvirt-guests.service.in
> index 0f0c41c..d41bf2b 100644
> --- a/tools/libvirt-guests.service.in
> +++ b/tools/libvirt-guests.service.in
> @@ -6,8 +6,8 @@ After=syslog.target network.target
>  EnvironmentFile=-/etc/sysconfig/libvirt-guests
>  # Hack just call traditional service until we factor
>  # out the code
> -ExecStart=/etc/init.d/libvirt-guests start
> -ExecStop=/etc/init.d/libvirt-guests stop
> +ExecStart= libexecdir@/libvirt-guests.sh start
> +ExecStop= libexecdir@/libvirt-guests.sh stop
>  Type=oneshot
>  RemainAfterExit=yes
>  StandardOutput=journal+console
> diff --git a/tools/libvirt-guests.sh.in b/tools/libvirt-guests.sh.in
> new file mode 100644
> index 0000000..1c9c46b
> --- /dev/null
> +++ b/tools/libvirt-guests.sh.in
> @@ -0,0 +1,573 @@
> +#!/bin/sh
> +
> +sysconfdir="@sysconfdir@"
> +localstatedir="@localstatedir@"
> +libvirtd="@sbindir@"/libvirtd
> +
> +# Source function library.
> +test ! -r "$sysconfdir"/rc.d/init.d/functions ||
> +    . "$sysconfdir"/rc.d/init.d/functions
> +
> +# Source gettext library.
> +# Make sure this file is recognized as having translations: _("dummy")
> +. "@bindir@"/gettext.sh
> +
> +export TEXTDOMAIN="@PACKAGE@" TEXTDOMAINDIR="@localedir@"
> +
> +URIS=default
> +ON_BOOT=start
> +ON_SHUTDOWN=suspend
> +SHUTDOWN_TIMEOUT=300
> +PARALLEL_SHUTDOWN=0
> +START_DELAY=0
> +BYPASS_CACHE=0
> +
> +test -f "$sysconfdir"/sysconfig/libvirt-guests &&
> +    . "$sysconfdir"/sysconfig/libvirt-guests
> +
> +LISTFILE="$localstatedir"/lib/libvirt/libvirt-guests
> +VAR_SUBSYS_LIBVIRT_GUESTS="$localstatedir"/lock/subsys/libvirt-guests
> +
> +RETVAL=0
> +
> +# retval COMMAND ARGUMENTS...
> +# run command with arguments and convert non-zero return value to 1 and set
> +# the global return variable
> +retval() {
> +    "$@"
> +    if [ $? -ne 0 ]; then
> +        RETVAL=1
> +        return 1
> +    else
> +        return 0
> +    fi
> +}
> +
> +# run_virsh URI ARGUMENTS...
> +# start virsh and let it execute ARGUMENTS on URI
> +# If URI is "default" virsh is called without the "-c" argument
> +# (using libvirt's default connection)
> +run_virsh() {
> +    uri=$1
> +    shift
> +
> +    if [ "x$uri" = xdefault ]; then
> +        virsh "$@" </dev/null
> +    else
> +        virsh -c "$uri" "$@" </dev/null
> +    fi
> +}
> +
> +# run_virsh_c URI ARGUMENTS
> +# Same as "run_virsh" but the "C" locale is used instead of
> +# the system's locale.
> +run_virsh_c() {
> +    ( export LC_ALL=C; run_virsh "$@" )
> +}
> +
> +# test_connect URI
> +# check if URI is reachable
> +test_connect()
> +{
> +    uri=$1
> +
> +    run_virsh "$uri" connect 2>/dev/null
> +    if [ $? -ne 0 ]; then
> +        eval_gettext "Can't connect to \$uri. Skipping."
> +        echo
> +        return 1
> +    fi
> +}
> +
> +# list_guests URI PERSISTENT
> +# List running guests on URI.
> +# PERSISTENT argument options:
> +# --persistent: list only persistent guests
> +# --transient: list only transient guests
> +# [none]: list both persistent and transient guests
> +list_guests() {
> +    uri=$1
> +    persistent=$2
> +
> +    list=$(run_virsh_c "$uri" list --uuid $persistent)
> +    if [ $? -ne 0 ]; then
> +        RETVAL=1
> +        return 1
> +    fi
> +
> +    echo $list
> +}
> +
> +# guest_name URI UUID
> +# return name of guest UUID on URI
> +guest_name() {
> +    uri=$1
> +    uuid=$2
> +
> +    run_virsh "$uri" domname "$uuid" 2>/dev/null
> +}
> +
> +# guest_is_on URI UUID
> +# check if guest UUID on URI is running
> +# Result is returned by variable "guest_running"
> +guest_is_on() {
> +    uri=$1
> +    uuid=$2
> +
> +    guest_running=false
> +    id=$(run_virsh "$uri" domid "$uuid")
> +    if [ $? -ne 0 ]; then
> +        RETVAL=1
> +        return 1
> +    fi
> +
> +    [ -n "$id" ] && [ "x$id" != x- ] && guest_running=true
> +    return 0
> +}
> +
> +# started
> +# Create the startup lock file
> +started() {
> +    touch "$VAR_SUBSYS_LIBVIRT_GUESTS"
> +}
> +
> +# start
> +# Start or resume the guests
> +start() {
> +    [ -f "$LISTFILE" ] || { started; return 0; }
> +
> +    if [ "x$ON_BOOT" != xstart ]; then
> +        gettext "libvirt-guests is configured not to start any guests on boot"
> +        echo
> +        rm -f "$LISTFILE"
> +        started
> +        return 0
> +    fi
> +
> +    isfirst=true
> +    bypass=
> +    test "x$BYPASS_CACHE" = x0 || bypass=--bypass-cache
> +    while read uri list; do
> +        configured=false
> +        set -f
> +        for confuri in $URIS; do
> +            set +f
> +            if [ "x$confuri" = "x$uri" ]; then
> +                configured=true
> +                break
> +            fi
> +        done
> +        set +f
> +        if ! "$configured"; then
> +            eval_gettext "Ignoring guests on \$uri URI"; echo
> +            continue
> +        fi
> +
> +        test_connect "$uri" || continue
> +
> +        eval_gettext "Resuming guests on \$uri URI..."; echo
> +        for guest in $list; do
> +            name=$(guest_name "$uri" "$guest")
> +            eval_gettext "Resuming guest \$name: "
> +            if guest_is_on "$uri" "$guest"; then
> +                if "$guest_running"; then
> +                    gettext "already active"; echo
> +                else
> +                    if "$isfirst"; then
> +                        isfirst=false
> +                    else
> +                        sleep $START_DELAY
> +                    fi
> +                    retval run_virsh "$uri" start $bypass "$name" \
> +                        >/dev/null && \
> +                    gettext "done"; echo
> +                fi
> +            fi
> +        done
> +    done <"$LISTFILE"
> +
> +    rm -f "$LISTFILE"
> +    started
> +}
> +
> +# suspend_guest URI GUEST
> +# Do a managed save on a GUEST on URI. This function returns after the guest
> +# was saved.
> +suspend_guest()
> +{
> +    uri=$1
> +    guest=$2
> +
> +    name=$(guest_name "$uri" "$guest")
> +    label=$(eval_gettext "Suspending \$name: ")
> +    bypass=
> +    slept=0
> +    test "x$BYPASS_CACHE" = x0 || bypass=--bypass-cache
> +    printf '%s...\n' "$label"
> +    run_virsh "$uri" managedsave $bypass "$guest" >/dev/null &
> +    virsh_pid=$!
> +    while true; do
> +        sleep 1
> +        kill -0 "$virsh_pid" >/dev/null 2>&1 || break
> +
> +        slept=$(($slept + 1))
> +        if [ $(($slept % 5)) -eq 0 ]; then
> +            progress=$(run_virsh_c "$uri" domjobinfo "$guest" 2>/dev/null | \
> +                    awk '/^Data processed:/{print $3, $4}')
> +            if [ -n "$progress" ]; then
> +                printf '%s%s\n' "$label" "$progress"
> +            else
> +                printf '%s%s\n' "$label" "..."
> +            fi
> +        fi
> +    done
> +    retval wait "$virsh_pid" && printf '%s%s\n' "$label" "$(gettext "done")"
> +}
> +
> +# shutdown_guest URI GUEST
> +# Start a ACPI shutdown of GUEST on URI. This function return after the quest
> +# was successfully shutdown or the timeout defined by $SHUTDOWN_TIMEOUT expires.
> +shutdown_guest()
> +{
> +    uri=$1
> +    guest=$2
> +
> +    name=$(guest_name "$uri" "$guest")
> +    eval_gettext "Starting shutdown on guest: \$name"
> +    echo
> +    retval run_virsh "$uri" shutdown "$guest" >/dev/null || return
> +    timeout=$SHUTDOWN_TIMEOUT
> +    check_timeout=false
> +    if [ $timeout -gt 0 ]; then
> +        check_timeout=true
> +        format=$(eval_gettext "Waiting for guest %s to shut down, %d seconds left\n")
> +    else
> +        slept=0
> +        format=$(eval_gettext "Waiting for guest %s to shut down\n")
> +    fi
> +    while ! $check_timeout || [ "$timeout" -gt 0 ]; do
> +        sleep 1
> +        guest_is_on "$uri" "$guest" || return
> +        "$guest_running" || break
> +
> +        if $check_timeout; then
> +            if [ $(($timeout % 5)) -eq 0 ]; then
> +                printf "$format" "$name" "$timeout"
> +            fi
> +            timeout=$(($timeout - 1))
> +        else
> +            slept=$(($slept + 1))
> +            if [ $(($slept % 5)) -eq 0 ]; then
> +                printf "$format" "$name"
> +            fi
> +        fi
> +    done
> +
> +    if guest_is_on "$uri" "$guest"; then
> +        if "$guest_running"; then
> +            eval_gettext "Shutdown of guest \$name failed to complete in time."
> +        else
> +            eval_gettext "Shutdown of guest \$name complete."
> +        fi
> +    fi
> +}
> +
> +# shutdown_guest_async URI GUEST
> +# Start a ACPI shutdown of GUEST on URI. This function returns after the command
> +# was issued to libvirt to allow parallel shutdown.
> +shutdown_guest_async()
> +{
> +    uri=$1
> +    guest=$2
> +
> +    name=$(guest_name "$uri" "$guest")
> +    eval_gettext "Starting shutdown on guest: \$name"
> +    echo
> +    retval run_virsh "$uri" shutdown "$guest" > /dev/null
> +}
> +
> +# guest_count GUEST_LIST
> +# Returns number of guests in GUEST_LIST
> +guest_count()
> +{
> +    set -- $1
> +    echo $#
> +}
> +
> +# check_guests_shutdown URI GUESTS
> +# check if shutdown is complete on guests in "GUESTS" and returns only
> +# guests that are still shutting down
> +check_guests_shutdown()
> +{
> +    uri=$1
> +    guests=$2
> +
> +    guests_up=
> +    for guest in $guests; do
> +        if ! guest_is_on "$uri" "$guest" >/dev/null 2>&1; then
> +            eval_gettext "Failed to determine state of guest: \$guest. Not tracking it anymore."
> +            echo
> +            continue
> +        fi
> +        if "$guest_running"; then
> +            guests_up="$guests_up $guest"
> +        fi
> +    done
> +    echo "$guests_up"
> +}
> +
> +# print_guests_shutdown URI BEFORE AFTER
> +# Checks for differences in the lists BEFORE and AFTER and prints
> +# a shutdown complete notice for guests that have finished
> +print_guests_shutdown()
> +{
> +    uri=$1
> +    before=$2
> +    after=$3
> +
> +    for guest in $before; do
> +        case " $after " in
> +            *" $guest "*) continue;;
> +        esac
> +
> +        name=$(guest_name "$uri" "$guest")
> +        eval_gettext "Shutdown of guest \$name complete."
> +        echo
> +    done
> +}
> +
> +# shutdown_guests_parallel URI GUESTS
> +# Shutdown guests GUESTS on machine URI in parallel
> +shutdown_guests_parallel()
> +{
> +    uri=$1
> +    guests=$2
> +
> +    on_shutdown=
> +    check_timeout=false
> +    timeout=$SHUTDOWN_TIMEOUT
> +    if [ $timeout -gt 0 ]; then
> +        check_timeout=true
> +        format=$(eval_gettext "Waiting for %d guests to shut down, %d seconds left\n")
> +    else
> +        slept=0
> +        format=$(eval_gettext "Waiting for %d guests to shut down\n")
> +    fi
> +    while [ -n "$on_shutdown" ] || [ -n "$guests" ]; do
> +        while [ -n "$guests" ] &&
> +              [ $(guest_count "$on_shutdown") -lt "$PARALLEL_SHUTDOWN" ]; do
> +            set -- $guests
> +            guest=$1
> +            shift
> +            guests=$*
> +            shutdown_guest_async "$uri" "$guest"
> +            on_shutdown="$on_shutdown $guest"
> +        done
> +        sleep 1
> +
> +        set -- $guests
> +        guestcount=$#
> +        set -- $on_shutdown
> +        shutdowncount=$#
> +
> +        if $check_timeout; then
> +            if [ $(($timeout % 5)) -eq 0 ]; then
> +                printf "$format" $(($guestcount + $shutdowncount)) "$timeout"
> +            fi
> +            timeout=$(($timeout - 1))
> +            if [ $timeout -le 0 ]; then
> +                eval_gettext "Timeout expired while shutting down domains"; echo
> +                RETVAL=1
> +                return
> +            fi
> +        else
> +            slept=$(($slept + 1))
> +            if [ $(($slept % 5)) -eq 0 ]; then
> +                printf "$format" $(($guestcount + $shutdowncount))
> +            fi
> +        fi
> +
> +        on_shutdown_prev=$on_shutdown
> +        on_shutdown=$(check_guests_shutdown "$uri" "$on_shutdown")
> +        print_guests_shutdown "$uri" "$on_shutdown_prev" "$on_shutdown"
> +    done
> +}
> +
> +# stop
> +# Shutdown or save guests on the configured uris
> +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 -lt 0 ]; then
> +            gettext "SHUTDOWN_TIMEOUT must be equal or greater than 0"
> +            echo
> +            RETVAL=6
> +            return
> +        fi
> +    fi
> +
> +    : >"$LISTFILE"
> +    set -f
> +    for uri in $URIS; do
> +        set +f
> +
> +        test_connect "$uri" || continue
> +
> +        eval_gettext "Running guests on \$uri URI: "
> +
> +        list=$(list_guests "$uri")
> +        if [ $? -eq 0 ]; then
> +            empty=true
> +            for uuid in $list; do
> +                "$empty" || printf ", "
> +                printf %s "$(guest_name "$uri" "$uuid")"
> +                empty=false
> +            done
> +
> +            if "$empty"; then
> +                gettext "no running guests."
> +            fi
> +            echo
> +        fi
> +
> +        if "$suspending"; then
> +            transient=$(list_guests "$uri" "--transient")
> +            if [ $? -eq 0 ]; then
> +                empty=true
> +                for uuid in $transient; do
> +                    if "$empty"; then
> +                        eval_gettext "Not suspending transient guests on URI: \$uri: "
> +                        empty=false
> +                    else
> +                        printf ", "
> +                    fi
> +                    printf %s "$(guest_name "$uri" "$uuid")"
> +                done
> +                echo
> +                # reload domain list to contain only persistent guests
> +                list=$(list_guests "$uri" "--persistent")
> +                if [ $? -ne 0 ]; then
> +                    eval_gettext "Failed to list persistent guests on \$uri"
> +                    echo
> +                    RETVAL=1
> +                    set +f
> +                    return
> +                fi
> +            else
> +                gettext "Failed to list transient guests"
> +                echo
> +                RETVAL=1
> +                set +f
> +                return
> +            fi
> +        fi
> +
> +        if [ -n "$list" ]; then
> +            echo "$uri" "$list" >>"$LISTFILE"
> +        fi
> +    done
> +    set +f
> +
> +    if [ -s "$LISTFILE" ]; then
> +        while read uri list; do
> +            if "$suspending"; then
> +                eval_gettext "Suspending guests on \$uri URI..."; echo
> +            else
> +                eval_gettext "Shutting down guests on \$uri URI..."; echo
> +            fi
> +
> +            if [ "$PARALLEL_SHUTDOWN" -gt 1 ] &&
> +               ! "$suspending"; then
> +                shutdown_guests_parallel "$uri" "$list"
> +            else
> +                for guest in $list; do
> +                    if "$suspending"; then
> +                        suspend_guest "$uri" "$guest"
> +                    else
> +                        shutdown_guest "$uri" "$guest"
> +                    fi
> +                done
> +            fi
> +        done <"$LISTFILE"
> +    else
> +        rm -f "$LISTFILE"
> +    fi
> +
> +    rm -f "$VAR_SUBSYS_LIBVIRT_GUESTS"
> +}
> +
> +# gueststatus
> +# List status of guests
> +gueststatus() {
> +    set -f
> +    for uri in $URIS; do
> +        set +f
> +        echo "* $uri URI:"
> +        retval run_virsh "$uri" list || echo
> +    done
> +    set +f
> +}
> +
> +# rh_status
> +# Display current status: whether saved state exists, and whether start
> +# has been executed.  We cannot use status() from the functions library,
> +# since there is no external daemon process matching this init script.
> +rh_status() {
> +    if [ -f "$LISTFILE" ]; then
> +        gettext "stopped, with saved guests"; echo
> +        RETVAL=3
> +    else
> +        if [ -f "$VAR_SUBSYS_LIBVIRT_GUESTS" ]; then
> +            gettext "started"; echo
> +        else
> +            gettext "stopped, with no saved guests"; echo
> +        fi
> +        RETVAL=0
> +    fi
> +}
> +
> +# usage [val]
> +# Display usage string, then exit with VAL (defaults to 2).
> +usage() {
> +    program_name=$0
> +    eval_gettext "Usage: \$program_name {start|stop|status|restart|"\
> +"condrestart|try-restart|reload|force-reload|gueststatus|shutdown}"; echo
> +    exit ${1-2}
> +}
> +
> +# See how we were called.
> +if test $# != 1; then
> +    usage
> +fi
> +case "$1" in
> +    --help)
> +        usage 0
> +        ;;
> +    start|stop|gueststatus)
> +        "$1"
> +        ;;
> +    restart)
> +        stop && start
> +        ;;
> +    condrestart|try-restart)
> +        [ -f "$VAR_SUBSYS_LIBVIRT_GUESTS" ] && stop && start
> +        ;;
> +    reload|force-reload)
> +        # Nothing to do; we reread configuration on each invocation
> +        ;;
> +    status)
> +        rh_status
> +        ;;
> +    shutdown)
> +        ON_SHUTDOWN=shutdown
> +        stop
> +        ;;
> +    *)
> +        usage
> +        ;;
> +esac
> +exit $RETVAL
> 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]