# This file contains common functions used in init and in hooks msg () { [ "${quiet}" != "y" ] && echo $@ } err () { echo "ERROR: $@" } poll_device() { local device=$1 seconds=${2//[!0-9]} [ -z "$seconds" ] && seconds=5 [ -b "$device" ] && return 0 if [ "$udevd_running" -eq 1 ]; then msg "Waiting $seconds seconds for device $device ..." while [ ! -b "$device" -a "$seconds" -gt 0 ]; do sleep 1 seconds=$(( $seconds - 1 )) done fi [ -b "$device" ] } launch_interactive_shell() { export PS1='[ramfs \W]\$ ' [ "$1" = "--exec" ] && exec sh -i sh -i } major_minor_to_device() { local dev [ -e "/sys/dev/block/$1:$2" ] || return 1 if dev=$(readlink -f "/sys/dev/block/$1:$2" 2>/dev/null); then echo "/dev/${dev##*/}" return 0 fi return 1 } parse_cmdline() { local w in_quotes lhs rhs in_quotes=0 for w in $(cat /proc/cmdline); do if [ ${in_quotes} -eq 0 ]; then case "${w}" in \#*) break ;; # ignore everything after a # in the commandline # The kernel passes those to init on its own [0123456Ss]) ;; single) ;; rw|ro) rwopt="$w" ;; # only export stuff that does work with ash :) =*) ;; *=*) rhs=${w#*=} lhs=${w%%=*} lhs=${lhs//[-.]/_} if [ '"' = "${rhs:0:1}" ]; then if [ "${rhs:$((${#rhs}-1))}" = '"' ]; then rhs="${rhs:1:$((${#rhs}-2))}" else rhs="${rhs:1}" in_quotes=1 continue fi fi [ "$lhs" = "${lhs//[^0-9a-zA-Z]}" ] && [ "$lhs" = "${lhs#[0-9]}" ] && eval ${lhs}=\${rhs} ;; *) lhs=${w//[-.]/_} [ "$lhs" = "${lhs//[^0-9a-zA-Z]}" ] && [ "$lhs" = "${lhs#[0-9]}" ] && eval ${lhs}=y ;; esac else if [ '"' = "${w:$((${#w}-1))}" ]; then rhs="${rhs} ${w%\"}" in_quotes=0 [ "$lhs" = "${lhs//[^0-9a-zA-Z]}" ] && [ "$lhs" = "${lhs#[0-9]}" ] && eval ${lhs}=\${rhs} else rhs="${rhs} ${w}" fi fi done } resolve_device() { local major minor dev device=$1 case $device in # resolve tag name to block device UUID=*|LABEL=*) dev=$(blkid -lt "$device" -o device) [ -n "$device" ] && device=$dev ;; esac case $device in /dev/*) if poll_device "$device" "$rootdelay"; then echo "$device" return 0 fi # block device, e.g. (/dev/sda1) -> /sys/class/block/sda1/dev if [ -e /sys/class/block/${device:5}/dev ]; then IFS=':' read major minor < "/sys/class/block/${device:5}/dev" fi ;; [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]|[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]) # hex encoded major/minor, such as from LILO major=$(( 0x0$device >> 8 )) minor=$(( 0x0$device & 0xff )) ;; 0x[0-9a-fA-F][0-9a-fA-F]*) major=$(( $device >> 8 )) minor=$(( $device & 0xff )) ;; esac if [ -n "$major" -a -n "$minor" ]; then device=$(major_minor_to_device "$major" "$minor" || echo '/dev/root') if [ ! -b "$device" ]; then msg "Creating device node with major $major and minor $minor." >&2 mknod "$device" b "$major" "$minor" fi echo "$device" return 0 fi return 1 } default_mount_handler() { local rootdev if ! rootdev=$(resolve_device "$root"); then err "Unable to determine major/minor number of root device '$root'." echo "You are being dropped to a recovery shell" echo " Type 'exit' to try and continue booting" launch_interactive_shell msg "Trying to continue (this will most likely fail) ..." fi if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$rootdev" "$1"; then echo "You are now being dropped into an emergency shell." launch_interactive_shell msg "Trying to continue (this will most likely fail) ..." fi } # vim: set ft=sh ts=4 sw=4 et: