From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> This enhancement virtlockd so that it can receive a pre-opened UNIX domain socket from systemd at launch time, and adds the systemd service/socket unit files * daemon/libvirtd.service.in: Require virtlockd to be running * libvirt.spec.in: Add virtlockd systemd files * src/Makefile.am: Install systemd files * src/locking/lock_daemon.c: Support socket activation * src/locking/virtlockd.service.in, src/locking/virtlockd.socket.in: systemd unit files * src/rpc/virnetserverservice.c, src/rpc/virnetserverservice.h: Add virNetServerServiceNewFD() method * src/rpc/virnetsocket.c, src/rpc/virnetsocket.h: Add virNetSocketNewListenFD method Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- libvirt.spec.in | 6 ++++ src/Makefile.am | 51 ++++++++++++++++++++++++++-- src/locking/lock_daemon.c | 73 ++++++++++++++++++++++++++++++++++++++-- src/locking/virtlockd.service.in | 13 +++++++ src/locking/virtlockd.socket.in | 8 +++++ 5 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 src/locking/virtlockd.service.in create mode 100644 src/locking/virtlockd.socket.in diff --git a/libvirt.spec.in b/libvirt.spec.in index 69d8c58..62938e5 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1428,6 +1428,7 @@ done %if %{with_systemd} if [ $1 -eq 1 ] ; then # Initial installation + /bin/systemctl enable virtlockd.socket >/dev/null 2>&1 || : /bin/systemctl enable libvirtd.service >/dev/null 2>&1 || : /bin/systemctl enable cgconfig.service >/dev/null 2>&1 || : fi @@ -1452,8 +1453,10 @@ fi %if %{with_systemd} if [ $1 -eq 0 ] ; then # Package removal, not upgrade + /bin/systemctl --no-reload disable virtlockd.socket > /dev/null 2>&1 || : /bin/systemctl --no-reload disable libvirtd.service > /dev/null 2>&1 || : /bin/systemctl stop libvirtd.service > /dev/null 2>&1 || : + /bin/systemctl stop virtlockd.service > /dev/null 2>&1 || : fi %else if [ $1 = 0 ]; then @@ -1467,6 +1470,7 @@ fi /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ $1 -ge 1 ] ; then # Package upgrade, not uninstall + /bin/systemctl try-restart virtlockd.service >/dev/null 2>&1 || : /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || : fi %endif @@ -1565,6 +1569,8 @@ fi %{_sysconfdir}/rc.d/init.d/virtlockd %if %{with_systemd} %{_unitdir}/libvirtd.service +%{_unitdir}/virtlockd.service +%{_unitdir}/virtlockd.socket %endif %doc daemon/libvirtd.upstart %config(noreplace) %{_sysconfdir}/sysconfig/libvirtd diff --git a/src/Makefile.am b/src/Makefile.am index e088d9b..b402297 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1575,6 +1575,53 @@ virtlockd.init: locking/virtlockd.init.in $(top_builddir)/config.status +EXTRA_DIST += locking/virtlockd.service.in locking/virtlockd.socket.in + +if WITH_LIBVIRTD +if LIBVIRT_INIT_SCRIPT_SYSTEMD + +SYSTEMD_UNIT_DIR = /lib/systemd/system + +BUILT_SOURCES += virtlockd.service virtlockd.socket + +install-systemd: virtlockd.init install-sysconfig + mkdir -p $(DESTDIR)$(SYSTEMD_UNIT_DIR) + $(INSTALL_SCRIPT) virtlockd.service \ + $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ + $(INSTALL_SCRIPT) virtlockd.socket \ + $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ + +uninstall-systemd: uninstall-sysconfig + rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/virtlockd.service + rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/virtlockd.socket +else +install-systemd: +uninstall-systemd: +endif +else +install-systemd: +uninstall-systemd: +endif + +virtlockd.service: locking/virtlockd.service.in $(top_builddir)/config.status + $(AM_V_GEN)sed \ + -e "s!::localstatedir::!$(localstatedir)!g" \ + -e "s!::sbindir::!$(sbindir)!g" \ + -e "s!::sysconfdir::!$(sysconfdir)!g" \ + < $< > $@-t && \ + chmod a+x $@-t && \ + mv $@-t $@ + +virtlockd.socket: locking/virtlockd.socket.in $(top_builddir)/config.status + $(AM_V_GEN)sed \ + -e "s!::localstatedir::!$(localstatedir)!g" \ + -e "s!::sbindir::!$(sbindir)!g" \ + -e "s!::sysconfdir::!$(sysconfdir)!g" \ + < $< > $@-t && \ + chmod a+x $@-t && \ + mv $@-t $@ + + if HAVE_SANLOCK lockdriverdir = $(libdir)/libvirt/lock-driver lockdriver_LTLIBRARIES = sanlock.la @@ -1793,7 +1840,7 @@ endif endif EXTRA_DIST += $(SECURITY_DRIVER_APPARMOR_HELPER_SOURCES) -install-data-local: install-init +install-data-local: install-init install-systemd if WITH_LIBVIRTD $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/lockd" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/lockd" @@ -1843,7 +1890,7 @@ if WITH_NETWORK $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml endif -uninstall-local:: uninstall-init +uninstall-local:: uninstall-init uninstall-systemd if WITH_LIBVIRTD rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/lockd" ||: rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/lockd" ||: diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index 94b41db..7bc6917 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -454,8 +454,69 @@ virLockDaemonSetupSignals(virNetServerPtr srv) return 0; } + static int -virLockDaemonSetupNetworking(virNetServerPtr srv, const char *sock_path) +virLockDaemonSetupNetworkingSystemD(virNetServerPtr srv) +{ + virNetServerServicePtr svc; + const char *pidstr; + const char *fdstr; + unsigned long long procid; + unsigned int nfds; + + if (!(pidstr = getenv("LISTEN_PID"))) { + VIR_DEBUG("No LISTEN_FDS from systemd"); + return 0; + } + + if (virStrToLong_ull(pidstr, NULL, 10, &procid) < 0) { + VIR_DEBUG("Malformed LISTEN_PID from systemd %s", pidstr); + return 0; + } + + if ((pid_t)procid != getpid()) { + VIR_DEBUG("LISTEN_PID %s is not for us %llu", + pidstr, (unsigned long long)getpid()); + return 0; + } + + if (!(fdstr = getenv("LISTEN_FDS"))) { + VIR_DEBUG("No LISTEN_FDS from systemd"); + return 0; + } + + if (virStrToLong_ui(fdstr, NULL, 10, &nfds) < 0) { + VIR_DEBUG("Malformed LISTEN_FDS from systemd %s", fdstr); + return 0; + } + + if (nfds > 1) { + VIR_DEBUG("Too many (%d) file descriptors from systemd", + nfds); + nfds = 1; + } + + unsetenv("LISTEN_PID"); + unsetenv("LISTEN_FDS"); + + if (nfds == 0) + return 0; + + /* Systemd passes FDs, starting immediately after stderr, + * so the first FD we'll get is '3'. */ + if (!(svc = virNetServerServiceNewFD(3, 0, false, 1, NULL))) + return -1; + + if (virNetServerAddService(srv, svc, NULL) < 0) { + virObjectUnref(svc); + return -1; + } + return 1; +} + + +static int +virLockDaemonSetupNetworkingNative(virNetServerPtr srv, const char *sock_path) { virNetServerServicePtr svc; @@ -672,6 +733,7 @@ int main(int argc, char **argv) { char *pid_file = NULL; int pid_file_fd = -1; char *sock_file = NULL; + int rv; struct option opts[] = { { "verbose", no_argument, &verbose, 1}, @@ -810,7 +872,14 @@ int main(int argc, char **argv) { goto cleanup; } - if (virLockDaemonSetupNetworking(lockDaemon->srv, sock_file) < 0) { + if ((rv = virLockDaemonSetupNetworkingSystemD(lockDaemon->srv)) < 0) { + ret = VIR_LOCK_DAEMON_ERR_NETWORK; + goto cleanup; + } + + /* Only do this, if systemd did not pass a FD */ + if (rv == 0 && + virLockDaemonSetupNetworkingNative(lockDaemon->srv, sock_file) < 0) { ret = VIR_LOCK_DAEMON_ERR_NETWORK; goto cleanup; } diff --git a/src/locking/virtlockd.service.in b/src/locking/virtlockd.service.in new file mode 100644 index 0000000..a9f9f93 --- /dev/null +++ b/src/locking/virtlockd.service.in @@ -0,0 +1,13 @@ +[Unit] +Description=Virtual machine lock manager +Requires=virtlockd.socket +After=syslog.target + +[Service] +EnvironmentFile=-/etc/sysconfig/virtlockd +ExecStart=@sbindir@/virtlockd +ExecReload=/bin/kill -HUP $MAINPID +# Loosing the locks is a really bad thing that will +# cause the machine to be fenced (rebooted), so make +# sure we discourage OOM killer +OOMScoreAdjust=-900 diff --git a/src/locking/virtlockd.socket.in b/src/locking/virtlockd.socket.in new file mode 100644 index 0000000..0589a29 --- /dev/null +++ b/src/locking/virtlockd.socket.in @@ -0,0 +1,8 @@ +[Unit] +Description=Virtual machine lock manager socket + +[Socket] +ListenStream=/var/run/libvirt/virtlockd/virtlockd.sock + +[Install] +WantedBy=multi-user.target -- 1.7.11.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list