#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2000,2020 # 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 # # sccsid = "@(#)35 1.40 src/rsct/cfg_access/cthactrl.sh, cfg.access, rsct_rady, rady2035a 5/29/20 16:28:38" # # usage: # cthactrl -i -c -n -e [-t type] [-p ports] # initialize the RSCT, where = gpfs or scaffold for now, =[RPD|CAA|] # 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=/opt/rsct/install/bin:/opt/rsct/bin:/usr/bin:/bin:/usr/sbin:/sbin export PATH CTROOT=/var/ct # basecmd=$(basename $0) # get machine ID OS=$(uname -s) # Set the RSCTBIN to /usr/sbin/rsct/bin on AIX if [[ $OS = "AIX" ]] then RSCTBIN=/usr/sbin/rsct/bin else RSCTBIN=/opt/rsct/bin fi # list of CCAL commands CCAL_CMDS="ct_hats_info ct_hags_info ct_topology_info \ ct_read_machines_lst ct_write_machines_lst" # ######################################################################### # 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 if [[ -f /usr/bin/locale ]]; then LOCALE=`/usr/bin/locale` else LOCALE=`/bin/locale` fi # /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="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 } # #***************************************************************************= # Link CCAL scripts to cfgmgr if not done already # argument "cmdenv" (e.g. cfgmgr) function link_ccal_cmds { cmdenv=$1 if [[ -z $cmdenv ]]; then cmdenv="cfgmgr" fi # visit each command for name in ${CCAL_CMDS} do abs_curname=${RSCTBIN}/$name # NOTE: # NOTE: Use the absolte pathname to match it with the installed symlink # cur_resolvedname=$(cd $RSCTBIN; ls -l $name 2>/dev/null | awk '{print $NF}') abs_goalname=${RSCTBIN}/$cmdenv/$name if [[ -z $cur_resolvedname ]] || [[ $cur_resolvedname != $abs_goalname ]] then # unlink the symbolic link if exist # and relink them to "cfgmgr" CCAL so that ConfigRM can use them rm -f $abs_curname (cd $RSCTBIN; ln -fs $abs_goalname $name) fi done } #***************************************************************************= # # process '-p ' option. The consists of # {comma,colon} separated list of pairs of {subsys}={port} # Input: # (For example, "cthats=12345,cthags=12346") # Output: variables with _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 (_port_number=) 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:t: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 t ) CLSTTYPE=$OPTARG;; # cluster type 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 # # # 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. link_ccal_cmds $CLSTENV # 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 /opt/rsct/bin/rmcctrl ]]; then ## # stop RMC & RM ... for smooth transition ## /opt/rsct/bin/rmcctrl -K ##fi # stop HATS/HAGS subsystems $RSCTBIN/cthagsctrl -k $RSCTBIN/cthatsctrl -k # setup the cluster info & dir if [[ -z $CLSTTYPE ]]; then CLSTTYPE="RPD" fi cfghact -c $CLSTNAME -n $NODENUM -t "$CLSTTYPE" -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 # No CritRsrcActive check $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 cfghact -d -x #(Cmdline only) if [ -x /opt/rsct/bin/rmcctrl ] || [ -x /opt/rsct/bin/rmcctrl ] then # start RMC if cfghact does not start them 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 cfghact -z -x # (Cmdline only) if [ -x /opt/rsct/bin/rmcctrl ] || [ -x /opt/rsct/bin/rmcctrl ] then # start RMC if cfghact does not start them rmcctrl -A 2> /dev/null fi print_dbgmsg "Deinstalling HATS/HAGS done" ;; esac exit_script # exit this script exit 1 # just in case