Add canonical mount options zfs-mount-generator
lib/libzfs/libzfs_mount.c:zfs_add_options provides the canonical mount options used by a `zfs mount` command. Because we cannot call `zfs mount` directly from a systemd.mount unit, we mirror that logic in zfs-mount-generator. The zed script is updated to cache these properties as well. Include a mini-tutorial in the manual page, properly substitute configuration paths in zfs-mount-generator.8.in, and standardize the Makefile. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: Antonio Russo <antonio.e.russo@gmail.com> Closes #7453
This commit is contained in:
parent
29badadd4e
commit
68fded8146
|
@ -44,9 +44,10 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
|
||||||
;;
|
;;
|
||||||
|
|
||||||
set|inherit)
|
set|inherit)
|
||||||
# Only act if the mountpoint or canmount setting is altered.
|
# Only act if one of the tracked properties is altered.
|
||||||
case "${ZEVENT_HISTORY_INTERNAL_STR}" in
|
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
|
||||||
canmount=*|mountpoint=*) ;;
|
canmount|mountpoint|atime|relatime|devices|exec| \
|
||||||
|
readonly|setuid|nbmand) ;;
|
||||||
*) exit 0 ;;
|
*) exit 0 ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
@ -60,8 +61,10 @@ esac
|
||||||
zed_lock zfs-list
|
zed_lock zfs-list
|
||||||
trap abort_alter EXIT
|
trap abort_alter EXIT
|
||||||
|
|
||||||
"${ZFS}" list -H -tfilesystem -oname,mountpoint,canmount -r "${ZEVENT_POOL}" \
|
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec,readonly"
|
||||||
>"${FSLIST_TMP}"
|
PROPS="${PROPS},setuid,nbmand"
|
||||||
|
|
||||||
|
"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
||||||
|
|
||||||
# Sort the output so that it is stable
|
# Sort the output so that it is stable
|
||||||
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
|
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
|
||||||
|
|
|
@ -49,38 +49,123 @@ req_dir="${dest_norm}/local-fs.target.wants/"
|
||||||
mkdir -p "${req_dir}"
|
mkdir -p "${req_dir}"
|
||||||
|
|
||||||
# All needed information about each ZFS is available from
|
# All needed information about each ZFS is available from
|
||||||
# zfs list -H -t filesystem -oname,mountpoint,canmount
|
# zfs list -H -t filesystem -o <properties>
|
||||||
# cached in $FSLIST, and each line is processed by the following function:
|
# cached in $FSLIST, and each line is processed by the following function:
|
||||||
|
# See the list below for the properties and their order
|
||||||
|
|
||||||
process_line() {
|
process_line() {
|
||||||
|
|
||||||
|
# -o name
|
||||||
|
dataset="${1}"
|
||||||
|
p_mountpoint="${2}"
|
||||||
|
p_canmount="${3}"
|
||||||
|
p_atime="${4}"
|
||||||
|
p_relatime="${5}"
|
||||||
|
p_devices="${6}"
|
||||||
|
p_exec="${7}"
|
||||||
|
p_readonly="${8}"
|
||||||
|
p_setuid="${9}"
|
||||||
|
p_nbmand="${10}"
|
||||||
|
|
||||||
# Check for canmount=off .
|
# Check for canmount=off .
|
||||||
if [ "${3}" = "off" ] ; then
|
if [ "${p_canmount}" = "off" ] ; then
|
||||||
return
|
return
|
||||||
elif [ "${3}" = "noauto" ] ; then
|
elif [ "${p_canmount}" = "noauto" ] ; then
|
||||||
# Don't let a noauto marked mountpoint block an "auto" market mountpoint
|
# Don't let a noauto marked mountpoint block an "auto" market mountpoint
|
||||||
return
|
return
|
||||||
elif [ "${3}" = "on" ] ; then
|
elif [ "${p_canmount}" = "on" ] ; then
|
||||||
: # This is OK
|
: # This is OK
|
||||||
else
|
else
|
||||||
do_fail "invalid canmount"
|
do_fail "invalid canmount"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for legacy and blank mountpoints.
|
# Check for legacy and blank mountpoints.
|
||||||
if [ "${2}" = "legacy" ] ; then
|
if [ "${p_mountpoint}" = "legacy" ] ; then
|
||||||
return
|
return
|
||||||
elif [ "${2}" = "none" ] ; then
|
elif [ "${p_mountpoint}" = "none" ] ; then
|
||||||
return
|
return
|
||||||
elif [ "${2%"${2#?}"}" != "/" ] ; then
|
elif [ "${p_mountpoint%"${p_mountpoint#?}"}" != "/" ] ; then
|
||||||
do_fail "invalid mountpoint $*"
|
do_fail "invalid mountpoint $*"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape the mountpoint per systemd policy.
|
# Escape the mountpoint per systemd policy.
|
||||||
mountfile="$(systemd-escape "${2#?}").mount"
|
mountfile="$(systemd-escape "${p_mountpoint#?}").mount"
|
||||||
|
|
||||||
|
# Parse options
|
||||||
|
# see lib/libzfs/libzfs_mount.c:zfs_add_options
|
||||||
|
opts=""
|
||||||
|
|
||||||
|
# atime
|
||||||
|
if [ "${p_atime}" = on ] ; then
|
||||||
|
# relatime
|
||||||
|
if [ "${p_relatime}" = on ] ; then
|
||||||
|
opts="${opts},atime,relatime"
|
||||||
|
elif [ "${p_relatime}" = off ] ; then
|
||||||
|
opts="${opts},atime,strictatime"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid relatime\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
elif [ "${p_atime}" = off ] ; then
|
||||||
|
opts="${opts},noatime"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid atime\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
|
||||||
|
# devices
|
||||||
|
if [ "${p_devices}" = on ] ; then
|
||||||
|
opts="${opts},dev"
|
||||||
|
elif [ "${p_devices}" = off ] ; then
|
||||||
|
opts="${opts},nodev"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid devices\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
|
||||||
|
# exec
|
||||||
|
if [ "${p_exec}" = on ] ; then
|
||||||
|
opts="${opts},exec"
|
||||||
|
elif [ "${p_exec}" = off ] ; then
|
||||||
|
opts="${opts},noexec"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid exec\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
|
||||||
|
# readonly
|
||||||
|
if [ "${p_readonly}" = on ] ; then
|
||||||
|
opts="${opts},ro"
|
||||||
|
elif [ "${p_readonly}" = off ] ; then
|
||||||
|
opts="${opts},rw"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid readonly\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
|
||||||
|
# setuid
|
||||||
|
if [ "${p_setuid}" = on ] ; then
|
||||||
|
opts="${opts},suid"
|
||||||
|
elif [ "${p_setuid}" = off ] ; then
|
||||||
|
opts="${opts},nosuid"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid setuid\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
|
||||||
|
# nbmand
|
||||||
|
if [ "${p_nbmand}" = on ] ; then
|
||||||
|
opts="${opts},mand"
|
||||||
|
elif [ "${p_nbmand}" = off ] ; then
|
||||||
|
opts="${opts},nomand"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator.sh: (%s) invalid nbmand\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
|
||||||
# If the mountpoint has already been created, give it precedence.
|
# If the mountpoint has already been created, give it precedence.
|
||||||
if [ -e "${dest_norm}/${mountfile}" ] ; then
|
if [ -e "${dest_norm}/${mountfile}" ] ; then
|
||||||
printf 'zfs-mount-generator.sh: %s.mount already exists\n' "${2}" \
|
printf 'zfs-mount-generator.sh: %s already exists\n' "${mountfile}" \
|
||||||
>/dev/kmsg
|
>/dev/kmsg
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
@ -97,14 +182,14 @@ After=zfs-import.target
|
||||||
Wants=zfs-import.target
|
Wants=zfs-import.target
|
||||||
|
|
||||||
[Mount]
|
[Mount]
|
||||||
Where=${2}
|
Where=${p_mountpoint}
|
||||||
What=${1}
|
What=${dataset}
|
||||||
Type=zfs
|
Type=zfs
|
||||||
Options=zfsutil,auto
|
Options=defaults${opts},zfsutil
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Finally, create the appropriate dependencies based on the ZFS properties.
|
# Finally, create the appropriate dependency
|
||||||
[ "$3" = "on" ] & ln -s "../${mountfile}" "${req_dir}"
|
ln -s "../${mountfile}" "${req_dir}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Feed each line into process_line
|
# Feed each line into process_line
|
||||||
|
|
|
@ -4,7 +4,6 @@ dist_man_MANS = \
|
||||||
vdev_id.8 \
|
vdev_id.8 \
|
||||||
zdb.8 \
|
zdb.8 \
|
||||||
zfs.8 \
|
zfs.8 \
|
||||||
zfs-mount-generator.8 \
|
|
||||||
zfs-program.8 \
|
zfs-program.8 \
|
||||||
zgenhostid.8 \
|
zgenhostid.8 \
|
||||||
zinject.8 \
|
zinject.8 \
|
||||||
|
@ -12,24 +11,18 @@ dist_man_MANS = \
|
||||||
zstreamdump.8
|
zstreamdump.8
|
||||||
|
|
||||||
nodist_man_MANS = \
|
nodist_man_MANS = \
|
||||||
zed.8
|
zed.8 \
|
||||||
|
zfs-mount-generator.8
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
zed.8.in
|
zed.8.in \
|
||||||
|
zfs-mount-generator.8.in
|
||||||
|
|
||||||
zed.8: $(srcdir)/zed.8.in
|
$(nodist_man_MANS): %: %.in
|
||||||
|
-$(SED) -e 's,@libexecdir\@,$(libexecdir),g' \
|
||||||
do_subst = $(SED) \
|
-e 's,@runstatedir\@,$(runstatedir),g' \
|
||||||
-e 's|@libexecdir[@]|$(libexecdir)|g' \
|
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
||||||
-e 's|@runstatedir[@]|$(runstatedir)|g' \
|
$< >'$@'
|
||||||
-e 's|@sysconfdir[@]|$(sysconfdir)|g'
|
|
||||||
|
|
||||||
$(nodist_man_MANS): Makefile
|
|
||||||
$(RM) $@ $@.tmp
|
|
||||||
srcdir=''; \
|
|
||||||
test -f ./$@.in || srcdir=$(srcdir)/; \
|
|
||||||
$(do_subst) $${srcdir}$@.in >$@.tmp
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
install-data-local:
|
install-data-local:
|
||||||
$(INSTALL) -d -m 0755 "$(DESTDIR)$(mandir)/man8"
|
$(INSTALL) -d -m 0755 "$(DESTDIR)$(mandir)/man8"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
.TH "ZFS\-MOUNT\-GENERATOR" "8" "ZFS" "zfs-mount-generator" "\""
|
.TH "ZFS\-MOUNT\-GENERATOR" "8" "ZFS" "zfs-mount-generator" "\""
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
zfs\-mount\-generator \- generates systemd mount units for zfs
|
zfs\-mount\-generator \- generates systemd mount units for ZFS
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B /lib/systemd/system-generators/zfs\-mount\-generator
|
.B /lib/systemd/system-generators/zfs\-mount\-generator
|
||||||
.sp
|
.sp
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The zfs\-mount\-generator implements the \fBGenerators Specification\fP
|
zfs\-mount\-generator implements the \fBGenerators Specification\fP
|
||||||
of
|
of
|
||||||
.BR systemd (1),
|
.BR systemd (1),
|
||||||
and is called during early boot to generate
|
and is called during early boot to generate
|
||||||
|
@ -26,7 +26,7 @@ information on ZFS mountpoints must be stored separately. The output
|
||||||
of the command
|
of the command
|
||||||
.PP
|
.PP
|
||||||
.RS 4
|
.RS 4
|
||||||
zfs list -H -oname,mountpoint,canmount
|
zfs list -H -o name,mountpoint,canmount,atime,relatime,devices,exec,readonly,setuid,nbmand
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
for datasets that should be mounted by systemd, should be kept
|
for datasets that should be mounted by systemd, should be kept
|
||||||
|
@ -45,6 +45,33 @@ history_event-zfs-list-cacher.sh .
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
.sp
|
.sp
|
||||||
|
.SH EXAMPLE
|
||||||
|
To begin, enable tracking for the pool:
|
||||||
|
.PP
|
||||||
|
.RS 4
|
||||||
|
touch
|
||||||
|
.RI @sysconfdir@/zfs/zfs-list.cache/ POOLNAME
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
Then, enable the tracking ZEDLET:
|
||||||
|
.PP
|
||||||
|
.RS 4
|
||||||
|
ln -s "@libexecdir@/zfs/zed.d/history_event-zfs-list-cacher.sh" "@sysconfdir@/zfs/zed.d/"
|
||||||
|
|
||||||
|
systemctl enable zed.service
|
||||||
|
|
||||||
|
systemctl restart zed.service
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
Force the running of the ZEDLET by setting canmount=on for at least one dataset in the pool:
|
||||||
|
.PP
|
||||||
|
.RS 4
|
||||||
|
zfs set canmount=on
|
||||||
|
.I DATASET
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
This forces an update to the stale cache file.
|
||||||
|
.sp
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR zfs (5)
|
.BR zfs (5)
|
||||||
.BR zfs-events (5)
|
.BR zfs-events (5)
|
Loading…
Reference in New Issue