#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2007 
# 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 
#
#  @(#)35   1.31         src/rsct/cfg_access/cthactrl.sh, cfg.access, rsct_relgh, relghs001a 5/8/06 09:55:57
#
# usage:
#	cthactrl -i -c <clstname> -n <node_number> -e <environ> [-p ports]
#		initialize the RSCT, where <env> = gpfs or scaffold for now
#	cthactrl -d		deleteAllLCs HA subsystems (all non-RPD definitions)
#	cthactrl -s		start HA subsystems
#	cthactrl -k		stop HA subsystems
#	cthactrl -K		Force forceOffline RPD/LC and switch to IW mode
#	cthactrl -b		rebuild machines.lst
#	cthactrl -r		refresh HA subsystems
#	cthactrl -z		deinstall HA subsystems
#
# Set path to known value
PATH=/usr/sbin/rsct/install/bin:/usr/sbin/rsct/bin:/usr/bin:/bin:/usr/sbin:/sbin
export PATH

RSCTBIN=/usr/sbin/rsct/bin
CTROOT=/var/ct

basecmd=$(basename $0)

#########################################################################
# Get the current Locale and determine whether English output is also needed
# Output: LOCALE
#         PRINT_ENG_MSG
#########################################################################
get_current_locale()
{
   # Check if current locale is a English
   LOCALE=`/usr/bin/locale`
   # /usr/bin/locale may produce LC_MESSAGES=en_US or LC_MESSAGES="en_US".
   # We use two sed "s" commands, the first one gets rid of LC_MESSAGES=,
   # the second one removes the two surrounding '"' if they are there.
   LOCALE=`echo "$LOCALE" | grep LC_MESSAGES | sed "s/LC_MESSAGES=//;s/\"//g"`

   # Do not print English messages if the local language is English.
   # C and POSIX are special locales. Treat them as en_US.
   if [[ "$LOCALE" = "C" || "$LOCALE" = "POSIX" ]]; then
        PRINT_ENG_MSG="NO"
   else
        # A locale may look like en_US or en_US.ISO8859-1. Use cut command
        # to remove the language encoding.
        LOCALE=`echo "$LOCALE" | cut -f 1 -d "."`
        if [[ "$LOCALE" = "en_US" || "$LOCALE" = "En_US" || "$LOCALE" = "en_GB" || "$LOCALE" = "En_GB" ]]
        then
                # Local language is English.
                PRINT_ENG_MSG="NO"
        else
                # Local language is not English (including "$LOCALE"=""),
                # which should not happen in normal cases)
                PRINT_ENG_MSG="YES"
        fi
   fi
}

#########################################################################
#                                                                       #
# Function: print_message                                               #
# Description: wrapper for message printing. All messages go to stderr. #
#     For now, all messages are printed in both English and the current #
#     language unless current language is en_US, C, or POSIX.           #
#                                                                       #
#     This subroutine makes it easy to print messages in  either English#
#     or current language or both. Also, it ensure all messages will be #
#     printed to the same stream.                                       #
#########################################################################

print_message()
{
    MSGCMD2="/usr/sbin/rsct/bin/hadspmsg cfgaccess ha_com.cat"
    print -u2 "`${MSGCMD2} $*`"

#    if [[ $PRINT_ENG_MSG = "YES" ]]
#    then
#        print -u2 "`LC_ALL=en_US ${MSGCMD2} $*`"
#    fi
}


#
function print_dbgmsg
{
   if [[ -n $HA_CCAL_LOG ]]; then
	print `date` ${basecmd}: "$*" >> $HA_CCAL_LOG
   fi
}

#

#***************************************************************************=

