#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r714 src/43haes/usr/sbin/cluster/events/utils/cl_acquire_sna_dlc.sh 1.19 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1998,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 
# @(#)40  1.19  src/43haes/usr/sbin/cluster/events/utils/cl_acquire_sna_dlc.sh, hacmp.hawan, 61haes_r714 12/12/07 05:15:47

###############################################################################
#
#  Name:  cl_acquire_sna_dlc
#
#  This script is used to reconfigure Communications Server resources on the 
#  given interface
#
# Arguments:    INTERFACE - Interface name (e.g. en0, tr0)
#		SNA_CONNECTIONS - Highly Available Comm Links
#
# Returns:      0 - Success
#               1 - Failure
#		2 - Usage error
#
# Called by: acquire_service_addr, acquire_takeover_addr
# Calls to: snaversion, mkdevename
#
# Environment:  VERBOSE_LOGGING
###############################################################################

###############################################################################
#
# Name: mkdevname
#
#	Make a device name from an interface name. That is,  translate
#	en0 to ent0, tr0 to tok0, etc.
#
# Arguments: Interface Name
#
# Returns: 0 success
#	   1 failure
###############################################################################
mkdevname () {
	typeset PS4_FUNC="mkdevname"
	[[ "$VERBOSE_LOGGING" = "high" ]] && set -x
	TYPE=$(expr "$1" : "^\([a-z]*\)[0-9]*")
	NUM=$(expr "$1" : "^[a-z]*\([0-9]*\)")

	if [ -z "$NUM" ]
	then
		cl_log 530 "$PROGNAME: Invalid interface name." $PROGNAME
		return 1
	fi

	case "$TYPE" in
	"en"|"et")		# Ethernet
       		NAME="ent$NUM"
		;;
	"tr")			# token ring
       		NAME="tok$NUM"
		;;
	"fi")			# FDDI
       		NAME="fddi$NUM"
		;;
	"hdlc"|"twd")		# qllc (get the COMIO port name)
		NAME=$(lsx25 | awk "\$2 == \"$1\" { print \$4 }")
		NUM=$(expr "$NAME" : "^x25s\([0-9]*\)")
		NAME="comio${NUM}"
		;;
	*)			# default
       		NAME="$TYPE$NUM"
		;;
	esac
	echo $NAME
	return 0
}
###############################################################################

PROGNAME=$(basename ${0})
export PATH="$($(dirname ${0})/../../utilities/cl_get_path all)"
[[ "$VERBOSE_LOGGING" = "high" ]] && set -x
[[ "$VERBOSE_LOGGING" = "high" ]] && version='1.19'
HA_DIR="$(cl_get_path)"

echo "Starting execution of $0 with parameters $*" $0 "$*"

