systemd: directly notify systemd instead of using sd_notify

The sd_notify method is used to tell systemd when libvirtd
has finished starting up. All it does is send a datagram
containing the string parameter to systemd on a UNIX socket
named in the NOTIFY_SOCKET environment variable. Rather than
pulling in the systemd libraries for this, just code the
notification directly in libvirt as this is a stable ABI
from systemd's POV which explicitly allows independant
implementations:

See "Reimplementable Independently" column in the
"$NOTIFY_SOCKET Daemon Notifications" row:

https://www.freedesktop.org/wiki/Software/systemd/InterfacePortabilityAndStabilityChart/

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1314881

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2016-06-06 15:03:27 +01:00
parent 1b5f1884a2
commit c0bc172383
5 changed files with 50 additions and 55 deletions

View File

@ -256,7 +256,6 @@ LIBVIRT_CHECK_SANLOCK
LIBVIRT_CHECK_SASL
LIBVIRT_CHECK_SELINUX
LIBVIRT_CHECK_SSH2
LIBVIRT_CHECK_SYSTEMD_DAEMON
LIBVIRT_CHECK_UDEV
LIBVIRT_CHECK_WIRESHARK
LIBVIRT_CHECK_NSS
@ -2787,7 +2786,6 @@ LIBVIRT_RESULT_SANLOCK
LIBVIRT_RESULT_SASL
LIBVIRT_RESULT_SELINUX
LIBVIRT_RESULT_SSH2
LIBVIRT_RESULT_SYSTEMD_DAEMON
LIBVIRT_RESULT_UDEV
LIBVIRT_RESULT_WIRESHARK
LIBVIRT_RESULT_NSS

View File

@ -79,7 +79,6 @@
%define with_firewalld 0%{!?_without_firewalld:0}
%define with_libssh2 0%{!?_without_libssh2:0}
%define with_wireshark 0%{!?_without_wireshark:0}
%define with_systemd_daemon 0%{!?_without_systemd_daemon:0}
%define with_pm_utils 1
# Finally set the OS / architecture specific special cases
@ -133,7 +132,6 @@
# Fedora has systemd, libvirt still used sysvinit there.
%if 0%{?fedora} || 0%{?rhel} >= 7
%define with_systemd 1
%define with_systemd_daemon 1
%define with_pm_utils 0
%endif
@ -268,9 +266,6 @@ BuildRequires: python
%if %{with_systemd}
BuildRequires: systemd-units
%endif
%if %{with_systemd_daemon}
BuildRequires: systemd-devel
%endif
%if %{with_xen} || %{with_libxl}
BuildRequires: xen-devel
%endif
@ -1061,12 +1056,6 @@ rm -rf .git
%define arg_wireshark --without-wireshark-dissector
%endif
%if %{with_systemd_daemon}
%define arg_systemd_daemon --with-systemd-daemon
%else
%define arg_systemd_daemon --without-systemd-daemon
%endif
%if %{with_pm_utils}
%define arg_pm_utils --with-pm-utils
%else
@ -1157,7 +1146,6 @@ rm -f po/stamp-po
--with-driver-modules \
%{?arg_firewalld} \
%{?arg_wireshark} \
%{?arg_systemd_daemon} \
%{?arg_pm_utils} \
--with-nss-plugin \
%{arg_packager} \

View File

@ -1,34 +0,0 @@
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 <http://www.gnu.org/licenses/>.
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])
])

View File

@ -1107,12 +1107,12 @@ 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) \
$(SYSTEMD_DAEMON_CFLAGS) $(POLKIT_CFLAGS) $(GNUTLS_CFLAGS) \
$(POLKIT_CFLAGS) $(GNUTLS_CFLAGS) \
-I$(srcdir)/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) $(SYSTEMD_DAEMON_LIBS) \
$(SECDRIVER_LIBS) $(NUMACTL_LIBS) \
$(POLKIT_LIBS)

View File

@ -21,8 +21,9 @@
#include <config.h>
#ifdef WITH_SYSTEMD_DAEMON
# include <systemd/sd-daemon.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
#include "virsystemd.h"
@ -34,6 +35,7 @@
#include "virutil.h"
#include "virlog.h"
#include "virerror.h"
#include "virfile.h"
#define VIR_FROM_THIS VIR_FROM_SYSTEMD
@ -480,9 +482,50 @@ int virSystemdTerminateMachine(const char *name)
void
virSystemdNotifyStartup(void)
{
#ifdef WITH_SYSTEMD_DAEMON
sd_notify(0, "READY=1");
#endif
#ifdef HAVE_SYS_UN_H
const char *path;
const char *msg = "READY=1";
int fd;
struct sockaddr_un un = {
.sun_family = AF_UNIX,
};
struct iovec iov = {
.iov_base = (char *)msg,
.iov_len = strlen(msg),
};
struct msghdr mh = {
.msg_name = &un,
.msg_namelen = sizeof(un),
.msg_iov = &iov,
.msg_iovlen = 1,
};
if (!(path = virGetEnvBlockSUID("NOTIFY_SOCKET"))) {
VIR_DEBUG("Skipping systemd notify, not requested");
return;
}
/* NB sun_path field is *not* NUL-terminated, hence >, not >= */
if (strlen(path) > sizeof(un.sun_path)) {
VIR_WARN("Systemd notify socket path '%s' too long", path);
return;
}
memcpy(un.sun_path, path, strlen(path));
if (un.sun_path[0] == '@')
un.sun_path[0] = '\0';
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0) {
VIR_WARN("Unable to create socket FD");
return;
}
if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
VIR_WARN("Failed to notify systemd");
VIR_FORCE_CLOSE(fd);
#endif /* HAVE_SYS_UN_H */
}
static int