#
# process '-p <portspec>' option. The <portspec> consists of
# {comma,colon} separated list of pairs of {subsys}={port}
# Input: <portspec>
#     (For example, "cthats=12345,cthags=12346")
# Output: variables with <subsys>_port_number=<port_number>
#     cthats_port_number=12345
#     cthags_port_number=12346
# Note: currently supports only {cthats|cthags}_port_number
#
function parse_port_spec
{
   typeset -l psubsys	# psubsys is always lower case
   portspec=$*
   if [[ -z $portspec ]]; then
	return 	# nothing to do
   fi
   # something is in the input
   print_dbgmsg "parse_port_spec $portspec"
   IFS_SAVE=$IFS
   IFS_item=":,"	# separator between portspec
   IFS="$IFS_item"	# set the separator
   for item in $portspec
   do
	print_dbgmsg "portitem: $item"
	IFS="\="		# field sep (subsys=portnumber)
	set -A flds -- $item
	if [[ -n ${flds[0]} && -n ${flds[1]} ]]; then
		psubsys=${flds[0]}	# lower case of subsysname
		# set a variable (<subsys>_port_number=<port#>)
		if [[ $psubsys = cthats ]]; then
			cthats_port_number=${flds[1]}
			print_dbgmsg "cthats_port_number=${cthats_port_number}"
		elif [[ $psubsys = cthags ]]; then
			cthags_port_number=${flds[1]}
			print_dbgmsg "cthags_port_number=${cthags_port_number}"
		else
			print_dbgmsg "${psubsys} is not supported"
		fi
	else
		print_dbgmsg "item ($item) is ignored."
	fi
	IFS="$IFS_item"		# restore IFS
   done
   IFS=$IFS_SAVE
}

#
# Check whether a peer domain is already configured
# If so, exit immediately

function Check_PeerDomain_Then_Exit
{
   CLUSTERS_FILE=/var/ct/cfg/clusters
   if [[ -f $CLUSTERS_FILE ]]; then
	CLNAMES=$(grep -v "IW" $CLUSTERS_FILE | awk '{print $1}' | grep -v "-")
	if [[ $? -eq 0 ]]; then
		# This node is already part of a peer domain
		# Yes there a domain with "$CLNAMES"
		print_message EMSG109 $basecmd
		exit 1;
	fi
   fi
   return 0
}


# return (1 + 'OR'ed reason-codes) if an error happens
# reason code for cthatsctrl = 0x02 (2)
# reason code for cthagsctrl = 0x04 (4)
# input: (ts_rc, gs_rc)
function exit_script
{
   rc=0
   if [[ $ts_rc -ne 0 || $gs_rc -ne 0 ]]; then
	rc=1
	if [[ $ts_rc -ne 0 ]]; then let rc=rc+2; fi
	if [[ $gs_rc -ne 0 ]]; then let rc=rc+4; fi
   fi
   exit $rc
}

#
# main function starts
print_dbgmsg "$* called"
get_current_locale

# parse the arguments
gs_rc=0         # cthagsctrl return code
ts_rc=0         # cthatsctrl return code
PORTSPEC=""
Argcount=0
while getopts ":ic:n:e:p:bdsKkrzh" opt
do
    case $opt in
	i )     Op=init;     Argcount=$((Argcount + 1));;
	a ) 	Op=add;	     Argcount=$((Argcount + 1));;
	c )	CLSTNAME=$OPTARG;; 	# cluster name
	n )	NODENUM=$OPTARG;;	# node number
	e )	CLSTENV=$OPTARG;;	# cluster environment
	p )	PORTSPEC="$PORTSPEC,$OPTARG";;	# PORTSPEC
	d )     Op=deleteAllLCs;      Argcount=$((Argcount + 1));;
	s )     Op=start;    	Argcount=$((Argcount + 1));;
	b )	Op=rebuild;	Argcount=$((Argcount + 1));;
	r )     Op=refresh;  	Argcount=$((Argcount + 1));;
	k )     Op=stop;     	Argcount=$((Argcount + 1));;
	K )	Op=forceOfflineNode;	Argcount=$((Argcount + 1));;
	z )     Op=deinstall;   Argcount=$((Argcount + 1));;
	h )     Op=help
                print_message IMSG_cthactrl_Usage $basecmd
		exit 0;;
        ? ) print_message EMSG100 $basecmd $OPTARG
                print_message IMSG_cthactrl_Usage $basecmd
		exit 1;;
    esac