set -u
if [ $# -lt 1 ] ; then
    cl_echo 4050 "Usage: $PROGNAME interface HA Comm Links" $PROGNAME
    exit 2
fi

INTERFACE=$1
shift 1
SNA_CONNECTIONS=$*

#SNA DLCs are changed at the device adapter level
DEVICE=$(mkdevname $INTERFACE)
if (($? != 0)) 
then
   cl_log 533 "$PROGNAME: Unable to make device name for interface $INTERFACE." $PROGNAME $INTERFACE
   exit 1
fi

#Determine SNA version
ISSNA5=$(snaversion)
if (( $ISSNA5 == 2 )) ; then
   cl_echo 4151 "Communications Server not installed or unsupported version."
   exit 1   
fi

if (( $ISSNA5 ))
then
    #SNA must be running to be able to change anything
    snaadmin query_node
    if (($? != 0))
    then
	sna start
	if (($? != 0))
	then
	    cl_log 4152 "Unable to start Communications Server."
	    exit 1
	fi
    fi

    #SNA needs to know the dlc type
    TYPEDEV=$(expr "$DEVICE" : "^\([a-z]*\)[0-9]*")
    case $TYPEDEV in
	ent)
		DLCTYPE="ETHERNET"
		DEFDLC=define_ethernet_dlc;;
	tok)
		DLCTYPE="TR"
		DEFDLC=define_tr_dlc;;
	fddi)
		DLCTYPE="FDDI"
		DEFDLC=define_fddi_dlc;;
	comio)
		DLCTYPE="X25"
		DEFDLC=define_qllc_dlc;;
    esac

    #For each SNA_CONNECTION issue the appropriate command
    #to configure the SNA DLC profile to use the specified
    #interface.

    for LINKNAME in $SNA_CONNECTIONS
    do
	#get link information
	LINKTYPE=$(cllscommlinks -C -t All | \
		awk "BEGIN { FS=\":\" } \$1 == \"${LINKNAME}\" { print \$2 }")
	if [[ "${LINKTYPE}" = "snalan" ]]
	then
		eval $(cllscommlinks -C -t snalan | \
			awk "BEGIN { FS=\":\" } \$1 == \"${LINKNAME}\" { \
			printf(\"snadlc='%s' PORTS='%s' LINKS='%s'\", \
			\$3, \$4, \$5) }" )

	elif [[ "${LINKTYPE}" = "snax25" ]]
	then
		eval $(cllscommlinks -C -t snax25 | \
			awk "BEGIN { FS=\":\" } \$1 == \"${LINKNAME}\" { \
			printf(\"snadlc='%s' PORTS='%s' LINKS='%s'\", \
			\$8, \$9, \$10) }" )

	else
		# this is not an sna link
		exit 0
	fi

	#see if the dlc uses $DLCTYPE
	DLC=$(snaadmin query_dlc, dlc_name=$snadlc | \
	grep "$DLCTYPE")
	if [[ -n $DLC ]]
	then
	    #retrieve the adapter number and make a device name
	    ADP=$(snaadmin -d query_dlc, dlc_name=$snadlc | \
		grep adapter_number | cut -f2 -d"=" | cut -c2-)
	    if [[ -n $ADP ]]
	    then
		SNADEV=$TYPEDEV$ADP
	    else
	    	SNADEV=$DEVICE
	    fi
	else
	    SNADEV=$DEVICE
	fi	

        if [[ $DEVICE != $SNADEV ]]
        then
	#issue change commands
	    NUM=$(expr $DEVICE : "^[a-z]*\([0-9]*\)")
	    if [[ $DLCTYPE = "ETHERNET" ]]
	    then
		ETHERTYPE=$(snaadmin -d query_dlc, dlc_name=$snadlc | \
		    grep ethernet_type | cut -f2 -d"=")
		COMMA=", ethernet_type = "
	    else
		ETHERTYPE=""
		COMMA=""
	    fi
	    snaadmin $DEFDLC, dlc_name = $snadlc, adapter_number=$NUM, initially_active="NO"$COMMA$ETHERTYPE
	    if (($? != 0))
	    then
		cl_log 4153 "Unable to modify DLC $snadlc." $snadlc
		exit 1
	    fi

        fi
    done

