#!/usr/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2019,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # @(#) 7d4c34b 43haes/usr/sbin/cluster/sa/filenet/sbin/cl_filenet_db_ce_pe_import.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2010 # 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 #----------------------------------------------------------------------------- # # Name: cl_filenet_db_ce_pe_import # # DB2 Smart Assist import function for adding and removing HACMP resources. # # Syntax: # cl_filenet_db_ce_pe_import [-D | -v] [-M] {-a | -r} -o # -n # -i # -d # -l # -w # # Arguments: # -C Component ID # # -D Turn on debug mode. # # -A Application Name - Smart assistant application identifier # # -v Turn on verbose mode. # # -a Add/change all necessary HACMP resources for the specified DB2 instance. # If the resources already exist, they will be removed and then added. # This is the change/modify mode. # # -r Remove all HACMP resources for the specified DB2 instance. # # -o DB2 UDB instance owning node. This is the node that has the # highest priority. # # -n DB2 UDB takeover node(s). These nodes will be appended to the # instance owning node and then passed to "claddgrp -n". Takeover # nodelist is colon-separated. # # -i DB2 UDB instance name (owner) to be made highly available or # removed. This is the only option required when removing (-r) # the resources. # # -d DB2 UDB database name. This database is used by the # Custom SQL Monitor. # # -l The TCP/IP service IP label used by DB2 to communicate with # other application tiers and/or clients. # # -w The HACMP IP-based network where the service IP label (-l) is on. # # -M Delete pre-existing configuration (modify mode) # # Returns: # 0 on Success (import completed without error) # 1 on Warning (import completed with warning(s)) # 2 on Failure (import failed due to pre-verification failure) # 3 on Failure (import failed due to failure in adding resource) # #----------------------------------------------------------------------------- . /usr/es/lib/ksh93/func_include version='1.1 $Source: 61haes_r711 43haes/usr/sbin/cluster/sa/filenet/sbin/cl_filenet_db_ce_pe_import.sh 2$' #----------------------------------------------------------------------------- # Global Definitions: #----------------------------------------------------------------------------- RECOVERY_ODM=/tmp/cl_db_ce_pe_import_RemRes_recovery_odm RECOVERY_CMDS=/tmp/cl_db_ce_pe_import_RemRes_recovery_cmds typeset -A MSGS MSGS=( [1,3]="INFO: Verifying DB2 instance owner %s.\n" [1,4]="ERROR: DB2 instance owner (%s) does not exist!\n" [1,5]="ERROR: DB2 instance discovery data required but not found!\n" [1,6]="INFO: Sourcing in DB2 instance discovery data.\n" [2,2]="INFO: Verifying the existance of DB2 instance.\n" [2,3]="ERROR: The DB2 instance %s does not seem to be available!\n" [2,4]="ERROR: A DB2 instance must be properly configured for instance owner %s!\n" [2,5]="INFO: Verifying the database to be monitored by the custom SQL monitor.\n" [2,6]="ERROR: Database %s does not seem to be available for custom SQL monitoring!\n" [2,7]="INFO: Verifying the correctness of the owning node.\n" [2,8]="ERROR: The instance owning node (%s) cannot be in the takeover node(s) (%s) list!\n" [2,9]="INFO: Verifying all supplied nodes are valid HACMP nodes.\n" [2,10]="ERROR: Node %s is not a cluster node!\n" [2,11]="ERROR: Both instance owning node and takeover node(s) must be cluster nodes!\n" [2,12]="ERROR: Function AddResources failed!\n" [2,14]="ERROR: Unexpected DB2 import action encountered!\n" [2,15]="ERROR: Failed cleaning up existing resources!\n" [2,16]="ERROR: No resources have been added!\n" [2,17]="ERROR: Failed creating HACMP Application Server for instance %s!\n" [2,20]="ERROR: Failed adding HACMP SQL Monitor to the Meta Database!\n" [2,21]="ERROR: Failed creating HACMP Process Monitor for instance %s!\n" [2,22]="ERROR: Failed adding HACMP Process Monitor to the Meta Database!\n" [2,23]="ERROR: Failed creating HACMP Resource Group for instance %s!\n" [2,24]="ERROR: Failed updating HACMP Resource Group for instance %s!\n" [2,25]="ERROR: Failed adding HACMP Resource Group to the Meta Database!\n" [2,30]="ERROR: Failed removing DB2 Instance Application Server from HACMP!\n" [2,31]="ERROR: Failed removing DB2 Instance Resource Group from HACMP!\n" [2,32]="HACMP network %s is not enable for IPAT via IP Aliases!\n" [2,33]="ERROR: Function CheckInputs failed!\n" [2,39]="WARNING: The DB Instance Application Server does not exist in HACMP!\n" [2,40]="INFO: The DB2 Instance Resource Group does not exist in HACMP!\n" [2,41]="ERROR: Failed creating SQL Monitor hard link for %s on node %s!\n" [2,42]="ERROR: Failed stopping the DB2 instance %s on node %s!\n" [2,43]="INFO: Stopping instance %s on node %s!\n" [2,44]="WARNING: Instance %s on node %s is still running!\n" [2,45]="INFO: Sleeping for %s seconds (up to a total of %s seconds)...\n" [2,46]="INFO: Instance %s on node %s is stopped!\n" [2,47]="ERROR: Instance %s on node %s should be manually stopped before continuing!\n" [2,48]="INFO: Instance %s is not running on any node!\n" [2,49]="ERROR: Missing required argument(s) to import!\n" [2,50]="ERROR: Failed adding DATABASE_TO_MONITOR to the Meta Database!\n" [2,53]="ERROR: Failed creating HACMP Service IP Label for instance %s!\n" [2,57]="ERROR: Failed removing DB2 Instance Service IP Label from HACMP!\n" [2,58]="WARNING: The DB2 Instance Service IP Label does not exist in HACMP!\n" [2,59]="ERROR: The DB2 instance selected: %s is already defined to the HACMP\n\ cluster configuration with application: %s.\n" ) PROGNAME=$(basename ${0}) PATH="$($(dirname ${0})/../../../utilities/cl_get_path all)" PATH=$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/sbin:/usr/es/sbin/cluster/sa/sbin FPATH_BASE=/usr/es/lib/ksh93 FPATH=$FPATH_BASE/hacmp:$FPATH_BASE/sa:$FPATH_BASE/db2:$FPATH_BASE/aix:\ $FPATH_BASE/aix/odm:$FPATH_BASE/db2/vg:$FPATH_BASE/util:$FPATH_BASE/util/list export PATH FPATH export ODMDIR=/etc/objrepos export DB2SA_HOME="/usr/es/sbin/cluster/sa/db2" export DB2SA_ETC_PATH="$DB2SA_HOME/etc" export DB2SA_SBIN_DIR="$DB2SA_HOME/sbin" export DB2SA_DISC_FILE="$DB2SA_ETC_PATH/db2.disc" export DEBUG=${DEBUG:-"0"} export VERBOSE=${VERBOSE:-"0"} export ADD_RESOURCES=0 export REMOVE_RESOURCES=0 export INSTANCE_OWNING_NODE="" export TAKEOVER_NODES="" export INSTANCE_NAME="" # same as DATABASE_TO_MONITOR export DATABASE_NAME="" export SERVICE_LABEL="" export IP_NETWORK="" export DB2SALOG="/var/hacmp/log/db2sa.log" export DB2SACAT="db2sa.cat" # Add or Remove export ACTION="" NUM_ARGS=$# MODIFY_MODE=false RG="" #----------------------------------------------------------------------------- # # Name: usage # # Prints usage message and exits the program. # # Arguments: none # # Global Variables: # DB2SACAT # # Returns: does not return # function usage { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x dspmsg -s 10 filenetsa.cat 2 "Usage: cl_filenet_db_ce_pe_import [-D | -v] {-a | -r} -o \n\ \t-n -i \n\ \t-d -l -w [-M] [-F | -S]\n\ \n\ -D Turn on debug mode.\n\ -v Turn on verbose mode.\n\ -a Add/change all necessary HACMP resources for the specified DB2 instance.\n\ If the resources already exist, they will be removed and then added.\n\ This is the change/modify mode.\n\ -r Remove all HACMP resources for the specified DB2 instance.\n\ -o DB2 UDB instance owning node. This is the node that has the highest priority.\n\ -n DB2 UDB takeover node(s). These nodes will be appended to the instance\n\ owning node and then passed to \"claddgrp -n\". Takeover nodelist is colon-separated.\n\ -i DB2 UDB instance name (owner) to be made highly available or removed. This is the\n\ only option required when removing (-r) the resources.\n\ -d DB2 UDB database name. This database is used by the Custom SQL Monitor.\n\ -l The TCP/IP service IP label used by DB2 to communicate with other application\n\ tiers and/or clients.\n\ -w The HACMP IP-based network where the service IP label (-l) is on.\n\ -M Delete the pre-existing configuration (modify mode)\n\ -F Signal First Resource Group with respect to Mutual takeover configuration.\n\ -S Signal Second Resource Group with respect to Mutual takeover configuration.\n" exit 1 } function errmsg { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset set=$1 typeset id=$2 shift shift KLIB_DB2_print_message $set $id "${MSGS[$set,$id]}" $* } #----------------------------------------------------------------------------- # Name: RemoveResources # # Description: # Removes (-r) HACMP resources for DB2 Smart Assist. This function # removes all the HACMP resources its counterpart function, AddResources # added for INSTANCE_NAME. # Entries added by AddResources in the HACMPsa_metadata ODM will also # be cleaned up. # # This function, for the most part, will print out a warning and # continue removing other resources should it fails removing a # particular resource. # # Syntax: # RemoveResources # # Arguments: none # # Global Variables: # INSTANCE_NAME # NODE_LIST # DB2SA_SBIN_DIR # # Returns: # 0 on SUCCESS # 1 on FAILURE function RemoveResources { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x REMOVE_ERROR=0 # set to 1 if any of the remove fails sa_type="SA_DB2Instance" key="$APPLICATION_NAME" # Determine if the instance resource group exists first prior to removing typeset group=$(KLIB_AIX_ODM_get_odm_fields "sa_key=$key and sa_type=SA_DB2Instance" \ "HACMPgroup" "group") if [[ -z $group ]]; then errmsg 2 40 fi typeset service_label=$(KLIB_AIX_ODM_get_odm_fields "name=SERVICE_LABEL and \ group=$group" "HACMPresource" "value") # Now, we remove all entries from HACMP. # Remove Application Server from the HACMP Configuration cllsserv -n $INSTANCE_NAME"_ApplicationServer" > /dev/null 2>&1 if [[ $? -eq 0 ]]; then clrmserv $INSTANCE_NAME"_ApplicationServer" if [[ $? -ne 0 ]]; then errmsg 2 30 REMOVE_ERROR=1 fi else errmsg 2 39 fi # Remove Service IP Label from the HACMP. clvt query service_ip $SERVICE_LABEL > /dev/null 2>&1 if (( $? == 0 )); then clrmnode -a $SERVICE_LABEL if [[ $? -ne 0 ]]; then errmsg 2 57 REMOVE_ERROR=1 fi else errmsg 2 58 fi # Remove Resource Group from the HACMP configuration # All of the metadata will be removed at the time the RG # metadata is removed if [[ -n $group ]]; then # # Removing the depedency, if any with # the RG we are going to remove. # We can't remove the RG, without removing # any dependency exists with the RG. # clvt delete dependency RG=$group 1>/dev/null 2>&1 clrmgrp -g $group if (( $? != 0 )); then errmsg 2 31 REMOVE_ERROR=1 fi fi # Remove the hard link for SQL Monitor for $INSTANCE_NAME for node in $NODE_LIST do cl_rsh $node "$DB2SA_SBIN_DIR/cl_db2link -r $INSTANCE_NAME" > /dev/null 2>&1 if (( $? != 0 )); then errmsg 2 42 $INSTANCE_NAME $node REMOVE_ERROR=1 fi done return $REMOVE_ERROR } #----------------------------------------------------------------------------- # # Name: StopInstance # # Checks the $NODE_LIST to make sure the instance is not running anywhere. If # found running, an attempt will be made to stop it. # # Arguments: none # # Global Variables: # INSTANCE_NAME # NODE_LIST # # Returns: # 0 on SUCCESS # 1 on FAILURE # function StopInstance { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x export NODE2STOP="" # The product (*) of these will dictate how long we wait for the # instance to stop. We wait up to $TOTAL_SLEEP_TIME seconds for the # instance to stop. typeset -i SLEEP_TIME=5 # in seconds typeset -i SLEEP_CYCLE=120 typeset -i TOTAL_SLEEP_TIME (( TOTAL_SLEEP_TIME = $SLEEP_TIME * $SLEEP_CYCLE )) # Verify and stop the instance if running. for node in $NODE_LIST do cl_rsh $node "LC_ALL=C ps -fu$INSTANCE_NAME -o args | grep -v grep | grep -w db2sysc" > /dev/null 2>&1 if (( $? == 0 )); then NODE2STOP="$node" cl_rsh $NODE2STOP "$DB2SA_SBIN_DIR/cl_db2stop $INSTANCE_NAME" > /dev/null 2>&1 errmsg 2 43 $INSTANCE_NAME $NODE2STOP fi done if [[ -z $NODE2STOP ]]; then errmsg 2 48 $INSTANCE_NAME return 0 fi # Check to see if the instance is stopped, if not, cycle through a sleep # to give it more time. while (( $SLEEP_CYCLE > 0 )) do cl_rsh $NODE2STOP "LC_ALL=C ps -fu$INSTANCE_NAME -o args | grep -v grep | grep -w db2sysc" > /dev/null 2>&1 if (( $? == 0 )); then errmsg 2 44 $INSTANCE_NAME $NODE2STOP errmsg 2 45 $SLEEP_TIME $TOTAL_SLEEP_TIME sleep $SLEEP_TIME (( SLEEP_CYCLE = $SLEEP_CYCLE - 1 )) else errmsg 2 46 $INSTANCE_NAME $NODE2STOP return 0 fi done errmsg 2 47 $INSTANCE_NAME $NODE2STOP return 1 } #----------------------------------------------------------------------------- # # Name: CheckInputs # # Description: # # Checks a number of basic conditions and inputs to make sure nothing major is # missing before adding any resources. The checking here is by no mean # exhaustive since this script is meant to be called from SMIT and that DB2 # Instance Discovery and Pre-Verification should have been executed prior to # calling DB2 Import. # # Arguments: none # # Global Variables: # INSTANCE_NAME # INSTANCE_OWNING_NODE # TAKEOVER_NODES # DATABASE_NAME # IP_NETWORK # # Returns: # 0 on SUCCESS # 1 on FAILURE # function CheckInputs { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x # Make sure the DB2 instance owner is a valid system user. errmsg 1 3 $INSTANCE_NAME lsuser -a home $INSTANCE_NAME > /dev/null 2>&1 if [[ $? -ne 0 ]]; then errmsg 1 4 $INSTANCE_NAME exit 1 fi # Make sure the DB2 instance exists in the Instance Discovery Database. errmsg 2 2 xDB2INSTANCE=`KLIB_DB2_disc_get_instance_value $INSTANCE_NAME "DB2INSTANCE"` > /dev/null 2>&1 if [[ -z $xDB2INSTANCE ]]; then errmsg 2 3 $INSTANCE_NAME errmsg 2 4 $INSTANCE_NAME exit 1 fi # Make sure the DB2 instance database to be monitored exists in the Meta Database. errmsg 2 5 xDATABASE_NAME=`LC_ALL=C KLIB_DB2_disc_get_instance_value $INSTANCE_NAME "DATABASES" | grep -i -w $DATABASE_NAME` > /dev/null 2>&1 if [[ -z $xDATABASE_NAME ]]; then errmsg 2 6 $DATABASE_NAME exit 1 fi # Make sure the owning node (-o) is not also part of the takeover node(s) (-n). errmsg 2 7 NODE_LIST_OK=1 # assuming it's OK for i in $TAKEOVER_NODES do if [[ "$i" == "$INSTANCE_OWNING_NODE" ]]; then NODE_LIST_OK=0 # The instance owning node cannot also be part of the takeover nodes! fi done if (( $NODE_LIST_OK == "0" )); then errmsg 2 8 $INSTANCE_OWNING_NODE $TAKEOVER_NODES exit 1 fi # Make sure all cluster nodes (-o & -n) are valid HACMP nodes. errmsg 2 9 for node in $INSTANCE_OWNING_NODE $TAKEOVER_NODES do KLIB_HACMP_is_known_node $node if [[ $? -ne 0 ]]; then errmsg 2 10 $node errmsg 2 11 exit 1 fi done # Make sure $IP_NETWORK is using IPAT via IP Aliases (alias = 1 in HACMPnetwork). LC_ALL=C odmget -q "name = $IP_NETWORK" HACMPnetwork | grep -q 'alias = "1"' if (( $? != 0 )); then errmsg 2 32 $IP_NETWORK exit 1 fi return 0 } #----------------------------------------------------------------------------- # # Function: GenerateRecoveryScript # # Description: Run the recovery script and recover to PIT prior to removal # # Arguments: instance - DB2 instance name # # Global Variables: # RECOVERY_CMDS # RECOVERY_ODM # # Returns: 0 if successful # !0 if a failure occurred # function GenerateRecoveryScript { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset instance=$1 typeset key="$APPLICATION_NAME" typeset group=$(KLIB_AIX_ODM_get_odm_fields "sa_key=$key and sa_type=SA_DB2Instance and group="$INSTANCE_NAME"_ResourceGroup" "HACMPgroup" "group") typeset service_label=$(KLIB_AIX_ODM_get_odm_fields "name=SERVICE_LABEL and group=$group" "HACMPresource" "value") typeset application_server=$(KLIB_HACMP_get_appserver $group) echo "/usr/bin/odmdelete -o HACMPgroup -q group=$group" > $RECOVERY_CMDS echo "/usr/bin/odmdelete -o HACMPresource -q group=$group" >> $RECOVERY_CMDS echo "/usr/bin/odmdelete -o HACMPsa_metadata -q application_id=$APPLICATION_NAME" >> $RECOVERY_CMDS echo "/usr/bin/odmdelete -o HACMPserver -q name=$application_server" >> $RECOVERY_CMDS echo "/usr/bin/odmdelete -o HACMPadapter -q ip_label=$service_label" >> $RECOVERY_CMDS MONITORS=$(LC_ALL=C clvt query application $application_server | \ grep ASSOCIATEDMONITORS | \ awk -F= '{print $2}' | sed -e "s/\"//g") for app_mon in $MONITORS do echo "/usr/bin/odmdelete -o HACMPmonitor -q monitor=$app_mon" >> $RECOVERY_CMDS done echo "/usr/bin/odmdelete -o HACMPrgdependency -q group_parent=$group" >> $RECOVERY_CMDS echo "/usr/bin/odmdelete -o HACMPrgdependency -q group_child=$group" >> $RECOVERY_CMDS echo "/usr/bin/odmdelete -o HACMPrg_loc_dependency -q group_name=$group" >> $RECOVERY_CMDS /usr/bin/odmget -q group=$group HACMPgroup > $RECOVERY_ODM /usr/bin/odmget -q group=$group HACMPresource >> $RECOVERY_ODM /usr/bin/odmget -q "application_id=$APPLICATION_NAME" HACMPsa_metadata >> $RECOVERY_ODM /usr/bin/odmget -q "name=$application_server" HACMPserver >> $RECOVERY_ODM /usr/bin/odmget -q "ip_label=$service_label" HACMPadapter >> $RECOVERY_ODM for app_mon in $MONITORS do /usr/bin/odmget -q "monitor=$app_mon" HACMPmonitor >> $RECOVERY_ODM done /usr/bin/odmget -q group_parent=$group HACMPrgdependency >> $RECOVERY_ODM /usr/bin/odmget -q group_child=$group HACMPrgdependency >> $RECOVERY_ODM /usr/bin/odmget -q group_name=$group HACMPrg_loc_dependency >> $RECOVERY_ODM # # Providing execute permissions # /usr/bin/chmod u+x $RECOVERY_CMDS /usr/bin/chmod u+x $RECOVERY_ODM } #----------------------------------------------------------------------------- # # Function: RunRecoveryScript # # Description: Run the recovery script and recover to PIT prior to removal # # Arguments: na # # Global Variables: # RECOVERY_CMDS # RECOVERY_ODM # # Returns: 0 if successful # !0 if a failure occurred # function RunRecoveryScript { set +u [[ "$VERBOSE_LOGGING" == "high" ]] && set -x set -u /usr/bin/ksh93 $RECOVERY_CMDS 2>/dev/null /usr/bin/odmadd $RECOVERY_ODM 2>/dev/null } #----------------------------------------------------------------------------- # # Function: RemoveRecoveryScript # # Description: Remove the recovery script files from /tmp/ # prior to exiting # # Arguments: na # # Global Variables: # RECOVERY_CMDS # RECOVERY_ODM # # Returns: 0 if successful # !0 if a failure occurred # function RemoveRecoveryScript { set +u [[ "$VERBOSE_LOGGING" == "high" ]] && set -x set -u rm -f $RECOVERY_ODM $RECOVERY_CMDS } ################################################################################# # # Function: Add_DB_CE_PE_resources # # Description: Updates DB for Content Engine resources in DB for Process Engine # RG and vice versa. # # Syntax: # Add_DB_CE_PE_resources # # Arguments: none # # Global Variables: # INSTANCE_NAME # DATABASE_NAME # APPLICATION_NAME # # Returns: # 0 on SUCCESS # 1 on FAILURE # ################################################################################# function Add_DB_CE_PE_resources { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset -n SHARED_VGS=$1 for DB in $DATABASE_NAME do claddappmon MONITOR_TYPE=user name="${INSTANCE_NAME}_${DB}_SQLMonitor" \ RESOURCE_TO_MONITOR="${INSTANCE_NAME}_ApplicationServer" \ INVOCATION='longrunning' \ MONITOR_METHOD="$DB2SA_SBIN_DIR/cl_db2cmon -i $INSTANCE_NAME -A $APPLICATION_NAME -d $DB" \ MONITOR_INTERVAL='120' \ HUNG_MONITOR_SIGNAL='9' \ STABILIZATION_INTERVAL='240' \ RESTART_COUNT='3' \ RESTART_INTERVAL='1440' \ FAILURE_ACTION='fallover' \ CLEANUP_METHOD="$DB2SA_SBIN_DIR/cl_db2stop $INSTANCE_NAME" \ RESTART_METHOD="$DB2SA_SBIN_DIR/cl_db2start $INSTANCE_NAME" if (( $? != 0 )); then errmsg 2 19 $INSTANCE_NAME return 1 fi done set -a eval $(clvt query resource_group "$INSTANCE_NAME"_ResourceGroup) set +a # # Find out the unique VG list # VG_LIST=$VOLUME_GROUP SHARED_VGS=${SHARED_VGS// /} for VG in $SHARED_VGS; do available=0 for VG_IN_RG in $VOLUME_GROUP; do [[ $VG == $VG_IN_RG ]] && { available=1 break } done (( $available -eq 0 )) && { VG_LIST="$VG_LIST $VG" } done # Add the resources to the resource group clvt modify resource_group "${INSTANCE_NAME}_ResourceGroup" \ VOLUME_GROUP="$VG_LIST" APPLICATIONS="$APPLICATIONS" \ SERVICE_LABEL="$SERVICE_LABEL" FORCED_VARYON='false' \ VG_AUTO_IMPORT='true' FSCHECK_TOOL='fsck' \ RECOVERY_METHOD='parallel' FS_BEFORE_IPADDR='false' if (( $? != 0 )); then errmsg 2 24 $INSTANCE_NAME return 1 fi for DB in $DATABASE_NAME do claddsaapp -a "$APPLICATION_NAME" \ SQL_MONITOR="${INSTANCE_NAME}_${DB}_SQLMonitor" || { errmsg 2 20 return 1 } done # # cl_db2cmon needs this to figure out which DB to monitor. # Find out the existing DBs to monitor from HACMPsa_metadata ODM # DBS_MONITOR="" DBS_MONITOR=$(clodmget -q "application_id=$APPLICATION_NAME and \ name=DATABASE_TO_MONITOR" -f value -d "=" HACMPsa_metadata) if [[ -n $DBS_MONITOR ]]; then DBS_MONITOR=${DBS_MONITOR//\"/} DBS_MONITOR="$DBS_MONITOR $DATABASE_NAME" else DBS_MONITOR="$DATABASE_NAME" fi claddsaapp -a "$APPLICATION_NAME" \ DATABASE_TO_MONITOR="$DBS_MONITOR" || { errmsg 2 50 return 1 } name=$(KLIB_AIX_ODM_get_odm_fields "value=${INSTANCE_NAME}_ResourceGroup and application_id=$APPLICATION_NAME" "HACMPsa_metadata" "name") clrmsaapp -a $APPLICATION_NAME $name RG="FILENET_DB_PE_CE_RESOURCE_GROUP" claddsaapp -a $APPLICATION_NAME \ $RG="${INSTANCE_NAME}_ResourceGroup" || { errmsg 2 25 return 1 } return 0 } #----------------------------------------------------------------------------- # # Name: AddResources # # Description: # Adds (-a) HACMP resources for DB2 Smart Assist. If the resources # already exist, they will be removed and then added. Entries will # also be added to the HACMPsa_metadata ODM. Application Discovery # will remove the resources constructed by this function # # Syntax: # AddResources # # Arguments: none # # Global Variables: # INSTANCE_NAME # INSTANCE_OWNING_NODE # TAKEOVER_NODES # SERVICE_LABEL # IP_NETWORK # NODE_LIST # DB2SA_SBIN_DIR # # Returns: # 0 on SUCCESS # 1 on FAILURE # function AddResources { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x DB2HOME_VG=$(KLIB_DB2_disc_get_instance_value $INSTANCE_NAME "DB2HOME_VG") OTHERVGS=$(KLIB_DB2_disc_get_instance_value $INSTANCE_NAME "OTHERVGS") SHARED_VGS="$DB2HOME_VG $OTHERVGS" # all the shared VG(s) for the instance typeset source_node=$(KLIB_DB2_disc_get_instance_value $INSTANCE_NAME "CLUSTER_NODE") typeset application typeset DB_MON typeset DB_CE_RG typeset DB_PE_RG typeset DB_PE_CE_RG for node in $TAKEOVER_NODES; do KLIB_DB2_VG_node_pvid_compare $source_node $node $DB2HOME_VG || { SHARED_VGS="$OTHERVGS" break } done [[ "$COMPONENT_ID" == "FILENET_DB_PROCESS_ENGINE" ]] && { application=$(KLIB_AIX_ODM_get_odm_fields "name=INSTANCE_NAME and value=$INSTANCE_NAME" "HACMPsa_metadata" "application_id") [[ -n "$application" ]] && { DB_CE_RG=$(KLIB_AIX_ODM_get_odm_fields "name=FILENET_DB_CE_RESOURCE_GROUP and application_id=$application" "HACMPsa_metadata" "value") DB_PE_CE_RG=$(KLIB_AIX_ODM_get_odm_fields "name=FILENET_DB_PE_CE_RESOURCE_GROUP and application_id=$application" "HACMPsa_metadata" "value") [[ -n $DB_CE_RG && -z $DB_PE_CE_RG ]] && { DB_CE_RG=${DB_CE_RG//\"/} KLIB_SA_logmsg INFO 11 3 filenetsa.cat "The Database for Process and Content Engine, both are deployed\n\ under same DB2 instance %1\$s, so adding required resources\n\ of Database for %2\$s Engine onto Database for\n\ %3\$s Engine Resource Group %4\$s" $INSTANCE_NAME Process Content $DB_CE_RG RC=$(Add_DB_CE_PE_resources SHARED_VGS) return $RC } } } [[ "$COMPONENT_ID" == "FILENET_DB_CONTENT_ENGINE" ]] && { application=$(KLIB_AIX_ODM_get_odm_fields "name=INSTANCE_NAME and value=$INSTANCE_NAME" "HACMPsa_metadata" "application_id") [[ -n "$application" ]] && { DB_PE_RG=$(KLIB_AIX_ODM_get_odm_fields "name=FILENET_DB_PE_RESOURCE_GROUP and application_id=$application" "HACMPsa_metadata" "value") DB_PE_CE_RG=$(KLIB_AIX_ODM_get_odm_fields "name=FILENET_DB_PE_CE_RESOURCE_GROUP and application_id=$application" "HACMPsa_metadata" "value") [[ -n $DB_PE_RG && -z $DB_PE_CE_RG ]] && { DB_PE_RG=${DB_PE_RG//\"/} KLIB_SA_logmsg INFO 11 3 filenetsa.cat "The Database for Process and Content Engine, both are deployed\n\ under same DB2 instance %1\$s, so adding required resources\n\ of Database for %2\$s Engine onto Database for\n\ %3\$s Engine Resource Group %4\$s" $INSTANCE_NAME Content Process $DB_PE_RG RC=$(Add_DB_CE_PE_resources SHARED_VGS) return $RC } } } # # Check, is there any application configured with the # input application name # clquerysaapp -a $APPLICATION_NAME 1>/dev/null 2>&1 (( $? == 0 )) && { KLIB_SA_logmsg ERROR 9999 9999 filenetsa.cat "There exist some configuration \ with application name %1\$s\n\ Please choose a different application name" $APPLICATION_NAME return 1 } # First remove any pre-existing resources for this application id RemoveResources (( $? != 0 )) && { return 1 } # Add an entry into the HACMPsa_metadata ODM for the application id # and SMARTASSIST_ID and COMPONENT_ID claddsaapp -a "$APPLICATION_NAME" SMARTASSIST_ID='FILENET' \ COMPONENT_ID="$COMPONENT_ID" APPLICATION_NAME="$APPLICATION_NAME" INSTANCE_NAME="$INSTANCE_NAME" # Add the DB2 instance metadata to HACMPsa_metadata via the application # discovery framework (claddsaapp) KLIB_DB2_add_instance_to_metadata $INSTANCE_NAME APPLICATION_NAME sa_type="SA_DB2Instance" key="$INSTANCE_NAME" # Create the Service IP Label claddnode -Tservice -B"$SERVICE_LABEL" -w"$IP_NETWORK" if [[ $? -ne 0 ]]; then errmsg 2 53 $INSTANCE_NAME return 1 fi # Remove the application server first, in case it already exists clrmserv $INSTANCE_NAME"_ApplicationServer" >/dev/null 2>&1 # Create the Instance Application Server claddserv -s $INSTANCE_NAME"_ApplicationServer" \ -b "$DB2SA_SBIN_DIR/cl_db2start ${INSTANCE_NAME}" \ -e "$DB2SA_SBIN_DIR/cl_db2stop ${INSTANCE_NAME}" if [[ $? -ne 0 ]]; then errmsg 2 17 $INSTANCE_NAME return 1 fi # Create the Instance SQL Monitor for DB in $DATABASE_NAME do claddappmon MONITOR_TYPE=user name="${INSTANCE_NAME}_${DB}_SQLMonitor" \ RESOURCE_TO_MONITOR="${INSTANCE_NAME}_ApplicationServer" \ INVOCATION='longrunning' \ MONITOR_METHOD="$DB2SA_SBIN_DIR/cl_db2cmon -i $INSTANCE_NAME -A $APPLICATION_NAME -d $DB" \ MONITOR_INTERVAL='120' \ HUNG_MONITOR_SIGNAL='9' \ STABILIZATION_INTERVAL='240' \ RESTART_COUNT='3' \ RESTART_INTERVAL='1440' \ FAILURE_ACTION='fallover' \ CLEANUP_METHOD="$DB2SA_SBIN_DIR/cl_db2stop $INSTANCE_NAME" \ RESTART_METHOD="$DB2SA_SBIN_DIR/cl_db2start $INSTANCE_NAME" if (( $? != 0 )); then errmsg 2 19 $INSTANCE_NAME return 1 fi claddsaapp -a "$APPLICATION_NAME" \ SQL_MONITOR="${INSTANCE_NAME}_${DB}_SQLMonitor" \ $name="$value" || { errmsg 2 20 return 1 } done # # Find out the existing DBs to monitor from HACMPsa_metadata ODM # DBS_MONITOR="" DBS_MONITOR=$(clodmget -q "application_id=$APPLICATION_NAME and \ name=DATABASE_TO_MONITOR" -f value -d "=" HACMPsa_metadata) if [[ -n $DBS_MONITOR ]]; then DBS_MONITOR=${DBS_MONITOR//\"/} DBS_MONITOR="$DBS_MONITOR $DATABASE_NAME" else DBS_MONITOR="$DATABASE_NAME" fi # cl_db2cmon needs this to figure out which DB to monitor claddsaapp -a "$APPLICATION_NAME" \ DATABASE_TO_MONITOR="$DBS_MONITOR" || { errmsg 2 50 return 1 } # Create the Instance Process Monitor claddappmon MONITOR_TYPE=process name="${INSTANCE_NAME}_ProcessMonitor" \ RESOURCE_TO_MONITOR="${INSTANCE_NAME}_ApplicationServer" \ INVOCATION='longrunning' \ PROCESSES='db2sysc' \ PROCESS_OWNER="$INSTANCE_NAME" \ INSTANCE_COUNT='1' \ STABILIZATION_INTERVAL='240' \ RESTART_COUNT='3' \ RESTART_INTERVAL='1440' \ FAILURE_ACTION='fallover' \ CLEANUP_METHOD="$DB2SA_SBIN_DIR/cl_db2stop $INSTANCE_NAME" \ RESTART_METHOD="$DB2SA_SBIN_DIR/cl_db2start $INSTANCE_NAME" if (( $? != 0 )); then errmsg 2 21 $INSTANCE_NAME return 1 fi claddsaapp -a $APPLICATION_NAME \ PROCESS_MONITOR="${INSTANCE_NAME}_ProcessMonitor" || { errmsg 2 22 return 1 } [[ -z "$RG" ]] && { [[ "$COMPONENT_ID" == "FILENET_DB_PROCESS_ENGINE" ]] && { RG="FILENET_DB_PE_RESOURCE_GROUP" } [[ "$COMPONENT_ID" == "FILENET_DB_CONTENT_ENGINE" ]] && { RG="FILENET_DB_CE_RESOURCE_GROUP" } } claddsaapp -a $APPLICATION_NAME \ $RG="${INSTANCE_NAME}_ResourceGroup" || { errmsg 2 25 return 1 } # Create the Instance Resource Group claddgrp -g "${INSTANCE_NAME}_ResourceGroup" \ -n "$NODE_LIST" \ -S 'OHN' -O 'FNPN' -B 'NFB' \ -A SA_DB2Instance -K ${APPLICATION_NAME} if (( $? != 0 )); then errmsg 2 23 $INSTANCE_NAME return 1 fi # Add the resources to the resource group claddres -g "${INSTANCE_NAME}_ResourceGroup" \ SERVICE_LABEL="$SERVICE_LABEL" \ APPLICATIONS="${INSTANCE_NAME}_ApplicationServer" \ VOLUME_GROUP="$SHARED_VGS" \ FORCED_VARYON='false' \ VG_AUTO_IMPORT='true' \ FILESYSTEM="" \ FSCHECK_TOOL='fsck' \ RECOVERY_METHOD='parallel' \ FS_BEFORE_IPADDR='false' \ EXPORT_FILESYSTEM= \ MOUNT_FILESYSTEM= \ NFS_NETWORK="" \ SHARED_TAPE_RESOURCES= \ DISK="" \ AIX_FAST_CONNECT_SERVICES= \ COMMUNICATION_LINKS= \ MISC_DATA="" if (( $? != 0 )); then errmsg 2 24 $INSTANCE_NAME return 1 fi # # Creating Dependencies # 1. Process Engine RG should start after DB for Process Engine RG # 2. Content Engine RG should start after DB for Content Engine RG # CE_RG=$(clodmget -q "name=CONTENT_ENGINE_RESOURCE_GROUP" -f value -d "=" HACMPsa_metadata) CE_RG=${CE_RG//\"/} AE_CE_RG=$(clodmget -q "name=FILENET_AE_CE_RESOURCE_GROUP" -f value -d "=" HACMPsa_metadata) AE_CE_RG=${AE_CE_RG//\"/} PE_RG=$(clodmget -q "name=PROCESS_ENGINE_RESOURCE_GROUP" -f value -d "=" HACMPsa_metadata) PE_RG=${PE_RG//\"/} AE_RG=$(clodmget -q "name=APPLICATION_ENGINE_RESOURCE_GROUP" -f value -d "=" HACMPsa_metadata) AE_RG=${AE_RG//\"/} [[ "$RG" == "FILENET_DB_PE_RESOURCE_GROUP" ]] && { [[ -n "$PE_RG" ]] && { clrgdependency -t 'START_AFTER' -a -c "$PE_RG" -p "${INSTANCE_NAME}_ResourceGroup" (( $? != 0 )) && return 1 } # # Establishing NODECOLLOCATION dependency across process engine RG and # DB for Process engine RG # clrgdependency -t 'NODECOLLOCATION' -a -l "${INSTANCE_NAME}_ResourceGroup $PE_RG" (( $? != 0 )) && return 1 } [[ "$RG" == "FILENET_DB_CE_RESOURCE_GROUP" ]] || [[ "$RG" == "FILENET_DB_PE_CE_RESOURCE_GROUP" ]] && { [[ -n "$AE_RG" && -n "$CE_RG" && -n "$PE_RG" ]] && { clrgdependency -t 'START_AFTER' -d -c "$PE_RG" -p "$CE_RG" (( $? != 0 )) && return 1 } } [[ "$RG" == "FILENET_DB_CE_RESOURCE_GROUP" ]] && { [[ -n "$CE_RG" ]] && { clrgdependency -t 'START_AFTER' -a -c "$CE_RG" -p "${INSTANCE_NAME}_ResourceGroup" (( $? != 0 )) && return 1 } [[ -n "$AE_CE_RG" ]] && { clrgdependency -t 'START_AFTER' -a -c "$AE_CE_RG" -p "${INSTANCE_NAME}_ResourceGroup" (( $? != 0 )) && return 1 } } [[ "$RG" == "FILENET_DB_PE_CE_RESOURCE_GROUP" ]] && { [[ -n "$CE_RG" ]] && { clrgdependency -t 'START_AFTER' -a -c "$CE_RG" -p "${INSTANCE_NAME}_ResourceGroup" (( $? != 0 )) && return 1 } [[ -n "$AE_CE_RG" ]] && { clrgdependency -t 'START_AFTER' -a -c "$AE_CE_RG" -p "${INSTANCE_NAME}_ResourceGroup" (( $? != 0 )) && return 1 } [[ -n "$PE_RG" ]] && { clrgdependency -t 'START_AFTER' -a -c "$PE_RG" -p "${INSTANCE_NAME}_ResourceGroup" (( $? != 0 )) && return 1 # # Establishing NODECOLLOCATION dependency across process engine RG and # DB for Process engine RG # clrgdependency -t 'NODECOLLOCATION' -a -l "${INSTANCE_NAME}_ResourceGroup $PE_RG" (( $? != 0 )) && return 1 } } return 0 } #----------------------------------------------------------------------------- # Main: #----------------------------------------------------------------------------- umask -S u=rw,g=,o= [[ $NUM_ARGS -eq 0 ]] && usage while getopts DA:C:Mvaro:n:i:d:l:w: option do case $option in D) # Verbose on + Debug on VERBOSE=1 DEBUG=1 ;; A) # application name APPLICATION_NAME=$OPTARG ;; C) # Component Identifier either DB2_NON_DPF_SINGLE or # DB2_NON_DPF_MUTUAL COMPONENT_ID=$OPTARG ;; v) # Verbose on VERBOSE=1 ;; a) # Add Resources if [[ "$REMOVE_RESOURCES" == "1" ]]; then usage fi ACTION="add" ADD_RESOURCES=1 ;; r) # Remove Resources if [[ "$ADD_RESOURCES" == "1" ]]; then usage fi ACTION="remove" REMOVE_RESOURCES=1 ;; o) # Primary cluster node that owns the instance INSTANCE_OWNING_NODE=$OPTARG ;; n) # Standby cluster node(s) that is/are capable of hosting the instance TAKEOVER_NODES="$OPTARG" TAKEOVER_NODES=$(echo $TAKEOVER_NODES | sed -e "s/\:/ /g") ;; i) # Name of instance to be made highly available INSTANCE_NAME=$OPTARG ;; d) # Name of instance database to be used by the custom SQL monitor DATABASE_NAME=$OPTARG ;; l) # Service IP label for instance SERVICE_LABEL=$OPTARG ;; w) # IP network where Service IP label lives IP_NETWORK=$OPTARG ;; M) # Delete the pre-existing configuration (modify mode) MODIFY_MODE=true ;; *) usage esac done export NODE_LIST="$INSTANCE_OWNING_NODE $TAKEOVER_NODES" if (( $ADD_RESOURCES == 0 )) && (( $REMOVE_RESOURCES == 0 )); then errmsg 2 49 usage fi errmsg 1 6 if [[ -f $DB2SA_DISC_FILE ]]; then . $DB2SA_DISC_FILE else if [[ "$ACTION" == "add" ]]; then errmsg 1 5 exit 1 fi fi # Verify and, if needed, stop the instance before moving on. StopInstance if (( $? != 0 )); then errmsg 2 42 $INSTANCE_NAME $INSTANCE_OWNING_NODE exit 1 fi if [[ "$ACTION" == "add" ]]; then clsapre CheckInputs if [[ $? -ne 0 ]]; then errmsg 2 33 exit 1 fi # # Remove the pre-existing configuration (modify mode) # [[ "$MODIFY_MODE" == "true" ]] && { GenerateRecoveryScript $INSTANCE_NAME set -a eval $(clquerysaapp -a $APPLICATION_NAME RESOURCE_GROUP) set +a service_ip_label=$(clodmget -q "name=SERVICE_LABEL and \ group=$RESOURCE_GROUP" -f value -d "=" HACMPresource) service_ip_label=${service_ip_label//\"/} [[ -n $service_ip_label ]] && clvt delete service_ip $service_ip_label # # Removing the depedency, if any with # the RG we are going to remove. # We can't remove the RG, without removing # any dependency exists with the RG. # clvt delete dependency RG=$RESOURCE_GROUP 1>/dev/null 2>&1 clvt delete resource_group $RESOURCE_GROUP RG=$(clodmget -q "value=$RESOURCE_GROUP" -f name -d "=" HACMPsa_metadata) RG=${RG//\"/} clrmsaapp -a $APPLICATION_NAME } # # Determine if the instance we're attempting to add is already part of an # HACMP configuration (configured using DB2 smart assist) # # Check to ensure another resource group with the same application name hasn't been # created (using DB2 smart assist) # application=$(KLIB_AIX_ODM_get_odm_fields "name=RESOURCE_GROUP and value=${INSTANCE_NAME}_ResourceGroup" "HACMPsa_metadata" "application_id") [[ -n $application ]] && { errmsg 2 59 $INSTANCE_NAME $application exit 1 } AddResources if [[ $? -ne 0 ]]; then RemoveResources clquerysaapp -a $APPLICATION_NAME > /dev/null 2>&1 (( $? == 0 )) && { clrmsaapp -a $APPLICATION_NAME } # # When something went wrong while adding resources # during change of application, we are restoring # back the original configuration. # [[ "$MODIFY_MODE" == "true" ]] && { RunRecoveryScript RemoveRecoveryScript } errmsg 2 12 exit 1 fi [[ "$MODIFY_MODE" == "true" ]] && RemoveRecoveryScript clsapost -v (( $? != 0 )) && exit 1 else errmsg 2 14 exit 1 fi exit 0