1#!/bin/sh 2# shellcheck disable=SC2034 3 4command -v getarg >/dev/null || . /lib/dracut-lib.sh || . /usr/lib/dracut/modules.d/99base/dracut-lib.sh 5 6TAB=" " 7 8ZPOOL_IMPORT_OPTS= 9if getargbool 0 zfs_force -y zfs.force -y zfsforce; then 10 warn "ZFS: Will force-import pools if necessary." 11 ZPOOL_IMPORT_OPTS=-f 12fi 13 14_mount_dataset_cb() { 15 # shellcheck disable=SC2154 16 mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}" 17} 18 19# mount_dataset DATASET 20# mounts the given zfs dataset. 21mount_dataset() { 22 dataset="${1}" 23 mountpoint="$(zfs get -H -o value mountpoint "${dataset}")" 24 ret=0 25 26 # We need zfsutil for non-legacy mounts and not for legacy mounts. 27 if [ "${mountpoint}" = "legacy" ] ; then 28 mount -t zfs "${dataset}" "${NEWROOT}" || ret=$? 29 else 30 mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" || ret=$? 31 32 if [ "$ret" = "0" ]; then 33 for_relevant_root_children "${dataset}" _mount_dataset_cb || ret=$? 34 fi 35 fi 36 37 return "${ret}" 38} 39 40# for_relevant_root_children DATASET EXEC 41# Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup 42# Used by zfs-nonroot-necessities.service and friends, too! 43for_relevant_root_children() { 44 dataset="${1}" 45 exec="${2}" 46 47 zfs list -t filesystem -Ho name,mountpoint,canmount -r "${dataset}" | 48 ( 49 _ret=0 50 while IFS="${TAB}" read -r dataset mountpoint canmount; do 51 [ "$canmount" != "on" ] && continue 52 53 case "$mountpoint" in 54 /etc|/bin|/lib|/lib??|/libx32|/usr) 55 # 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 56 "${exec}" "${dataset}" "${mountpoint}" || _ret=$? 57 ;; 58 *) 59 # Up to the real init to remount everything else it might need 60 ;; 61 esac 62 done 63 exit "${_ret}" 64 ) 65} 66 67# Parse root=, rootfstype=, return them decoded and normalised to zfs:AUTO for auto, plain dset for explicit 68# 69# True if ZFS-on-root, false if we shouldn't 70# 71# Supported values: 72# root= 73# root=zfs 74# root=zfs: 75# root=zfs:AUTO 76# 77# root=ZFS=data/set 78# root=zfs:data/set 79# root=zfs:ZFS=data/set (as a side-effect; allowed but undocumented) 80# 81# rootfstype=zfs AND root=data/set <=> root=data/set 82# rootfstype=zfs AND root= <=> root=zfs:AUTO 83# 84# '+'es in explicit dataset decoded to ' 's. 85decode_root_args() { 86 if [ -n "$rootfstype" ]; then 87 [ "$rootfstype" = zfs ] 88 return 89 fi 90 91 xroot=$(getarg root=) 92 rootfstype=$(getarg rootfstype=) 93 94 # shellcheck disable=SC2249 95 case "$xroot" in 96 ""|zfs|zfs:|zfs:AUTO) 97 root=zfs:AUTO 98 rootfstype=zfs 99 return 0 100 ;; 101 102 ZFS=*|zfs:*) 103 root="${xroot#zfs:}" 104 root="${root#ZFS=}" 105 root=$(echo "$root" | tr '+' ' ') 106 rootfstype=zfs 107 return 0 108 ;; 109 esac 110 111 if [ "$rootfstype" = "zfs" ]; then 112 case "$xroot" in 113 "") root=zfs:AUTO ;; 114 *) root=$(echo "$xroot" | tr '+' ' ') ;; 115 esac 116 return 0 117 fi 118 119 return 1 120} 121