#!/bin/sh
#
# geninitrd functions

# Find root device from fstab.
#
# @param	string	$fstab location of /etc/fstab
# @return	false on failure
# 
# Sets global variables:
# - $rootdev
# - $rootFS
#
find_root() {
	local fstab="$1"
	local function="${PROGRAM:+$PROGRAM: }find_root"

	eval $(awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab)
	if [ -z "$rootdev" ]; then
		echo >&2 "$function: can't find real device for rootfs"
		return 1
	fi

	case $rootdev in
	LABEL=*)
		if [ ! -x /sbin/blkid ]; then
			echo >&2 "$function: /sbin/blkid is missing"
			return 2
		fi

		local label=${rootdev#"LABEL="}
		local dev=$(/sbin/blkid -t LABEL="$label" -o device)
		if [ "$dev" -a -r "$dev" ]; then
			rootdev=$dev
		fi
		;;

	UUID=*)
		if [ ! -x /sbin/blkid ]; then
			echo >&2 "$function: /sbin/blkid is missing"
			return 2
		fi

		local uuid=${rootdev#"UUID="}
		local dev=$(/sbin/blkid -t UUID="$uuid" -o device)

		if [ "$dev" -a -r "$dev" ]; then
			rootdev=$dev
		fi
		;;
	esac

	if [[ "$rootdev" = /dev/dm-* ]]; then
		local node
		node=$(dm_lvm2_name "$rootdev") || exit
		if [ "$node" ]; then
			rootdev="$node"
		fi
	fi

	if [ ! -r "$rootdev" ]; then
		echo >&2 "$function: can't find real device for $rootdev"
		return 1
	fi

	return 0
}

# resolve /dev/dm-0 to lvm2 node
# which they got from blkid program fs was specifed as UUID= in fstab
dm_lvm2_name() {
	local node="$1"

	# redirect output to tmpfile so we won't get subshell
	local tmp ret
	tmp=$(mktemp) || exit

	/sbin/lvdisplay -c 2>/dev/null | awk -F: '{print $1}' > $tmp
	while read dev; do
		count=$(ls -Ll $dev $node | awk '{print $5, $6}' | sort -u | wc -l)
		if [ "$count" = 1 ]; then
			ret="$dev"
			break
		fi
	done < $tmp
	rm -f $tmp

	if [ -z "$ret" ]; then
		ret=$node
	fi
	echo "$ret"
}
