[libvirt] [PATCH 10/12] Enable systemd socket activation with virtlockd

Michal Privoznik mprivozn at redhat.com
Fri Oct 5 11:24:24 UTC 2012


On 12.09.2012 18:29, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> 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 at redhat.com>
> ---
>  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
> 

ACK

> 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
> 




More information about the libvir-list mailing list