From fccbb49ccaf7ffe067052d800dad08448a666cab Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 5 Mar 2014 12:50:17 -0500 Subject: [PATCH] Fix libvirt-guests.service on host boot (bz #1031696) --- ...tion-fields-to-systemd-service-files.patch | 54 +++++ ...eMachine-Set-dependencies-for-slices.patch | 41 ++++ ...ests-Wait-for-libvirtd-to-initialize.patch | 61 ++++++ ...Notify-systemd-that-we-re-accepting-.patch | 193 ++++++++++++++++++ libvirt.spec | 17 +- 5 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 0001-Add-Documentation-fields-to-systemd-service-files.patch create mode 100644 0002-virSystemdCreateMachine-Set-dependencies-for-slices.patch create mode 100644 0003-libvirt-guests-Wait-for-libvirtd-to-initialize.patch create mode 100644 0004-virNetServerRun-Notify-systemd-that-we-re-accepting-.patch diff --git a/0001-Add-Documentation-fields-to-systemd-service-files.patch b/0001-Add-Documentation-fields-to-systemd-service-files.patch new file mode 100644 index 0000000..e5f19bf --- /dev/null +++ b/0001-Add-Documentation-fields-to-systemd-service-files.patch @@ -0,0 +1,54 @@ +From f599cc7aa26bc0218e8cd0311d7307931763345a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Guido=20G=C3=BCnther?= +Date: Wed, 8 Jan 2014 19:55:19 +0100 +Subject: [PATCH] Add Documentation fields to systemd service files + +We point to the manpages where available and redirect to libvirt's +homepage as a last resort. + +(cherry picked from commit 1b9f5aa7fe67d9d4bb843db3580bdbc917c49a10) +--- + daemon/libvirtd.service.in | 2 ++ + src/locking/virtlockd.service.in | 2 ++ + tools/libvirt-guests.service.in | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/daemon/libvirtd.service.in b/daemon/libvirtd.service.in +index 25979ef..dc2433a 100644 +--- a/daemon/libvirtd.service.in ++++ b/daemon/libvirtd.service.in +@@ -9,6 +9,8 @@ Before=libvirt-guests.service + After=network.target + After=dbus.service + After=iscsid.service ++Documentation=man:libvirtd(8) ++Documentation=http://libvirt.org + + [Service] + EnvironmentFile=-/etc/sysconfig/libvirtd +diff --git a/src/locking/virtlockd.service.in b/src/locking/virtlockd.service.in +index 0ef9923..059c14e 100644 +--- a/src/locking/virtlockd.service.in ++++ b/src/locking/virtlockd.service.in +@@ -1,6 +1,8 @@ + [Unit] + Description=Virtual machine lock manager + Requires=virtlockd.socket ++Documentation=man:virtlockd(8) ++Documentation=http://libvirt.org + + [Service] + EnvironmentFile=-/etc/sysconfig/virtlockd +diff --git a/tools/libvirt-guests.service.in b/tools/libvirt-guests.service.in +index d48d4b8..d8d7adf 100644 +--- a/tools/libvirt-guests.service.in ++++ b/tools/libvirt-guests.service.in +@@ -1,6 +1,8 @@ + [Unit] + Description=Suspend Active Libvirt Guests + After=network.target libvirtd.service ++Documentation=man:libvirtd(8) ++Documentation=http://libvirt.org + + [Service] + EnvironmentFile=-/etc/sysconfig/libvirt-guests diff --git a/0002-virSystemdCreateMachine-Set-dependencies-for-slices.patch b/0002-virSystemdCreateMachine-Set-dependencies-for-slices.patch new file mode 100644 index 0000000..213ced0 --- /dev/null +++ b/0002-virSystemdCreateMachine-Set-dependencies-for-slices.patch @@ -0,0 +1,41 @@ +From 08abb8225b8104693e71d0f0e610edfdefb085f2 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 21 Feb 2014 10:16:36 +0100 +Subject: [PATCH] virSystemdCreateMachine: Set dependencies for slices + +https://bugzilla.redhat.com/show_bug.cgi?id=1031696 + +When creating a new domain, we let systemd know about it by calling +CreateMachine() function via dbus. Systemd then creates a scope and +places domain into it. However, later when the host is shutting +down, systemd computes the shutdown order to see what processes can +be shut down in parallel. And since we were not setting +dependencies at all, the slices (and thus domains) were most likely +killed before libvirt-guests.service. So user domains that had to +be saved, shut off, whatever were in fact killed. This problem can +be solved by letting systemd know that scopes we're creating must +not be killed before libvirt-guests.service. + +Signed-off-by: Michal Privoznik +(cherry picked from commit ba79e3879e771417ee90e125d8b38743a867d7d1) +--- + src/util/virsystemd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 1ba37cc..4e2721b 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -242,8 +242,10 @@ int virSystemdCreateMachine(const char *name, + iscontainer ? "container" : "vm", + (unsigned int)pidleader, + rootdir ? rootdir : "", +- 1, "Slice", "s", +- slicename) < 0) ++ 3, ++ "Slice", "s", slicename, ++ "After", "as", 1, "libvirtd.service", ++ "Before", "as", 1, "libvirt-guests.service") < 0) + goto cleanup; + + ret = 0; diff --git a/0003-libvirt-guests-Wait-for-libvirtd-to-initialize.patch b/0003-libvirt-guests-Wait-for-libvirtd-to-initialize.patch new file mode 100644 index 0000000..8a9f05e --- /dev/null +++ b/0003-libvirt-guests-Wait-for-libvirtd-to-initialize.patch @@ -0,0 +1,61 @@ +From 393ffe6c3f7c72bfe8c6d254adf37e6f42169024 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 21 Feb 2014 12:46:08 +0100 +Subject: [PATCH] libvirt-guests: Wait for libvirtd to initialize + +I've noticed that in some cases systemd was quick enough and even +if libvirt-guests.service is marked to be started after the +libvirtd.service my guests were not resumed as +libvirt-guests.sh failed to connect. This is because of a +simple fact: systemd correctly starts libvirt-guests after it +execs libvirtd. However, the daemon is not able to accept +connections right from the start. It's doing some +initialization which may take ages. This problem is not limited +to systemd only, indeed. Any init system that is able to startup +services in parallel (e.g. OpenRC) may run into this situation. +The fix is to try connecting not only once, but continuously a few +times with a small sleep in between tries. + +Signed-off-by: Michal Privoznik +(cherry picked from commit 4e7fc8305a53676ba2362bfaa8ca05c4851b7e12) +--- + tools/libvirt-guests.sh.in | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/tools/libvirt-guests.sh.in b/tools/libvirt-guests.sh.in +index 38e93c5..4bbd4e4 100644 +--- a/tools/libvirt-guests.sh.in ++++ b/tools/libvirt-guests.sh.in +@@ -37,6 +37,8 @@ SHUTDOWN_TIMEOUT=300 + PARALLEL_SHUTDOWN=0 + START_DELAY=0 + BYPASS_CACHE=0 ++CONNECT_RETRIES=10 ++RETRIES_SLEEP=1 + + test -f "$sysconfdir"/sysconfig/libvirt-guests && + . "$sysconfdir"/sysconfig/libvirt-guests +@@ -87,12 +89,17 @@ 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 ++ for ((i = 0; i < ${CONNECT_RETRIES}; i++)); do ++ run_virsh "$uri" connect 2>/dev/null ++ if [ $? -eq 0 ]; then ++ return 0; ++ fi ++ sleep ${RETRIES_SLEEP} ++ eval_gettext "Unable to connect to libvirt currently. Retrying .. \$i" ++ done ++ eval_gettext "Can't connect to \$uri. Skipping." ++ echo ++ return 1 + } + + # list_guests URI PERSISTENT diff --git a/0004-virNetServerRun-Notify-systemd-that-we-re-accepting-.patch b/0004-virNetServerRun-Notify-systemd-that-we-re-accepting-.patch new file mode 100644 index 0000000..5fff5c3 --- /dev/null +++ b/0004-virNetServerRun-Notify-systemd-that-we-re-accepting-.patch @@ -0,0 +1,193 @@ +From 876861ca02d466c70ab0782bbdb4bf03d4e03148 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 21 Feb 2014 13:06:42 +0100 +Subject: [PATCH] virNetServerRun: Notify systemd that we're accepting clients + +Systemd does not forget about the cases, where client service needs to +wait for daemon service to initialize and start accepting new clients. +Setting a dependency in client is not enough as systemd doesn't know +when the daemon has initialized itself and started accepting new +clients. However, it offers a mechanism to solve this. The daemon needs +to call a special systemd function by which the daemon tells "I'm ready +to accept new clients". This is exactly what we need with +libvirtd-guests (client) and libvirtd (daemon). So now, with this +change, libvirt-guests.service is invoked not any sooner than +libvirtd.service calls the systemd notify function. + +Signed-off-by: Michal Privoznik +(cherry picked from commit 68954fb25c4a75c5c2c213f57927eb188cca2239) +--- + configure.ac | 2 ++ + daemon/libvirtd.service.in | 1 + + m4/virt-systemd-daemon.m4 | 34 ++++++++++++++++++++++++++++++++++ + src/Makefile.am | 4 ++-- + src/libvirt_private.syms | 1 + + src/rpc/virnetserver.c | 5 +++++ + src/util/virsystemd.c | 12 ++++++++++++ + src/util/virsystemd.h | 2 ++ + 8 files changed, 59 insertions(+), 2 deletions(-) + create mode 100644 m4/virt-systemd-daemon.m4 + +diff --git a/configure.ac b/configure.ac +index aea0bd3..0d5cf59 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -228,6 +228,7 @@ LIBVIRT_CHECK_SANLOCK + LIBVIRT_CHECK_SASL + LIBVIRT_CHECK_SELINUX + LIBVIRT_CHECK_SSH2 ++LIBVIRT_CHECK_SYSTEMD_DAEMON + LIBVIRT_CHECK_UDEV + LIBVIRT_CHECK_YAJL + +@@ -2731,6 +2732,7 @@ LIBVIRT_RESULT_SANLOCK + LIBVIRT_RESULT_SASL + LIBVIRT_RESULT_SELINUX + LIBVIRT_RESULT_SSH2 ++LIBVIRT_RESULT_SYSTEMD_DAEMON + LIBVIRT_RESULT_UDEV + LIBVIRT_RESULT_YAJL + AC_MSG_NOTICE([ libxml: $LIBXML_CFLAGS $LIBXML_LIBS]) +diff --git a/daemon/libvirtd.service.in b/daemon/libvirtd.service.in +index dc2433a..e1f2a07 100644 +--- a/daemon/libvirtd.service.in ++++ b/daemon/libvirtd.service.in +@@ -13,6 +13,7 @@ Documentation=man:libvirtd(8) + Documentation=http://libvirt.org + + [Service] ++Type=notify + EnvironmentFile=-/etc/sysconfig/libvirtd + ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS + ExecReload=/bin/kill -HUP $MAINPID +diff --git a/m4/virt-systemd-daemon.m4 b/m4/virt-systemd-daemon.m4 +new file mode 100644 +index 0000000..8516e41 +--- /dev/null ++++ b/m4/virt-systemd-daemon.m4 +@@ -0,0 +1,34 @@ ++dnl The libsystemd-daemon.so library ++dnl ++dnl Copyright (C) 2012-2013 Red Hat, Inc. ++dnl ++dnl This library is free software; you can redistribute it and/or ++dnl modify it under the terms of the GNU Lesser General Public ++dnl License as published by the Free Software Foundation; either ++dnl version 2.1 of the License, or (at your option) any later version. ++dnl ++dnl This library is distributed in the hope that it will be useful, ++dnl but WITHOUT ANY WARRANTY; without even the implied warranty of ++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++dnl Lesser General Public License for more details. ++dnl ++dnl You should have received a copy of the GNU Lesser General Public ++dnl License along with this library. If not, see ++dnl . ++dnl ++ ++AC_DEFUN([LIBVIRT_CHECK_SYSTEMD_DAEMON],[ ++ LIBVIRT_CHECK_PKG([SYSTEMD_DAEMON], [libsystemd-daemon], [0.27.1]) ++ ++ old_CFLAGS="$CFLAGS" ++ old_LIBS="$LIBS" ++ CFLAGS="$CFLAGS $SYSTEMD_DAEMON_CFLAGS" ++ LIBS="$LIBS $SYSTEMD_DAEMON_LIBS" ++ AC_CHECK_FUNCS([sd_notify]) ++ CFLAGS="$old_CFLAGS" ++ LIBS="$old_LIBS" ++]) ++ ++AC_DEFUN([LIBVIRT_RESULT_SYSTEMD_DAEMON],[ ++ LIBVIRT_RESULT_LIB([SYSTEMD_DAEMON]) ++]) +diff --git a/src/Makefile.am b/src/Makefile.am +index 1a2cf6b..f813b68 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -933,11 +933,11 @@ libvirt_util_la_SOURCES = \ + libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \ + $(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) \ + $(DBUS_CFLAGS) $(LDEXP_LIBM) $(NUMACTL_CFLAGS) \ +- -I$(top_srcdir)/src/conf ++ $(SYSTEMD_DAEMON_CFLAGS) -I$(top_srcdir)/src/conf + libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \ + $(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \ + $(LIB_CLOCK_GETTIME) $(DBUS_LIBS) $(MSCOM_LIBS) $(LIBXML_LIBS) \ +- $(SECDRIVER_LIBS) $(NUMACTL_LIBS) ++ $(SECDRIVER_LIBS) $(NUMACTL_LIBS) $(SYSTEMD_DAEMON_LIBS) + + + noinst_LTLIBRARIES += libvirt_conf.la +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index d7bed65..babca5f 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1955,6 +1955,7 @@ virSystemdCreateMachine; + virSystemdMakeMachineName; + virSystemdMakeScopeName; + virSystemdMakeSliceName; ++virSystemdNotifyStartup; + virSystemdTerminateMachine; + + +diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c +index 2306e10..df61036 100644 +--- a/src/rpc/virnetserver.c ++++ b/src/rpc/virnetserver.c +@@ -38,6 +38,7 @@ + #include "virnetservermdns.h" + #include "virdbus.h" + #include "virstring.h" ++#include "virsystemd.h" + + #ifndef SA_SIGINFO + # define SA_SIGINFO 0 +@@ -1085,6 +1086,10 @@ void virNetServerRun(virNetServerPtr srv) + goto cleanup; + } + ++ /* We are accepting connections now. Notify systemd ++ * so it can start dependent services. */ ++ virSystemdNotifyStartup(); ++ + VIR_DEBUG("srv=%p quit=%d", srv, srv->quit); + while (!srv->quit) { + /* A shutdown timeout is specified, so check +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 4e2721b..d9837ce 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -21,6 +21,10 @@ + + #include + ++#ifdef WITH_SYSTEMD_DAEMON ++# include ++#endif ++ + #include "virsystemd.h" + #include "virdbus.h" + #include "virstring.h" +@@ -302,3 +306,11 @@ cleanup: + VIR_FREE(machinename); + return ret; + } ++ ++void ++virSystemdNotifyStartup(void) ++{ ++#ifdef WITH_SYSTEMD_DAEMON ++ sd_notify(0, "READY=1"); ++#endif ++} +diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h +index d9845e1..7fed456 100644 +--- a/src/util/virsystemd.h ++++ b/src/util/virsystemd.h +@@ -46,4 +46,6 @@ int virSystemdTerminateMachine(const char *name, + const char *drivername, + bool privileged); + ++void virSystemdNotifyStartup(void); ++ + #endif /* __VIR_SYSTEMD_H__ */ diff --git a/libvirt.spec b/libvirt.spec index 06ac4e9..e6b7c07 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -367,7 +367,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 1.1.3.4 -Release: 1%{?dist}%{?extra_release} +Release: 2%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -378,6 +378,12 @@ URL: http://libvirt.org/ %endif Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz +# Fix libvirt-guests.service on host boot (bz #1031696) +Patch0001: 0001-Add-Documentation-fields-to-systemd-service-files.patch +Patch0002: 0002-virSystemdCreateMachine-Set-dependencies-for-slices.patch +Patch0003: 0003-libvirt-guests-Wait-for-libvirtd-to-initialize.patch +Patch0004: 0004-virNetServerRun-Notify-systemd-that-we-re-accepting-.patch + %if %{with_libvirtd} Requires: libvirt-daemon = %{version}-%{release} %if %{with_network} @@ -1161,6 +1167,12 @@ of recent versions of Linux (and other OSes). %prep %setup -q +# Fix libvirt-guests.service on host boot (bz #1031696) +%patch0001 -p1 +%patch0002 -p1 +%patch0003 -p1 +%patch0004 -p1 + %build %if ! %{with_xen} %define _without_xen --without-xen @@ -2118,6 +2130,9 @@ fi %endif %changelog +* Wed Mar 05 2014 Cole Robinson - 1.1.3.4-2 +- Fix libvirt-guests.service on host boot (bz #1031696) + * Tue Feb 18 2014 Cole Robinson - 1.1.3.4-1 - Rebased to version 1.1.3.4 - Fix domain events when ACLs are used (bz #1058839)