# # Copyright 2021 Stuart Winter, Donostia, Spain. # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ########################################################################### # Script : /await_device # Purpose: Await for the root device, a single or a list of devices to # become available within /dev. # # This solves some issues on the RockPro64 where it takes longer # than usual on some boots for a USB-connected drive to appear. # Status : ARM LOCAL # Author : Stuart Winter # Date...: 27-Apr-2021 # Version: 1.00 ########################################################################### # # An exposition of the Kernel cmdline options follows: # # awaitrootdev Await the appearance of the root device (as configured # by the 'rootdev=' cmdline operator) within /dev, after # waiting for the duration specified by the 'waitforroot=' # Kernel cmdline operator. # # On occasion, the RockPro64's USB storage bus would take time # to come online and would cause a boot failure. # This option has been tested using native storage devices # such as /dev/sda. # However, this has not been tested with LUKS, LVM or RAID # and this author suspects it will be incompatible. # # If you have trouble with this, remove it from the boot # options below, and if you have trouble with your storage # sub systems coming online, try the next option: # # awaitdev= Await the appearance of one or a number of devices within # /dev. # # If you have trouble with LVM, LUKS or RAID subsystems during # boot, it may be because the underlying storage layer upon # which the abstraction layer relies, has yet to come online. # # This code is executed directly after '/init' pauses for any # delay specified in the Kernel cmdline operators: # waitforroot=*|rootdelay= # Subsequently, the LVM, RAID and LUKS handling code will # execute. # # Do not use both 'awaitdev=' and 'awaitrootdev' together. # If you are not using any abstraction layer, and have the # root filesystem on 'native' storage (e.g. /dev/sda) then # only use 'awaitrootdev'. # # The syntax a comma separated list of device names, relative # to /dev: # awaitdev=sda2,sda3 # ########################################################################### # Scan for file system labels: function scan_label() { lsblk -o label -rin | grep -Eq "^${1}$" } # Await a block device: function await_block_device() { [ -r ${1} ] && return 0 # exit silently if the device is present echo -n "Waiting for ${1} to come online.." while [ ! -r ${1} ]; do echo -n . sleep 1 done echo } # Await a labeled file system: function await_labeled_device() { local label=${1#LABEL=} # remove the 'LABEL=' prefix # Exit silently if the labeled file system is already present: scan_label "${label}" && return 0 echo -n "Waiting for labeled file system '${label}' to come online.." while ! scan_label "${label}"; do echo -n . sleep 1 done echo } # Await the root device if configured: if grep -iq "awaitrootdev" /proc/cmdline 2> /dev/null ; then # Ensure the root device is a block device rather than # set by 'LABEL=' # This is the Slackware default. # If you need to await a particular device, use the awaitdev= functionality # below, as this only takes block device names. [[ "$ROOTDEV" =~ ^/dev/.* ]] && await_block_device $ROOTDEV [[ "$ROOTDEV" =~ LABEL= ]] && await_labeled_device $ROOTDEV fi # Await any other configured devices to become available within /dev if grep -iq "awaitdev=[a-zA-Z0-9]" /proc/cmdline 2> /dev/null ; then awaitdevlist="$( sed 's/.*awaitdev=\([^ ]*\).*/\1/' < /proc/cmdline )" if [ ! -z "${awaitdevlist}" ]; then IFS=, for awaiteddev in ${awaitdevlist} ; do await_device /dev/${awaiteddev} done fi fi