else
    #Version 4.2

    #If an SNA DLC is changed, verifysna will be run. When verifysna
    #finishes successfully, SNA will be stopped and restarted.  

    RESTARTSNA=0

    TYPEDEV=$(expr "$DEVICE" : "^\([a-z]*\)[0-9]*")
    case $TYPEDEV in
	ent)
		DLCTYPE=sna_dlc_ethernet;;
	tok)
		DLCTYPE=sna_dlc_token_ring;;
	fddi)
		DLCTYPE=sna_dlc_fddi;;
    esac
    #execute pre-version 5 command path
    for snadlc in $SNA_CONNECTIONS
    do
        SNADEV=$(qrysnaobj -t $DLCTYPE $snadlc | \
	grep datalink_device_name | cut -f2 -d"\"")

        if [[ $DEVICE != $SNADEV ]]
        then
	    if [[ $DLCTYPE = "sna_dlc_ethernet" ]]
	    then
		ETHERTYPE=$(qrysnaobj -t $DLCTYPE $snadlc | \
		    grep dlc_protocol | cut -f2 -d"=")
		SWITCH="-p "
	    else
		ETHERTYPE=""
		SWITCH=""
	    fi
	    #issue change commands
	    chsnaobj -t $DLCTYPE -d $DEVICE $SWITCH $ETHERTYPE $snadlc
	    if (($? != 0))
	    then
		cl_log 4153 "Unable to modify DLC $snadlc." $snadlc
		exit 1
	    fi
	    RESTARTSNA=1
        fi
    done
    if (( $RESTARTSNA ))
    then
	#run the verifysna command and check the output
	VERIFY=$(verifysna -R )
	if (($? != 0))
	then
	    cl_log 4154 "The verifysna command failed. Changes will \
			 not take affect."
	    exit 1
	fi
	#see if sna is running, if not then exit 0
	sna -d global
	if (($? != 0))
	then
	    cl_echo 4155 "Profiles successfully changed."
	    exit 0
	fi
	#To effect a changed DLC SNA must be restarted

	#Test to see if there are any sessions active
        #If so, build the session recovery file
        $(sna -d s | cut -c26-50 | sed /"^  *"/,/-/d | \
                sort > /tmp/sna.session)
        if [[ ! -s /tmp/sna.session ]]
        then
            #There were no sessions
            rm /tmp/sna.session
        fi
        #Test to see if there are any link stations active
        #If so, build the link station recovery file
        for l_s in $(lssnaobj -t link_station -U)
        do
            sna -d l | grep $l_s
            if (($? == 0))
            then
                echo $l_s >> /tmp/sna.link_station
                sna -stop l -p $l_s
            fi
        done

        #Now stop SNA (normal stop)
        sna -stop sna -t n
        if (($? != 0))
 	then
	    sna -stop sna -t c
	    if (($? != 0))
	    then
		cl_log 4156 "Unable to stop Communications Server."
		exit 1
	    fi
	fi

        #At this point SNA is down, just restart SNA
        #and restart any saved resources

        #Start SNA
        startsrc -s sna
        if (($? != 0))
        then
            cl_log 4152 "Unable to start Communications Server."
            exit 1
        fi

        #Now start the link stations
        if [[ -f /tmp/sna.link_station ]]
        then
            for l_s in $(cat /tmp/sna.link_station)
            do
                sna -s l -p $l_s
                if (($? != 0))
                then
		cl_log 4158 "Unable to start link station $l_s." $l_s
                fi
            done
            rm /tmp/sna.link_station
        fi
        #Now start the saved sessions
        if [[ -f /tmp/sna.session ]]
        then
            LINES=$(wc -l /tmp/sna.session | cut -c6-7)
            count=1
            while ((count <= LINES))
            do
                #Work out which sessions may be currently active
                #since starting a link station may also activate
                #a session
                $(sna -d s | cut -c26-50 |sed /"^  *"/,/-/d | \
                sort > /tmp/sna.session.current)
                $(diff /tmp/sna.session /tmp/sna.session.current | \
                grep "<" > /tmp/sna.session.diff)

                if [[ -s /tmp/sna.session.diff ]]
                then
                    #Open reading stream
		    exec 9< /tmp/sna.session.diff
                    read -u9 line
                    PARTNERLU=$(echo $line | cut -f2 -d" ")
                    MODE=$(echo $line | cut -f3 -d" ")
                    sna -s s -pn $PARTNERLU -m $MODE
                    #Close reading stream
                    exec 9<&-
                    rm /tmp/sna.session.current
                    rm /tmp/sna.session.diff
                fi
                ((count = count +1))
            done
            rm /tmp/sna.session
        fi
    fi
fi

exit 0


