Skip to content

Commit

Permalink
Add systemd unit files for ZFS startup
Browse files Browse the repository at this point in the history
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 <[email protected]>
Closes #2108
  • Loading branch information
Lalufu authored and behlendorf committed Feb 5, 2014
1 parent c5cb66a commit 881f45c
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 3 deletions.
29 changes: 29 additions & 0 deletions config/user-systemd.m4
Original file line number Diff line number Diff line change
@@ -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)
])
11 changes: 11 additions & 0 deletions config/user-sysvinit.m4
Original file line number Diff line number Diff line change
@@ -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)
])
2 changes: 2 additions & 0 deletions config/user.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion etc/Makefile.am
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions etc/modules-load.d/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.conf
13 changes: 13 additions & 0 deletions etc/modules-load.d/Makefile.am
Original file line number Diff line number Diff line change
@@ -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 '' \
'[email protected]' >'$@'

distclean-local::
-$(RM) $(modulesload_DATA)
1 change: 1 addition & 0 deletions etc/modules-load.d/zfs.conf.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
zfs

This comment has been minimized.

Copy link
@Rudd-O

Rudd-O Apr 18, 2014

Contributor

This will cause automatic pool import when this module is loaded, which may happen way before block devices are present.

The patch also doesn't seem to contemplate support for root on ZFS.

This comment has been minimized.

Copy link
@behlendorf

behlendorf Apr 18, 2014

Contributor

I believe pool import should occur after the block device are available due to the following in the service files.

Requires=systemd-udev-settle.service
After=systemd-udev-settle.service

The patch also doesn't seem to contemplate support for root on ZFS.

That's true, but this is definitely a step in the right direction for most installations. I'm all for building on this to properly handle the root on ZFS case.

1 change: 1 addition & 0 deletions etc/systemd/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SUBDIRS = system
3 changes: 3 additions & 0 deletions etc/systemd/system/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.service
*.target
*.preset
2 changes: 2 additions & 0 deletions etc/systemd/system/50-zfs.preset.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ZFS is enabled by default
enable zfs.*
31 changes: 31 additions & 0 deletions etc/systemd/system/Makefile.am
Original file line number Diff line number Diff line change
@@ -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' \
'[email protected]' >'$@'

$(systemdpreset_DATA):
-$(SED) -e 's,@bindir\@,$(bindir),g' \
-e 's,@sbindir\@,$(sbindir),g' \
-e 's,@sysconfdir\@,$(sysconfdir),g' \
'[email protected]' >'$@'

distclean-local::
-$(RM) $(systemdunit_DATA) $(systemdpreset_DATA)
11 changes: 11 additions & 0 deletions etc/systemd/system/zfs-import-cache.service.in
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions etc/systemd/system/zfs-import-scan.service.in
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions etc/systemd/system/zfs-mount.service.in
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions etc/systemd/system/zfs-share.service.in
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions etc/systemd/system/zfs.target.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[Unit]
Description=ZFS startup target
Requires=zfs-mount.service
Requires=zfs-share.service

[Install]
WantedBy=multi-user.target
51 changes: 49 additions & 2 deletions rpm/generic/zfs.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand All @@ -95,7 +123,8 @@ image which is ZFS aware.
--with-dracutdir=%{_dracutdir} \
--disable-static \
%{debug} \
%{blkid}
%{blkid} \
%{systemd}
make %{?_smp_mflags}

%install
Expand All @@ -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
Expand All @@ -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
Expand Down

3 comments on commit 881f45c

@Rudd-O
Copy link
Contributor

@Rudd-O Rudd-O commented on 881f45c Apr 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I note there doesn't seem to be support for root on ZFS yet, and mounting file systems is done globally (-a) preventing interleaving of non-ZFS and ZFS file systems at different depths of the hierarchy of the mount tree.

:-\ My tree had a different implementation that has its problems, of course, but does support both features.

@behlendorf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it would be nice to support both of those use cases. My suggestion would be to open a new issue for each of those features and those most familiar with systemd can hash out the right way to add that functionality.

@Lalufu
Copy link
Contributor Author

@Lalufu Lalufu commented on 881f45c May 6, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The basic idea was to replace the functionality offered by the SysV init script (and fix some low hanging issues in the process).

I'm happy to look at booting from ZFS and the interleaving mount issue (the latter first, probably). If you file bugs for this please notify me.

Please sign in to comment.