From a667bc372c44684f92b4f303948ed389449b145f Mon Sep 17 00:00:00 2001 From: Antonio Russo Date: Tue, 9 Jul 2019 07:58:47 -0600 Subject: [PATCH] systemd zvol target Modify the recent zfs-volumes.target to Requires= zfs-volume@.service units that are dynamically generated for each zvol by the existing systemd-generator infrastructure at boot time. This is an alternative to the zfs-volume-wait.service. Each unit polls once per second, exiting if it detects the zvol link, succeeding unconditionally after a 30 second timeout. Signed-off-by: Antonio Russo --- cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in | 5 +++++ etc/systemd/system-generators/Makefile.am | 1 + etc/systemd/system-generators/zfs-mount-generator.in | 10 ++++++++++ etc/systemd/system/50-zfs.preset.in | 2 ++ etc/systemd/system/Makefile.am | 2 ++ etc/systemd/system/zfs-volume@.service.in | 9 +++++++++ 6 files changed, 29 insertions(+) create mode 100644 etc/systemd/system/zfs-volume@.service.in diff --git a/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in b/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in index 6d0f44ab3260..d0c108da3ee8 100755 --- a/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in +++ b/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in @@ -65,6 +65,11 @@ PROPS="name,mountpoint,canmount,atime,relatime,devices,exec,readonly" PROPS="${PROPS},setuid,nbmand,encroot,keylocation" "${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}" +"${ZFS}" list -H -t volume -o name -r "${ZEVENT_POOL}" | while read -r name +do + # fake "zvol" mountpoint + printf '%s\tzvol\toff\n' "$name" >> "${FSLIST_TMP}" +done # Sort the output so that it is stable sort "${FSLIST_TMP}" -o "${FSLIST_TMP}" diff --git a/etc/systemd/system-generators/Makefile.am b/etc/systemd/system-generators/Makefile.am index b4df01322211..f6f826e0608f 100644 --- a/etc/systemd/system-generators/Makefile.am +++ b/etc/systemd/system-generators/Makefile.am @@ -9,6 +9,7 @@ $(systemdgenerator_SCRIPTS): %: %.in -e 's,@runstatedir\@,$(runstatedir),g' \ -e 's,@sbindir\@,$(sbindir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ + -e 's,@systemdunitdir\@,$(systemdunitdir),g' \ $< >'$@' # Double-colon rules are allowed; there are multiple independent definitions. diff --git a/etc/systemd/system-generators/zfs-mount-generator.in b/etc/systemd/system-generators/zfs-mount-generator.in index be2c1420cd70..2688ff2dc5e4 100755 --- a/etc/systemd/system-generators/zfs-mount-generator.in +++ b/etc/systemd/system-generators/zfs-mount-generator.in @@ -46,6 +46,8 @@ fi # avoid regressions, this dependency is reduced to "wants" rather than # "requires". **THIS MAY CHANGE** req_dir="${dest_norm}/local-fs.target.wants/" +zvol_reqdir="${dest_norm}/zfs-volumes.target.requires" +mkdir -p "${zvol_reqdir}" mkdir -p "${req_dir}" # All needed information about each ZFS is available from @@ -74,6 +76,14 @@ process_line() { p_encroot="${11}" p_keyloc="${12}" + if [ "${p_mountpoint}" = "zvol" ] ; then + # special case of zvol + unit="zfs-volume@$(systemd-escape "${dataset}").service" + ln -s "@systemdunitdir@/zfs-volume@.service" \ + "${zvol_reqdir}/${unit}" + return + fi + # Check for canmount=off . if [ "${p_canmount}" = "off" ] ; then return diff --git a/etc/systemd/system/50-zfs.preset.in b/etc/systemd/system/50-zfs.preset.in index e4056a92cd98..81020451df03 100644 --- a/etc/systemd/system/50-zfs.preset.in +++ b/etc/systemd/system/50-zfs.preset.in @@ -4,6 +4,8 @@ disable zfs-import-scan.service enable zfs-import.target enable zfs-mount.service enable zfs-share.service +disable zfs-volumes.target +disable zfs-volume@.service enable zfs-zed.service enable zfs-volume-wait.service enable zfs.target diff --git a/etc/systemd/system/Makefile.am b/etc/systemd/system/Makefile.am index 4e14467a044f..09aa3f9c555c 100644 --- a/etc/systemd/system/Makefile.am +++ b/etc/systemd/system/Makefile.am @@ -9,6 +9,7 @@ systemdunit_DATA = \ zfs-share.service \ zfs-volume-wait.service \ zfs-import.target \ + zfs-volume@.service \ zfs-volumes.target \ zfs.target @@ -18,6 +19,7 @@ EXTRA_DIST = \ $(top_srcdir)/etc/systemd/system/zfs-import-scan.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-volume@.service.in \ $(top_srcdir)/etc/systemd/system/zfs-import.target.in \ $(top_srcdir)/etc/systemd/system/zfs-volume-wait.service.in \ $(top_srcdir)/etc/systemd/system/zfs-volumes.target.in \ diff --git a/etc/systemd/system/zfs-volume@.service.in b/etc/systemd/system/zfs-volume@.service.in new file mode 100644 index 000000000000..7e3e8855ad44 --- /dev/null +++ b/etc/systemd/system/zfs-volume@.service.in @@ -0,0 +1,9 @@ +[Unit] +Description=ZFS zvol %I ready +Before=zfs-volumes.target +DefaultDependencies=no + +[Service] +ExecStart=/bin/sh -c 'timeout=30 ; while [ $timeout -gt 0 ] ; do [ -e "/dev/zvol/$0" ] && exit 0 ; sleep 1 ; timeout=$((timeout-1)); done ; echo "zvol $0 unavailable"' %I +Type=oneshot +RemainAfterExit=yes