*) 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
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
fi
rootok=0
-need_shutdown
#!/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
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