#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/lib/nim/methods/c_disc_target.sh 1.4.1.1 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2009,2010 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)53    1.4.1.1  src/bos/usr/lib/nim/methods/c_disc_target.sh, cmdnim, bos720  3/9/10  11:57:43
#
#############################################################################
# c_disc_target -a operation=[discover|destroy]
#               -a target=targetname 
#               -a dump_port=port 
#               -a ipaddr=ip_address 
#               -a lun_id=lun_id
#############################################################################
NIMPATH=${0%/*}
NIMPATH=${NIMPATH%/*}
[[ ${NIMPATH} = ${0} ]] && NIMPATH=/usr/lpp/bos.sysmgt/nim
NIM_METHODS="${NIMPATH}/methods"
. ${NIM_METHODS}/c_sh_lib

REMOTEDUMPLOG="/var/adm/ras/remotedump.log"

#############################################################################
# FUNCTION: odm_add
#
# PARAMETERS: input : target_iqn
#             input : port
#             input : ip
#
# DESCRIPTION: add iSCSI target device parameters in ODM
#############################################################################
odm_add() {
	${ECHO} "Entering odm_add function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	port=$2
	ip=$3

	# make sure we replace any existing ODM entry
	${RMISCSI} -l iscsi0 -t $target_iqn > /dev/null 2>&1
	# create new ODM entry
	ERR=`${MKISCSI} -l iscsi0 -g static -t $target_iqn -n $port -i $ip 2>&1 1>/dev/null`
	[ $? -ne 0 ] && {
		${C_ERRMSG} ${ERR_FAIL_ODM_CONFIG} ${C_ERRMSG_ERR}  "$target_iqn" "" "" "" | ${TEE} -a  ${REMOTEDUMPLOG} 1>&2
		${ECHO} ${ERR} | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
	}

	return 0
}
#############################################################################
# FUNCTION: odm_del
#
# PARAMETERS: input : target_iqn
#             input : port
#             input : ip
#
# DESCRIPTION: delete iSCSI target device parameters in ODM
#############################################################################
odm_del() {
	${ECHO} "Entering odm_del function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	port=$2
	ip=$3

	# make sure we replace any existing ODM entry
	ERR=`${RMISCSI} -l iscsi0 -t $target_iqn  -n $port -i $ip  2>&1 1>/dev/null`
	[ $? -ne 0 ] && {
		${C_ERRMSG} ${ERR_FAIL_ODM_UNCONFIG} ${C_ERRMSG_ERR}  "$target_iqn" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		${ECHO} ${ERR} | ${TEE} -a  ${REMOTEDUMPLOG} 1>&2
		return 1
	}
	return 0
}
#############################################################################
# FUNCTION: file_add
#
# PARAMETERS: input : target_iqn
#             input : port
#             input : ip
#
# DESCRIPTION: add iSCSI target device parameters in flat file
#############################################################################
file_add() {
	${ECHO} "Entering file_add function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	port=$2
	ip=$3

	file=$(${LSATTR} -El iscsi0 -a disc_filename -F value)
	[ ! -f "$file" ] && {
		${C_ERRMSG} ${ERR_FILE_NOT_EXIST} ${C_ERRMSG_ERR} "$file" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
	}
	# check if an entry already exists
	${GREP} "$target_iqn" $file > /dev/null && return 0

	${ECHO} "$ip $port $target_iqn" >> $file

	return 0
}
#############################################################################
# FUNCTION: file_del
#
# PARAMETERS: input : target_iqn
#             input : port
#             input : ip
#
# DESCRIPTION: delete iSCSI target device parameters in flat file
#############################################################################
file_del() {
	${ECHO} "Entering file_del function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	port=$2
	ip=$3

	file=$(${LSATTR} -El iscsi0 -a disc_filename -F value)
	[ ! -f "$file" ] && {
		${C_ERRMSG} ${ERR_FILE_NOT_EXIST} ${C_ERRMSG_ERR} "$file" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
	}
	# check if an entry already exists
	${GREP} -wv "^$ip $port $target_iqn" $file > $file.back
	${MV} $file.back $file
	return 0
}
#############################################################################
# FUNCTION: print_hdisk_name
#
# PARAMETERS: input : target_iqn lun_id
#
# DESCRIPTION: print iSCSI disk name for a specific target IQN
#############################################################################
print_hdisk_name() {
	${ECHO} "Entering print_hdisk_name function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	lun_id=$2
	hdisk=""

	hdisklist=`${ODMGET} -q"attribute=target_name and \
			     value=$target_iqn" CuAt | \
		   ${GREP} -w name | ${CUT} -d\" -f 2`

	set -- $hdisklist
	while [ $1 -a -z "$hdisk" ]
	do
		hdisk=`${ODMGET} -q "name=$1 and attribute=lun_id \
			   and value=$lun_id" CuAt | \
		       ${GREP} -w name | ${CUT} -d\" -f 2`
		shift
	done

	[ -z "$hdisk" ] && return 1

	${ECHO} $hdisk | ${TEE} -a ${REMOTEDUMPLOG}
	return 0 
}
#############################################################################
# FUNCTION: discover
#
# PARAMETERS: input : target_iqn port ip_address lun_id
#
# DESCRIPTION: configures and returns 
#              the disk name matching the `targetname port ip_address lun_id` 
#              values on the target.
#############################################################################
discover() {
	${ECHO} "Entering discover function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	port=$2
	ip=$3
	lun_id=$4

	# check if disk is already configured
	print_hdisk_name $target $lun_id
	[ $? -eq 0 ] && return 0

	# configure disk
	disc_policy=$(${LSATTR} -El iscsi0 -a disc_policy -F value)
	case ${disc_policy} in
	odm)
		odm_add $target $dump_port $ipaddr
		[ $? -ne 0 ] && return 1
		;;
	file)
		file_add $target $dump_port $ipaddr
		[ $? -ne 0 ] && return 1
		;;
	*)
		${C_ERRMSG} ${ERR_UNSUPPORTED_POLICY} ${C_ERRMSG_ERR} "${disc_policy}" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
		;;
	esac

	ERR=`${CFGMGR} -l iscsi0 2>&1 1>/dev/null`
	[ $? -ne 0 ] && {
		${C_ERRMSG} ${ERR_FAILED_CONFIG} ${C_ERRMSG_ERR} "iscsi0" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		${ECHO} ${ERR} | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
	}

	print_hdisk_name $target $lun_id
	[ $? -ne 0 ] && {
		case ${disc_policy} in
		odm)	
			odm_del $target $dump_port $ipaddr
			;;
		file)
			file_del $target $dump_port $ipaddr
			;;
		esac
		${C_ERRMSG} ${ERR_FAILED_TARGET_LUN} ${C_ERRMSG_ERR} "$target" "$lun_id" "" ""  | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
	}
	return 0
}
#############################################################################
# FUNCTION: destroy
#
# PARAMETERS: input : target_iqn port ip_address lun_id
#
# DESCRIPTION: Unconfigure and remove the disk matching the 
#              `target_iqn port ip_address lun_id`. 
#              Remove the iSCSI target if it has no disk left.
#############################################################################
destroy() {
	${ECHO} "Entering destroy function: $*" >> ${REMOTEDUMPLOG}

	target_iqn=$1
	port=$2
	ip=$3
	lun_id=$4
	hdisk=""

	# check if disk is already configured
	hdisk=`print_hdisk_name $target $lun_id`
	[ -z "$hdisk" -o $? -ne 0 ] && {
		${C_ERRMSG} ${ERR_NO_DISK_TARGET_LUN} ${C_ERRMSG_ERR} "$target_iqn" "$lun_id" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
	}

	# remove  disk
	ERR=`${RMDEV} -dl $hdisk 2>&1 1>/dev/null`
	[ $? -ne 0 ] && {  
		${C_ERRMSG} ${ERR_DISK_DELETE_FAIL} ${C_ERRMSG_ERR} "$hdisk" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		${ECHO} ${ERR} | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
   }
	
	#any disk left for the target ?
	nbdisk=`${ODMGET} -q"attribute=target_name and value=$target_iqn" CuAt | \
			${GREP} -wc name `;
   [ $nbdisk -gt 0 ] && return 0
	
	# no disk left, remove the target
	disc_policy=$(${LSATTR} -El iscsi0 -a disc_policy -F value)
	case ${disc_policy} in
	odm)
		odm_del $target $dump_port $ipaddr
		[ $? -ne 0 ] && return 1
		;;
	file)
		file_del $target $dump_port $ipaddr
		[ $? -ne 0 ] && return 1
		;;
	*)
		${C_ERRMSG} ${ERR_UNSUPPORTED_POLICY} ${C_ERRMSG_ERR} "${disc_policy}" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
		;;
	esac

	ERR=`${CFGMGR} -l iscsi0 2>&1 1>/dev/null`
	[ $? -ne 0 ] && {  
		${C_ERRMSG} ${ERR_FAILED_CONFIG} ${C_ERRMSG_ERR} "iscsi0" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		${ECHO} ${ERR} | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
		return 1
   }

	return 0
}
##############################################################################
# MAIN: c_disc_target -a operation=[discover|destroy] 
#                     -a target=targetname -a dump_port=port 
#                     -a ipaddr=ip_address -a lun_id=lun_id
#
# PARAMETERS:  input: targetname port ip_address lun_id
# 
# DESCRIPTION: Discover: On the initiator, configures and returns 
#              the disk name matching the `targetname port ip_address lun_id` 
#              values on the target.
#              Destroy: On the initiator, unconfigure and remove the disk name
#              matching the `targetname port ip_address lun_id` values on 
#              the target. Remove the target iSCSI target if it has no disk
#              left.
# 
###############################################################################
${ECHO} "" >> ${REMOTEDUMPLOG}
${DATE} >> ${REMOTEDUMPLOG}
${ECHO} "Entering c_disc_target script: $*" >> ${REMOTEDUMPLOG}

REQUIRED_ATTRS="target dump_port ipaddr lun_id operation"

target=""
dump_port=""
lun_id=""
ipaddr=""
operation=""

while getopts a:v c 
do
	case ${c} in
		a) 	parse_attr_ass "${OPTARG}"
			eval ${variable}=\"${value}\"
			;;
		v)   # verbose mode (for debugging)
			set -x
			for i in $(typeset +f)
			do
				typeset -ft $i
			done
	 		 ;;
	    \?)     # unknown option
           print ${ERR_BAD_OPT} ${OPTARG} | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
          ;;
        esac
done

# check for missing attrs
ck_attrs

# consider lun_id as hexa number even if 0x is missing
# add 0x if missing for ODM compliance check
[ -n "$lun_id" ] && lun_id=0x${lun_id#0x} 

# check operation parameters
[ "$operation" != "discover"  -a  "$operation" != "destroy" ] && {
	${C_ERRMSG} ${ERR_WRONG_PARAM} ${C_ERRMSG_ERR} "$operation" "" "" "" | ${TEE} -a ${REMOTEDUMPLOG} 1>&2
	exit 1;
	}

$operation $target $dump_port $ipaddr $lun_id

exit $?


