From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> This patch adds support for a systemd init service for libvirtd and libvirt-guests. The libvirtd.service is *not* written to use socket activation, since we want libvirtd to start on boot so it can do guest auto-start. The libvirt-guests.service is pretty lame, just exec'ing the original init script for now. Ideally we would factor out the functionality, into some shared tool. Instead of ./configure --with-init-script=redhat You can now do ./configure --with-init-script=systemd Or better still: ./configure --with-init-script=systemd+redhat * configure.ac: Add systemd, and systemd+redhat options to --with-init-script option * daemon/Makefile.am: Install systemd services * daemon/libvirtd.sysconf: Add note about unused env variable with systemd * daemon/libvirtd.service.in: libvirtd systemd service unit * libvirt.spec.in: Add scripts to installing systemd services and migrating from legacy init scripts * tools/Makefile.am: Install systemd services * tools/libvirt-guests.init.sh: Rename to tools/libvirt-guests.init.in * tools/libvirt-guests.service.in: systemd service unit --- configure.ac | 32 +++++-- daemon/.gitignore | 1 + daemon/Makefile.am | 77 ++++++++++++----- daemon/libvirtd.service.in | 20 ++++ daemon/libvirtd.sysconf | 3 + libvirt.spec.in | 93 +++++++++++++++++++- po/POTFILES.in | 2 +- tools/Makefile.am | 63 +++++++++++--- ...bvirt-guests.init.sh => libvirt-guests.init.in} | 0 tools/libvirt-guests.service.in | 13 +++ 10 files changed, 257 insertions(+), 47 deletions(-) create mode 100644 daemon/libvirtd.service.in rename tools/{libvirt-guests.init.sh => libvirt-guests.init.in} (100%) create mode 100644 tools/libvirt-guests.service.in diff --git a/configure.ac b/configure.ac index 3b7535e..f155666 100644 --- a/configure.ac +++ b/configure.ac @@ -329,16 +329,30 @@ dnl init script flavor dnl AC_MSG_CHECKING([for init script flavor]) AC_ARG_WITH([init-script], - [AC_HELP_STRING([--with-init-script=@<:@redhat|auto|none@:>@], + [AC_HELP_STRING([--with-init-script=@<:@redhat|systemd|systemd+redhat|upstart|auto|none@:>@], [Style of init script to install @<:@default=auto@:>@])]) -if test "x$with_init_script" = "x" || test "x$with_init_script" = "xauto"; then - if test "$cross_compiling" = yes || test ! -f /etc/redhat-release; then - with_init_script=none - else - with_init_script=redhat - fi -fi -AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test x$with_init_script = xredhat) +init_redhat=no +init_systemd=no +case "$with_init_script" in + systemd+redhat) + init_redhat=yes + init_systemd=yes + ;; + systemd) + init_systemd=yes + ;; + redhat) + init_redhat=yes + ;; + *) + if test "$cross_compiling" != yes && test -f /etc/redhat-release; then + init_redhat=yes + with_init_script=redhat + fi + ;; +esac +AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test "$init_redhat" = "yes") +AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_SYSTEMD], test "$init_systemd" = "yes") AC_MSG_RESULT($with_init_script) dnl RHEL-5 has a peculiar version of Xen, which requires some special casing diff --git a/daemon/.gitignore b/daemon/.gitignore index ab3d093..2873143 100644 --- a/daemon/.gitignore +++ b/daemon/.gitignore @@ -7,6 +7,7 @@ Makefile.in libvirt_qemud libvirtd libvirtd.init +libvirtd.service libvirtd*.logrotate libvirtd.8 libvirtd.8.in diff --git a/daemon/Makefile.am b/daemon/Makefile.am index e8c47ae..92b6b86 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -170,13 +170,14 @@ policyfile = libvirtd.policy-1 endif endif -install-data-local: install-init install-data-sasl install-data-polkit \ - install-logrotate +install-data-local: install-init install-systemd install-data-sasl install-data-polkit \ + install-logrotate install-sysctl mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt -uninstall-local:: uninstall-init uninstall-data-sasl uninstall-data-polkit +uninstall-local:: uninstall-init uninstall-systemd uninstall-data-sasl uninstall-data-polkit \ + uninstall-sysctl rmdir $(DESTDIR)$(localstatedir)/log/libvirt || : rmdir $(DESTDIR)$(localstatedir)/run/libvirt || : rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || : @@ -234,25 +235,56 @@ install-logrotate: $(LOGROTATE_CONFS) $(INSTALL_DATA) libvirtd.lxc.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc $(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml -if LIBVIRT_INIT_SCRIPT_RED_HAT -install-init: libvirtd.init - mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d \ - $(DESTDIR)$(sysconfdir)/sysconfig \ - $(DESTDIR)$(sysconfdir)/sysctl.d - $(INSTALL_SCRIPT) libvirtd.init \ - $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd +install-sysconfig: + mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig $(INSTALL_DATA) $(srcdir)/libvirtd.sysconf \ $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd +uninstall-sysconfig: + rm -f $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd + +install-sysctl: + mkdir -p $(DESTDIR)$(sysconfdir)/sysctl.d $(INSTALL_DATA) $(srcdir)/libvirtd.sysctl \ $(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd -uninstall-init: - rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd \ - $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd \ - $(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd +uninstall-sysctl: + rm -f $(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd + +if LIBVIRT_INIT_SCRIPT_RED_HAT BUILT_SOURCES += libvirtd.init +install-init: install-sysconfig libvirtd.init + mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d + $(INSTALL_SCRIPT) libvirtd.init \ + $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd + +uninstall-init: uninstall-sysconfig + rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd +else +install-init: +uninstall-init: +endif # LIBVIRT_INIT_SCRIPT_RED_HAT + + +EXTRA_DIST += libvirtd.service.in +if LIBVIRT_INIT_SCRIPT_SYSTEMD + +SYSTEMD_UNIT_DIR = /lib/systemd/system +BUILT_SOURCES += libvirtd.service + +install-systemd: install-sysconfig libvirtd.service + mkdir -p $(DESTDIR)$(SYSTEMD_UNIT_DIR) + $(INSTALL_SCRIPT) libvirtd.service \ + $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service + +uninstall-systemd: uninstall-sysconfig + rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service +else +install-systemd: +uninstall-systemd: +endif # LIBVIRT_INIT_SCRIPT_SYSTEMD + libvirtd.init: libvirtd.init.in $(top_builddir)/config.status $(AM_V_GEN)sed \ -e s!\@localstatedir\@!@localstatedir@!g \ @@ -262,18 +294,21 @@ libvirtd.init: libvirtd.init.in $(top_builddir)/config.status chmod a+x $@-t && \ mv $@-t $@ +libvirtd.service: libvirtd.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 $@ + + check-local: $(AM_V_GEN)if test -x '$(AUGPARSE)'; then \ '$(AUGPARSE)' -I $(srcdir) $(srcdir)/test_libvirtd.aug; \ fi -else - -install-init: -uninstall-init: -libvirtd.init: - -endif # LIBVIRT_INIT_SCRIPT_RED_HAT # This must be added last, since functions it provides/replaces # are used by nearly every other library. diff --git a/daemon/libvirtd.service.in b/daemon/libvirtd.service.in new file mode 100644 index 0000000..9661428 --- /dev/null +++ b/daemon/libvirtd.service.in @@ -0,0 +1,20 @@ +# NB we don't use socket activation. When libvirtd starts it will +# spawn any virtual machines registered for autostart. We want this +# to occur on every boot, regardless of whether any client connects +# to a socket. Thus socket activation doesn't have any benefit + +[Unit] +Description=Virtualization daemon +After=syslog.target +After=udev.target +After=avahi.target +After=dbus.target +Before=libvirt-guests.service + +[Service] +EnvironmentFile=-/etc/sysconfig/libvirtd +ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/daemon/libvirtd.sysconf b/daemon/libvirtd.sysconf index b730c5e..ab273c8 100644 --- a/daemon/libvirtd.sysconf +++ b/daemon/libvirtd.sysconf @@ -1,4 +1,7 @@ # Override the default config file +# NOTE: This setting is no longer honoured if using +# systemd. Set '--config /etc/libvirt/libvirtd.conf' +# in LIBVIRTD_ARGS instead. #LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf # Listen for TCP/IP connections diff --git a/libvirt.spec.in b/libvirt.spec.in index d4e3e17..0379998 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -78,6 +78,7 @@ %define with_dtrace 0%{!?_without_dtrace:0} %define with_cgconfig 0%{!?_without_cgconfig:0} %define with_sanlock 0%{!?_without_sanlock:0} +%define with_systemd 0%{!?_without_systemd:0} # Non-server/HV driver defaults which are always enabled %define with_python 0%{!?_without_python:1} @@ -111,6 +112,11 @@ %define with_hyperv 0 %endif +# Although earlier Fedora has systemd, libvirt still used sysvinit +%if 0%{?fedora} >= 17 +%define with_systemd 1 +%endif + # RHEL-5 has restricted QEMU to x86_64 only and is too old for LXC %if 0%{?rhel} == 5 %ifnarch x86_64 @@ -329,7 +335,9 @@ Requires: libcgroup # All build-time requirements BuildRequires: python-devel - +%if %{with_systemd} +BuildRequires: systemd-units +%endif %if %{with_xen} BuildRequires: xen-devel %endif @@ -474,6 +482,13 @@ BuildRequires: nfs-utils # Fedora build root suckage BuildRequires: gawk +%if %{with_systemd} +Requires(post): systemd-units +Requires(post): systemd-sysv +Requires(preun): systemd-units +Requires(postun): systemd-units +%endif + %description Libvirt is a C toolkit to interact with the virtualization capabilities of recent versions of Linux (and other OSes). The main package includes @@ -696,6 +711,13 @@ of recent versions of Linux (and other OSes). %define with_packager --with-packager="%{who}, %{when}, %{where}" %define with_packager_version --with-packager-version="%{release}" +%if %{with_systemd} +# We use 'systemd+redhat', so if someone installs upstart or +# legacy init scripts, they can still start libvirtd, etc +%define init_scripts --with-init_script=systemd+redhat +%else +%define init_scripts --with-init_script=redhat +%endif %configure %{?_without_xen} \ %{?_without_qemu} \ @@ -736,7 +758,7 @@ of recent versions of Linux (and other OSes). %{with_packager_version} \ --with-qemu-user=%{qemu_user} \ --with-qemu-group=%{qemu_group} \ - --with-init-script=redhat \ + %{init_scripts} \ --with-remote-pid-file=%{_localstatedir}/run/libvirtd.pid make %{?_smp_mflags} gzip -9 ChangeLog @@ -744,7 +766,7 @@ gzip -9 ChangeLog %install rm -fr %{buildroot} -%makeinstall +%makeinstall SYSTEMD_UNIT_DIR=%{?buildroot:%{buildroot}}%{_unitdir} for i in domain-events/events-c dominfo domsuspend hellolibvirt openauth python xml/nwfilter systemtap do (cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in) @@ -893,6 +915,13 @@ do done %endif +%if %{with_systemd} +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl enable libvirtd.service >/dev/null 2>&1 || : + /bin/systemctl enable cgconfig.service >/dev/null 2>&1 || : +fi +%else %if %{with_cgconfig} # Starting with Fedora 16, systemd automounts all cgroups, and cgconfig is # no longer a necessary service. @@ -908,25 +937,64 @@ if [ "$1" -ge "1" ]; then /sbin/service libvirtd condrestart > /dev/null 2>&1 fi %endif +%endif %preun %if %{with_libvirtd} +%if %{with_systemd} +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable libvirtd.service > /dev/null 2>&1 || : + /bin/systemctl stop libvirtd.service > /dev/null 2>&1 || : +fi +%else if [ $1 = 0 ]; then /sbin/service libvirtd stop 1>/dev/null 2>&1 /sbin/chkconfig --del libvirtd fi %endif +%endif + +%postun +%if %{with_libvirtd} +%if %{with_systemd} +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ $1 -ge 1 ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || : +fi +%endif +%endif + +%if %{with_libvirtd} +%if %{with_systemd} +%triggerun -- libvirt < 0.9.4 +%{_bindir}/systemd-sysv-convert --save libvirtd >/dev/null 2>&1 ||: + +# If the package is allowed to autostart: +/bin/systemctl --no-reload enable libvirtd.service >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +/sbin/chkconfig --del libvirtd >/dev/null 2>&1 || : +/bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || : +%endif +%endif %preun client +%if %{with_systemd} +%else if [ $1 = 0 ]; then /sbin/chkconfig --del libvirt-guests rm -f /var/lib/libvirt/libvirt-guests fi +%endif %post client /sbin/ldconfig +%if %{with_systemd} +%else /sbin/chkconfig --add libvirt-guests if [ $1 -ge 1 ]; then level=$(/sbin/runlevel | /bin/cut -d ' ' -f 2) @@ -937,9 +1005,22 @@ if [ $1 -ge 1 ]; then /sbin/service libvirt-guests start > /dev/null 2>&1 || true fi fi +%endif %postun client -p /sbin/ldconfig +%if %{with_systemd} +%triggerun client -- libvirt < 0.9.4 +%{_bindir}/systemd-sysv-convert --save libvirt-guests >/dev/null 2>&1 ||: + +# If the package is allowed to autostart: +/bin/systemctl --no-reload enable libvirt-guests.service >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +/sbin/chkconfig --del libvirt-guests >/dev/null 2>&1 || : +/bin/systemctl try-restart libvirt-guests.service >/dev/null 2>&1 || : +%endif + %if %{with_libvirtd} %files %defattr(-, root, root) @@ -957,6 +1038,9 @@ fi %{_sysconfdir}/libvirt/nwfilter/*.xml %{_sysconfdir}/rc.d/init.d/libvirtd +%if %{with_systemd} +%{_unitdir}/libvirtd.service +%endif %doc daemon/libvirtd.upstart %config(noreplace) %{_sysconfdir}/sysconfig/libvirtd %config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf @@ -1113,6 +1197,9 @@ 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 %config(noreplace) %{_sysconfdir}/sysconfig/libvirt-guests %dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/ diff --git a/po/POTFILES.in b/po/POTFILES.in index a3685e8..0fd4442 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -151,5 +151,5 @@ 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.init.in tools/virsh.c diff --git a/tools/Makefile.am b/tools/Makefile.am index c96c7d9..2e8018e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -25,7 +25,6 @@ EXTRA_DIST = \ virt-sanlock-cleanup.in \ virt-sanlock-cleanup.8 \ virsh.pod \ - libvirt-guests.init.sh \ libvirt-guests.sysconf DISTCLEANFILES = @@ -153,22 +152,33 @@ install-data-local: install-init uninstall-local: uninstall-init +install-sysconfig: + mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig + $(INSTALL_DATA) $(srcdir)/libvirt-guests.sysconf \ + $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests + +uninstall-sysconfig: + rm -f $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests + +EXTRA_DIST += libvirt-guests.init.in + if LIBVIRT_INIT_SCRIPT_RED_HAT -install-init: libvirt-guests.init +install-init: libvirt-guests.init install-sysconfig mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d $(INSTALL_SCRIPT) libvirt-guests.init \ $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests - mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig - $(INSTALL_DATA) $(srcdir)/libvirt-guests.sysconf \ - $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests -uninstall-init: - rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests \ - $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests +uninstall-init: install-sysconfig + rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests BUILT_SOURCES += libvirt-guests.init -libvirt-guests.init: libvirt-guests.init.sh $(top_builddir)/config.status +else +install-init: +uninstall-init: +endif # LIBVIRT_INIT_SCRIPT_RED_HAT + +libvirt-guests.init: libvirt-guests.init.in $(top_builddir)/config.status $(AM_V_GEN)sed \ -e 's!\@PACKAGE\@!$(PACKAGE)!g' \ -e 's!\@bindir\@!$(bindir)!g' \ @@ -179,11 +189,38 @@ libvirt-guests.init: libvirt-guests.init.sh $(top_builddir)/config.status < $< > $@-t && \ chmod a+x $@-t && \ mv $@-t $@ + + + +EXTRA_DIST += libvirt-guests.service.in + +if LIBVIRT_INIT_SCRIPT_SYSTEMD +install-systemd: libvirt-guests.service install-sysconfig + mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/systemd.d + $(INSTALL_SCRIPT) libvirt-guests.service \ + $(DESTDIR)$(sysconfdir)/rc.d/systemd.d/libvirt-guests + +uninstall-systemd: install-sysconfig + rm -f $(DESTDIR)$(sysconfdir)/rc.d/systemd.d/libvirt-guests + +BUILT_SOURCES += libvirt-guests.service + else -install-init: -uninstall-init: -libvirt-guests.init: -endif # LIBVIRT_INIT_SCRIPT_RED_HAT +install-systemd: +uninstall-systemd: +endif # LIBVIRT_INIT_SCRIPT_SYSTEMD + +libvirt-guests.service: libvirt-guests.service.in $(top_builddir)/config.status + $(AM_V_GEN)sed \ + -e 's!\@PACKAGE\@!$(PACKAGE)!g' \ + -e 's!\@bindir\@!$(bindir)!g' \ + -e 's!\@localedir\@!$(localedir)!g' \ + -e 's!\@localstatedir\@!$(localstatedir)!g' \ + -e 's!\@sbindir\@!$(sbindir)!g' \ + -e 's!\@sysconfdir\@!$(sysconfdir)!g' \ + < $< > $@-t && \ + chmod a+x $@-t && \ + mv $@-t $@ CLEANFILES = $(bin_SCRIPTS) diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.in similarity index 100% rename from tools/libvirt-guests.init.sh rename to tools/libvirt-guests.init.in diff --git a/tools/libvirt-guests.service.in b/tools/libvirt-guests.service.in new file mode 100644 index 0000000..bc63e91 --- /dev/null +++ b/tools/libvirt-guests.service.in @@ -0,0 +1,13 @@ +[Unit] +Description=Suspend Active Libvirt Guests +After=syslog.target network.target + +[Service] +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 + +[Install] +WantedBy=multi-user.target -- 1.7.6.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list