diff --git a/etc/rc.d/fsck b/etc/rc.d/fsck index 23bbe2e5fe64..bd3122a20110 100755 --- a/etc/rc.d/fsck +++ b/etc/rc.d/fsck @@ -31,7 +31,21 @@ fsck_start() fsck -p fi - case $? in + err=$? + if [ ${err} -eq 3 ]; then + echo "Warning! Some of the devices might not be" \ + "available; retrying" + root_hold_wait + check_startmsgs && echo "Restarting file system checks:" + if checkyesno background_fsck; then + fsck -F -p + else + fsck -p + fi + err=$? + fi + + case ${err} in 0) ;; 2) @@ -68,7 +82,7 @@ fsck_start() stop_boot ;; *) - echo "Unknown error; help!" + echo "Unknown error ${err}; help!" stop_boot ;; esac diff --git a/etc/rc.d/mountcritlocal b/etc/rc.d/mountcritlocal index 798130d2b239..f52c565d65c6 100755 --- a/etc/rc.d/mountcritlocal +++ b/etc/rc.d/mountcritlocal @@ -37,37 +37,12 @@ mountcritlocal_start() done mount_excludes=${mount_excludes%,} - # Originally, root mount hold had to be released before mounting - # the root filesystem. This delayed the boot, so it was changed - # to only wait if the root device isn't readily available. This - # can result in this script executing before all the devices - such - # as graid(8) - are available. Thus, should the mount fail, - # we will wait for the root mount hold release and retry. mount -a -t ${mount_excludes} err=$? if [ ${err} -ne 0 ]; then - echo echo 'Mounting /etc/fstab filesystems failed,' \ 'will retry after root mount hold release' - - waited=0 - while [ ${waited} -lt ${root_hold_delay} ]; do - holders="$(sysctl -n vfs.root_mount_hold)" - if [ -z "${holders}" ]; then - break; - fi - if [ ${waited} -eq 0 ]; then - echo -n "Waiting ${root_hold_delay}s" \ - "for the root mount holders: ${holders}" - else - echo -n . - fi - if [ ${waited} -eq ${root_hold_delay} ]; then - break 2 - fi - sleep 1 - waited=$(($waited + 1)) - done + root_hold_wait mount -a -t ${mount_excludes} err=$? fi diff --git a/etc/rc.subr b/etc/rc.subr index d04e25371c16..8da111acec8f 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -1954,6 +1954,37 @@ geli_make_list() echo ${devices2} } +# Originally, root mount hold had to be released before mounting +# the root filesystem. This delayed the boot, so it was changed +# to only wait if the root device isn't readily available. This +# can result in rc scripts executing before all the devices - such +# as graid(8), or USB disks - can be accessed. This function can +# be used to explicitly wait for root mount holds to be released. +root_hold_wait() +{ + local wait waited holders + + waited=0 + while true; do + holders="$(sysctl -n vfs.root_mount_hold)" + if [ -z "${holders}" ]; then + break; + fi + if [ ${waited} -eq 0 ]; then + echo -n "Waiting ${root_hold_delay}s" \ + "for the root mount holders: ${holders}" + else + echo -n . + fi + if [ ${waited} -ge ${root_hold_delay} ]; then + echo + break + fi + sleep 1 + waited=$(($waited + 1)) + done +} + # Find scripts in local_startup directories that use the old syntax # find_local_scripts_old() {