done

if ((Argcount == 0))
then
        # no argument specified
        print_message EMSG101 $basecmd 
        print_message IMSG_cthactrl_Usage $basecmd
        exit 1
fi

if ((Argcount > 1))
then
        # More than one argument specified
        print_message EMSG102 $basecmd 
        print_message IMSG_cthactrl_Usage $basecmd
        exit 1
fi

#
# list of CCAL commands
CCAL_CMDS="ct_hats_info ct_hags_info ct_topology_info \
           ct_read_machines_lst ct_write_machines_lst"
#
#
#
if [[ $Op = "init" ]]; then
	# NODENAME, NODENUM and CLSTENV must be specified
	print_dbgmsg "Initialize HATS/HAGS"

	if [[ -z $CLSTNAME || -z $NODENUM || -z $CLSTENV ]]; then
	    # check whether the parameters are correct
            # Parameter are incorrect
            print_message EMSG100 $basecmd "$CLSTNAME $NODENUM $CLSTENV"
            print_message IMSG_cthactrl_Usage $basecmd
	    exit 1;
	fi

	# check the existence of all ccal_cmds in $CLSTENV
        for name in ${CCAL_CMDS}
        do
            srcname=${RSCTBIN}/${CLSTENV}/$name
            if [[ ! -a $srcname ]]; then
		# Not all ccal cmds are found.
		# Not all commands found in $CLSTENV.
		# Environ $CLSTENV not established
                print_message EMSG103 $basecmd "$CLSTENV "
                exit 1;
            fi
        done
	# All CCAL_CMDS are found...

	# Check whether there is already a peer domain configured....
	# If so, exit immediately
	Check_PeerDomain_Then_Exit

	# set the symbolic links to ccal cmds (ct_*) for the clstenv.
        for name in ${CCAL_CMDS}
	do
	    srcname=${RSCTBIN}/${CLSTENV}/$name
	    if [[ ! -a $srcname ]]; then
		# $srcname not found.
                print_message EMSG104 $basecmd $srcname
		exit 1;
	    fi
	    rm -f ${RSCTBIN}/$name
	    ln -fs $srcname ${RSCTBIN}/$name
	done

	# Even if RMC is installed, RMC does not need to be restarted
	# because RMC will continue to see "IW" mode other than "RPD" domain
	## if [[ -x /usr/sbin/rsct/bin/rmcctrl ]]; then
	##	# stop RMC & RM ... for smooth transition
        ## 	/usr/sbin/rsct/bin/rmcctrl -K
	##fi

	# stop HATS/HAGS subsystems
        $RSCTBIN/cthagsctrl -k
        $RSCTBIN/cthatsctrl -k

	# setup the cluster info & dir
	/usr/sbin/rsct/install/bin/cfghact -c $CLSTNAME -n $NODENUM -f

	# process 'PORTSPEC'
	if [[ -n $PORTSPEC ]]; then
	    parse_port_spec ${PORTSPEC}
 	fi

	# Add HATS subsystem
	if [[ -n ${cthats_port_number} ]]; then
	    print_dbgmsg "Override hats port number ${cthats_port_number}"
	    $RSCTBIN/cthatsctrl -a -p${cthats_port_number}
	else
	    $RSCTBIN/cthatsctrl -a
 	fi
	ts_rc=$?

	# Add HAGS subsystem
	if [[ -n ${cthags_port_number} ]]; then
	    print_dbgmsg "Override hags port number ${cthags_port_number}"
	    $RSCTBIN/cthagsctrl -a -p${cthags_port_number}
	else
	    $RSCTBIN/cthagsctrl -a
	fi
	gs_rc=$?

	print_dbgmsg "Initialization done gs=$gs_rc ts=$ts_rc"
	exit_script	# exit the script
