#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r714 src/43haes/usr/sbin/cluster/cspoc/utilities/cl_mkssa.sh 1.7 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2000,2004 
# 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 
# @(#)74  1.7  src/43haes/usr/sbin/cluster/cspoc/utilities/cl_mkssa.sh, hacmp.cspoc, 61haes_r714 12/2/04 18:13:07

###############################################################################
#
#	cl_mkssa
#
#	Implements the code for SSA branch of the CSPOC cl_mkdisk script.
#
#	Syntax: cl_mkssa \
#		-c disk \
#		-s ssar \
#		-t hdisk \
#		-p <nodename-parent_device> \
#		-w <connection address> \
#		-a <Attribute=Value>
#
#       where:
#       -c disk 	Defines the device class as 'disk'.
#	-s ssar		Defines the device subclass as 'ssar' (SSA).
#	-t hdisk	Defines the type of disk to be added
#			This is ignored when making the pdisk,
#			but used when making the hdisk.
#	-w <connection address>
#			Defines the connection address, such as the
#			SCSI ID for SCSI devices.
#	-p <nodename-parent_device ...>
#			Defines one or more name-name pairs.  The first
#			name is the name of node on which the parent
#			device, specified by the second name, exists.
#	   Optional.    Passed from cl_mkdisk only for its convencience.
#	-a <Attribute=Value> Defines attributes specific to a disk type
#	   Optional.    Passed from cl_mkdisk only for its convencience.
#
#	I.e.:	the same arguments as are passed to cl_mkdisk itself
#		sans the CSPOC-specific flags (and their values).
#		NOTE, however, this utility script is only called
#		in the case that <subclass> is "ssar".
#
#	================================================================
#				!!!!  WARNING:  !!!!
#				====  ========  ====
#	This script is intended *only* as an auxiliary to cl_mkdisk.cel.
#	It should never be called interactively,  from the command line.
#	================================================================
#
#	Return Values:
#         0	success
#         1	failure
#	 -1	usage error
#
###############################################################################

PROGNAME=$(basename ${0})
#PATH="$($(dirname ${0})/cl_get_path all)"
#HA_DIR="$(cl_get_path)"

# Initialize variables that should be set by command-line flags.
# (Wherever possible, flags and related values
# are listed in 'canonical' rather than alphabetical order.)
#
CLMKSSAR_DISK=''
CLMKSSAR_SUBCLASS=''
CLMKSSAR_DISK_TYPE=''
CLMKSSAR_CONNAD=''
CLMKSSAR_NNPD=''
CLMKSSAR_ATTVAL=''

# Parse the command line.
#
optstr='c:s:t:w:p:a:'
while getopts h${optstr} optn; do
   case $optn in
     h)	usage	;;

     c)	CLMKSSAR_DISK=${OPTARG}		;;
     s)	CLMKSSAR_SUBCLASS=${OPTARG}	;;
     t)	CLMKSSAR_DISK_TYPE=${OPTARG}	;;
     w)	CLMKSSAR_CONNAD=${OPTARG}	;;
     p)	CLMKSSAR_NNPD=${OPTARG}		;;
     a)	CLMKSSAR_ATTVAL=${OPTARG}	;;

	esac; done
shift `echo "$OPTIND - 1" | bc`

# Validate the number of non-flag arguments.  (Should be exactly none.)
# ---------------------------------------------------------------------

