rootdelay on zfs should be adaptive

The 'rootdelay' boot option currently pauses the boot for a specified
amount of time. The original intent was to ensure that slower
configurations would have ample time to enumerate the devices to make
importing the root pool successful. This, however, causes unnecessary
boot delay for environments like Azure which set this parameter by
default.

This commit changes the initramfs logic to pause until it can
successfully load the 'zfs' module. The timeout specified by
'rootdelay' now becomes the maximum amount of time that initramfs will
wait before failing the boot.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Prakash Surya <prakash.surya@delphix.com>
Signed-off-by: George Wilson <gwilson@delphix.com>
Closes #14430
This commit is contained in:
George Wilson 2023-02-02 18:11:35 -05:00 committed by GitHub
parent 05b72415d1
commit f18e083bf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -272,30 +272,46 @@ import_pool()
# with more logging etc. # with more logging etc.
load_module_initrd() load_module_initrd()
{ {
[ -n "$ROOTDELAY" ] && ZFS_INITRD_PRE_MOUNTROOT_SLEEP="$ROOTDELAY" ZFS_INITRD_PRE_MOUNTROOT_SLEEP=${ROOTDELAY:-0}
if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt 0 ] 2>/dev/null if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt 0 ]; then
then [ "$quiet" != "y" ] && zfs_log_begin_msg "Delaying for up to '${ZFS_INITRD_PRE_MOUNTROOT_SLEEP}' seconds."
if [ "$quiet" != "y" ]; then fi
zfs_log_begin_msg "Sleeping for" \
"$ZFS_INITRD_PRE_MOUNTROOT_SLEEP seconds..." START=$(/bin/date -u +%s)
END=$((START+ZFS_INITRD_PRE_MOUNTROOT_SLEEP))
while true; do
# Wait for all of the /dev/{hd,sd}[a-z] device nodes to appear.
if command -v wait_for_udev > /dev/null 2>&1 ; then
wait_for_udev 10
elif command -v wait_for_dev > /dev/null 2>&1 ; then
wait_for_dev
fi fi
sleep "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP"
#
# zpool import refuse to import without a valid
# /proc/self/mounts
#
[ ! -f /proc/self/mounts ] && mount proc /proc
# Load the module
if load_module "zfs"; then
ret=0
break
else
ret=1
fi
[ "$(/bin/date -u +%s)" -gt "$END" ] && break
sleep 1
done
if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt 0 ]; then
[ "$quiet" != "y" ] && zfs_log_end_msg [ "$quiet" != "y" ] && zfs_log_end_msg
fi fi
# Wait for all of the /dev/{hd,sd}[a-z] device nodes to appear. [ "$ret" -ne 0 ] && return 1
if command -v wait_for_udev > /dev/null 2>&1 ; then
wait_for_udev 10
elif command -v wait_for_dev > /dev/null 2>&1 ; then
wait_for_dev
fi
# zpool import refuse to import without a valid /proc/self/mounts
[ ! -f /proc/self/mounts ] && mount proc /proc
# Load the module
load_module "zfs" || return 1
if [ "$ZFS_INITRD_POST_MODPROBE_SLEEP" -gt 0 ] 2>/dev/null if [ "$ZFS_INITRD_POST_MODPROBE_SLEEP" -gt 0 ] 2>/dev/null
then then