systemd mount generator and tracking ZEDLET

zfs-mount-generator implements the "systemd generator" protocol,
producing systemd.mount units from the cached outputs of zfs list,
during early boot, integrating with systemd.

Each pool has an indpendent cache of the command

  zfs list -H -oname,mountpoint,canmount -tfilesystem -r $pool

which is kept synchronized by the ZEDLET

  history_event-zfs-list-cacher.sh

Datasets not in the cache will be loaded later in the boot process by
zfs-mount.service, including pools without a cache.

Among other things, this allows for complex mount hierarchies.

Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Richard Laager <rlaager@wiktel.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Antonio Russo <antonio.e.russo@gmail.com>
Closes #7329
This commit is contained in:
Antonio Russo
2018-04-06 17:11:09 -04:00
committed by Brian Behlendorf
parent 5c27ec1088
commit 55d80e651a
12 changed files with 282 additions and 3 deletions
+10 -1
View File
@@ -4,7 +4,8 @@ DEFAULT_INCLUDES += \
-I$(top_srcdir)/include \
-I$(top_srcdir)/lib/libspl/include
EXTRA_DIST = zed.d/README
EXTRA_DIST = zed.d/README \
zed.d/history_event-zfs-list-cacher.sh.in
sbin_PROGRAMS = zed
@@ -60,6 +61,7 @@ dist_zedexec_SCRIPTS = \
zed.d/all-syslog.sh \
zed.d/data-notify.sh \
zed.d/generic-notify.sh \
zed.d/history_event-zfs-list-cacher.sh \
zed.d/resilver_finish-notify.sh \
zed.d/scrub_finish-notify.sh \
zed.d/statechange-led.sh \
@@ -69,6 +71,13 @@ dist_zedexec_SCRIPTS = \
zed.d/pool_import-led.sh \
zed.d/resilver_finish-start-scrub.sh
zed.d/history_event-zfs-list-cacher.sh: %: %.in
-$(SED) -e 's,@bindir\@,$(bindir),g' \
-e 's,@runstatedir\@,$(runstatedir),g' \
-e 's,@sbindir\@,$(sbindir),g' \
-e 's,@sysconfdir\@,$(sysconfdir),g' \
$< >'$@'
zedconfdefaults = \
all-syslog.sh \
data-notify.sh \
+1
View File
@@ -0,0 +1 @@
history_event-zfs-list-cacher.sh
+73
View File
@@ -0,0 +1,73 @@
#!/bin/sh
#
# Track changes to enumerated pools for use in early-boot
set -ef
FSLIST_DIR="@sysconfdir@/zfs/zfs-list.cache"
FSLIST_TMP="@runstatedir@/zfs-list.cache.new"
FSLIST="${FSLIST_DIR}/${ZEVENT_POOL}"
# If the pool specific cache file is not writeable, abort
[ -w "${FSLIST}" ] || exit 0
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
zed_exit_if_ignoring_this_event
zed_check_cmd "${ZFS}" sort diff grep
# If we are acting on a snapshot, we have nothing to do
printf '%s' "${ZEVENT_HISTORY_DSNAME}" | grep '@' && exit 0
# We obtain a lock on zfs-list to avoid any simultaneous writes.
# If we run into trouble, log and drop the lock
abort_alter() {
zed_log_msg "Error updating zfs-list.cache!"
zed_unlock zfs-list
}
finished() {
zed_unlock zfs-list
trap - EXIT
exit 0
}
case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
create|"finish receiving"|import|destroy|rename)
;;
export)
zed_lock zfs-list
trap abort_alter EXIT
echo > "${FSLIST}"
finished
;;
set|inherit)
# Only act if the mountpoint or canmount setting is altered.
case "${ZEVENT_HISTORY_INTERNAL_STR}" in
canmount=*|mountpoint=*) ;;
*) exit 0 ;;
esac
;;
*)
# Ignore all other events.
exit 0
;;
esac
zed_lock zfs-list
trap abort_alter EXIT
"${ZFS}" list -H -tfilesystem -oname,mountpoint,canmount -r "${ZEVENT_POOL}" \
>"${FSLIST_TMP}"
# Sort the output so that it is stable
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
# Don't modify the file if it hasn't changed
diff -q "${FSLIST_TMP}" "${FSLIST}" || mv "${FSLIST_TMP}" "${FSLIST}"
rm -f "${FSLIST_TMP}"
finished