# ZFS boot stub for initramfs-tools. zfs_test_import() { if zpool import -o readonly=on -N "$ZFS_RPOOL" >/dev/null 2>&1 then ZFS_HEALTH=$(zpool list -H -o health "$ZFS_RPOOL" 2>/dev/null) fi while [ "$retry_nr" -lt "$delay" ] do ZFS_STDERR=$(zpool export "$ZFS_RPOOL" >/dev/null) if ! echo "$ZFS_STDERR" | grep -q "is busy" then break fi /bin/sleep 1 retry_nr=$(( $retry_nr + 1 )) done } mountroot() { [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-top" run_scripts /scripts/local-top [ "$quiet" != "y" ] && log_end_msg [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount" run_scripts /scripts/local-premount [ "$quiet" != "y" ] && log_end_msg # Wait for all of the /dev/{hd,sd}[a-z] device nodes to appear. wait_for_udev modprobe zfs zfs_autoimport_disable=1 ZFS_BOOTFS=${ROOT#ZFS=} ZFS_RPOOL=$(echo "$ZFS_BOOTFS" | sed -e 's,/.*,,') delay=${ROOTDELAY:-0} if [ "$delay" -gt 0 ] then # Try to import the pool read-only. If it does not import with # the ONLINE status, wait and try again. The pool could be # DEGRADED because a drive is really missing, or it might just # be slow to be detected. retry_nr=0 zfs_test_import while [ "$retry_nr" -lt "$delay" ] && [ "$ZFS_HEALTH" != "ONLINE" ] do [ "$quiet" != "y" ] && log_begin_msg "Retrying ZFS read-only import" /bin/sleep 1 zfs_test_import retry_nr=$(( $retry_nr + 1 )) [ "$quiet" != "y" ] && log_end_msg done unset retry_nr unset ZFS_HEALTH fi unset delay # At this point, the pool either imported cleanly, or we ran out of the # allowed time (rootdelay). Perform the read-write import. ZFS_STDERR=$(zpool import -N "$ZFS_RPOOL" 2>&1) ZFS_ERROR=$? if [ "$ZFS_ERROR" -ne 0 ] then panic "Command: zpool import -N $ZFS_RPOOL Message: $ZFS_STDERR Error: $ZFS_ERROR Manually import the root pool at the command prompt and then exit. Hint: Try: zpool import -f -R / -N $ZFS_RPOOL" fi # Set elevator=noop on the root pool's vdevs' disks. ZFS already # does this for wholedisk vdevs (for all pools), so this is only # important for partitions. zpool status -L "$ZFS_RPOOL" 2>/dev/null | awk '/^\t / && !/(mirror|raidz)/ { dev=$1; sub(/[0-9]+$/, "", dev); print dev }' | while read i do if [ -e "/sys/block/$i/queue/scheduler" ] then echo noop > "/sys/block/$i/queue/scheduler" fi done # Force the mountpoint to the only correct value for a root filesystem. [ "$quiet" != "y" ] && log_begin_msg "Setting mountpoint=/ on ZFS filesystem $ZFS_BOOTFS" ZFS_STDERR=$(zfs set mountpoint=/ "$ZFS_BOOTFS" 2>&1) [ "$quiet" != "y" ] && log_end_msg # Ideally, the root filesystem would be mounted like this: # # zpool import -R "$rootmnt" -N "$ZFS_RPOOL" # zfs mount -o mountpoint=/ "$ZFS_BOOTFS" # # but the MOUNTPOINT prefix is preserved on descendent filesystem after # the pivot into the regular root, which later breaks things like # `zfs mount -a` and the /etc/mtab refresh. [ "$quiet" != "y" ] && log_begin_msg "Mounting ZFS filesystem $ZFS_BOOTFS" ZFS_STDERR=$(mount -t zfs -o zfsutil "$ZFS_BOOTFS" "$rootmnt" 2>&1) ZFS_ERROR=$? [ "$quiet" != "y" ] && log_end_msg if [ "$ZFS_ERROR" -ne 0 ] then panic "Command: mount -t zfs -o zfsutil $ZFS_BOOTFS $rootmnt Message: $ZFS_STDERR Error: $ZFS_ERROR Manually mount the root filesystem on $rootmnt and then exit." fi unset ZFS_BOOTFS unset ZFS_RPOOL unset ZFS_STDERR unset ZFS_ERROR [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom" run_scripts /scripts/local-bottom [ "$quiet" != "y" ] && log_end_msg }