if [ $# -ne 0 ]
   then	exit -1; fi

# Validate the values of the flags.
# ---------------------------------

# Most, if not all, of the flags are *expected* to be passed by cl_mkdisk.
# However, only the -w flag and its value are *required*.
#
if [ -z "${CLMKSSAR_CONNAD}" ]
   then exit -1; fi

# Some flags are required to have specific values.
#
if [ ! -z "${CLMKSSAR_DISK}" -a "${CLMKSSAR_DISK}" != "disk" ]
   then	exit -1; fi
if [ ! -z "${CLMKSSAR_SUBCLASS}" -a "${CLMKSSAR_SUBCLASS}" != "ssar" ]
   then	exit -1; fi
if [ ! -z "${CLMKSSAR_DISK_TYPE}" -a "${CLMKSSAR_DISK_TYPE}" != "hdisk" ]
   then	exit -1; fi

# Get lists of SSA-related adapters.
#
ssa_std_devs=`lsdev -CS1 -cadapter -tssa    -Fname`
ssa_160_devs=`lsdev -CS1 -cadapter -tssa160 -Fname`

# Get unused connection locations for SSA adapter(s)
# available for SSA logical disks (hdisks).
#
for adapnm in ${ssa_std_devs} ${ssa_160_devs} ; do
	ssacand -a ${adapnm} -L
	done | sort | tr '\n' ' ' | read conn_addrs

# If the specified connection address is not in that list,
#    then return with an error.  (Should never happen.)
#
print ${conn_addrs} | grep -q ${CLMKSSAR_CONNAD}
if [ $? -ne 0 ]
   then	# Conn. addr. '${CLMKSSAR_CONNAD}' already associated with an hdisk.
   	exit 1
	fi

# Get unused connection locations for SSA adapter(s)
# available for SSA physical disks (pdisks).
#
for adapnm in ${ssa_std_devs} ${ssa_160_devs} ; do
	ssacand -a ${adapnm} -P
	done | sort | tr '\n' ' ' | read conn_addrs

# If the specified connection address IS in that list,
#    then go make a pdisk using it.
#
print ${conn_addrs} | grep -q ${CLMKSSAR_CONNAD}
if [ $? -eq 0 ]
   then	# Conn. addr. '${CLMKSSAR_CONNAD}' is available for pdisk.

	# Construct ODM query to get device types of defined SSA disks.
	#
	query='uniquetype like pdisk/ssar/* and attribute = connwhere_shad'

	# Use ODM query to get device types of defined SSA disks.
	#
	odmget -q "${query}" PdAt |\
		grep "uniquetype = " |\
		awk '{print $3}' |\
		sed 's,^"pdisk/ssar/,,' |\
		sed 's,"$,,' |\
		tr '\n' ' ' | read dtlist

	# Build most of the command line that we will use in the next step.
	# Note that by prefabricating it this way,
	# we can enclose the varible value in singlequotes.
	#
	pdisk_args="-c pdisk -s ssar -p 'ssar' -w '${CLMKSSAR_CONNAD}' -a '${CLMKSSAR_ATTVAL}'"

	# Try creating each type of device in turn
	#   using the connection address specified by the user.
	# Most of these will fail, either because:
	#   the specified device is not detected;
	#   a device is already configured at the specified
	#   location;
	#   or perhaps some other reason.
	# However, the operation might succeed for one of them.
	# If it does, we stop.
	#
	for disktype in ${dtlist}; do
		foo=`mkdev ${pdisk_args} -t ${disktype} 2>&1`
		sts=$?
		if [ $sts -eq 0 ]; then break; fi
		done
	#
	# Note that we do not check whether the preceding loop
	# was successful, or unsuccesful, or unnecessary
	# (because the pdisk had already been created previously).
	# The result is that, IFF the specified pdisk can exist,
	# then by now it does.

#  else	# Conn. addr. '${CLMKSSAR_CONNAD}' already associated with a pdisk.
   fi	# Conn. addr. '${CLMKSSAR_CONNAD}' is/not available for pdisk.

# Now we create the hdisk.
#
# (We use a non-trivial invocation
# so that we can both capture the return code and read any output.
# If we just do the 'mkdev' command and pipe it to 'read',
# all we get for a return code is that of the 'read' command.)
#
hdisk_args="-c disk -s ssar -t hdisk -p 'ssar' -w ${CLMKSSAR_CONNAD} -a ${CLMKSSAR_ATTVAL}"
foo="$(mkdev $hdisk_args 2>&1)"
sts=$?
if [ ${sts} -ne 0 ]
   then	# 'mkdev $hdisk_args' returned ${sts}.
   	exit 1
   fi

# Parse the output of the command.
#
# The 'junk' in the arglist of 'read'
# ensures that hdiskname will consist of a single token.
#
print $foo | read hdiskname havailp junk

# Now we check to see whether the hdisk we just created
# happens to have a corresponding pdisk.
#
# Again, we do not care whether it existed previously
# or we wound up creating it on the fly.
# If there is a pdisk for this hdisk, this is good.
# If not, we exit with a status indicating failure.
#
# N.B.  The 'ssaxlate' command will return 0 if the hdisk is defined,
# *regardless* of whether there is an equivalent pdisk.
# (It returns non-zero only in the event of an out-and-out error.)
# This being the case,
# we have to capture the output and interpret it
# to be sure that there is a pdisk defined for this hdisk.
#
foo="$(ssaxlate -l ${hdiskname} 2>&1)"
sts=$?
if [ ${sts} -ne 0 ]
   then	# 'ssaxlate -l ${hdiskname}' returned ${sts}.
   	exit 1
   fi

# Parse the output of the command.
#
# The 'junk' in the arglist of 'read'
# ensures that pdiskname will consist of a single token.
#
print ${foo} | read pdiskname junk
if [ -z "${pdiskname}" ]
   then
	# No pdisk was created for hdisk, nor was one already available.
	exit 1
   fi

# If we get this far, we return success.
# --------------------------------------
exit 0
