diff --git a/contrib/dracut/90zfs/mount-zfs.sh.in b/contrib/dracut/90zfs/mount-zfs.sh.in index 51e107bb35..3b6be314cd 100755 --- a/contrib/dracut/90zfs/mount-zfs.sh.in +++ b/contrib/dracut/90zfs/mount-zfs.sh.in @@ -10,17 +10,29 @@ case "${root}" in *) return ;; esac -if command -v systemctl >/dev/null; then - # If sysroot.mount exists, the initial RAM disk configured - # it to mount ZFS on root. In that case, we bail early. - loadstate="$(systemctl --system --show -p LoadState sysroot.mount || true)" - if [ "${loadstate}" = "LoadState=not-found" -o "${loadstate}" = "" ] ; then - info "ZFS: sysroot.mount absent, mounting root with mount-zfs.sh" - else - info "ZFS: sysroot.mount present, delegating root mount to it" - return - fi +GENERATOR_FILE=/run/systemd/generator/sysroot.mount +GENERATOR_EXTENSION=/run/systemd/generator/sysroot.mount.d/zfs-enhancement.conf + +if [ -e "$GENERATOR_FILE" -a -e "$GENERATOR_EXTENSION" ] ; then + # If the ZFS sysroot.mount flag exists, the initial RAM disk configured + # it to mount ZFS on root. In that case, we bail early. This flag + # file gets created by the zfs-generator program upon successful run. + info "ZFS: There is a sysroot.mount and zfs-generator has extended it." + info "ZFS: Delegating root mount to sysroot.mount." + # Let us tell the initrd to run on shutdown. + # We have a shutdown hook to run + # because we imported the pool. + need_shutdown + # We now prevent Dracut from running this thing again. + for zfsmounthook in "$hookdir"/mount/*zfs* ; do + if [ -f "$zfsmounthook" ] ; then + rm -f "$zfsmounthook" + fi + done + return fi +info "ZFS: No sysroot.mount exists or zfs-generator did not extend it." +info "ZFS: Mounting root with the traditional mount-zfs.sh instead." # Delay until all required block devices are present. udevadm settle @@ -45,6 +57,10 @@ ZFS_DATASET="${ZFS_DATASET:-${root#zfs:}}" ZFS_POOL="${ZFS_DATASET%%/*}" if import_pool "${ZFS_POOL}" ; then + # Let us tell the initrd to run on shutdown. + # We have a shutdown hook to run + # because we imported the pool. + need_shutdown info "ZFS: Mounting dataset ${ZFS_DATASET}..." if mount_dataset "${ZFS_DATASET}" ; then ROOTFS_MOUNTED=yes @@ -53,4 +69,3 @@ if import_pool "${ZFS_POOL}" ; then fi rootok=0 -need_shutdown diff --git a/contrib/dracut/90zfs/zfs-generator.sh.in b/contrib/dracut/90zfs/zfs-generator.sh.in index aa12fb856d..c6384f5835 100755 --- a/contrib/dracut/90zfs/zfs-generator.sh.in +++ b/contrib/dracut/90zfs/zfs-generator.sh.in @@ -1,21 +1,32 @@ #!/bin/bash +echo "zfs-generator: starting" >> /dev/kmsg + GENERATOR_DIR="$1" -[ -z "$GENERATOR_DIR" ] && exit 1 +[ -n "$GENERATOR_DIR" ] || { + echo "zfs-generator: no generator directory specified, exiting" >> /dev/kmsg + exit 1 +} [ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh [ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh -type getarg >/dev/null 2>&1 || . "$dracutlib" +type getarg >/dev/null 2>&1 || { + echo "zfs-generator: loading Dracut library from $dracutlib" >> /dev/kmsg + . "$dracutlib" +} [ -z "$root" ] && root=$(getarg root=) [ -z "$rootfstype" ] && rootfstype=$(getarg rootfstype=) [ -z "$rootflags" ] && rootflags=$(getarg rootflags=) +# If root is not ZFS= or zfs: or rootfstype is not zfs +# then we are not supposed to handle it. [ "${root##zfs:}" = "${root}" -a "${root##ZFS=}" = "${root}" -a "$rootfstype" != "zfs" ] && exit 0 -# If root is set to zfs:AUTO, then we know sysroot.mount will not be generated -# so we have no need to enhance it. -# See https://github.com/zfsonlinux/zfs/pull/4558#discussion_r61118952 for details. +# If root is set to zfs:AUTO, then we are also not +# supposed to handle it, and it should be handled +# by the traditional Dracut mount hook. +# See https://github.com/zfsonlinux/zfs/pull/4558#discussion_r61118952 if [ "${root}" = "zfs:AUTO" ] ; then exit 0 fi @@ -32,16 +43,23 @@ fi root="${root##zfs:}" root="${root##ZFS=}" +echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf >> /dev/kmsg + [ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR" -[ -d "$GENERATOR_DIR/sysroot.mount.d" ] || mkdir "$GENERATOR_DIR/sysroot.mount.d" +[ -d "$GENERATOR_DIR"/sysroot.mount.d ] || mkdir "$GENERATOR_DIR"/sysroot.mount.d { echo "[Unit]" + echo "Before=initrd-root-fs.target" echo "After=zfs-import-scan.service" echo "After=zfs-import-cache.service" - echo "" echo "[Mount]" echo "What=${root}" echo "Type=${rootfstype}" echo "Options=${rootflags}" -} > "$GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf" +} > "$GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf + +[ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires +ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount + +echo "zfs-generator: finished" >> /dev/kmsg