#!/bin/sh # shellcheck disable=SC2034 command -v getarg >/dev/null || . /lib/dracut-lib.sh || . /usr/lib/dracut/modules.d/99base/dracut-lib.sh TAB=" " ZPOOL_IMPORT_OPTS= if getargbool 0 zfs_force -y zfs.force -y zfsforce; then warn "ZFS: Will force-import pools if necessary." ZPOOL_IMPORT_OPTS=-f fi _mount_dataset_cb() { # shellcheck disable=SC2154 mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}" } # mount_dataset DATASET # mounts the given zfs dataset. mount_dataset() { dataset="${1}" mountpoint="$(zfs get -H -o value mountpoint "${dataset}")" ret=0 # We need zfsutil for non-legacy mounts and not for legacy mounts. if [ "${mountpoint}" = "legacy" ] ; then mount -t zfs "${dataset}" "${NEWROOT}" || ret=$? else mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" || ret=$? if [ "$ret" = "0" ]; then for_relevant_root_children "${dataset}" _mount_dataset_cb || ret=$? fi fi return "${ret}" } # for_relevant_root_children DATASET EXEC # Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup # Used by zfs-nonroot-necessities.service and friends, too! for_relevant_root_children() { dataset="${1}" exec="${2}" zfs list -t filesystem -Ho name,mountpoint,canmount -r "${dataset}" | ( _ret=0 while IFS="${TAB}" read -r dataset mountpoint canmount; do [ "$canmount" != "on" ] && continue case "$mountpoint" in /etc|/bin|/lib|/lib??|/libx32|/usr) # If these aren't mounted we may not be able to get to the real init at all, or pollute the dataset holding the rootfs "${exec}" "${dataset}" "${mountpoint}" || _ret=$? ;; *) # Up to the real init to remount everything else it might need ;; esac done exit "${_ret}" ) } # Parse root=, rootfstype=, return them decoded and normalised to zfs:AUTO for auto, plain dset for explicit # # True if ZFS-on-root, false if we shouldn't # # Supported values: # root= # root=zfs # root=zfs: # root=zfs:AUTO # # root=ZFS=data/set # root=zfs:data/set # root=zfs:ZFS=data/set (as a side-effect; allowed but undocumented) # # rootfstype=zfs AND root=data/set <=> root=data/set # rootfstype=zfs AND root= <=> root=zfs:AUTO # # '+'es in explicit dataset decoded to ' 's. decode_root_args() { if [ -n "$rootfstype" ]; then [ "$rootfstype" = zfs ] return fi xroot=$(getarg root=) rootfstype=$(getarg rootfstype=) # shellcheck disable=SC2249 case "$xroot" in ""|zfs|zfs:|zfs:AUTO) root=zfs:AUTO rootfstype=zfs return 0 ;; ZFS=*|zfs:*) root="${xroot#zfs:}" root="${root#ZFS=}" root=$(echo "$root" | tr '+' ' ') rootfstype=zfs return 0 ;; esac if [ "$rootfstype" = "zfs" ]; then case "$xroot" in "") root=zfs:AUTO ;; *) root=$(echo "$xroot" | tr '+' ' ') ;; esac return 0 fi return 1 }