# Local filesystem mounting			-*- shell-script -*-

local_top()
{
	if [ "${local_top_used}" != "yes" ]; then
		[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-top"
		run_scripts /scripts/local-top
		[ "$quiet" != "y" ] && log_end_msg
	fi
	local_top_used=yes
}

local_block()
{
	[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-block"
	run_scripts /scripts/local-block "$@"
	[ "$quiet" != "y" ] && log_end_msg
}

local_premount()
{
	if [ "${local_premount_used}" != "yes" ]; then
		[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount"
		run_scripts /scripts/local-premount
		[ "$quiet" != "y" ] && log_end_msg
	fi
	local_premount_used=yes
}

local_bottom()
{
	if [ "${local_premount_used}" = "yes" ] || [ "${local_top_used}" = "yes" ]; then
		[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
		run_scripts /scripts/local-bottom
		[ "$quiet" != "y" ] && log_end_msg
	fi
	local_premount_used=no
	local_top_used=no
}

# $1=device to mount
# $2=optionname (for root and etc)
local_device_setup()
{
	wait_for_udev 10

	# Load ubi with the correct MTD partition and return since fstype
	# doesn't work with a char device like ubi.
	if [ -n "$UBIMTD" ]; then
		modprobe ubi mtd=$UBIMTD
		return
	fi

	# Don't wait for a root device that doesn't have a corresponding
	# device in /dev (ie, mtd0)
	if [ "${1#/dev}" = "$1" ]; then
		return
	fi

	# If the root device hasn't shown up yet, give it a little while
	# to allow for asynchronous device discovery (e.g. USB).  We
	# also need to keep invoking the local-block scripts in case
	# there are devices stacked on top of those.
	if [ ! -e "$1" ] || ! $(get_fstype "$1" >/dev/null); then
		log_begin_msg "Waiting for $2 file system"

		# Timeout is max(30, rootdelay) seconds (approximately)
		slumber=30
		if [ ${ROOTDELAY:-0} -gt $slumber ]; then
			slumber=$ROOTDELAY
		fi

		while true; do
			sleep 1
			local_block "$1"
			if [ -e "$1" ] && get_fstype "$1" >/dev/null; then
				wait_for_udev 10
				log_end_msg 0
				break
			fi
			slumber=$(( ${slumber} - 1 ))
			if [ ${slumber} -eq 0 ]; then
				log_end_msg 1 || true
				break
			fi
		done
	fi

	# We've given up, but we'll let the user fix matters if they can
	while [ ! -e "$1" ]; do
		# give hint about renamed root
		case "$1" in
		/dev/hd*)
			suffix="${1#/dev/hd}"
			major="${suffix%[[:digit:]]}"
			major="${major%[[:digit:]]}"
			if [ -d "/sys/block/sd${major}" ]; then
				echo "WARNING bootdevice may be renamed. Try $2=/dev/sd${suffix}"
			fi
			;;
		/dev/sd*)
			suffix="${1#/dev/sd}"
			major="${suffix%[[:digit:]]}"
			major="${major%[[:digit:]]}"
			if [ -d "/sys/block/hd${major}" ]; then
				echo "WARNING bootdevice may be renamed. Try $2=/dev/hd${suffix}"
			fi
			;;
		esac
		echo "Gave up waiting for $2 device.  Common problems:"
		echo " - Boot args (cat /proc/cmdline)"
		echo "   - Check rootdelay= (did the system wait long enough?)"
	        # Only applies to root= and etc=:
		if [ "${2#/}" = "$2" ]; then
			echo "   - Check $2= (did the system wait for the right device?)"
		fi
		echo " - Missing modules (cat /proc/modules; ls /dev)"
		panic "ALERT!  $1 does not exist.  Dropping to a shell!"
	done
}

local_mount_root()
{
	local_top
	local_device_setup "${ROOT}" root

	# Get the root filesystem type if not set
	if [ -z "${ROOTFSTYPE}" ]; then
		FSTYPE=$(get_fstype "${ROOT}")
	else
		FSTYPE=${ROOTFSTYPE}
	fi

	local_premount

	ROOT=$(resolve_device "$ROOT")

	if [ "${readonly}" = "y" ]; then
		roflag=-r
	else
		roflag=-w
	fi

	# FIXME This has no error checking
	modprobe ${FSTYPE}

	checkfs ${ROOT} root

	# FIXME This has no error checking
	# Mount root
	if [ "${FSTYPE}" != "unknown" ]; then
		mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
	else
		mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
	fi
}

local_mount_fs()
{
	read_fstab_entry "$1"
	MNT_FSNAME=$(resolve_device "$MNT_FSNAME")

	local_device_setup "$MNT_FSNAME" "$1"

	local_premount

	MNT_FSNAME=$(resolve_device "$MNT_FSNAME")

	if [ "${readonly}" = "y" ]; then
		roflag=-r
	else
		roflag=-w
	fi

	# FIXME This has no error checking
	modprobe "${MNT_TYPE}"

	checkfs "$MNT_FSNAME" "$MNT_DIR"

	# FIXME This has no error checking
	# Mount filesystem
	mount ${roflag} -t "${MNT_TYPE}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}"
}

mountroot()
{
	local_mount_root
}

mount_top()
{
	# Note, also called directly in case it's overridden.
	local_top
}

mount_premount()
{
	# Note, also called directly in case it's overridden.
	local_premount
}

mount_bottom()
{
	# Note, also called directly in case it's overridden.
	local_bottom
}