fi

#
# Check the parameters
if [[ -n $CLSTNAME || -n $NODENUM || -n $CLSTENV || -n $PORTSPEC ]]; then
   # Parameter is incorrect
   print_message EMSG100 $basecmd "$CLSTNAME $NODENUM $CLSTENV $PORTSPEC"
   print_message IMSG_cthactrl_Usage $basecmd
   exit 1;
fi

#

case $Op in
   add )
   	#add subsystems
        #Use -i option to configure HATS/HAGS
        print_message EMSG100 $basecmd $Op 
	exit 1
	;;


   rebuild )
	$RSCTBIN/cthatsctrl -b
	ts_rc=$?
	#..$RSCTBIN/cthagsctrl -?
	;;

   refresh )
	$RSCTBIN/cthatsctrl -r
	ts_rc=$?
	$RSCTBIN/cthagsctrl -r
	gs_rc=$?
	;;
  
   start )
	$RSCTBIN/cthatsctrl -s
	ts_rc=$?
	$RSCTBIN/cthagsctrl -s
	gs_rc=$?
	;;

   stop )
	$RSCTBIN/cthagsctrl -k
	gs_rc=$?
	$RSCTBIN/cthatsctrl -k
	ts_rc=$?
	;;

   forceOfflineNode )

	# stop RMC, RMs & HATS/HAGS and wait until they are stopped
	$RSCTBIN/rmcctrl -z

        $RSCTBIN/cthagsctrl -k
        gs_rc=$?
        $RSCTBIN/cthatsctrl -k
        ts_rc=$?

	# get IW clusterID
	IWClusterID=$(grep -w "IW" /var/ct/cfg/clusters | awk '{print $1}')
	if [[ -n ${IWClusterID} ]]
	then
		print "${IWClusterID}" > /var/ct/cfg/default_cluster
		print "${IWClusterID}" > /var/ct/cfg/current_cluster
	fi

	# restart RMC
	$RSCTBIN/rmcctrl -s

	;;

   deleteAllLCs )
	#deleteAllLCs subsystems
	print_dbgmsg "Deleting HATS/HAGS"

        if [[ -x ${RSCTBIN}/ct_hats_info ]]; then
                ClstEnv=$(${RSCTBIN}/ct_hats_info 2> /dev/null | \
                        grep ENVIRONMENT | awk '{print $2}')
        fi
        if [[ -z ${ClstEnv} ]]; then
                ClstEnv="cfgmgr"
        fi

	/usr/sbin/rsct/install/bin/cfghact -d -x

	#(Cmdline only)
        if [[ -x /usr/sbin/rsct/bin/rmcctrl ]]
        then
                # start RMC if cfghact does not start them 
                /usr/sbin/rsct/bin/rmcctrl -s 2> /dev/null
        fi

	print_dbgmsg "Deleting HATS/HAGS done"

	;;


   deinstall )

	print_dbgmsg "Deinstalling HATS/HAGS"

	if [[ -x ${RSCTBIN}/ct_hats_info ]]; then
		ClstEnv=$(${RSCTBIN}/ct_hats_info 2> /dev/null | \
			grep ENVIRONMENT | awk '{print $2}')
	fi
	if [[ -z ${ClstEnv} ]]; then
		ClstEnv="cfgmgr"
	fi

	/usr/sbin/rsct/install/bin/cfghact -z -x

	# (Cmdline only)
	if [[ -x /usr/sbin/rsct/bin/rmcctrl ]]
	then
		# start RMC if cfghact does not start them
		/usr/sbin/rsct/bin/rmcctrl -A 2> /dev/null
	fi

	print_dbgmsg "Deinstalling HATS/HAGS done"

	;;
esac

exit_script	# exit this script
exit 1		# just in case

