From 881f45c6a8f44486f76c4713ecef0d533d6601e8 Mon Sep 17 00:00:00 2001 From: Ralf Ertzinger Date: Sun, 19 Jan 2014 15:36:49 +0100 Subject: [PATCH] Add systemd unit files for ZFS startup This adds systemd unit files replacing the functionality offered by the SysV init script found in etc/init.d. It has been developed and tested on Fedora 19, Fedora 20 and openSuSE 13.1. Four unit files and one target are offered. zfs-import-cache.service: Import pools from /etc/zfs/zpool.cache. This unit will wait for udev to settle. zfs-import-scan.service: Import pools by scanning /dev/disk/by-id for zvols. This unit will only run if /etc/zfs/zpool.cache is not present. This unit will wait for udev to settle zfs-mount.service: Mount ZFS native filesystems. It contains a dependency to be loaded before local-fs.target. zfs-share.service: Share NFS/SMB filesystems. This unit contains a dependency that will cause it to be restarted whenever the smb or nfs-server unit is restarted, restoring the shares added. zfs.target: This target pulls in the other units in order to start ZFS. It's the only unit that can be enabled/disabled, all other services are static and pulled in by dependencies. It will honour zfs=off and zfs=no options on the kernel command line. Signed-off-by: Brian Behlendorf Closes #2108 --- config/user-systemd.m4 | 29 +++++++++++ config/user-sysvinit.m4 | 11 ++++ config/user.m4 | 2 + configure.ac | 3 ++ etc/Makefile.am | 3 +- etc/modules-load.d/.gitignore | 1 + etc/modules-load.d/Makefile.am | 13 +++++ etc/modules-load.d/zfs.conf.in | 1 + etc/systemd/Makefile.am | 1 + etc/systemd/system/.gitignore | 3 ++ etc/systemd/system/50-zfs.preset.in | 2 + etc/systemd/system/Makefile.am | 31 +++++++++++ .../system/zfs-import-cache.service.in | 11 ++++ etc/systemd/system/zfs-import-scan.service.in | 11 ++++ etc/systemd/system/zfs-mount.service.in | 15 ++++++ etc/systemd/system/zfs-share.service.in | 11 ++++ etc/systemd/system/zfs.target.in | 7 +++ rpm/generic/zfs.spec.in | 51 ++++++++++++++++++- 18 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 config/user-systemd.m4 create mode 100644 config/user-sysvinit.m4 create mode 100644 etc/modules-load.d/.gitignore create mode 100644 etc/modules-load.d/Makefile.am create mode 100644 etc/modules-load.d/zfs.conf.in create mode 100644 etc/systemd/Makefile.am create mode 100644 etc/systemd/system/.gitignore create mode 100644 etc/systemd/system/50-zfs.preset.in create mode 100644 etc/systemd/system/Makefile.am create mode 100644 etc/systemd/system/zfs-import-cache.service.in create mode 100644 etc/systemd/system/zfs-import-scan.service.in create mode 100644 etc/systemd/system/zfs-mount.service.in create mode 100644 etc/systemd/system/zfs-share.service.in create mode 100644 etc/systemd/system/zfs.target.in diff --git a/config/user-systemd.m4 b/config/user-systemd.m4 new file mode 100644 index 0000000000..5988945b44 --- /dev/null +++ b/config/user-systemd.m4 @@ -0,0 +1,29 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_SYSTEMD], [ + AC_ARG_ENABLE(systemd, + AC_HELP_STRING([--enable-systemd], + [install systemd unit/preset files [[default: yes]]]), + [],enable_systemd=yes) + + AC_ARG_WITH(systemdunitdir, + AC_HELP_STRING([--with-systemdunitdir=DIR], + [install systemd unit files in dir [[/usr/lib/systemd/system]]]), + systemdunitdir=$withval,systemdunitdir=/usr/lib/systemd/system) + + AC_ARG_WITH(systemdpresetdir, + AC_HELP_STRING([--with-systemdpresetdir=DIR], + [install systemd preset files in dir [[/usr/lib/systemd/system-preset]]]), + systemdpresetdir=$withval,systemdpresetdir=/usr/lib/systemd/system-preset) + + AS_IF([test "x$enable_systemd" = xyes], + [ + ZFS_INIT_SYSTEMD=systemd + ZFS_MODULE_LOAD=modules-load.d + modulesloaddir=/usr/lib/modules-load.d + ]) + + AC_SUBST(ZFS_INIT_SYSTEMD) + AC_SUBST(ZFS_MODULE_LOAD) + AC_SUBST(systemdunitdir) + AC_SUBST(systemdpresetdir) + AC_SUBST(modulesloaddir) +]) diff --git a/config/user-sysvinit.m4 b/config/user-sysvinit.m4 new file mode 100644 index 0000000000..65dcc38192 --- /dev/null +++ b/config/user-sysvinit.m4 @@ -0,0 +1,11 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_SYSVINIT], [ + AC_ARG_ENABLE(sysvinit, + AC_HELP_STRING([--enable-sysvinit], + [install SysV init scripts [default: yes]]), + [],enable_sysvinit=yes) + + AS_IF([test "x$enable_sysvinit" = xyes], + [ZFS_INIT_SYSV=init.d]) + + AC_SUBST(ZFS_INIT_SYSV) +]) diff --git a/config/user.m4 b/config/user.m4 index 4f9963787d..da1cdea331 100644 --- a/config/user.m4 +++ b/config/user.m4 @@ -3,6 +3,8 @@ dnl # Default ZFS user configuration dnl # AC_DEFUN([ZFS_AC_CONFIG_USER], [ ZFS_AC_CONFIG_USER_UDEV + ZFS_AC_CONFIG_USER_SYSTEMD + ZFS_AC_CONFIG_USER_SYSVINIT ZFS_AC_CONFIG_USER_DRACUT ZFS_AC_CONFIG_USER_ARCH ZFS_AC_CONFIG_USER_IOCTL diff --git a/configure.ac b/configure.ac index 7c48094262..7787530d34 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,9 @@ AC_CONFIG_FILES([ etc/Makefile etc/init.d/Makefile etc/zfs/Makefile + etc/systemd/Makefile + etc/systemd/system/Makefile + etc/modules-load.d/Makefile man/Makefile man/man1/Makefile man/man5/Makefile diff --git a/etc/Makefile.am b/etc/Makefile.am index 65882b55ef..a62678b4e5 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1 +1,2 @@ -SUBDIRS = init.d zfs +SUBDIRS = zfs $(ZFS_INIT_SYSTEMD) $(ZFS_INIT_SYSV) $(ZFS_MODULE_LOAD) +DIST_SUBDIRS = init.d zfs systemd modules-load.d diff --git a/etc/modules-load.d/.gitignore b/etc/modules-load.d/.gitignore new file mode 100644 index 0000000000..fee9217083 --- /dev/null +++ b/etc/modules-load.d/.gitignore @@ -0,0 +1 @@ +*.conf diff --git a/etc/modules-load.d/Makefile.am b/etc/modules-load.d/Makefile.am new file mode 100644 index 0000000000..980cb85199 --- /dev/null +++ b/etc/modules-load.d/Makefile.am @@ -0,0 +1,13 @@ +modulesload_DATA = \ + $(top_srcdir)/etc/modules-load.d/zfs.conf + +EXTRA_DIST = \ + $(top_srcdir)/etc/modules-load.d/zfs.conf.in + +$(modulesload_DATA): + -$(SED) \ + -e '' \ + '$@.in' >'$@' + +distclean-local:: + -$(RM) $(modulesload_DATA) diff --git a/etc/modules-load.d/zfs.conf.in b/etc/modules-load.d/zfs.conf.in new file mode 100644 index 0000000000..73304bc2cd --- /dev/null +++ b/etc/modules-load.d/zfs.conf.in @@ -0,0 +1 @@ +zfs diff --git a/etc/systemd/Makefile.am b/etc/systemd/Makefile.am new file mode 100644 index 0000000000..d4008c0dd0 --- /dev/null +++ b/etc/systemd/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = system diff --git a/etc/systemd/system/.gitignore b/etc/systemd/system/.gitignore new file mode 100644 index 0000000000..efada54ad9 --- /dev/null +++ b/etc/systemd/system/.gitignore @@ -0,0 +1,3 @@ +*.service +*.target +*.preset diff --git a/etc/systemd/system/50-zfs.preset.in b/etc/systemd/system/50-zfs.preset.in new file mode 100644 index 0000000000..4efdd72006 --- /dev/null +++ b/etc/systemd/system/50-zfs.preset.in @@ -0,0 +1,2 @@ +# ZFS is enabled by default +enable zfs.* diff --git a/etc/systemd/system/Makefile.am b/etc/systemd/system/Makefile.am new file mode 100644 index 0000000000..31521ceccb --- /dev/null +++ b/etc/systemd/system/Makefile.am @@ -0,0 +1,31 @@ +systemdpreset_DATA = \ + $(top_srcdir)/etc/systemd/system/50-zfs.preset +systemdunit_DATA = \ + $(top_srcdir)/etc/systemd/system/zfs-import-scan.service \ + $(top_srcdir)/etc/systemd/system/zfs-import-cache.service \ + $(top_srcdir)/etc/systemd/system/zfs-mount.service \ + $(top_srcdir)/etc/systemd/system/zfs-share.service \ + $(top_srcdir)/etc/systemd/system/zfs.target + +EXTRA_DIST = \ + $(top_srcdir)/etc/systemd/system/zfs-import-scan.service.in \ + $(top_srcdir)/etc/systemd/system/zfs-import-cache.service.in \ + $(top_srcdir)/etc/systemd/system/zfs-mount.service.in \ + $(top_srcdir)/etc/systemd/system/zfs-share.service.in \ + $(top_srcdir)/etc/systemd/system/zfs.target.in \ + $(top_srcdir)/etc/systemd/system/50-zfs.preset.in + +$(systemdunit_DATA): + -$(SED) -e 's,@bindir\@,$(bindir),g' \ + -e 's,@sbindir\@,$(sbindir),g' \ + -e 's,@sysconfdir\@,$(sysconfdir),g' \ + '$@.in' >'$@' + +$(systemdpreset_DATA): + -$(SED) -e 's,@bindir\@,$(bindir),g' \ + -e 's,@sbindir\@,$(sbindir),g' \ + -e 's,@sysconfdir\@,$(sysconfdir),g' \ + '$@.in' >'$@' + +distclean-local:: + -$(RM) $(systemdunit_DATA) $(systemdpreset_DATA) diff --git a/etc/systemd/system/zfs-import-cache.service.in b/etc/systemd/system/zfs-import-cache.service.in new file mode 100644 index 0000000000..918a258a1a --- /dev/null +++ b/etc/systemd/system/zfs-import-cache.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=Import ZFS pools by cache file +DefaultDependencies=no +Requires=systemd-udev-settle.service +After=systemd-udev-settle.service +ConditionPathExists=@sysconfdir@/zfs/zpool.cache + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN diff --git a/etc/systemd/system/zfs-import-scan.service.in b/etc/systemd/system/zfs-import-scan.service.in new file mode 100644 index 0000000000..ab1b0f6935 --- /dev/null +++ b/etc/systemd/system/zfs-import-scan.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=Import ZFS pools by device scanning +DefaultDependencies=no +Requires=systemd-udev-settle.service +After=systemd-udev-settle.service +ConditionPathExists=!@sysconfdir@/zfs/zpool.cache + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@sbindir@/zpool import -d /dev/disk/by-id -aN diff --git a/etc/systemd/system/zfs-mount.service.in b/etc/systemd/system/zfs-mount.service.in new file mode 100644 index 0000000000..f1056af311 --- /dev/null +++ b/etc/systemd/system/zfs-mount.service.in @@ -0,0 +1,15 @@ +[Unit] +Description=Mount ZFS filesystems +DefaultDependencies=no +Wants=zfs-import-cache.service +Wants=zfs-import-scan.service +Requires=systemd-udev-settle.service +After=systemd-udev-settle.service +After=zfs-import-cache.service +After=zfs-import-scan.service +Before=local-fs.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@sbindir@/zfs mount -a diff --git a/etc/systemd/system/zfs-share.service.in b/etc/systemd/system/zfs-share.service.in new file mode 100644 index 0000000000..a21c9c663a --- /dev/null +++ b/etc/systemd/system/zfs-share.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=ZFS file system shares +After=nfs-server.service +After=smb.service +PartOf=nfs-server.service +PartOf=smb.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@sbindir@/zfs share -a diff --git a/etc/systemd/system/zfs.target.in b/etc/systemd/system/zfs.target.in new file mode 100644 index 0000000000..7d464873b7 --- /dev/null +++ b/etc/systemd/system/zfs.target.in @@ -0,0 +1,7 @@ +[Unit] +Description=ZFS startup target +Requires=zfs-mount.service +Requires=zfs-share.service + +[Install] +WantedBy=multi-user.target diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in index 1e64ac18ea..bbe2a7e503 100644 --- a/rpm/generic/zfs.spec.in +++ b/rpm/generic/zfs.spec.in @@ -10,7 +10,24 @@ %bcond_with debug %bcond_with blkid +%bcond_with systemd +# Generic enable switch for systemd +%if %{with systemd} +%define _systemd 1 +%endif + +# Fedora >= 15 comes with systemd, but only >= 18 has +# the proper macros +%if 0%{?fedora} >= 18 +%define _systemd 1 +%endif + +# opensuse >= 12.1 comes with systemd, but only >= 13.1 +# has the proper macros +%if 0%{?suse_version} >= 1310 +%define _systemd 1 +%endif Name: @PACKAGE@ Version: @VERSION@ @@ -38,6 +55,12 @@ BuildRequires: libuuid-devel BuildRequires: libblkid-devel %endif %endif +%if 0%{?_systemd} +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +BuildRequires: systemd +%endif %description This package contains the ZFS command line utilities and libraries. @@ -85,6 +108,11 @@ image which is ZFS aware. %else %define blkid --without-blkid %endif +%if 0%{?_systemd} + %define systemd --enable-systemd --with-systemdunitdir=%{_unitdir} --with-systemdpresetdir=%{_presetdir} --disable-sysvinit +%else + %define systemd --enable-sysvinit --disable-systemd +%endif %setup -q @@ -95,7 +123,8 @@ image which is ZFS aware. --with-dracutdir=%{_dracutdir} \ --disable-static \ %{debug} \ - %{blkid} + %{blkid} \ + %{systemd} make %{?_smp_mflags} %install @@ -105,16 +134,28 @@ find %{?buildroot}%{_libdir} -name '*.la' -exec rm -f {} \; %post /sbin/ldconfig +%if 0%{?_systemd} +%systemd_post zfs.target +%else [ -x /sbin/chkconfig ] && /sbin/chkconfig --add zfs +%endif exit 0 %preun +%if 0%{?_systemd} +%systemd_preun zfs.target +%else if [ $1 -eq 0 ] ; then [ -x /sbin/chkconfig ] && /sbin/chkconfig --del zfs fi +%endif exit 0 -%postun -p /sbin/ldconfig +%postun +/sbin/ldconfig +%if 0%{?_systemd} +%systemd_postun zfs.target +%endif %files %doc AUTHORS COPYRIGHT DISCLAIMER @@ -129,7 +170,13 @@ exit 0 %{_udevdir}/zvol_id %{_udevdir}/rules.d/* %config(noreplace) %{_sysconfdir}/%{name} +%if 0%{?_systemd} +/usr/lib/modules-load.d/* +%{_unitdir}/* +%{_presetdir}/* +%else %{_sysconfdir}/init.d/* +%endif %files devel %{_libdir}/*.so