1#!/bin/sh 2# shellcheck disable=SC2016,SC1004 3 4grep -wq debug /proc/cmdline && debug=1 5[ -n "$debug" ] && echo "zfs-generator: starting" >> /dev/kmsg 6 7GENERATOR_DIR="$1" 8[ -n "$GENERATOR_DIR" ] || { 9 echo "zfs-generator: no generator directory specified, exiting" >> /dev/kmsg 10 exit 1 11} 12 13[ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh 14[ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh 15command -v getarg >/dev/null 2>&1 || { 16 [ -n "$debug" ] && echo "zfs-generator: loading Dracut library from $dracutlib" >> /dev/kmsg 17 . "$dracutlib" 18} 19 20. /lib/dracut-zfs-lib.sh 21 22[ -z "$root" ] && root=$(getarg root=) 23[ -z "$rootfstype" ] && rootfstype=$(getarg rootfstype=) 24[ -z "$rootflags" ] && rootflags=$(getarg rootflags=) 25 26# If root is not ZFS= or zfs: or rootfstype is not zfs 27# then we are not supposed to handle it. 28[ "${root##zfs:}" = "${root}" ] && 29 [ "${root##ZFS=}" = "${root}" ] && 30 [ "$rootfstype" != "zfs" ] && 31 exit 0 32 33case ",${rootflags}," in 34 *,zfsutil,*) ;; 35 ,,) rootflags=zfsutil ;; 36 *) rootflags="zfsutil,${rootflags}" ;; 37esac 38 39if [ "${root}" != "zfs:AUTO" ]; then 40 root="${root##zfs:}" 41 root="${root##ZFS=}" 42fi 43 44[ -n "$debug" ] && echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf" >> /dev/kmsg 45 46 47mkdir -p "$GENERATOR_DIR"/sysroot.mount.d "$GENERATOR_DIR"/initrd-root-fs.target.requires "$GENERATOR_DIR"/dracut-pre-mount.service.d 48{ 49 echo "[Unit]" 50 echo "Before=initrd-root-fs.target" 51 echo "After=zfs-import.target" 52 echo 53 echo "[Mount]" 54 if [ "${root}" = "zfs:AUTO" ]; then 55 echo "PassEnvironment=BOOTFS" 56 echo 'What=${BOOTFS}' 57 else 58 echo "What=${root}" 59 fi 60 echo "Type=zfs" 61 echo "Options=${rootflags}" 62} > "$GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf 63ln -fs ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount 64 65 66if [ "${root}" = "zfs:AUTO" ]; then 67 { 68 echo "[Unit]" 69 echo "Before=initrd-root-fs.target" 70 echo "After=sysroot.mount" 71 echo "DefaultDependencies=no" 72 echo 73 echo "[Service]" 74 echo "Type=oneshot" 75 echo "PassEnvironment=BOOTFS" 76 echo "ExecStart=/bin/sh -c '" ' \ 77 . /lib/dracut-zfs-lib.sh; \ 78 _zfs_nonroot_necessities_cb() { \ 79 zfs mount | grep -m1 -q "^$1 " && return 0; \ 80 echo "Mounting $1 on /sysroot$2"; \ 81 mount -o zfsutil -t zfs "$1" "/sysroot$2"; \ 82 }; \ 83 for_relevant_root_children "${BOOTFS}" _zfs_nonroot_necessities_cb;' \ 84 "'" 85 } > "$GENERATOR_DIR"/zfs-nonroot-necessities.service 86 ln -fs ../zfs-nonroot-necessities.service "$GENERATOR_DIR"/initrd-root-fs.target.requires/zfs-nonroot-necessities.service 87else 88 # We can solve this statically at generation time, so do! 89 _zfs_generator_cb() { 90 dset="${1}" 91 mpnt="${2}" 92 unit="sysroot$(echo "$mpnt" | sed 's;/;-;g').mount" 93 94 { 95 echo "[Unit]" 96 echo "Before=initrd-root-fs.target" 97 echo "After=sysroot.mount" 98 echo 99 echo "[Mount]" 100 echo "Where=/sysroot${mpnt}" 101 echo "What=${dset}" 102 echo "Type=zfs" 103 echo "Options=zfsutil" 104 } > "$GENERATOR_DIR/${unit}" 105 ln -fs ../"${unit}" "$GENERATOR_DIR"/initrd-root-fs.target.requires/"${unit}" 106 } 107 108 for_relevant_root_children "${root}" _zfs_generator_cb 109fi 110 111 112{ 113 echo "[Unit]" 114 echo "After=zfs-import.target" 115} > "$GENERATOR_DIR"/dracut-pre-mount.service.d/zfs-enhancement.conf 116 117[ -n "$debug" ] && echo "zfs-generator: finished" >> /dev/kmsg 118 119exit 0 120