# LOG_FILE, LOG, DEV_LOG, TARGET is global variable,
# they can export from environment variable,
# if not definition, will configure default value.

# installation log file
[ -z "$LOG_FILE" ] && LOG_FILE="/var/log/install.log"

# LOG have two value, true and stdout
# true: log will record to $LOG_FILE
# stdout: log will print to stand out, very usefull for debug
[ -z "$LOG" ] && LOG="true"

# the log of command operation
# ex: stdout of command: mkfs.ext3 /dev/hda2
[ -z "$DEV_LOG" ] && DEV_LOG="/dev/tty8"

# the root directory of hardisk mount
[ -z "$TARGET" ] && TARGET="/mnt"


mkdir -p $(dirname $LOG_FILE)
mkdir -p $(dirname $DEV_LOG)
mkdir -p "$TARGET"

stdout ()
{
	# process % in partition
	local log=$(echo $*|sed "s/%/%%/g")
	printf "$log\n"
}

log ()
{
	local DATE=$(date "+%Y/%m/%d %T")

	# process % in partition
	local log=$(echo $*|sed "s/%/%%/g")
	case "$LOG" in
		true) printf "$DATE $log\n" >>"$LOG_FILE" ;;
		stdout) stdout "$DATE $log"  ;;
		*) : ;;
	esac
}

err ()
{
	log "error: $(basename $0): $*" >&2
}

warn ()
{
	log "warning: $(basename $0): $*" >&2
}

info ()
{
	log "info: $(basename $0): $1"
	if [ "$2" == "stdout" ];then
		stdout "@$1"
	fi
}

# erv stands for "Evaluate Return Value"
erv ()
{
	ret="${?}"
	if [ "$ret" -ne 0 ];then
		exit $ret
	fi
}

# recursively umount directory,
# argument can be a device node or mountpoint.
# if argument is a device node:
#   1.if a device be mounted on a directory, then umount this device's mountpoint, 
#	if a device has been mounted on this mountpoint's subdirectory, then recurisve
#	umount device of this subdirectory , finally, umount the device that you want 
#	be umounted.
#	2.if have a device has been mounted on multi-direcetory, then umount these 
#	direcectories one by one, use method 1.
# if argument is a mountpoint, then umount this mountpoint, if have device has been mounted on 
# this mountpoint's subdirectory, the recursively umount subdirectory, finally umount the directory.
# ex:	1.reumount /dev/hda5
#		2.reumount /mnt/
reumount ()
{
	if [ $# -ne 1 ];then
		err "$FUNCNAME function argument error, it must have 1 argument !"
		return 1
	fi
	
	local arg
	arg="$1"
	local multi_mountpoint

	# if arg is a device node
	if [ ! -d "$arg" ];then
		multi_mountpoint=$(grep "^$arg " /proc/mounts|awk '{print $2}')
	else
		# delete last "/" in mountpoint
		# mountpoint in /proc/mounts don't have "/" at last
		multi_mountpoint=$(echo $arg|sed "s%/$%%")
	fi

	# may be a device has been mounted in multi-mountpoint.
	# ex: /dev/hda5 mount at /mnt and /cdrom at the same time,
	# this case appear when $TARGET has been changed, when mount paritions.
	for mmp in $multi_mountpoint; do
		# sort -k2 -r ensure long mountpoint sort at front of short mountpoint,
		# so, we can umount long mountpoint before short mountpoint.
		# ex: /usr/lib, /, /usr, after sort is /usr/lib, /usr, /
		# this mean that /usr/lib is umounted first, then umount /usr, finally umount /
		for mp in $(grep "$mmp" /proc/mounts|sort -k2 -r |awk '{print $2}');do
			umount $mp 1>>"$DEV_LOG" 2>&1
		done
	done
}

update_udev()
{
	killall udevd
	start_udev 1>/dev/null 2>/dev/null
}

#
# get device uuid/by-id/by-path info
# if not found return NULL
# ex: get_disk_sym /dev/sda1 by-uuid
#
get_disk_sym ()
{
	if [ $# -ne 2 ];then
		err "$FUNCNAME function argument error, it must have 2 argument !"
		return 1
	fi

	local partition="$1"
	local type="$2"
	local devname=""

	local path=$(udevadm info -q path -n $partition)

	# if not update udev, uuid or by-id may use old one.
	update_udev
	# scsci's by-id may be have multi-links, we get first link
	# update hard disk informations.
	devname=$(udevadm info -q symlink -p $path|tr " " "\n"|grep "$type"|head -n 1)

	echo "$devname"

}


