#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72F src/bos/usr/lib/nim/methods/c_switch_master.sh 1.8.1.6 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2001,2017 # 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 # @(#)71 1.8.1.6 src/bos/usr/lib/nim/methods/c_switch_master.sh, cmdnim, bos72F, f2017_09A7 2/24/17 13:51:40 # # COMPONENT_NAME: CMDNIM # # FUNCTIONS: ./usr/lib/nim/methods/c_switch_master.sh # # ORIGINS: 27 # # # (C) COPYRIGHT International Business Machines Corp. 1993 # All Rights Reserved # Licensed Materials - Property of IBM # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # include common NIM shell defines/functions NIMPATH=/usr/lpp/bos.sysmgt/nim NIM_METHODS="${NIMPATH}/methods" . ${NIM_METHODS}/c_sh_lib IFCONFIG="/etc/ifconfig" NETSTAT="/usr/bin/netstat" NIMINIT="/usr/sbin/niminit" #---------------------------- module globals -------------------------------- REQUIRED_ATTRS="originator new_master" OPTIONAL_ATTRS="connect async show_progress" platform="" pif_name="" ring_speed="" cable_type="" TYPE="" force="" mv_niminfo="" rc=0 OK_TO_UPDATE="" # ---------------------------- switch_master # # NAME: switch_master # # FUNCTION: Changes the defined master for a NIM client # # RETURNS: (int) # 0 = SUCCESS # 1 = FAILURE # # --------------------------------------------------------------------------- # # function switch_master { if [[ -s ${NIMINFO} ]]; then . ${NIMINFO} fi # if new_master = nim_master_hostname, then return if [[ ${new_master} = ${NIM_MASTER_HOSTNAME} ]] then return 0 fi # if originator != nim_master_hostname, then check nim_master_hostname_list if [[ ${NIM_MASTER_HOSTNAME} != ${originator} ]] \ && [[ `${ECHO} ${NIM_MASTER_HOSTNAME} | ${CUT} -f1 -d.` != ${originator} ]] \ && [[ ${force:=no} != yes ]] then for mstr in ${NIM_MASTER_HOSTNAME_LIST} do if [[ ${mstr} = ${originator} ]] \ || [[ `${ECHO} ${mstr} | ${CUT} -f1 -d.` = ${originator} ]] then OK_TO_UPDATE="yes" break fi done if [[ -z $OK_TO_UPDATE ]]; then ##### send this to originator instead of current_master [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R failure error ${ERR_INVALID_MASTER} fi fi if [[ -z "${NIM_MASTER_HOSTNAME}" ]] \ || [[ ${NIM_MASTER_HOSTNAME} = ${originator} ]] \ || [[ `${ECHO} ${NIM_MASTER_HOSTNAME} | ${CUT} -f1 -d.` = ${originator} ]] \ || [[ ${force:=no} = yes ]] \ || [[ ${OK_TO_UPDATE} = yes ]] then # construct niminit call - hostname=${NIM_HOSTNAME%%.*} platform=`${BOOTINFO} -p` if [[ -n $NIM_IPV6_HOSTS ]] then for i in $NIM_IPV6_HOSTS do # separate IP address from hostname IFS='|' set -- $i addr=$1 hname=$2 # select that address if hname match NIM_HOSTNAME if [[ $hname == $NIM_HOSTNAME ]] then IP_HOSTNAME=$addr fi done fi if [[ -n $NIM_HOSTS ]] then for i in ${NIM_HOSTS} do # separate IP address from hostname addr=${i%%:*} hname=${i##*:} # select that address if hname match NIM_HOSTNAME if [[ $hname == $NIM_HOSTNAME ]] then IP_HOSTNAME=$addr fi done fi pif_name=`${NETSTAT} -n -if inet | \ ${AWK} -v cmp=${IP_HOSTNAME} '{if ($4 == cmp) print $1 }'` if [[ ${pif_name} = tr* ]]; then ring_speed=`${MKTCPIP} -S ${pif_name} 2>&1 | \ ${AWK} 'BEGIN { RS="\n"; FS=":" } \ { for (i=1;i<=NF;i++) \ { if ( match($i,/speed/) ) (j=i) } \ if (NR==2) {print $j} }'` TYPE="-a ring_speed1=${ring_speed}"; else if [[ ${pif_name} = e[nt]* ]]; then cable_type=`${MKTCPIP} -S ${pif_name} 2>&1 | \ ${AWK} 'BEGIN { RS="\n"; FS=":" } \ { for (i=1;i<=NF;i++) \ { if ( match($i,/type/) ) (j=i) } \ if (NR==2) {print $j} }'` TYPE="-a cable_type1=${cable_type}"; fi fi # temporarily remove /etc/niminfo ${MV} /etc/niminfo /etc/niminfo.cnm >/dev/null 2>&1 mv_niminfo="yes" connect=${connect:-$NIM_SHELL} # now lets run niminit ${NIMINIT} ${show_progress:+-v} -a name=${NIM_NAME} \ -a master=${new_master} \ -a pif_name=${pif_name} ${TYPE} \ -a platform=${platform} \ -a restart_nimsh=no \ ${connect:+-a connect=$connect} 2>${ERR} if [[ $? != 0 ]]; then #### replace /etc/niminfo in case the the master removed it ${MV} /etc/niminfo.cnm /etc/niminfo ##### send this to originator instead of current_master [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R failure err_from_cmd ${NIMINIT} fi return 0 else ##### send this to originator instead of current_master # return the appropriate error code to the calling method; # print the formatted msg from calling method [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R failure error ${ERR_INVALID_MASTER} fi } # end of switch_master function direct_switch_master { TEMP=/tmp/$$ # backup existing copies of .rhosts and niminfo if [[ ! -s $NIMINFO || ! -s $RHOSTS ]] then exit 444 else $CP $NIMINFO ${NIMINFO}.previous $CP $RHOSTS ${RHOSTS}.previous fi #change the .rhosts file $SED "s/${originator}/${new_master}/" $RHOSTS > $TEMP 2>/dev/null $CP $TEMP $RHOSTS 2>&1 >/dev/null #change the niminfo file $SED "s/${originator}/${new_master}/" $NIMINFO > $TEMP 2>/dev/null $CP $TEMP $NIMINFO 2>&1 >/dev/null #clean up $RM $TEMP 2>&1 > /dev/null } #---------------------------- c_switch_master # # NAME: c_switch_master # # FUNCTION: # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # 1 = failure # #------------------------------------------------------------------------------- # signal processing trap cleanup 0 trap err_signal 1 2 11 15 # normally, we perform NIM initialization # but its not needed since we're recreating # the niminfo file # initialize local variables typeset c="" # set parameters from command line while getopts :a:qvfn c do case ${c} in a) # validate the attr ass parse_attr_ass "${OPTARG}" # include the assignment for use in this environment eval ${variable}=\"${value}\" ;; q) # show attr info cmd_what exit 0 ;; v) # verbose mode (for debugging) set -x for i in $(typeset +f) do typeset -ft $i done ;; f) # force option force=yes ;; n) #if changing the master's if1 only, then edit the files directly #the force flag must be set in order to use this direct=yes ;; \?) # unknown option error ${ERR_BAD_OPT} ${OPTARG} ;; esac done [[ ${async} = yes ]] && NIM_ASYNC=yes # check for missing attrs ck_attrs # mk_tmp_dir # doing asynchronous processing? (ie. master not waiting for script to finish) if [[ ${NIM_ASYNC} = yes ]] then # update the state of the client object # Only do so if not called from nim_script. The state is updated # there instead. ##### send this to originator instead of current_master #####[[ ${NIM_SCRIPT} != yes ]] && ${NIMCLIENT} -R success : # set the following variable so that errors are appended to err_info # attribute on the client object. When c_installp is called from # the nim_script, the async flag is not passed to this script so # this variable is exported there. ##### send this to originator instead of current_master ####UPDT_CL_ERR_INFO=yes fi # if the files are being edited directly, then do it and exit if [[ $direct = "yes" && $force = "yes" ]] then direct_switch_master if [[ $rc -ne 0 ]] then ##### send this to originator instead of current_master # update state on master if it isn't waiting for us to finish [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R failure else # update state on master if it isn't waiting for us to finish [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R success fi # this takes us from takeover_success to ready # update state on master if it isn't waiting for us to finish [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R success exit 0 fi # change if switch_master then # remove original niminfo file ${RM} /etc/niminfo.cnm >/dev/null 2>&1 # update state on master if it isn't waiting for us to finish [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R success else # keep original niminfo file, but only if created during # the current method call - could be an old one [[ -n ${mv_niminfo} ]] && \ ${MV} /etc/niminfo.cnm /etc/niminfo >/dev/null 2>&1 ##### send this to originator instead of current_master # update state on master if it isn't waiting for us to finish [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R failure fi # this takes us from takeover_success to ready # update state on master if it isn't waiting for us to finish [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R success # until a master can be specified to nimclient - send one more result to # acount for the transition from takeover_setup to takeover [[ ${NIM_ASYNC} = yes ]] && ${NIMCLIENT} -R success # all done exit $rc