#!/bin/sh
PSTORAGE_ISCSI_LIB=/usr/libexec/pstorage-iscsi/iscsi_functions
ROOT=""
IQN=""
FORCE=""
SHOW_ALL=""
IQN=""
ARGS="${@}"

function print_usage {
        exec 1>&2
	echo "List existing iSCSI targets."
        echo "Usage:"
	echo " pstorage-iscsi list [-r,--root ROOT_DIR] [--all] [-t,--target IQN]"
        echo "Options:"
	echo "  -r,--root ROOT_DIR      set ISCSI_ROOT instead of use"
	echo "                          /etc/pstorage/iscsi/config (optional)."
	echo "  --all                   show all targets on ISCSI_ROOT."
	echo "  -t,--target IQN         show information only for specified target."
        echo " "
        exit 1
}

function parse_args {

        while [ "${#}" -gt 0 ]; do
                case "${1}" in
			"-t"|"--target")
				[ -z "${2}" ] && print_usage
				IQN="${2}"
				shift
				shift
				;;
			"--all")
				SHOW_ALL="yes"
				shift
				;;
			"-r"|"--root")
				[ -z "${2}" ] && print_usage
				ROOT="${2}"
				shift
				shift
				;;
			"-h"|"--help")
				print_usage
				;;
                        *)
                                echo "Unknown option '${1}'." 1>&2
                                print_usage
                                ;;
                esac
        done
}

function get_ploop_size {
	local path="$1"
	$PLOOP info -s "$path/DiskDescriptor.xml" 2>/dev/null | grep "^size:" | awk '{ print $2 }'
	return $?	
}

function get_lun_info {
	local ctl_port="$1"
	local lun_id="$2"
	local max_lun_id=`$TGTADM -C $ctl_port --mode target --op show 2>/dev/null | grep "LUN:" | awk '{ print $2 }' | sort -nr | head -n 1`
	[ -z "$max_lun_id" ] && return
	max_lun_id=$[ $max_lun_id + 1]
	$TGTADM -C $ctl_port --mode target --op show | tr '\n' '_' | sed "s/Target.*\(LUN: 0.*\)Account information:.*/\1 LUN: ${max_lun_id=}/" | sed "s/.*\(LUN: ${lun_id}.*\)LUN: $[$lun_id + 1].*/\1/" | tr '_' '\n'
}

function print_lun {
	local target="$1"
	local lun="$2"
	local lun_id=`expr "$(basename $lun)" : "^lun\([0-9]*\)" `
	local online=""
	local size=`get_ploop_size "$lun"`
	if [ -n "$size" ] ; then
		size="$[$size * 512 / 1048576]M"
	else
		size="unknown size"
	fi

	used=`ls --block-size=m -l -n "$lun/ploop" 2>/dev/null | awk '{ print $5 }'`
	[ -z "$used" ] && used="Unknown"

	if [ -f "$ISCSI_ROOT/$target/control/.running" ] ; then
		ctl_port=`cat "$ISCSI_ROOT/$target/control/.running" 2>/dev/null`
		online=`get_lun_info $ctl_port $lun_id | grep "Online:" | tr '\n' ' ' | awk '{ print $2 }'`
	fi

	[ -z "$online" ] && online="No"
	
	echo "${lun_id}!$size!$used!$online" | awk -F '!' '{ printf " LUN: %3s, Size: %6s, Used: %6s, Online %s\n", $1,$2,$3,$4}'
}

function print_initiators {
	local target="$1"
	if [ -f "$ISCSI_ROOT/$target/control/.running" ] ; then
		ctl_port=`cat "$ISCSI_ROOT/$target/control/.running" 2>/dev/null`
		$TGTADM -C $ctl_port --mode target --op show | grep "Initiator: " | \
			awk '{ printf " Initiator:   %s (%s)\n", $2,$4}'
	fi
}

function print_target_info {
	local target="$1"
	local status="stopped"
	local is_local="no"
        if [ ! -d  "$ISCSI_ROOT/$target" ] ; then
                echo "Target $target doesn't exist on $ISCSI_ROOT" 1>&2
                exit 1
        fi

	[ -f $ISCSI_ROOT/$target/control/.running ] && status="running"
	pcs_iscsi_is_registered_local $target >/dev/null 2>&1
	[ $? -eq 0 ] && is_local="yes"
	echo "Target $target:"
	echo " Portals:     `cat $ISCSI_ROOT/$target/control/address`"
	echo " Status:      $status"
	echo " Registered:  $is_local"
	if [ -f $ISCSI_ROOT/$target/control/host ] ; then
	echo " Owner:       `cat $ISCSI_ROOT/$target/control/host`"
	fi
	print_initiators "$target"
        luns=`ls -d "$ISCSI_ROOT/$target/"lun[0-9]* 2>/dev/null`
        if [ -n "$luns" ] ; then
                for l in $luns; do
			print_lun $target $l
                done
        fi
}

function print_target {
	local path="$1"
	local target="$2"
	local is_local="$3"
	local status="stopped"
	[ -f $path/control/.running ] && status="running"
	echo "($status) $target"
}

function list_all {
	ls -d $ISCSI_ROOT/iqn*pstorage* 2>/dev/null | while read path
	do
		[ -z "$path" -o ! -d "$path" -o "$(dirname $path)" != "$ISCSI_ROOT" ] && continue
		target=`basename $path`
		is_local=""
		pcs_iscsi_is_registered_local $target >/dev/null 2>&1
		[ $? -eq 0 ] && is_local="yes"
		print_target $path $target $is_local
	done
}

function list_local {
	ls $ISCSI_ETC/targets 2>/dev/null| while read target
	do
		link="$ISCSI_ETC/targets/$target"
		[ ! -h "$link" ] && continue
		path=`/bin/readlink $link 2>/dev/null`
		[ -z "$path" -o ! -d "$path" -o "$(dirname $path)" != "$ISCSI_ROOT" ] && continue
		pcs_iscsi_is_registered_local $target >/dev/null 2>&1
		[ $? -ne 0 ] && continue
		print_target $path $target yes
	done
}


if [ ! -x $PSTORAGE_ISCSI_LIB ] ; then
	echo "Unable find executable $PSTORAGE_ISCSI_LIB" 1>&2
	exit 1
fi

source $PSTORAGE_ISCSI_LIB
[ -f $ISCSI_ETC/config ] && source $ISCSI_ETC/config

parse_args $ARGS

[ -n "${ROOT}" ] && ISCSI_ROOT="${ROOT}"
pcs_iscsi_check_root

if [ -n "$IQN" ] ; then
	pcs_iscsi_lock_exec print_target_info $IQN
	exit 0
fi

if [ -n "$SHOW_ALL" ] ; then
	list_all
else
	list_local
fi
exit 0
