#! /bin/bash
# Display iscsi targets

HOST_PATH=/sys/class/iscsi_host
SCSI_HOST=/sys/class/scsi_host
CLASS_PATH=/sys/class/iscsi_transport

# Copied directly from scsi.c
# weird '" '" syntax to preserve whitespace
typeset -a scsi_device_types=('"Direct-Access    "'
        '"Sequential-Access"'
        '"Printer          "'
        '"Processor        "'
        '"WORM             "'
        '"CD-ROM           "'
        '"Scanner          "'
        '"Optical Device   "'
        '"Medium Changer   "'
        '"Communications   "'
        '"Unknown          "'
        '"Unknown          "'
        '"RAID             "'
        '"Enclosure        "'
)

print_usage()
{
	echo
        echo "Usage: iscsi-ls [-c] [-l] [-i host_id]"
        echo "-c : iSCSI target configuration parameters"
        echo "-i : Details regarding the specific host ID"
        echo "-l : Lun details available on the target"
}

is_num()
{
	case "$1" in
	-*[!0-9]*) rval=0;;
	*) rval=1;;
	esac
}

find_host_ids()
{
	i=0
	if [ $opt_i ]; then
		hosts=host$opt_i
		if [ ! -e $SCSI_HOST/$hosts ]; then
			echo "Host $opt_i does not exist"
			exit 1
		fi
	else
		hosts=`ls -1 $SCSI_HOST/`
	fi
	for host in $hosts; do
		host=$SCSI_HOST/$host
		proc_name=`cat $host/proc_name`
		if [ "$proc_name" = "iscsi-sfnet" ]; then
			host_no=${host:${#SCSI_HOST} + 5}
			host_ids[$i]=$host_no
			let "i += 1"
		elif [ $opt_i ]; then
			echo "Device is not an iSCSI device"
		fi
	done
}

show_session_status()
{
        typeset -i drop_time=`cat $SCSI_HOST/host$1/session_drop_time`
        typeset -i est_time=`cat $SCSI_HOST/host$1/session_established_time`
        typeset -i session_alive=`cat $SCSI_HOST/host$1/session_established`

	if [ $session_alive -eq 0 ]; then
		echo -n "SESSION STATUS          : DROPPED AT "
		date -d ''$drop_time' seconds ago'
	else
		echo -n "SESSION STATUS          : ESTABLISHED AT "
		date -d ''$est_time' seconds ago'
	fi
}

print_common_info()
{
	echo "TARGET NAME             :" `cat $1/target_name`
        talias=`cat $1/target_alias`
        if [ "$talias" == "<NULL>" ]; then
            talias=""
        fi
	echo "TARGET ALIAS            : $talias" 
        luns=`ls -d $1/device/$2:0:0* 2> /dev/null`
        for lun in $luns; do
            lun=`echo $lun | sed s/.*device\\\///`
            bus_id=`echo $lun | awk 'BEGIN {FS=":"} {print $2}'`
            target_id=`echo $lun | awk 'BEGIN {FS=":"} {print $3}'`
            break;
        done
        echo "HOST ID                 : $2"
        echo "BUS ID                  : $bus_id"
	echo "TARGET ID               : $target_id"
	echo -n "TARGET ADDRESS          : "
	echo `cat $1/ip_address`:`cat $1/port`,`cat $1/tpgt`
	show_session_status $2
	echo -n "SESSION ID              : ISID" `cat $1/isid`
	echo " TSIH" `cat $1/tsih`
}

print_lun_info()
{
	luns=`ls -d $1/device/$2:0:0* | sort --field-separator=: --key=6 -n 2> /dev/null`
        echo ""
	echo "DEVICE DETAILS:"
	echo "---------------"
	for lun in $luns; do
		lun_no=${lun##[/]*[:]}
		echo -e "LUN ID : $lun_no"
		printf "  Vendor: %-8s" `cat $lun/vendor`
		printf " Model: %-16s" `cat $lun/model`
		printf " Rev: %-4s\n" `cat $lun/rev`
		typeset -i type=`cat $lun/type`
		type_count=${#scsi_device_types[*]}
		if [ $type -gt $type_count ]; then
			printf "  Type:   %-17s"  ${scsi_device_types[10]}
		else
			printf "  Type:   %-17s" ${scsi_device_types[$type]}
		fi
		typeset -i srev=`cat $lun/scsi_level`
		if [ $(( $srev - 1 )) -eq 0 ]; then
		srev=1
		else
			srev=$(( $srev - 1 ))
		fi
		printf "                ANSI SCSI revision: %02x\n" $srev
		unset device
		if [ -h $lun/block ]; then
			device=`ls -l $lun/block`
		elif [ -h $lun/tape ]; then
			device=`ls -l $lun/tape`
		fi
		if [ "$device" ]; then
			device=`echo $device | awk -F ' ' '{print $NF}'`
			device=${device##[.]*[/]}
			
			if [ `cat /sys/class/scsi_host/host$2/session_established` -eq 0 ]; then
				echo "  page83 type: UNKNOWN"
				echo "  page80: UNKNOWN"
			elif [ -h $lun/block ]; then
				p83=`scsi_id -p 0x83 -g -s /block/$device`
				type=`echo $p83 | sed -e "s/\(^.\).*/\1/"`
				p83=`echo $p83 | sed -e "s/^.//"`
				echo "  page83 type$type: $p83"

				p80=`scsi_id -p 0x80 -g -s /block/$device | awk '{print $3}' | od -t x1 -An | sed -e "s/ //g"`
				echo "  page80: $p80"
			elif [ -h $lun/tape ]; then
				p83=`scsi_id -p 0x83 -g -s /class/scsi_tape/$device`
				type=`echo $p83 | sed -e "s/\(^.\).*/\1/"`
				p83=`echo $p83 | sed -e "s/^.//"`
				echo "  page83 type$type: $p83"

				p80=`scsi_id -p 0x80 -g -s /class/scsi_tape/$device | awk '{print $3}' | od -t x1 -An | sed -e "s/ //g"`
				echo "  page80: $p80"
			fi
			echo "  Device: /dev/$device"
		else
			echo " "
		fi

	done
}

print_config_info()
{
	echo ""
	echo "TARGET CONFIGURATION KEYS :"
	echo "-------------------------"
	echo "INITIAL R2T             :" `cat $1/initial_r2t`
	echo "IMMEDIATE DATA          :" `cat $1/immediate_data`
	echo "HEADERDIGEST            :" `cat $1/header_digest`
	echo "DATA DIGEST             :" `cat $1/data_digest`
	echo "FIRSTBURSTLENGTH        :" `cat $1/first_burst_len`
	echo "MAXBURSTLENGTH          :" `cat $1/max_burst_len`
	echo -n "MAXRECVDATASEGMENTLENGTH: initiator - "
	cat $1/max_recv_data_segment_len
	echo -n "                          target    - "
	cat $1/max_xmit_data_segment_len
	echo "LOGIN TIMEOUT           :" `cat $SCSI_HOST/host$2/login_timeout`
	echo "ACTIVE TIMEOUT          :" `cat $SCSI_HOST/host$2/active_timeout`
	echo "IDLE TIMEOUT            :" `cat $SCSI_HOST/host$2/idle_timeout`
	echo "PING TIMEOUT            :" `cat $SCSI_HOST/host$2/ping_timeout`
}

while getopts ci:l opt; do
case $opt in
    c)
	opt_c=1;;
    i)
	if [ $OPTARG ]; then
		is_num $OPTARG
		if [ $rval -eq  1 ];then
			opt_i=$OPTARG
		else
			print_usage
			exit 1
		fi
	else
		print_usage
		exit 1
	fi;;
    l)
	opt_l=1;;
    ?)
	print_usage
	exit 1;;
esac
done

cat /proc/devices | grep -q iscsictl
if [ $? -ne 0 ]; then
	echo "###############################################################################"
	echo "iSCSI driver is not loaded"
	echo "###############################################################################"
	exit
fi

echo "*******************************************************************************"
echo -n "SFNet iSCSI Driver Version ..."
iscsid -v | awk '{ print $3 $4 $5 }'
echo "*******************************************************************************"

declare -a host_ids
find_host_ids
no_hosts=${#host_ids[*]}

i=0
while [ $i -lt $no_hosts ]; do
	target=$CLASS_PATH/target${host_ids[$i]}:0:0

	if [ -e $target ]; then
		print_common_info $target ${host_ids[$i]}

		if [ $opt_c ]; then
			print_config_info $target ${host_ids[$i]}
		fi

		if [ $opt_l ]; then
			print_lun_info $target ${host_ids[$i]}
		fi

		echo "*******************************************************************************"
	fi
	let "i += 1"
done
