#!/bin/bash
PSTORAGE_ISCSI_LIB=/usr/libexec/vstorage-iscsi/vstorage_functions
ROOT=""
IQN=""
PORTAL_ADDR=""
USER=""
ARGS="${@}"
PARAM=""

function print_usage {
	exec 1>&2
	echo " "
	echo "Change parameters for specified iSCSI target."
	echo "Usage:"
	echo " $CTL_TOOL ${CMD} -t,--target IQN"
	echo "                       [-a,--address ADDR] [-u,--user USER] [-l,--limit TYPE=VALUE]"
	echo "Options:"
	echo "  -t,--target IQN         target's IQN."
	echo "  -a,--address ADDR       New address for specified target."
	echo "  -u,--user USER          New user name for CHAP authentication."
	echo "  -u -,--user -           Disable CHAP authentication."
	echo "  -l, --limit TYPE=VALUE  IO/IOPS limit (max_kbps, max_iops)."
	echo " "
	exit 1
}

function check_param {

	if [ -z "$PARAM" ]; then
		PARAM="$1"
		return
	fi

	if [ -n "$PARAM" -a "$PARAM" != "$1" ]; then
		echo "Can't change different parameters at once." 1>&2
		print_usage
	fi
}

function parse_args {
	if [ ${#} -eq 0 ]; then
		echo "Command not specified, expected 'set'" 1>&2
		exit 1
	fi

	[ ${#} -eq 1 ] && print_usage

	LIMITS=()
	CMD="${1}"; shift
	while [ "${#}" -gt 0 ]; do
		case "${1}" in
			"-h"|"--help")
				print_usage
				;;
			"-r"|"--root")
				[ -z "${2}" ] && print_usage
				ROOT="${2}"
				shift
				shift
				;;
			"-t"|"--target")
				[ -z "${2}" ] && print_usage
				IQN="${2}"
				shift
				shift
				;;
			"-u"|"--user")
				[ -z "${2}" ] && print_usage
				USER="${2}"
				check_param USER
				shift
				shift
				;;
			"-a"|"--address")
				[ -z "${2}" ] && print_usage
				if [ -z "$PORTAL_ADDR" ] ; then
					PORTAL_ADDR="${2}"
				else
					PORTAL_ADDR="${PORTAL_ADDR} ${2}"
				fi
				check_param PORTAL_ADDR
				shift
				shift
				;;
			"-l"|"--limit")
				[ -z "${2}" ] && print_usage
				LIMITS+=("${2}")
				shift
				shift
				;;
			*)
				echo "Unknown option '${1}'." 1>&2
				print_usage
				;;
		esac
	done

	if [ -z "$IQN" ] ; then
		echo "Target (-t,--target) must be specified." 1>&2
		print_usage
	fi

	if [ -z "$PARAM" ] && [ ${#LIMITS[@]} -eq 0 ] ; then
		echo "No parameters to set." 1>&2
		print_usage
	fi

	if [ -n "$PORTAL_ADDR" ] ; then
		echo "[$PORTAL_ADDR]"
		PORTAL_ADDR=`${SCSI_TRANSPORT}_validate_addr "$PORTAL_ADDR"`
		[ -z "$PORTAL_ADDR" ] && print_usage
		echo "-> [$PORTAL_ADDR]"
	fi
}

function do_set_parameters {
	pcs_iscsi_check_target $IQN
	for (( i=0; i < ${#LIMITS[@]}; i++ )); do
		local limit_type=$(echo ${LIMITS[$i]} | cut -d "=" -f1)
		local limit_value=$(echo ${LIMITS[$i]} | cut -d "=" -f2)
		pcs_iscsi_set_limit "$IQN" "$limit_type" "$limit_value"
		if [ $? -ne 0 ]; then
			echo "Failed to set limit ${LIMITS[$i]} for target \"$IQN\"" 1>&2
			return 5
		fi
	done

	if [ -f "$ISCSI_SHM/.running/$IQN" ]; then
		if [ ${#LIMITS[@]} -gt 0 ]; then
			return 0
		else
			echo "Can't set parameters for running target, please stop it first." 1>&2
			return 1
		fi
	fi

	if [ -n "$USER" ] ; then
			pcs_iscsi_set_chap_account "$IQN" "$USER" "${ISCSI_ROOT}/$IQN"
			if [ $? -ne 0 ]; then 
			echo "Failed to change CHAP account." 1>&2
			return 2
		fi
	fi

	if [ -n "$PORTAL_ADDR" ] ; then
		tmp=`mktemp  ${ISCSI_ROOT}/tmp/set-address-$target.XXXXXXXX`
		if [ $? -ne 0 ] ; then
				echo "Can't create temporary file." 1>&2
				return 3
		fi

		msg=`echo "$PORTAL_ADDR" | dd of="$tmp" conv=fsync >/dev/null 2>&1`
		if [ $? -ne 0 ]; then
			echo "$msg"
			echo "Unable save addresses in $tmp" 1>&2
			rm -f "$tmp"
			return 4
		fi

		msg=`mv -f "$tmp" "$ISCSI_ROOT/$IQN/control/address" 2>&1`
		if [ $? -ne 0 ]; then
			echo "$msg" 2>&1
			echo "Failed to move $tmp in $ISCSI_ROOT/$IQN/control/address" 2>&1
			rm -f "$tmp"
			return 4
		fi
	fi

	return 0
}

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

ISCSI_ROOT=`pcs_iscsi_get_root "${ROOT}"`
pcs_iscsi_check_root
pcs_iscsi_lock_exec do_set_parameters
exit $?

