#!/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 # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r714 src/43haes/usr/sbin/cluster/sa/oracle/sbin/oracle_sa.sh 1.39.1.2 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2005,2013 # 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 # @(#) 20c8e9d 43haes/usr/sbin/cluster/sa/oracle/sbin/oracle_sa.sh, 726, 2147A_aha726, Oct 30 2021 04:20 PM # # This configuration assistant helps add or remove a cluster from # two nodes with a shared disk. The HACMP application server is the Oracle # Infrastructure Tier. # # # ------------------------------------------------------------- # # ------------------ Program Flow ----------------------------- # Defines (basic declarations) # assist_main (loop for next_state) # The following functions are called using the next_state mechanism # assist_init # ck_user # ck_sizes (size of /var, /tmp and swap space) # prompt_action (configure, unconfigure or readme) # 1 config_basic_cluster # 2 prompt_vg # 2 validate_vg # 3 prompt_fs # 3 validate_fs # 4 config_app_server # 5 define_service_IP_label # 6 config_resource_group # 7 define_private_network # 8 verify_and_sync # 9 start_wo_oracle # 10 inst_oracle #---------------------------- defines -------------------------------- # specifics for this assist # this is the user visible name of the assist to be applied by this program # OSA_NAME="Oracle Smart Assist" PROGNAME=$(basename ${0}) [[ "$VERBOSE_LOGGING" = "high" ]] && set -x typeset CMD=$0 # this is the path to the programs which support this assist # OSA_DIR=/usr/es/sbin/cluster/sa/oracle/sbin OSA_SCRIPTS_DIR=/usr/es/sbin/cluster/sa/oracle/scripts OSA_README=${OSA_DIR}/README OSA_OPTIONS=${OSA_DIR}/options LOG_DIR=/var/hacmp/log RUN_LOG=${LOG_DIR}/oracle_sa.log # These are the options which can be read from the options file - we specify # a few defaults here in case the options file cannot be read # APPVG="ora_vg" APPFS="/ora_cmd00fs" # # these defines are passed to the cluster configuration routines # ias infrastructure application server # The scripts are shipped with the oracle assist package. # oracle_server="oracle_ias" start=$OSA_SCRIPTS_DIR/infra.start stop=$OSA_SCRIPTS_DIR/infra.stop default_rg="oracle_ias_rg" OLDIFS=${IFS} EDITOR=${EDITOR:-vi} if [[ $EDITOR = *gvim ]] || [[ $EDITOR = *vim\ -g ]]; then EDITOR="$EDITOR -f" fi PAGER=${PAGER:-pg} # this is where we access the HACMP utilities TOOLS_DIR=/usr/es/sbin/cluster/utilities CSPOC_DIR=/usr/es/sbin/cluster/cspoc ASSIST_PATHS=/usr/bin:/usr/sbin:/bin:/etc:/usr/etc:${TOOLS_DIR}:${CSPOC_DIR} CLEAR_SCREEN="clear_screen" # # Default help messages # NO_HELP=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 122 "No help information is currently available for this field.\n") PROMPT_HELP1=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 123 "When prompted, you may enter:\n\ \t to take the default specified within \"()\"\n\ \t\"d\" to delete the default (ie, enter NULL as your answer)\n\ \t\"h\" for help information\n\ \t\"x\" to exit this program\n\ \tsome information\n") PROMPT_HELP2=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 124 "When prompted, you may enter:\n \t to take the default specified within \"()\"\n \t\"h\" for help information\n \t\"x\" to exit this program\n \tsome information\n") PROMPT_HELP3=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 125 "When prompted, you may enter:\n\ \t\"h\" for help information\n\ \t\"x\" to exit this program\n\ \tsome information\n") ASSIST_HELP=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 119 "\n oracle_sa Command\n\n\ Purpose\n\ Walks the administrator through the configuration steps necessary to\n\ create a two node cluster and install the oracle infrastructure tier\n\n\ Syntax\n\ oracle_sa [-h] [-v]\n\n\ Description\n\ oracle_sa is an interactive tool which will prompt you for the\n\ information required to configure a two node cluster and install \n\ the Oracle Infrastructure Tier. \n\ The components are a Shared Volume Group, Shared Filesystem, Application \n\ Server name with start and stop scripts, Service IP Label, Private Network,\n\ Resource Group and a Cluster name.\ \n\n\ Flags\n\ -h \tDisplays the help for this program.\n\ -v \tVerbose mode.\n -r \tRun this on remote node to check the prereqs only.\n") YES_NO_HELP=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 121 "You may enter either:\n\ \t to accept the default\n\ \ty|Y to answer \"yes\"\n\ \tn|N to answer \"no\"\n\ \th to get help\n\ \tx to exit assist_main\n") #---------------------------- globals -------------------------------- VERBOSE="" answer="" pathname="" validate_files="" #----------- command line values no_confirm="" #----------- state machine state="" prev_state="" next_state="" #---------------------------- use_x -------------------------------- # # NAME: use_x # # FUNCTION: # tells user to use "x" to exit # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function use_x { msg 98 "Enter \"x\" to exit or \"h\" to get help information.\n" } # end of use_x #******************************************************************************* #*************************** message functions ****************************** #******************************************************************************* #---------------------------- show_usage -------------------------------- # # NAME: show_usage # # FUNCTION: # displays the oracle_sa syntax message # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function show_usage { print "\ Usage:\n\ oracle_sa [-h] [-r] [-v]\n" } # end of show_usage #---------------------------- help -------------------------------- # # NAME: help # # FUNCTION: # display help text # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1-> = help message -or- keyword "file" followed by pathname # global: # # RETURNS: (int) # # OUTPUT: # writes help message to stdout #------------------------------------------------------------------------------- function help { ${CLEAR_SCREEN} if [[ $# -eq 0 ]]; then /usr/bin/dspmsg -s 1 oracle_sa.cat 91 "No help available for this field.\n" elif [[ ${1} = file\ ?* ]]; then set ${1} -- if [[ -s ${2} ]]; then cat ${2} msg NO_CLEAR "" else /usr/bin/dspmsg -s 1 oracle_sa.cat 91 "No help available for this field.\n" msg NO_CLEAR "" fi else print $* msg NO_CLEAR "" fi } # end of help #---------------------------- clear_screen -------------------------------- # # NAME: clear_screen # # FUNCTION: # clears screen and prints title # and task subtitle # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function clear_screen { # # dont clear if in verbose mode. # if [[ ${VERBOSE_LOGGING} != "high" ]]; then clear fi print " -----------------------------------------------------------------" /usr/bin/dspmsg -s 1 oracle_sa.cat 82 " ------[ PowerHA SystemMirror Oracle Smart Assist for Infrastructure Tier ]------\n" if [[ -n ${TASK} ]]; then if [[ -n ${task} ]]; then print " --[ ${task}/10 ${TASK} ]--" else print " --[ ${TASK} ]--" fi fi print " -----------------------------------------------------------------\n" } # end of clear_screen #---------------------------- msg -------------------------------- # # NAME: msg # # FUNCTION: # displays the specified message and waits for a response to continue # assumes that the dspmsg has been done first. # # EXECUTION ENVIRONMENT: # form msg "$msg" where msg comes from the catalog # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1-> = message to display # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function msg { typeset response="" if [ "$1" = "NO_CLEAR" ]; then shift else ${CLEAR_SCREEN} fi print $* | fmt -78 | cut -c1-78 print dspmsg -s 1 oracle_sa.cat 1 "Hit to continue " read response [[ "${response}" = x ]] && user_exit return 0 } # end of msg #---------------------------- msg_log -------------------------------- # # NAME: msg_log # # FUNCTION: # Send message to the log and # displays the specified message and waits for a response to continue # # EXECUTION ENVIRONMENT: # form msg_log MSG_ID $default_message # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1-> = message to display # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function msg_log { typeset response="" if [ "$1" = "NO_CLEAR" ]; then shift else ${CLEAR_SCREEN} fi MSG_ID=$1 shift 1 /usr/bin/dspmsg -s 1 oracle_sa.cat $MSG_ID "$@" [[ -n "$RUN_LOG" ]] && { LC_ALL='C' \ /usr/bin/dspmsg -s 1 oracle_sa.cat $MSG_ID "$@" >> $RUN_LOG } print /usr/bin/dspmsg -s 1 oracle_sa.cat 1 "Hit to continue " read response [[ "${response}" = x ]] && user_exit return 0 } # end of msg_log # # Seperator for function calls # #---------------------------- func_header -------------------------------- # # NAME: func_header # # FUNCTION: Writes header to the log for each task # # EXECUTION ENVIRONMENT: # # DATA STRUCTURES: # parameters: # global: # RUN_LOG # # RETURNS: (int) # # OUTPUT: The task header is written to the RUN_LOG. # #------------------------------------------------------------------------------- function func_header { # # Add the new task info to the header # # Add seperator to the log # print "========= ${task} $1 ===============" >> $RUN_LOG clear_screen } #---------------------------- log -------------------------------- # # NAME: log # # FUNCTION: Writes all arguments to the RUN_LOG # # EXECUTION ENVIRONMENT: Called from any other function in oracle assist # # DATA STRUCTURES: # parameters: # global: # RUN_LOG # # RETURNS: (int) # # OUTPUT: The log entry (all arguments to the function) written to the # RUN_LOG. # #------------------------------------------------------------------------------- function log { # # Sometimes the output is too long for vi. # print $* | fmt -78 | cut -c1-78 >>$RUN_LOG return $? } #---------------------------- yes_no -------------------------------- # # NAME: yes_no # # FUNCTION: # prompt for a yes/no response # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = prep message -or- keyword "file" followed by filename # 2 = question to ask # 3 = default # 4 = help text # global: # # RETURNS: (int) # 0 = answer was "yes" # 1 = answer was "no" # # OUTPUT: #------------------------------------------------------------------------------- function yes_no { if [ "$1" = "NO_CLEAR" ]; then shift no_clear="1" else no_clear="" fi typeset msg="${1}" typeset question="${2}" typeset default="${3:-y}" typeset help="${4:-${YES_NO_HELP}}" typeset answer="" # return immediately if no prompt given (used in validate_filenames) [[ -z "${question}" ]] && return 0 # prompt the user while : do if [[ -z $no_clear ]]; then ${CLEAR_SCREEN} fi # any message to print before the prompt? if [[ -n "${msg}" ]] then # keyword "file" used? if [[ "${msg}" = file\ +(?) ]] then set ${msg} -- [[ -s "${2}" ]] && cat ${2} else print -n ${msg} fi #print fi # prompt the user print -n " ${question}? (${default}) " read answer # what was the response? answer=${answer:-${default}} case ${answer} in [yY]) return 0;; [nN]) return 1;; x) user_exit;; *) help "${help}";; esac done } # end of yes_no #---------------------------- prompt -------------------------------- # # NAME: prompt # # FUNCTION: # prompts the user for information # the user's answer is returned via the global variable "answer" # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = prompt string # 2 = default value # 3 = "yes" if NULL answer acceptable; otherwise, msg to display # 4 = help message or keyword followed by more info # 5 = name of function to validate user's input # global: # answer # # RETURNS: (int) # 0 = ${answer} is non-NULL # 1 = ${answer} is NULL # # OUTPUT: #------------------------------------------------------------------------------- function prompt { typeset question="${1}" typeset default="${2}" typeset null_ok="${3:-no}" typeset help_txt="${4}" typeset validation=${5} typeset allow_default_removal="" answer="" # allow default to be removed? [[ -n "${default}" ]] && allow_default_removal=${null_ok} # set default help text if none given if [[ -z "${help_txt}" ]] then case "${allow_default_removal}" in yes) help_txt="${PROMPT_HELP1}" ;; no) help_txt="${PROMPT_HELP2}" ;; *) help_txt="${PROMPT_HELP3}" ;; esac fi # prompt the user while : do [[ -n "${default}" ]] && print -n "${question} (${default}): " || print -n "${question}: " read answer # what was the response? case "${answer}" in h) # specified help? case "${help_txt}" in file\ +(?)) # help text from a file set ${help_txt} -- if [[ -n "${2}" ]] && [[ -s ${2} ]] then ${CLEAR_SCREEN} msg ${2} else help "${NO_HELP}" fi ;; execute\ +(?)) # function to call set ${help_txt} -- [[ -n "${2}" ]] && ${2} || help "${NO_HELP}" ;; *) # generic text help "${help_txt}" ;; esac ;; x) # user requested exit user_exit ;; *(?)+([! ])*(?)) # user's answer if [[ ${answer} = d ]] && [[ "${allow_default_removal}" = yes ]] then # user wants to delete the default answer=default_deleted else # any routine given to validate this? if [[ -n "${validation}" ]] then # validate user's answer ${validation} "${answer}" && break || continue else break fi fi ;; *) # use the default answer="${default}" # any routine given to validate this? if [[ -n "${validation}" ]] then # validate user's answer ${validation} "${answer}" && break || continue else break fi ;; esac # Do we have an acceptable answer? if [[ "${answer}" = [hx] ]] then continue elif [[ ${null_ok} = yes ]] then break elif [[ -n "${answer}" ]] && [[ ${answer} != default_deleted ]] then echo here break else msg_text=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 92 "You have not entered any information yet.\n") msg "$msg_text" fi done [[ -n "${answer}" ]] && return 0 || return 1 } # end of prompt #---------------------------- prompt_list -------------------------------- # # NAME: prompt_list # # FUNCTION: # prompts the user to select from a list of choices # the user's answer is returned via the global variable "answer" # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = prompt string # 2 = string of choices # 3 = help message # global: # answer # # RETURNS: (int) # 0 = success # # OUTPUT: #----------------------------------------------------------------------------- function prompt_list { typeset question="${1}" typeset list="${2}" typeset help="${3}" typeset i="" typeset choice="" typeset -i num=1 answer="" # prompt the user while [[ -z "${answer}" ]] do print "${question}" num=1 for i in ${list} do print "\t${num}\t= ${i}" let num+=1 done msg_text=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 93 "\nSelect one of the above or (h) help or (x) exit: \n") print -n $msg_text read choice # what was the response? case "${choice}" in h) help "${help}";; x) user_exit;; +([0-9]) ) # make sure choice falls within given bounderies num=1 for i in ${list} do if [[ ${choice} = ${num} ]] then answer=${i} break fi let num+=1 done ;; esac done } # end of prompt_list #---------------------------- prompt_multiple ----------------------------- # # NAME: prompt_multiple # # FUNCTION: # prompts the user to select from a list of choices # the user's answer is returned via the global variable "answer" # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = prompt string # 2 = string of choices # 3 = help message # global: # answer # # RETURNS: (int) # 0 = success # # OUTPUT: #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # # Create a list of choices, one at a time. # function prompt_multiple { typeset question="${1}" typeset list="${2}" typeset help="${3}" typeset i="" typeset choice="" typeset -i num=1 answer="" # prompt the user while [[ -z "${for_ever}" ]] do clear_screen print "${question}" num=1 for i in ${list} do print "\t${num}\t= ${i}" let num+=1 done if [[ -n ${answer} ]]; then /usr/bin/dspmsg -s 1 oracle_sa.cat 94 "\nYou have selected %s \n" "${answer}" fi /usr/bin/dspmsg -s 1 oracle_sa.cat 181 "\nSelect one of the above to add to the list, or hit to accept the list,\nor (h) help or (x) exit: " read choice # what was the response? case "${choice}" in h) help "${help}";; x) user_exit;; "") break;; +([0-9]) ) # make sure choice falls within given bounderies let num=1 for i in ${list} do if [[ ${choice} = ${num} ]] then # # disallow redundant selections. rm [] from [new_name] # tmp=$(echo $i | sed "s/\[//g"|sed "s/\]//g") echo $answer | grep -sw $tmp if [[ $? -ne 0 ]]; then answer=$(echo ${answer} $i) fi /usr/bin/dspmsg -s 1 oracle_sa.cat 94 "\nYou have selected %s \n" "${answer}" fi let num+=1 done ;; esac done } # end of prompt_multiple #---------------------------- prompt_edit -------------------------------- # # NAME: prompt_edit # # FUNCTION: # prompts the user for information and puts them in an editor to answer # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = message # 2 = subject of prompt # 3 = template for the file # 4 = name of file to be edited # 5 = validation routine to call # 6 = help text # 7 = thing being validated (for display of Validating message) # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function prompt_edit { typeset message="${1}" typeset subject="${2}" typeset template="${3}" typeset filename="${4}" typeset validation="${5}" typeset help="${6}" typeset thing="${7}" typeset info=/tmp/$$.info typeset first_time=TRUE # prompt the user while : do if [ "$no_confirm" ]; then ${EDITOR} ${filename} elif [ "$first_time" ]; then yes_no "${message}You will now be put into the editor to ${subject}." \ "ok" "y" "${help}" && ${EDITOR} ${filename} else ${EDITOR} ${filename} fi # validate file? if [ ! "${validation}" ]; then break else ${CLEAR_SCREEN} if [ "$thing" ]; then print "Validating $thing..." fi ${validation} ${filename} >${info} 2>&1 && break fi yes_no "file ${info}" "Try again" "y" "${help}" || return 1 first_time= done return 0 } # end of prompt_edit #---------------------------- prompt_action ------------------------------ # # NAME: prompt_action # # FUNCTION: # prompts the user to select from a list of actions # the user's answer determines the next_state # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prompt_action { TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 180 "Choose to Configure, Unconfigure or view README.\n") task=0 answer="" quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 83 "\ This program helps you configure an HACMP two node cluster and the Oracle\n\ Infrastructure Tier software. Please select one of the following options:\n") configure=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 84 "Configure the PowerHA SystemMirror two node cluster.\n" ${OSA_NAME}) unconfigure=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 85 "Un-Configure the cluster.\n" ${OSA_NAME}) readme=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 86 "View the README information for the %s Assist.\n" ${OSA_NAME}) hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 87 "Select one of the options from the list.\n\ 1 - Configure - helps you add a two node cluster to your current configuration.\n\ 2 - Unconfigure - helps you remove the cluster and components from your system.\n\ 3 - View the README - Uses \"pg\" to view the REAMDE file, and returns to this page.\n") # prompt the user while [[ -z "${answer}" ]] do ${CLEAR_SCREEN} print "${quest}\n" let num=1 print "${num}\t= ${configure}\n" let num+=1 print "${num}\t= ${unconfigure}\n" let num+=1 print "${num}\t= ${readme}\n" let num+=1 /usr/bin/dspmsg -s 1 oracle_sa.cat 93 "\nSelect one of the above or (h) help or (x) exit: " read choice # what was the response? case "${choice}" in h) msg "$hlp" ;; x) user_exit;; [1-3]) if [[ ${choice} = "1" ]]; then next_state=config_basic_cluster fi if [[ ${choice} = "2" ]]; then next_state=unconfigure_assist fi if [[ ${choice} = "3" ]]; then next_state=show_readme fi break ;; esac done return 0 } # end of prompt_action #---------------------------- user_exit -------------------------------- # # NAME: user_exit # # FUNCTION: # user has requested exit # yes exists, no returns user back to calling place # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function user_exit { msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 88 "You have requested to exit oracle_sa.\n") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 89 "Do you really want to exit\n") note=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 90 "\nNote - You can undo any changes by running this program again \n\ and selecting the \"Unconfigure\" option. \n\n\ Additional details for this session may be found in %s.\n" $RUN_LOG) if [ "$no_confirm" ] || yes_no "$msg" "$quest" "y" then echo $note exit 99 fi } # end of user_exit #******************************************************************************* #*************************** validation functions ****************************** #******************************************************************************* #---------------------------- ck_user -------------------------------- # # NAME: ck_user # # FUNCTION: # checks the user (must be root) # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function ck_user { if (( 0 != $(id -u) )) && ! ckauth PowerHASM.admin ; then msg 95 "You must be root to use this program.\n" fi } #---------------------------- ck_options_file -------------------------------- # # NAME: ck_options_file # # FUNCTION: # read and parse the options file # The options file is a scratch pad to provide default values # for re-entry. It is not actually required. # # EXECUTION ENVIRONMENT: # # NOTES: # prints ERROR on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function ck_options_file { # does the options file exist ? if [[ ! -f ${OSA_OPTIONS} ]]; then msg_log "NO_CLEAR" 126 "ERROR: Could not locate the options file %s\n" ${OSA_OPTIONS} return 1 fi # parse the options file - note that the list of options checked for # is specific to this assist log "These are the default values that are read from the options file." exec 3< ${OSA_OPTIONS} while read -u3 option value rest do if [[ -n "${option}" ]] && [[ "${option}" != "#" ]]; then case ${option} in "APPVG" ) APPVG=${value} log "Read APPVG from the options file, value is \"${value}\"." ;; "APPFS" ) APPFS=${value} log "Read APPFS from the options file, value is \"${value}\"." ;; "APPFScmd" ) APPFScmd=${value} log "Read APPFScmd from the options file, value is \"${value}\"." ;; "APPFSdata" ) APPFSdata=${value} log "Read APPFSdata from the options file, value is \"${value}\"." ;; "APPFSins" ) APPFSins=${value} log "Read APPFSins from the options file, value is \"${value}\"." ;; "APPLV" ) APPLV=${value} log "Read APPLV from the options file, value is \"${value}\"." ;; "APPLVdata" ) APPLVdata=${value} log "Read APPLVdata from the options file, value is \"${value}\"." ;; "APPLVins" ) APPLVins=${value} log "Read APPLVins from the options file, value is \"${value}\"." ;; "APPLVcmd" ) APPLVcmd=${value} log "Read APPLVcmd from the options file, value is \"${value}\"." ;; "APPSERV" ) APPSERV=${value} log "Read APPSERV from the options file, value is \"${value}\"." ;; "SVC_IP_LABEL" ) SVC_IP_LABEL=${value} log "Read SVC_IP_LABEL from the options file, value is \"${value}\"." ;; "APAR_LIST" ) APAR_LIST=${value} log "Read APAR_LIST from the options file, value is \"${value}\"." ;; "SWAP_SPACE" ) SWAP_SPACE=${value} log "Read SWAP_SPACE from the options file, value is \"${value}\"." ;; "TMP_SPACE" ) TMP_SPACE=${value} log "Read TMP_SPACE from the options file, value is \"${value}\"." ;; "VAR_SPACE" ) VAR_SPACE=${value} log "Read VAR_SPACE from the options file, value is \"${value}\"." ;; "USR_SPACE" ) USR_SPACE=${value} log "Read USR_SPACE from the options file, value is \"${value}\"." ;; "FS_SIZE" ) FS_SIZE=${value} log "Read FS_SIZE from the options file, value is \"${value}\"." ;; "PRIM_NODE" ) if [[ -z $PRIM_NODE || $PRIM_NODE -eq "UNKOWN" ]]; then PRIM_NODE=${value} log "Read PRIM_NODE from the options file, value is \"${value}\"." else log "PRIM_NODE value is \"${value}\"." fi ;; "SECOND_NODE" ) if [[ -z $SECOND_NODE || $SECOND_NODE -eq "UNKOWN" ]]; then SECOND_NODE=${value} log "Read SECOND_NODE from the options file, value is \"${value}\"." else log "SECOND_NODE value is \"${value}\"." fi ;; "JAVA_HOME" ) JAVA_HOME=${value} log "Read JAVA_HOME from the options file, value is \"${value}\"." ;; "APPRG" ) APPRG=${value} log "Read APPRG from the options file, value is \"${value}\"." ;; "ZIP_HOME" ) ZIP_HOME=${value} log "Read ZIP_HOME from the options file, value is \"${value}\"." ;; "ORACLE_INSTALL" ) ORACLE_INSTALL=${value} log "Read ORACLE_INSTALL from the options file, value is \"${value}\"." ;; "ORACLE_HOME" ) ORACLE_HOME=${value} log "Read ORACLE_HOME from the options file, value is \"${value}\"." ;; "ORACLE_SCRIPTS" ) ORACLE_SCRIPTS=${value} log "Read ORACLE_SCRIPTS from the options file, value is \"${value}\"." ;; * ) log \ "ERROR: Unknown keyword \"${option}\" found - options file is not correct\n" ;; esac fi done return 0 } # end of ck_options_file #---------------------------- update_options_file ----------------------------- # # NAME: update_options_file # # FUNCTION: # update the stanzas in the options file # The options file is a scratch pad to provide default values # for re-entry. It is not actually required. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function update_options_file { # does the options file exist ? if [[ ! -f ${OSA_OPTIONS} ]]; then log "\ ERROR: Could not locate the options file ${OSA_OPTIONS}\n" #exit 1 return 1 fi # keyword and new value are passed as parameters keyword=${1} new_value=${2} keyword_found=false # parse the options file - note that we will only update the lines with # specific keywords rm -f ${OSA_OPTIONS}.X >/dev/null 2>&1 # clear the new file exec 3< ${OSA_OPTIONS} while read -u3 option value rest do if [[ -n "${option}" ]] && [[ "${option}" != "#" ]] && [[ ${option} = ${keyword} ]]; then echo \ "# The next following line was updated by the oracle_sa script on $(date)" >>${OSA_OPTIONS}.X echo "# $option $value $rest" >>${OSA_OPTIONS}.X echo \ "# New value:" >>${OSA_OPTIONS}.X echo "$option $new_value " >>${OSA_OPTIONS}.X keyword_found=true else # write back out unchanged echo "$option $value $rest" >>${OSA_OPTIONS}.X fi done # all done, replace original with updated file cp -f ${OSA_OPTIONS}.X ${OSA_OPTIONS} # make sure we were effective if [[ $? -ne 0 ]] || [[ ${keyword_found} = false ]]; then cmd="/usr/bin/dspmsg -s 1 oracle_sa.cat 127 "Encountered a problem changing the value of \"%s\" in file\n\ %s. The file may not be useable by this assist\n" ${keyword} ${OSA_OPTIONS}" msg_out=$($cmd >> $RUN_LOG) fi return 0 } # end of update_options_file #---------------------------- get_node_names ----------------------------- # # NAME: get_node_names # # FUNCTION: # define the Global long and short primary and secondary node names. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- # ----------------------- get_node_names --------------------------- function get_node_names { [[ "$VERBOSE_LOGGING" = "high" ]] && set -x func_header get_node_names # Get the hostnames of the two nodes. # # ------------ PRIM and SECOND NODE --------------- # # # For the primary node, if the cluster is running, use the cluster # local nodename otherwise use the short hostname. # clstr_running=0 clstr_out=$(/usr/sbin/cluster/utilities/cllsclstr >>$RUN_LOG 2>&1) if [[ $? -eq 0 ]]; then clstr_running=1 hacmp_node_name=$(${TOOLS_DIR}/get_local_nodename) if [[ -n $hacmp_node_name ]]; then short_primary=$hacmp_node_name else short_primary=$(/usr/bin/hostname -s) fi else short_primary=$(/usr/bin/hostname -s) fi # msg_log "NO_CLEAR" 219 "Using %s for the short node name.\n" ${short_primary} PRIM_NODE=$short_primary update_options_file "PRIM_NODE" "${PRIM_NODE}" log "The Primary Node is ${PRIM_NODE}" # # For the secondary node, if the cluster is running, choose from the list # of node names, otherwise select blindly, and check that it is reachable. # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 130 "h = help, x = exit\n\nEnter the name of the Secondary Node: ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 131 "The two node cluster has a primary node and a secondary node.\n") test=0 while [[ $test -eq 0 ]]; do test=1 if [[ $clstr_running -eq 1 ]]; then list=$(${TOOLS_DIR}/clnodename |/usr/bin/grep -v ${short_primary}) prompt_list "$msg" "${list}" "$hlp" sec_node=${answer} short_second=$sec_node else prompt "$msg" "$SECOND_NODE" "" "$hlp" out=$(/usr/bin/host ${answer} >> $RUN_LOG 2>&1) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 9 "Unable to resolve %s. Please try again or type x to exit.\n" "$answer" >&2 test=0 else sec_node=$(/usr/bin/host ${answer} | /usr/bin/awk '{print $1}') short_second=$(echo $sec_node |/usr/bin/awk -F"." '{print $1}') fi fi done SECOND_NODE=$short_second update_options_file "SECOND_NODE" "${short_second}" log "The Secondary Node is $SECOND_NODE " return 0 } #---------------------------- ck_sizes -------------------------------- # # NAME: ck_sizes # # FUNCTION: # checks the size of various fileystems # and runs ck_sizes on the remote node # Creates the group dba, and the user oracle # # EXECUTION ENVIRONMENT: # runs on primary and with -r, the secondary node. # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # # RETURNS: (int) # 0 = pre-reqs satisfied # exit = failure # # OUTPUT: #------------------------------------------------------------------------------- function ck_sizes { # # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x # # dont return header in clear_screen when called remotely # if [[ ${REMOTE_ONLY} = "yes" ]]; then print "========= ck_sizes ===============" >> $RUN_LOG else func_header ck_sizes fi if [[ -n $VERBOSE ]]; then log " Running ck_sizes.\n" fi rc=0 #--------------- check AIX Swap, TMP and VAR Storage Requirements ------------- # # APAR_LIST # To check that certain APARS are installed, use instfix -ik "IYnnnnn IYnnnnn" # They should be installed outside the assist. # if [[ -n $APAR_LIST ]] && [[ $APAR_LIST != "NONE" ]]; then list="\"${APAR_LIST}\"" /usr/sbin/instfix -ik $list >> $RUN_LOG 2>&1 fi # # SWAP_SPACE # Oracle Swap Space requirement is 1536MB # if [[ -z $SWAP_SPACE ]] || [[ $SWAP_SPACE -lt 1536 ]]; then SWAP_SPACE=1536 fi req_blocks=$(( SWAP_SPACE * 256 )) set -A blocks $(swap -s) free_blocks=${blocks[10]} # # if there are enough free blocks, move on # if [[ $free_blocks -lt $req_blocks ]]; then # # we need more blocks # delta_blocks=$(( req_blocks - free_blocks )) # convert to MB delta_MB=$(( delta_blocks / 256 )) log "Free swap size is too small, $delta_MB MB, repairing...." # # get swap disks, there maybe more than one swap Logical Volume # set -A sw_lv $(/usr/sbin/swap -l | /usr/bin/tail +2 | /usr/bin/awk '{print $1}') list=${sw_lv[*]} # # see if we have a swap lv that is active...there is always one. # found=0 for name in $list ; do swap_lv=$(echo $name |sed "s/\/dev\///") active=$(/usr/sbin/lsps -a | /usr/bin/grep $swap_lv |/usr/bin/awk '{print $6}') if [[ $active == "yes" ]]; then found=1 break fi done if [[ $found -eq 1 ]]; then # # find PP size(4,32,..), we inc by factors of PP size. use at least 1 # swap_pp_size=$(/usr/sbin/lslv -L ${swap_lv} | /bin/grep -s SIZE | /bin/awk '{print $6}') if [[ $delta_MB -le $swap_pp_size ]]; then factor=1 else factor=$(( delta_MB / swap_pp_size )) let factor+=1 # chps rounds down fi # increase the swap space cmd="/usr/sbin/chps -s $factor $swap_lv" chps_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log 270 "Unable to increase the swap space size" fi log "$cmd \n returned $chps_out" else log "no active swap space found $list" fi fi set -A blocks $(swap -s) free_space=$(( ${blocks[10]} / 256 )) log "Free AIX Swap Space is $free_space MB" # # TMP_SPACE # Temp Space requirement is 400MB # # Oracle requires 400 MB tmp space,800,000 512byte blocks if [[ -z $TMP_SPACE ]] || [[ $TMP_SPACE -lt 400 ]]; then TMP_SPACE=400 fi tmp_space=$(( TMP_SPACE * 2000 )) tmp_size=$(/usr/bin/df /tmp | /bin/grep tmp | /bin/awk '{print $3}') if [[ $tmp_size -lt $tmp_space ]]; then log "Free tmp size is too small, $tmp_size, repairing...." delta=$(( tmp_space - tmp_size )) cmd="/usr/sbin/chfs -a size=+$delta /tmp" chfs_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log 271 "chfs failed for %s" "/tmp" fi log "$cmd \n returned $chfs_out" fi current_tmp_size=$(/usr/bin/df /tmp | /bin/grep tmp | /bin/awk '{print $3}') MB_size=$(/usr/bin/df -m /tmp | /bin/grep tmp | /bin/awk '{print $3}') log "Free AIX Temp Space in 512k blocks is $current_tmp_size, $MB_size MB" # # VAR_SPACE # Var Space requirement is 25MB for clverify # # clverify requires 25 MB var space,50,000 512byte blocks if [[ -z $VAR_SPACE ]] || [[ $VAR_SPACE -lt 25 ]]; then VAR_SPACE=25 fi var_space=$(( VAR_SPACE * 2000 )) var_size=$(/usr/bin/df /var | /bin/grep var | /bin/awk '{print $3}') if [[ $var_size -lt $var_space ]]; then log "Free var size is too small, $var_size, repairing...." delta=$(( var_space - var_size )) cmd="/usr/sbin/chfs -a size=+$delta /var" chfs_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log 271 "chfs failed for %s" "/var" fi log "$cmd \n returned $chfs_out" fi current_var_size=$(/usr/bin/df /var | /bin/grep var | /bin/awk '{print $3}') MB_size=$(/usr/bin/df -m /var | /bin/grep var | /bin/awk '{print $3}') log "Free AIX VAR Space in 512k blocks is $current_var_size, $MB_size MB" # # USR_SPACE # if [[ -z $USR_SPACE ]] || [[ $USR_SPACE -lt 2.5 ]]; then USR_SPACE=2.5 fi usr_space=$(( USR_SPACE * 2000 )) usr_size=$(/usr/bin/df /usr | /bin/grep usr | /bin/awk '{print $3}') if [[ $usr_size -lt $usr_space ]]; then log "Free usr size is too small, $usr_size, repairing...." delta=$(( usr_space - usr_size )) cmd="/usr/sbin/chfs -a size=+$delta /usr" chfs_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log 271 "chfs failed for %s" "/usr" fi log "$cmd \n returned $chfs_out" fi current_usr_size=$(/usr/bin/df /usr | /bin/grep usr | /bin/awk '{print $3}') MB_size=$(/usr/bin/df -m /usr | /bin/grep usr | /bin/awk '{print $3}') log "Free AIX USR Space in 512k blocks is $current_usr_size, $MB_size MB" # # # See if clcomdES is running. this is the cluster rsh/rcp replacement. # lssrc -s clcomdES >/dev/null 2>&1 if [[ $? -eq 0 ]]; then log "clcomdES is running" else log 5 "Error:clcomdES is not running\n" exit 1 fi # # Only run this code on the primary node # if [[ ${REMOTE_ONLY} != "yes" ]]; then #--------------- check JCE version --------------------------- # check for Java Cryptology Extension 1.2.2 is on system rc1=0 if [[ ! -s $JAVA_HOME/jce-1_2_2.zip ]]; then if [[ ! -s $ZIP_HOME/jce-1_2_2.zip ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 228 "h = help, x = exit\n\nEnter the location for the Java Cryptography Extension (JCE)") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 229 "jce-1_2_2.zip is required for the Oracle installation.\n\ This file is available on the Java Web Site.\n") prompt "$msg" "$ZIP_HOME" "" "$hlp" if [[ -n ${answer} ]]; then ZIP_HOME=${answer} update_options_file "ZIP_HOME" "${answer}" jce=$(ls $ZIP_HOME/jce-1_2_2.zip 2>/dev/null) rc1=$? else rc1=1 fi fi fi # insure that the zip file exists for the OUI. if [[ $rc1 -eq 0 ]]; then log "JCE version is $jce" else msg_log 6 "Unable to find the Java Cryptography Extension.\n\ This is required for the Oracle Installation. Place the jce-1_2_2.zip file\n\ in a location writable by the user performing the Installation.\n\ Continuing... \n" fi else # # only run on remote node # /usr/sbin/lsgroup dba >>$RUN_LOG 2>&1 /usr/sbin/lsuser oracle >>$RUN_LOG 2>&1 fi # log "LANG value is $LANG" mode=$(/usr/sbin/bootinfo -K) log "The machine is running in $mode mode" answer="" return 0 } # end of ck_sizes #---------------------------- config_basic_cluster --------------------------- # # NAME: config_basic_cluster # # FUNCTION: # checks for and configures a basic two node cluster # Now the clrsh is running, runs checks on the remote node. # # EXECUTION ENVIRONMENT: # smitty cm_config_nodes.add_dmn # cllsclstr # clmodclstr # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function config_basic_cluster { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=1 # config_basic_cluster # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 70 "This task will define the basic PowerHA SystemMirror cluster.\n") func_header config_basic_cluster if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 7 \ "This task will configure the basic HACMP cluster required \n\ prior to installing Oracle. \n\ Running config_basic_cluster, next_state=prompt_vg.\n" >&2 fi next_state=prompt_vg # # Check if the cluster is already defined and running # clstr_out=$(/usr/sbin/cluster/utilities/cllsclstr 2>&1) if [[ $? -eq 0 ]]; then log "cllsclstr returned 0\n ${clstr_out}\n cluster is defined." else log "cllsclstr returned non-zero, cluster is not defined." # # Configure the two node cluster # rc=0 answer="" msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 133 "You may configure the cluster automatically or by using SMIT.\n") /usr/bin/dspmsg -s 1 oracle_sa.cat 132 "This task will configure a basic two node cluster using \n %s and %s.\n" $PRIM_NODE $SECOND_NODE prompt "$msg" "a" "" "$hlp" if [[ $answer = "s" ]]; then smitty cm_config_nodes.add_dmn rc=$? log "smitty cm_config_nodes.add_dmn returned $rc" elif [[ $answer = "a" ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 134 "h = Help, x = exit\n\nWhat is the cluster name?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 1 oracle_sa.cat 135 "This default name will be used in creating the cluster.\n") prompt "$msg" "oracle_ias_cluster" "" "$hlp" /usr/bin/dspmsg -s 1 oracle_sa.cat 274 "Running %s, this may take a few minutes....\n" "cluster initialization" cmd="/usr/es/sbin/cluster/utilities/clmodclstr -n $answer -p $SECOND_NODE -p $PRIM_NODE" cmd_out=$($cmd 2>&1) rc=$? log "$cmd produced \n $cmd_out returned $rc" /usr/bin/odmget HACMPcluster >>$RUN_LOG 2>&1 if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 10 "Command executed: %s returned %s.\n" "$cmd" $rc fi if [[ $rc -ne 0 ]]; then next_state=config_basic_cluster fi else msg_log "NO_CLEAR" 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" next_state=config_basic_cluster return 0 fi # # Check that smit or the command completed successfully, # if not, check hacmp installed and clcomdES running on both nodes. # clstr_out=$(/usr/sbin/cluster/utilities/cllsclstr >>$RUN_LOG 2>&1) if [[ $? -ne 0 ]]; then msg_log 11 \ "The cluster is not defined on this system. Check that HACMP is installed \nand clcomdES running on both nodes, then try again.\n" >&2 next_state=config_basic_cluster return 0 fi fi # from first check for running cluster # #------------------------------------------------ # # # Sync the system to pass the node names around. # Always run sync for now for cli_mkvg # sync_flag=$(/usr/bin/odmget HACMPcluster | /usr/bin/grep -w "handle =" | /usr/bin/awk '{print $3}') #if [[ $sync_flag -eq 0 ]]; then /usr/bin/dspmsg -s 1 oracle_sa.cat 274 "Running %s, this may take a few minutes...\n" "sync" $TOOLS_DIR/cldare -C interactive -rt 2>&1 >> $RUN_LOG if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 273 "The sync operation failed. Correct and try again." exit 1 fi #fi /usr/bin/odmget HACMPcluster >> $RUN_LOG 2>&1 # # Now that the cluster is defined, clrsh will work and we can check the 2nd node # # # see if the hacmp name and the hostname are the same # hacmp_node_name=$(${TOOLS_DIR}/get_local_nodename) if [[ -z $hacmp_node_name ]]; then msg_log "NO_CLEAR" 218 "The get_local_nodename returned a null name for this cluster.\n" else if [[ $hacmp_node_name != $short_primary ]]; then short_primary=$hacmp_node_name msg_log "NO_CLEAR" 219 "Using %s for the short node name.\n" $hacmp_node_name fi fi rem_out=$($TOOLS_DIR/cl_rsh $short_second date 2>&1) if [[ $? -ne 0 ]]; then msg_log 238 "clrsh failed. Check that clcomdES running on both nodes.\nclcomdES starts after PowerHA SystemMirror is installed, and the nodes rebooted.\n" exit 1 fi # # insure that the assist is installed on the secondary node # run ck_sizes on the secondary node # cmd=$($TOOLS_DIR/cl_rsh $short_second lslpp -l cluster.es.assist.oracle 2>&1) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 220 "cluster.es.assist.oracle fileset not found on the remote node.\nThis fileset must be installed on both nodes.\n" log "oracle fileset not found on the $short_second remote node\n${cmd}" ck_ver_fail="yes" exit 1 fi cmd=$($TOOLS_DIR/cl_rsh $short_second ls $OSA_DIR/oracle_sa 2>&1) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 221 "oracle_sa not found on the remote node.\n" log "oracle_sa not found on the $short_second remote node\n${cmd}" ck_ver_fail="yes" exit 1 fi cmd=$($TOOLS_DIR/cl_rsh $short_second $OSA_DIR/oracle_sa -r 2>&1) if [[ $? -ne 0 ]]; then log "ck_sizes failed on ${short_second},\n${cmd}" msg_log "NO_CLEAR" 222 "oracle_sa ck_sizes failed on the remote node.\n" ck_ver_fail="yes" exit 1 fi # # Check for a group named dba and a user named oracle # rc_u=0 rc_g=0 /usr/sbin/lsgroup dba >/dev/null 2>&1 if [[ $? -eq 0 ]]; then /usr/sbin/lsuser oracle >/dev/null 2>&1 if [[ $? -eq 0 ]]; then log "The \"dba\" group and \"oracle\" user exist." else /usr/sbin/cluster/sbin/cl_mkuser pgrp=dba oracle rc_u=$? log "cl_mkuser oracle for group dba, returned $rc_u" fi else /usr/sbin/cluster/sbin/cl_mkgroup dba >>$RUN_LOG 2>&1 rc_g=$? log "cl_mkgroup dba, returned $rc_g" /usr/sbin/cluster/sbin/cl_mkuser pgrp=dba oracle >>$RUN_LOG 2>&1 rc_u=$? log "cl_mkuser oracle for group dba, returned $rc_u" fi if [[ $rc_u -ne 0 ]] || [[ $rc_g -ne 0 ]]; then msg_log "NO_CLEAR" 266 "There is a problem with the user oracle or group dba.\nCheck that the oracle uid and the dba gid are the same on both cluster nodes." exit 1 fi # # Confirm that the group & user id match on the primary & backup nodes. # user_out=$(/usr/sbin/cluster/sbin/cl_lsuser -a id oracle ) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 266 "There is a problem with the user oracle or group dba.\nCheck that the oracle uid and the dba gid are the same on both cluster nodes." log "cl_lsuser returned $user_out" exit 1 fi group_out=$(/usr/sbin/cluster/sbin/cl_lsgroup -a id dba ) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 266 "There is a problem with the user oracle or group dba.\nCheck that the oracle uid and the dba gid are the same on both cluster nodes." log "cl_lsgroup returned $group_out" exit 1 fi # for each node, form is : oracle id= echo $user_out |read -A uids echo $group_out |read -A gids log "oracle uid for ${uids[0]} is ${uids[2]}, ${uids[3]} ${uids[5]}, dba gid for ${gids[0]} is ${gids[2]}, ${gids[3]} ${gids[5]} on the cluster nodes." if [[ ${uids[2]} != ${uids[5]} ]] || [[ ${gids[2]} != ${gids[5]} ]]; then msg_log "NO_CLEAR" 266 "There is a problem with the user oracle or group dba.\nCheck that the oracle uid and the dba gid are the same on both cluster nodes." exit 1 fi return 0 } # end config_basic_cluster #---------------------------- define_private_network ----------------------- # # NAME: define_private_network # # FUNCTION: # Define Private Network for Oracle. # choice of discovered networks, with the service IP network removed. # # EXECUTION ENVIRONMENT: # smitty -v cm_change_show_a_network_in_the_hacmp_cluster_select # cllsnw # clmodnetwork # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function define_private_network { # # Oracle requires that a network be flagged as private. # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=7 # define_private_network # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 179 "Oracle requires one network to be defined as private.\n") func_header define_private_network if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 12 "Running define_private_network, next_state=define_service_IP_label \n\ \n Oracle requires one network to be defined as \"private\". \n\ This task will let you change a network.\n" fi next_state=verify_and_sync rc=0 answer="" /usr/es/sbin/cluster/utilities/cllsnw >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then nw_list="" nw_list=$(LC_ALL=C /usr/es/sbin/cluster/utilities/cllsnw -bc | /usr/bin/tail +2 |/usr/bin/awk -F":" '{print $1 ":" $2 ":" $5}'|/usr/bin/grep -sw private| /usr/bin/sed "s/ /:/g") if [[ -n $nw_list ]]; then # remove the SVC_NW from this list if [[ -n ${SVC_NW} ]]; then list="" for nw in $nw_list ; do tmp=$(echo $nw |awk -F":" '{print $1}') if [[ $SVC_NW != $tmp ]]; then list=$(echo ${list} "$nw") fi done else list=$nw_list fi if [[ -n ${list} ]]; then list=$(echo ${list} "[new_name]") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 235 "h = help, x = exit\n\nChoose an existing private network for oracle, or [new_name]") prompt_list "$quest" "${list}" "$TASK" if [[ ${answer} != "[new_name]" ]]; then # A private network exists, return log "User selected ${answer} from these Private Networks\n ${nw_list}" return 0 fi # new name fi # -n list fi # if private nw_list fi # if cllsnw # # Didnt find a private network, or there was an error # echo $nw_list >> $RUN_LOG echo $nw_list | /usr/bin/grep ERROR if [[ $? -eq 0 ]]; then # smit does discover in cm_extended_config_menu_dmn clver_out=$(/usr/es/sbin/cluster/diag/clver -Nv) msg_log "NO_CLEAR" 13 "Found an error in the network configuration. \n\ Ran Discover process with these results: \n %s. \n\ Correct errors, if necessary, and continue.\n" $clver_out >&2 next_state=define_private_network return 0 fi # # change one network to private. # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 136 "h = Help, x = exit\n\n\Oracle requires that one network is defined as \"private\".\n\ Do you wish to select the private network\nAutomatically (a) or using SMIT (s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 137 "Choose any network other than the service IP network.\n") prompt "$msg" "a" "" "$hlp" rc1=0 rc2=0 # ---------------------- smit --------------------------- if [[ $answer = "s" ]]; then smitty -v cm_change_show_a_network_in_the_hacmp_cluster_select rc1=$? # # check that there is a private network # ck_nw_list="" ck_nw_list=$(LC_ALL=C /usr/es/sbin/cluster/utilities/cllsnw -bc | /usr/bin/awk -F":" '{print $2}'|/usr/bin/grep -qsw private) if [[ $? -ne 0 ]]; then print "$TASK" msg_log "NO_CLEAR" 257 "A new private network was not created." next_state=define_private_network return 0 fi new_nw_list="" new_nw_list=$(LC_ALL=C /usr/es/sbin/cluster/utilities/cllsnw -bc | /usr/bin/tail +2 |/usr/bin/awk -F":" '{print $1 ":" $2 ":" $5}'|/usr/bin/grep -sw private | /usr/bin/sed "s/ /:/g") if [[ ${nw_list} = ${new_nw_list} ]]; then print "$TASK" msg_log 257 "NO_CLEAR" "A new private network was not created." next_state=define_private_network return 0 fi out=$(echo $new_nw_list | /usr/bin/grep -sw $SVC_NW) if [[ $? -ne 0 ]]; then print "$TASK" msg_log 269 "The Service IP network cannot be used for the private network, try again." next_state=define_private_network return 0 fi # ------------------- automatic ---------------------- elif [[ $answer = "a" ]]; then nw_list="" /usr/es/sbin/cluster/utilities/cllsnw -bc >> $RUN_LOG 2>&1 nw_list=$(/usr/es/sbin/cluster/utilities/cllsnw -bc |/usr/bin/tail +2 | /usr/bin/awk -F":" '{print $1 ":" $5}'| /usr/bin/sed "s/ /:/g") # remove the SVC_NW from this list if [[ -n ${SVC_NW} ]]; then list="" for nw in $nw_list ; do tmp=$(echo $nw |awk -F":" '{print $1}') if [[ $SVC_NW != $tmp ]]; then list=$(echo ${list} "$nw") fi done else list=$nw_list fi if [[ -z ${list} ]]; then msg_log "NO_CLEAR" 138 "There are no networks available to choose from,\n\ please correct and run again.\n" next_state=define_private_network return 0 fi msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 139 "h = help, x = exit\n\n\ Select a number which corresponds to the network\n\ you wish to designate as a private network. ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 258 "This is the name of the network on which the Service IP Label/Address will be bound.") prompt_list "$msg" "${list}" "$hlp" log "\nThe user chose ${answer} for the private network\n" nw=$(echo $answer |/usr/bin/awk -F":" '{print $1}') return_msg=$(/usr/es/sbin/cluster/utilities/clmodnetwork -m -t private -n ${nw}) rc2=$? log "clmodnetwork returned ${return_msg}" if [[ $rc1 -ne 0 ]] || [[ $rc2 -ne 0 ]]; then msg 101 "clmodnetwork -m -t private -n %s failed.\n\ The command to select a private network failed, try again.\n\ or enter \"x\" and remove the resource group with clrmres.\n" $answer log "clmodnetwork -m -t private -n ${answer} failed." next_state=define_private_network return 0 fi else msg 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" next_state=define_private_network return 0 fi return 0 } # end define_private_network #---------------------------- define_service_IP_label ----------------------- # # NAME: define_service_IP_label # # FUNCTION: # Define the Service IP to HACMP # # EXECUTION ENVIRONMENT: # smitty cm_add_service_ip.dialog # claddnode # cllsnw # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function define_service_IP_label { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=5 # define_service_IP_label # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 71 "This task helps you define the Service IP label.\n") func_header define_service_IP_label next_state=config_resource_group # # See if it is already defined ok # svc_ip_list="" svc_ip_list=$(${TOOLS_DIR}/cllsif -c 2>/dev/null |/usr/bin/grep -v serial |/usr/bin/grep -sw service |/usr/bin/awk -F":" '{print $1 ":" $3}' | /usr/bin/sort -u) if [[ -n ${svc_ip_list} ]]; then svc_list="" svc_list=$(echo ${svc_ip_list} "[new_label]") msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 232 "h = help, x = exit\n\n\ Oracle Applications connect to the Infrastructure Tier through the\n\ Virtual IP (VIP), which HACMP calls the Service IP.\n\ Select an address from this list. ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 263 "This is the IP Label/Address over which clients connect to the\n\ Infrastructure Tier. This is the IP Label/Address which is kept highly\n\ available by HACMP.") prompt_list "$msg" "$svc_list" "$hlp" if [[ ${answer} != "[new_label]" ]]; then label=$(echo $answer |awk -F":" '{print $1}') SVC_NW=$(echo $answer |awk -F":" '{print $2}') if [[ $label != ${SVC_IP_LABEL} ]]; then SVC_IP_LABEL=$label update_options_file "SVC_IP_LABEL" "${label}" fi return 0 fi # if new_label fi # examine existing labels # --------------- smit ----------------------- # # smit or auto to create service ip # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 142 "h = Help, x = exit \n\n\ Do you wish to enter the Service IP label \nAutomatically (a) or using SMIT (s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 143 "Automatic will prompt for the service IP Label/Address\n\ and one of the discovered networks.\n") # # Smit or Automatic # prompt "$msg" "a" "" "$hlp" if [[ $answer = "s" ]]; then smitty cm_add_service_ip.dialog if [[ $? -ne 0 ]]; then msg_log 15 "smitty cm_add_service_ip.dialog failed. \n\ Check the cluster and network configuration and try again.\n" >&2 next_state=define_service_IP_label return 0 fi svc_new_list="" svc_new_list=$(${TOOLS_DIR}/cllsif -c 2>/dev/null |/usr/bin/grep -v serial |/usr/bin/grep -sw service |/usr/bin/awk -F":" '{print $1 ":" $3}' | /usr/bin/sort -u) # # was a new label created. is the new list empty, is the old list empty # are the lists the same. # if [[ -z $svc_new_list ]]; then msg_log 242 "A new service IP label was not created." next_state=define_service_IP_label return 0 fi if [[ -z $svc_ip_list ]]; then return 0 fi if [[ $svc_ip_list = $svc_new_list ]]; then msg_log 242 "A new service IP label was not created." next_state=define_service_IP_label return 0 fi #----------- automatic ---------------------- elif [[ $answer = "a" ]]; then # # get the service IP name to use # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 140 "Oracle clients connect to the database using the Service IP Label/Address. \n What is the name of the Service IP Label?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 141 "This IP Label/Address can be configured in a resource group to make the\n\ IP address highly available across multiple nodes.\n") prompt "$msg" "${SVC_IP_LABEL}" "" "$hlp" if [[ -z $answer ]]; then msg_log 9 "Unable to resolve %s.\nPlease try again.\n" "NULL" next_state=define_service_IP_label return 0 fi SVC_IP_LABEL=$answer update_options_file "SVC_IP_LABEL" "${answer}" # # check that it is resolvable # /usr/bin/host $answer >>$RUN_LOG 2>&1 if [[ $? -ne 0 ]]; then msg_log 9 "Unable to resolve %s.\nPlease try again.\n" $answer next_state=define_service_IP_label return 0 fi # # get the name of the network # show the hacmp name and the network names. use ":" instead of space # nw_list="" nw_list=$(/usr/es/sbin/cluster/utilities/cllsnw -bc |/usr/bin/tail +2 | /usr/bin/awk -F":" '{print $1":"$5}'| /usr/bin/sed "s/ /:/g") if [[ -z ${nw_list} ]]; then msg_log 16 "There are no networks available to choose from,\n\ please correct and try again.\n" >&2 next_state=define_service_IP_label return 0 fi msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 231 "h = help, x = exit\n\n\ Select a number which corresponds to the network \n\ you wish to designate for the service IP label. ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 264 "This is the name of the network on which the IP Label/Address will be bound.") prompt_list "$msg" "$nw_list" "$hlp" log "\nThe user chose ${answer} for the service IP label\n" nw=$(echo $answer |/usr/bin/awk -F":" '{print $1}') # # Now add the service IP and the Network selection to the cluster # svc_addr=$(/usr/es/sbin/cluster/utilities/claddnode -T service -B $SVC_IP_LABEL -w $nw 2>&1) if [[ $? -ne 0 ]]; then log "claddnode returned \n $svc_addr" msg_log "NO_CLEAR" 17 "Defining the Service IP label failed,\n\ check the cluster and network configuration and try again." next_state=define_service_IP_label return 0 fi SVC_NW=$nw # dont use this address for a private network later... log "Service IP call to claddnode returned \n $svc_addr" else msg "NO_CLEAR" 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" next_state=define_service_IP_label return 0 fi return 0 } # End define_service_IP_label #---------------------------- config_resource_group ------------------- # # NAME: config_resource_group # # FUNCTION: # This is a 2 step process, create the group, then add the resources. # Configure a HACMP resource group with policies and node list. # Adds the VG, Service IP label, & App Server resources to the group # A function has been added to verify the SMIT path # # EXECUTION ENVIRONMENT: # cllsgrp # smitty config_resource_group.dialog.custom # claddgrp # smitty cm_change_show_resources_std_resource_group_menu_dmn.select # claddres # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function ck_rg { # # This code will check the resource group. # List the VG, FS, Service IP, App Server, and RG name. # Check that the VG is on shared disks. # Issue a warning if any are NULL. # rg=$1 log "function ck_rg is testing rg $rg" rc=0 first="" second="" third="" fourth="" last="" $TOOLS_DIR/clshowres -g $rg | while read first second third fourth last ; do IFS=" " if [ "$first" = "Volume" -a "$second" = "Groups" ]; then rg_vg=$third if [[ -n $third ]]; then log "Volume Group is $third" else /usr/bin/dspmsg -s 1 oracle_sa.cat 247 "There is no Volume Group in this Resource Group\n" let rc+=1 fi elif [ "$first" = "Filesystems" -a "$second" != "Consistency" -a "$second" != "Recovery" -a "$second" != "to" -a "$second" != "mounted" ]; then if [[ -n $second ]]; then log "Filesystems are $second $third $fourth" else /usr/bin/dspmsg -s 1 oracle_sa.cat 248 "There is no Filesystem in this Resource Group\n" let rc+=1 fi elif [ "$first" = "Service" -a "$second" = "IP" -a "$third" = "Label" ]; then if [[ -n $fourth ]]; then log "Service IP Label is $fourth" else /usr/bin/dspmsg -s 1 oracle_sa.cat 249 "There is no Service IP Label in this Resource Group\n" let rc+=1 fi elif [ "$first" = "Resource" -a "$second" = "Group" -a "$third" = "Name" ]; then if [[ -n $fourth ]]; then log "Resource Group Name $fourth" else /usr/bin/dspmsg -s 1 oracle_sa.cat 250 "There is no Resource Group in this Resource Group\n" let rc+=1 fi elif [ "$first" = "Participating" -a "$second" = "Node" -a "$third" = "Name(s)" ]; then if [ -n "$fourth" -a -n "$last" ]; then log "Participating Nodes are $fourth $last" else /usr/bin/dspmsg -s 1 oracle_sa.cat 251 "There are not two Nodes in this Resource Group\n" let rc+=1 fi elif [ "$first" = "Application" -a "$second" = "Servers" ]; then if [[ -n $third ]]; then log "Application Server is $third" else /usr/bin/dspmsg -s 1 oracle_sa.cat 252 "There is no Application Server in this Resource Group\n" let rc+=1 fi fi first="" second="" third="" fourth="" last="" done # # check that the volume group has PVs on both nodes # if [[ -n $rg_vg ]]; then rc1=1 rc2=1 /usr/sbin/lspv |grep -qsw $rg_vg 2>/dev/null if [[ $? -eq 0 ]]; then log "$rg_vg has PVs on primary\n" rc1=0 fi list=$(/usr/es/sbin/cluster/utilities/cl_rsh $short_second /usr/sbin/lspv 2> /dev/null) echo $list | grep -qsw $rg_vg if [[ $? -eq 0 ]]; then log "$rg_vg has PVs on secondary\n" rc2=0 fi if [[ $rc1 -eq 1 ]] || [[ $rc2 -eq 1 ]]; then msg_log "NO_CLEAR" 245 "The Volume Group has to be on shared disks. Try again.\n" return 1 fi fi if [[ $rc -ne 0 ]]; then msg_log "NO_CLEAR" 246 "The Resource Group was not configured properly, try again.\n" return 1 fi return 0 } # # -------- find_name_in_list ---------------- # function find_name_in_list { name=$1 list=$2 found=0 for item in $list ; do if [[ $name = $item ]]; then found=1 break fi done return $found } # ------------------------------------------- function config_resource_group { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=6 # config_resource_group # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 72 "This task helps define and configure the Resource Group\n") func_header config_resource_group if [[ -n $VERBOSE ]]; then ${TOOLS_DIR}/cllsclstr msg_log "NO_CLEAR" 18 "This task helps you configure resources into an PowerHA SystemMirror resource group.\n\ Running config_resource_group, next_state=define_private_network\n" >&2 fi next_state=define_private_network # # Is this task already accomplished? # # get config info ${TOOLS_DIR}/cllsclstr >>${RUN_LOG} 2>&1 # query the current resource groups list="" list=$(${TOOLS_DIR}/cllsgrp 2>/dev/null) if [[ -n ${list} ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 216 "Choose and existing resource group, if any, or [new_rg] to create a new group. ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 265 "The resource group contains the Volume Group, Filesystems, \n\ Application Server, the Service IP Label and policies that govern its\n\ startup, fallover and fallback behavior.") log "cllsgrp found this group $list" grp_list=$(echo ${list} "[new_rg]") prompt_list "$msg" "${grp_list}" "$hlp" if [[ ${answer} != "[new_rg]" ]]; then ck_rg $answer if [[ $? -ne 0 ]]; then quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 256 "Do you wish to remove the %s resource group" "$answer") if yes_no "" "$quest" "y" then log "Removing $answer" ${TOOLS_DIR}/clrmgrp -g $answer >>$RUN_LOG 2>&1 fi next_state=config_resource_group return 0 fi # # log resource info and store name and continue # ${TOOLS_DIR}/clshowres -g $answer>> $RUN_LOG 2>&1 APPRG=$answer update_options_file "APPRG" "$answer" next_state=define_private_network import_update_vg return 0 fi # chose existing group fi # there is an existing group # # create a resource group # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 145 "h = Help, x = exit\n\n\ This task helps you create the HACMP Resource Group. \n\ Do you wish to enter do this Automatically (a) or using SMIT (s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 146 "Automatic will use the default name.\n") # # smit or automatic # prompt "$msg" "a" "" "$hlp" # ======================= smit ======================== if [[ $answer = "s" ]]; then smitty config_resource_group.dialog.custom if [ $? -ne 0 ]; then # try again log "Creating the resource group with smit failed." next_state=config_resource_group return 0 fi # smit failed new_list="" new_list=$(${TOOLS_DIR}/cllsgrp 2>/dev/null) if [[ ${list} = ${new_list} ]]; then log "SMIT did not create a new RG, new_list= ${new_list}" next_state=config_resource_group return 0 fi # smit failed for rg in $new_list ; do find_name_in_list "$rg" "$list" found=$? if [[ $found -eq 0 ]]; then last_rg=$rg break fi done log "SMIT created resource group $last_rg" # ======================= automatic ======================= elif [[ $answer = "a" ]]; then find_name_in_list "$default_rg" "$list" found=$? if [[ $found -eq 1 ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 253 "The default oracle_ias_rg already exists, select a new resource group name") prompt "$msg" "" "" "" find_name_in_list "$answer" "$list" if [[ $? -eq 0 ]]; then default_rg=$answer else msg_log 255 "NO_CLEAR" "This name already exists, try again" next_state=config_resource_group return 0 fi else msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 254 "What name do you wish to use for the resource group") prompt "$msg" "$default_rg" "" "" find_name_in_list "$answer" "$list" if [[ $? -eq 0 ]]; then default_rg=$answer else msg_log "NO_CLEAR" 255 "This name already exists, try again" next_state=config_resource_group return 0 fi fi node_list="$short_primary $short_second" cmd="/usr/es/sbin/cluster/utilities/claddgrp -s ignore -g $default_rg -S OHN -O FNPN -B FBHPN -n $node_list" log "$cmd" addgrp_out=$(/usr/es/sbin/cluster/utilities/claddgrp -s ignore -g $default_rg -S OHN -O FNPN -B FBHPN -n "$node_list" 2>&1) if [ $? -ne 0 ]; then msg_log "NO_CLEAR" 19 "Creating the resource group with claddgrp failed. Try again." next_state=config_resource_group return 0 else msg_log "NO_CLEAR" 230 "Created the %s Resource Group.\n" "$default_rg" fi # cli failed else msg "NO_CLEAR" 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" next_state=config_resource_group return 0 fi # # add resources to the group # new_list="" new_list=$(${TOOLS_DIR}/cllsgrp 2>/dev/null) for rg in $new_list ; do find_name_in_list "rg" "$list" found=$? if [[ $found -eq 0 ]]; then last_rg=$rg break fi done log "The new resource group is $last_rg" msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 147 "h = Help, x = exit\n\n\ This task helps you include the resources in the HACMP Resource Group. \n\ Do you wish to enter do this Automatically (a) or using SMIT (s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 148 "Automatic will add the application server, service IP label and the shared volume group to the resource group.\n") # # smit or automatic # prompt "$msg" "a" "" "$hlp" # ------------------ smit -------------------- if [[ $answer = "s" ]]; then smitty cm_change_show_resources_std_resource_group_menu_dmn.select if [ $? -ne 0 ]; then # try again log "configuring the resource group with smit failed." next_state=config_resource_group return 0 fi # smit failed # # check the resource group created by smit. # ck_rg $last_rg if [[ $? -ne 0 ]]; then quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 256 "Do you wish to remove the %s resource group" "$last_rg") if yes_no "" "$quest" "y" then log "Removing $last_rg" ${TOOLS_DIR}/clrmgrp -g $last_rg >>$RUN_LOG 2>&1 fi next_state=config_resource_group return 0 fi # -------------- auto -------------------- elif [[ $answer = "a" ]]; then add_cmd="/usr/es/sbin/cluster/utilities/claddres -g $last_rg SERVICE_LABEL=$SVC_IP_LABEL APPLICATIONS=$APPSERV VG_AUTO_IMPORT=false VOLUME_GROUP=$APPVG FORCED_VARYON=false FILESYSTEM=$APPFS" log "$add_cmd" add_out=$($add_cmd >> $RUN_LOG 2>&1) if [ $? -ne 0 ]; then print "$add_out" msg_log "NO_CLEAR" 19 "Creating the resource group failed. Try again." next_state=config_resource_group return 0 fi # cli failed else msg "NO_CLEAR" 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" next_state=config_resource_group return 0 fi # # Log results and store rg name # ${TOOLS_DIR}/clshowres -g $last_rg>> $RUN_LOG 2>&1 APPRG=$last_rg update_options_file "APPRG" "$last_rg" import_update_vg return 0 } # end config_resource_group #---------- import_update_vg ----------------------------- function import_update_vg { # # if the VG has been imported on the secondary node, then update it # otherwise, import it # sec_out=$($TOOLS_DIR/cl_rsh $short_second /usr/sbin/lsvg) log "These are the volume groups on the remote node $sec_out" echo $sec_out |/usr/bin/grep -qsw $APPVG if [[ $? -eq 0 ]]; then out=$(/usr/es/sbin/cluster/cspoc/cli_updatevg ${APPVG} 2>&1) rc=$? log "cli_updatevg returned $rc, $out" else PVLIST=$(/usr/sbin/lspv |/usr/bin/grep -ws ${APPVG} |/usr/bin/awk '{print $1}') out=$(/usr/es/sbin/cluster/cspoc/cli_importvg -y ${APPVG} ${PVLIST} 2>&1) rc=$? log "cli_importvg returned $rc, $out" fi return 0 } #---------------------------- verify_and_sync --------------------------- # # NAME: verify_and_sync # # FUNCTION: # Verify and Syncronize the HACMP Cluster # Uses the interactive correct mode # # EXECUTION ENVIRONMENT: # cl_clstop # clstrmgrES # cl_rsh # smitty cm_ver_and_sync.select # cldare # odmget HACMPcluster # smitty hacmp_testtool_auto_extended # cl_testtool_auto # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function verify_and_sync { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=8 # verify_and_sync # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 73 "This task will verify and synchronize the PowerHA SystemMirror cluster.\n") func_header verify_and_sync if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 20 "Running verify_and_sync, next_state=start_wo_oracle\n" >&2 fi next_state=start_wo_oracle # # There are no circumstances where the cluster should be running. verify.. # /usr/bin/lssrc -s clstrmgrES >> $RUN_LOG cmd_out=$($TOOLS_DIR/cl_rsh $short_second /usr/bin/lssrc -s clstrmgrES) echo $cmd_out >> $RUN_LOG # # verify and sync # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 149 "h = Help, x = exit\n\n\ This task will verify and synchronize the HACMP cluster. \n\ Verify and Synchronize automatically(a) or use smit(s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 150 "This step will verify the configuration and \"auto-correct\" problems.\n") prompt "$msg" "a" "" "$hlp" rc1=0 rc2=0 # # smit or automatic # if [[ $answer = "s" ]]; then smitty cm_ver_and_sync.select log "smitty cm_ver_and_sync.select returned $rc1" rc1=$? elif [[ $answer = "a" ]]; then ${TOOLS_DIR}/cldare -C interactive -rt rc2=$? log "${TOOLS_DIR}/cldare -C interactive -rt returned $rc2" else msg "NO_CLEAR" 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" next_state=verify_and_sync return 0 fi # # make sure that the verify passed and the sync worked. # odm_out=$(/usr/bin/odmget HACMPcluster | /usr/bin/grep -w "handle =" | /usr/bin/awk '{print $3}') log "The HACMPcluster handle returned ${odm_out}, 0=not synched,rc1= $rc1 rc2= $rc2" if [[ $rc1 -ne 0 ]] || [[ $rc2 -ne 0 ]] || [[ $odm_out -eq 0 ]]; then msg_log "NO_CLEAR" 22 "Check the cluster configuration and logs, and correct any problems.\n" >&2 msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 207 "The verification step failed. ") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 208 "Do you wish to try again ") if yes_no "$msg" "$quest" "y" then next_state=verify_and_sync return 0 else next_state=verify_and_sync exit 1 fi fi msg_log "NO_CLEAR" 223 "Completed the Cluster verify and sync task.\n" # # Ask to run the hacmp test tool to demonstrate the cluster operation. # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 151 "h = Help, x = exit\n\n\ This optional task will test that the cluster is operational. \n\ The test may take more than 30 minutes to complete. \n\ Instead, you may prefer to run this after Oracle is installed. \n\ Test automatically(a) or use smit(s) or not now(n)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 152 "This task will test the PowerHA SystemMirror cluster configuration by emulating \n\ events and falling over to the secondary node, and fallback to the primary node.\n") # # smit or automatic # clear_screen prompt "$msg" "n" "" "$hlp" rc1=0 rc2=0 if [[ $answer = "s" ]]; then smitty hacmp_testtool_auto_extended rc1=$? log "smitty hacmp_testtool_auto_extended returned $rc1" elif [[ $answer = "a" ]]; then /usr/es/sbin/cluster/cl_testtool/cl_testtool_auto rc2=$? log "/usr/es/sbin/cluster/cl_testtool/cl_testtool_auto returned $rc2" elif [[ $answer = "n" ]]; then return 0 else msg "NO_CLEAR" 102 "You may run the test at any time using smitty hacmp_testtool_auto_extended\n" return 0 # dont really want to start verify and sync over... fi return 0 } # End verify_and_sync #---------------------------- start_wo_oracle --------------------------- # # NAME: start_wo_oracle # # FUNCTION: # Start Cluster Services prior to Oracle Installation # # EXECUTION ENVIRONMENT: # smitty clstart # cl_rc.cluster # rc.cluster # lssrc # cl_rsh # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function start_wo_oracle { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=9 # start_wo_oracle # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 74 "This task will start PowerHA SystemMirror cluster services.\n") func_header start_wo_oracle if [[ -n $VERBOSE ]]; then msg_log 23 "Running start_wo_oracle, next_state=inst_oracle\n" fi next_state=inst_oracle # rc1=0 rc2=0 rc3=0 # # start the cluster # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 153 "h = help, x = exit \n\n\ This task will start HACMP cluster services which makes \n\ the cluster ready for Oracle installation. \n\ This may take a few minutes to run. \n\ Start HACMP Cluster automatically(a) or use smit(s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 154 "This step will start the PowerHA SystemMirror cluster services.\n") # # smit or automatic # prompt "$msg" "a" "" "$hlp" if [[ $answer = "s" ]]; then smitty clstart rc1=$? log "smitty clstart returned $rc" elif [[ $answer = "a" ]]; then # # note from the smit log, that rc.cluster is run on the remote node # then on the local node. it runs clstart: called with flags -smG -i # smit runs this command. # _SPOC_FORCE=Y /usr/es/sbin/cluster/cspoc/fix_args nop cl_rc.cluster '-N' -cspoc -n 'ppstest7,ppstest8' #cmd_out=$(${TOOLS_DIR}/cl_rc.cluster -boot -N -i 2>&1) # # The cl_rc.cluster does not work as expected, use this strategy # run rc.cluster on remote node, then primary # print "Running rc.cluster on $short_second" cmd_out=$(${TOOLS_DIR}/cl_rsh $short_second /usr/es/sbin/cluster/etc/rc.cluster -boot -N -i 2>&1) rc2=$? log "rc.cluster on the remote node returned \n ${cmd_out}" print "Running rc.cluster on $short_primary" cmd_returned=$(/usr/es/sbin/cluster/etc/rc.cluster -boot -N -i 2>&1) let rc2+=$? log "/usr/es/sbin/cluster/etc/rc.cluster -boot -N -i returned $rc2 \n ${cmd_returned}" fi # return 0 } # end start_wo_oracle #---------------------------- config_app_server ----------------------- # # NAME: config_app_server # # FUNCTION: # Configure the Application Server # A name is attached to the start&stop scripts that are shipped # with the assist. Ask user to verify that the ORACLE_HOME has # the name to be used during the oracle installation (OUI) # # EXECUTION ENVIRONMENT: # claddserv # cllsserv # smitty claddserv.dialog # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function config_app_server { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=4 # config_app_server # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 75 "This task will define the Infrastructure Tier Application.\n") func_header config_app_server if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 24 "Running config_app_server, next_state=define_service_IP_label\n" >&2 fi next_state=define_service_IP_label # # Is there a server with start and stop scripts already defined? # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 239 "Choose an existing Application Server, or [new_name]\n to create a new application server.") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 272 "\ Applications are managed by defining the application to HACMP as an \n\ application server resource. The application server includes the application\n\ start and stop scripts. HACMP uses these scripts when the application needs\n\ to be brought online or offline on a particular node, to keep the application\n\ highly available.") serv_list=$(/usr/es/sbin/cluster/utilities/cllsserv -c 2>&1) if [[ $? -eq 0 ]]; then # # list existing servers and new_name. # return if an existing server is chosen # list=$(echo ${serv_list} "[new_name]") prompt_list "$msg" "${list}" "$hlp" if [[ ${answer} != "[new_name]" ]]; then serv_name=$(echo $answer |/usr/bin/awk -F ":" '{print $1}') if [[ $serv_name != ${APPSERV} ]]; then APPSERV=$serv_name update_options_file "APPSERV" "${serv_name}" fi log "User selected from cllsserv found server ${serv_name}" return 0 fi fi #--------- none exist, or chose new_name --------------------------------- # # Get the name of the cluster and group names # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 158 "h = help, x = exit \n\n\ Add the oracle server to the cluster \nAutomatically(a) or use Smit(s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 159 "This step will add the server name, start script and stop script \nto the cluster.\n") prompt "$msg" "a" "" "$hlp" if [[ $answer = "s" ]]; then # ----------- smit path ------------------- smitty claddserv.dialog if [[ $? -ne 0 ]]; then msg_log 27 "This failed, correct and try again.\n" >&2 next_state=config_app_server return 0 fi # verify that smit actually created an appserver new_serv_list="" new_serv_list=$(/usr/es/sbin/cluster/utilities/cllsserv -c 2>&1) if [[ -z $new_serv_list ]]; then msg_log 240 "No new Application Server found, try again." next_state=config_app_server return 0 fi if [[ $serv_list = $new_serv_list ]]; then msg_log 240 "No new Application Server found, try again." next_state=config_app_server return 0 fi # a new app server was created. verify the selection and the scripts. for serv in $serv_list ; do last_name=$serv done msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 176 "This server was located, is it correct\n") if yes_no "$msg" "${last_name}" "y" then serv_name=$(echo $last_name |/usr/bin/awk -F ":" '{print $1}') if [[ $last_name != ${APPSERV} ]]; then APPSERV=$last_name update_options_file "APPSERV" "${last_name}" fi else next_state=config_app_server return 0 fi #------------ automatic path ----------------------- elif [[ $answer = "a" ]]; then # # Find the start and stop scripts # if [[ ! -s ${ORACLE_SCRIPTS}/infra_start ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 156 "What is the location of the infra_start and infra_stop script ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 157 "The infra_start and infra_stop scripts are shipped \n\ with the Oracle Smart Assist.\n") prompt "$msg" "${ORACLE_SCRIPTS}" "" "$hlp" ORACLE_SCRIPTS=${answer} update_options_file "ORACLE_SCRIPTS" "${answer}" log "The Oracle start and stop scripts are in ${answer}" fi if [[ ! -s ${ORACLE_SCRIPTS}/infra_start ]]; then msg_log 25 "Unable to find %s/infra_start.\n" ${ORACLE_SCRIPTS} >&2 next_state=config_app_server return 0 fi if [[ ! -s ${ORACLE_SCRIPTS}/infra_stop ]]; then msg_log 26 "Unable to find %s/infra_stop.\n" ${ORACLE_SCRIPTS} >&2 next_state=config_app_server return 0 fi # # Ask for the app server name # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 226 "What name do you wish to use for the Application Server ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 227 "Select a name for the Application Server that PowerHA SystemMirror will place\n\ in the Resource Group.\n") prompt "$msg" "${oracle_server}" "" "$hlp" new_name=${answer} # # check if this already exists. # $TOOLS_DIR/cllsserv >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then $TOOLS_DIR/cllsserv |/usr/bin/awk '{print $1}' |/usr/bin/grep -qsw $new_name if [[ $? -eq 0 ]]; then msg_log 241 "This Application Server already exists, try again." next_state=config_app_server return 0 fi # claddserv fail fi # there is no app server # # create new app server # cmd="/usr/es/sbin/cluster/utilities/claddserv -s $new_name -b $ORACLE_SCRIPTS/infra_start -e $ORACLE_SCRIPTS/infra_stop" cmd_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 28 "Creating an application server failed, correct and try again." log "$cmd returned \n $cmd_out" next_state=config_app_server return 0 fi #claddserv fail else next_state=config_app_server msg "NO_CLEAR" 100 "Choose automatically(a) or smit(s) or help(h) or exit(x)?" return 0 fi # # make sure that the app server is defined ok. # $TOOLS_DIR/cllsserv | /usr/bin/awk '{print $1}'|/usr/bin/grep -qsw $new_name if [[ $? -eq 0 ]]; then if [[ $new_name != ${APPSERV} ]]; then APPSERV=$new_name update_options_file "APPSERV" "${new_name}" fi else serv_out=$(/usr/es/sbin/cluster/utilities/cllsserv 2>&1) rc=$? log "cllsserv returned $rc with \n ${serv_out} " msg_log 27 "This failed, correct and try again.\n" next_state=config_app_server return 0 fi msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 214 "The infra_start and infra_stop scripts point to\n\ startias904infra.sh and stopias904infra.sh in the same directory. You are \n\ responsible to edit these ias904 scripts and enter the correct \n\ ORACLE_HOME directory. \nIf you are unsure, you can correct this after\n\ Oracle is installed.\n") prompt_edit "$msg" "startias904infra.sh" "" "$ORACLE_SCRIPTS/startias904infra.sh" prompt_edit "$msg" "stopias904infra.sh" "" "$ORACLE_SCRIPTS/stopias904infra.sh" return 0 } # end config_app_server #---------------------------- inst_oracle --------------------------- # # NAME: inst_oracle # # FUNCTION: # Oracle Installation and Configuration # runs oracles rootpre.sh pgm as root. # Starts oracle OUI installer as user oracle. # #EXECUTION ENVIRONMENT: # lsgroup # lsuser # mkuser # mkgroup # netstat # rootpre # cl_rsh # cl_rcp # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function inst_oracle { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=10 # inst_oracle # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 76 "This task will help you install and configure Oracle.\n") func_header inst_oracle if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 29 "Running inst_oracle, next_state=cleanup_and_finish\n" >&2 fi next_state=cleanup_and_finish msg_log 30 "This task will help you install and configure Oracle. \n\ Have the Oracle installation media available or mounted.\n\ After the installation, the infrastucture tier can be started by\n\ restarting the cluster from the smitty cl_cm_startstop_menu panel." # # set the DISPLAY for the OUI # screen_name=$(echo $DISPLAY) if [[ -z $screen_name ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 160 "h = Help, x = exit\n\n\ Please enter the DISPLAY variable. ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 161 "The DISPLAY variable is used by the oracle GUI.\n") prompt "$msg" "$screen_name" "" "$hlp" export DISPLAY=$answer log "The display variable is $DISPLAY" fi # # Check for port availability # oracle_port=$(/usr/bin/netstat -an | /usr/bin/grep 1521) if [[ $? -eq 0 ]]; then msg_log 275 "The 1521 port is in use, see the \n\ Oracle Application Server Installation Guide for this topic.\n" >&2 fi # # Execute the rootpre.sh on each cluster node # if [[ ! -s $ORACLE_INSTALL/rootpre.sh ]]; then msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 163 "What is the location of the rootpre.sh program ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 164 "The rootpre.sh program is part of the Oracle Distribution.\n") prompt "$msg" "$ORACLE_INSTALL" "" "$hlp" ls $answer/rootpre.sh >>$RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then export ORACLE_INSTALL=${answer} update_options_file "ORACLE_INSTALL" "${answer}" log "The Oracle Install programs are in ${answer}" else msg_log "NO_CLEAR" 32 "Unable to find rootpre.sh in this location, try again?\n" >&2 next_state=inst_oracle return 0 fi fi $ORACLE_INSTALL/rootpre.sh if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 33 "%s/rootpre.sh failed on %s \n\ run rootpre.sh as root, and continue.\n" $ORACLE_INSTALL $PRIM_NODE >&2 else msg_log "NO_CLEAR" 34 "rootpre.sh ran ok as root on the primary node.\n" >&2 fi # # cl_rsh will only use the short hostname # $TOOLS_DIR/cl_rsh $short_second $ORACLE_INSTALL/rootpre.sh if [[ $? -ne 0 ]]; then # maybe rootpre.sh is not in that location on remote node $TOOLS_DIR/cl_rcp $ORACLE_INSTALL/rootpre.sh ${short_second}:/tmp/rootpre.sh $TOOLS_DIR/cl_rsh $short_second /usr/bin/chmod +x /tmp/rootpre.sh $TOOLS_DIR/cl_rsh $short_second . /tmp/rootpre.sh if [[ $? -ne 0 ]]; then msg_log 35 "rootpre.sh failed on the secondary node. \n\ run rootpre.sh as root on the secondary node, and continue.\n" >&2 else msg_log "NO_CLEAR" 36 "rootpre.sh ran ok as root on the secondary node.\n" >&2 fi else msg_log "NO_CLEAR" 36 "rootpre.sh ran ok as root on secondary node.\n" >&2 fi # # Invode the OUI as user oracle, not root # if [[ -n $VERBOSE ]]; then msg_log 37 "Running runInstaller as user \"oracle\".\n" >&2 fi log Running "/usr/bin/su oracle $ORACLE_INSTALL/runInstaller -ignoreSysPrereqs" /usr/bin/su oracle $ORACLE_INSTALL/runInstaller -ignoreSysPrereqs if [[ $rc -ne 0 ]]; then msg_log "NO_CLEAR" 38 "Oracle runInstaller returned %s.\n" $rc >&2 next_state=inst_oracle return 0 fi } #---------------------------- cleanup_and_finish ----------------------------- # # NAME: cleanup_and_finish # # FUNCTION: # end program gracefully # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function cleanup_and_finish { # # Finished # TASK= task= #func_header cleanup_and_finish # # dont show these if we had a bad fall. # if [[ -n ${ck_ver_fail} ]] || [[ -n ${REMOTE_ONLY} ]] || [[ -n ${BAD_ARGS} ]]; then ${TOOLS_DIR}/cllsclstr >> ${RUN_LOG} 2>&1 ${TOOLS_DIR}/cllsserv >> ${RUN_LOG} 2>&1 ${TOOLS_DIR}/cllsres >> ${RUN_LOG} 2>&1 if [[ -n $VERBOSE ]]; then func_header "This is the Cluster" ${TOOLS_DIR}/cllsclstr func_header "This is the Application Server" ${TOOLS_DIR}/cllsserv func_header "This is the Resource Group" ${TOOLS_DIR}/cllsgrp func_header "These are the Resources" group_out=${TOOLS_DIR}/cllsgrp ${TOOLS_DIR}/cllsres -g $group_out fi /usr/bin/dspmsg -s 1 oracle_sa.cat 178 "\nAdditional details for this session may be found in \n %s\n\ This completes the HACMP section of the Oracle Smart Assist.\n\ The Oracle Universal Installer (OUI) will complete the Oracle section.\n\ Please send comments to HACMP at hafeedback@us.ibm.com.\n" $RUN_LOG fi return 0 } function complete_pgm { print " " # END OF PROGRAM } #---------------------------- prompt_vg -------------------------------- # # NAME: prompt_vg # # FUNCTION: # prompts for the volume group for use by the assist # removes VGs that contain the word root in their name. # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function prompt_vg { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=2 # prompt_vg # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 77 "This task will select a Shared Volume Group name.\n") func_header prompt_vg if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 39 "running prompt_vg next_state=validate_vg\n" >&2 fi next_state=validate_vg # # provide a list of existing VGs and an optional new name # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 165 "Select the shared volume group that will be used. ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 166 "Select a number which corresponds to the volume group you wish to use.\n Selecting [new_name] will create a new volume group\n") # # The pvids for each vg must be on both nodes. # prim_vg_list=$(/usr/sbin/lsvg |/usr/bin/grep -v root) sec_pvid_list=$(/usr/es/sbin/cluster/utilities/cl_rsh $short_second /usr/sbin/lspv | /usr/bin/awk '{print $2}') pick_list="" for vg in $prim_vg_list ; do prim_vg_pvid=$(/usr/sbin/lspv |/usr/bin/grep -sw $vg |/usr/bin/awk '{print $2}') not_found=0 for pvid in $prim_vg_pvid ; do out=$(echo $sec_pvid_list |/usr/bin/grep -qsw $pvid) if [[ $? -ne 0 ]]; then not_found=1 fi done if [[ $not_found -eq 0 ]]; then pick_list=$(echo ${pick_list} $vg) fi done if [[ -z $pick_list ]]; then answer="[new_name]" else # add new_name to the list list="" list=$(echo ${pick_list} "[new_name]") prompt_list "$msg" "${list}" "$hlp" fi if [[ $answer != $APPVG ]]; then APPVG=$answer update_options_file "APPVG" "${answer}" fi return 0 } # end of function prompt_vg #---------------------------- validate_vg -------------------------------- # # NAME: validate_vg # # FUNCTION: # validates the volume group used by the assist # Checks an existing vg or # uses cli_mkvg to create a vg with PVs that are free on both nodes. # # EXECUTION ENVIRONMENT: # smitty cl_createvg # clvaryonvg # lsvg # lspv # cli_mkvg # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function validate_vg { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=2 # validate_vg # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 78 "This task will check the Shared Volume Group.\n") func_header validate_vg if [[ -n $VERBOSE ]]; then msg_log 40 "Running validate_vg.\nChecking for volume group ${APPVG} ...\n" "${APPVG}" fi next_state=prompt_fs log "Checking for volume group ${APPVG} ...\n" if [[ ${APPVG} = "[new_name]" ]]; then exists=1 # doesnt exist else /usr/sbin/lsvg | /usr/bin/grep -qsw ${APPVG} exists=$? /usr/sbin/lsvg >> $RUN_LOG 2>&1 fi # ---------------------------------------------- # Check for an existing VG, offer to vary it on. # if [[ $exists -eq 0 ]]; then # found # # verify that the VG is shared, it has assigned PV on the backup node. # check for the name first, if that fails, check for pvids # out=$(${TOOLS_DIR}/cl_rsh $short_second /usr/sbin/lspv |/usr/bin/grep -qsw ${APPVG}) if [[ $? -ne 0 ]]; then # # The pvids for each vg must be on both nodes. # sec_pvid_list=$(/usr/es/sbin/cluster/utilities/cl_rsh $short_second /usr/sbin/lspv | /usr/bin/awk '{print $2}') prim_vg_pvid=$(/usr/sbin/lspv |/usr/bin/grep -sw $APPVG |/usr/bin/awk '{print $2}') not_found=0 for pvid in $prim_vg_pvid ; do out=$(echo $sec_pvid_list |/usr/bin/grep -qsw $pvid) if [[ $? -ne 0 ]]; then not_found=1 fi done if [[ $not_found -eq 1 ]]; then msg_log 268 "This Volume Group is not on a shared disk, try again." next_state=prompt_vg return 0 fi fi # pvid check # see if it is varied on varied_on=$(lsvg -o | grep -qsw ${APPVG}) if [[ $? -ne 0 ]]; then # not varied on out=$(/usr/es/sbin/cluster/utilities/clvaryonvg ${APPVG} 2>&1) if [[ $? -eq 0 ]]; then # varied on ok return 0 else log "clvaryon returned $out" # # the cluster work will be completed in import_update_vg # out=$(/usr/sbin/varyonvg ${APPVG} 2>&1) if [[ $? -eq 0 ]]; then # varied on ok return 0 else log "clvaryon returned $out" # can not continue without the vg being varied on. msg_log 41 "A problem occurred while trying to vary on the volume group.\n" next_state=prompt_vg return 0 fi fi # varyonvg rc else # # special processing for aix5.3 and IY71500 not installed # A climportvg -L failure has left the VG in the read-only state # perms_ck if [[ $? -ne 0 ]]; then next_state=prompt_vg return 0 fi fi # not varied on return 0 fi # # end of found vg processing # log "Volume group \"${APPVG}\" not found\n" # ----------------------------------------- # for aix 5.3, IY71500 has to be installed for cli_mkvg to work correctly # mkvg_rc will be used to check the cli_mkvg rc for both smit and auto # set -A level $(/usr/bin/oslevel | sed "s/\./ /g") # convert 5.3.0.0 to 5 3 0 0 out=$(/usr/sbin/instfix -ik IY71500 2>&1) rc=$? if (( (${level[0]} == 5) && (${level[1]} == 3) && ($rc != 0 ) )); then mkvg_rc=1 log "cli_mkvg will always return 1, oslevel is ${level[*]}\n$out" else mkvg_rc=0 # expect normal cli_mkvg return codes fi # ---------------------------------------- msg_log "NO_CLEAR" 42 "This task will configure a shared volume group.\n" >&2 rc=0 answer="" msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 189 "h = Help, x = exit \n\n\ Do you wish to create the shared volume group\n Automatically (a) or using SMIT (s)?") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 190 "The volume group will be on the shared disk. It will be used by oracle for the Infrastructure Tier.\n") prompt "$msg" "a" "" "$hlp" # ------------------ smit processing ------------------------ if [[ $answer = "s" ]]; then vg_list=$(/usr/sbin/lsvg) smitty cl_createvg rc=$? if (( ($rc != 0) && ($mkvg_rc == 0) )); then # valid cli_mkvg failure msg_log "NO_CLEAR" 43 "SMIT for cl_createvg was not successful, try again.\n" >&2 next_state=prompt_vg return 0 fi # cl_createvg rc # see if we have a new vg name new_vg_list=$(/usr/sbin/lsvg) if [[ $vg_list = $new_vg_list ]]; then msg_log "NO_CLEAR" 224 "No new Volume Group was found. Try again.\n" next_state=prompt_vg return 0 fi for vg in $new_vg_list ; do find_name_in_list "$vg" "$vg_list" found=$? if [[ $found -eq 0 ]]; then lastname=$vg break fi done # make sure its the right name. msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 225 "You have selected %s Shared Volume Group.\n" "${lastname}") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 201 "Is this correct\n") yes_no "$msg " "$quest" "y" if [[ $? -ne 0 ]]; then next_state=prompt_vg return 0 fi APPVG=$lastname log "The smit panel for cl_createvg returned $rc (success),\n\ new vg name is $lastname." update_options_file "APPVG" "${lastname}" next_state=prompt_fs # # aix5.3 without IY71500 # A climportvg -L failure may have left the VG in the read-only state # varied_on=$(lsvg -o | grep -sqw ${APPVG}) rc=$? if (( ($rc == 0) && ($mkvg_rc == 1) )); then perms_ck if [[ $? -ne 0 ]]; then next_state=prompt_vg return 0 fi fi # varied on with aix5.3 and IY71500 not installed # --------------------------------- varied_on=$(lsvg -o | grep -sqw ${APPVG}) if [[ $? -eq 0 ]]; then # varied on return 0 else $(/usr/es/sbin/cluster/utilities/clvaryonvg ${APPVG} >>${RUN_LOG}) if [[ $? -eq 0 ]]; then # varied on ok return 0 else msg_log 41 "A problem occurred while trying to vary on the volume group.\n" next_state=prompt_vg return 0 fi # varyonvg rc fi # is it varied on # ---------------------- auto processing --------------------------- # auto path # elif [[ $answer = "a" ]]; then # # Ask for the volume group name and pv(s), convert to pvid(s) # The user choose [new-name] from the picklist, use ora_vg for default # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 193 "What name do you wish to use for the Shared Volume Group ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 194 "Select a name for the shared volume group to be used to hold the oracle data.\n") prompt "$msg" "ora_vg" "" "$hlp" exists=$(lsvg | grep -qsw ${answer}) if [[ $? -eq 0 ]]; then # found msg_log "NO_CLEAR" 59 "This volume group is already defined. Select again.\n" >&2 next_state=prompt_vg return 0 fi #exists rc # # A new name has been selected, now select the pv(s) # APPVG=$answer update_options_file "APPVG" "${answer}" log "The user wants to create a shared vg named ${answer}" # # cli_mkvg uses the short hostname # # get a list of free PVs on each node, and # generate a list of those whose pvids are on each # pv_list="" pv_list=$(/usr/sbin/lspv |/usr/bin/grep -ws "None" |/usr/bin/awk '{print $1}') sec_pvid_list="" sec_pvid_list=$(${TOOLS_DIR}/cl_rsh $short_second /usr/sbin/lspv |/usr/bin/grep -ws "None"|/usr/bin/awk '{print $2}') cl_list="" for disk in $pv_list do pvid_disk=$(/usr/sbin/lspv |/usr/bin/grep -ws $disk|/usr/bin/awk '{print $2}') echo $sec_pvid_list | /usr/bin/grep -ws $pvid_disk >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then cl_list=$(echo ${cl_list} $disk) fi done log "These unused physical volumes were found. ${cl_list}" msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 209 "Select two Physical Volumes from the list for the Shared Volume Group\n if you plan to follow the Oracle recomendation of separating Data from Commands.") msg "$msg" quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 195 "Select Physical Volumes for the Shared Volume Group.\n") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 196 "Select Physical Volumes from this list, one at a time.\n\ These Physical Volumes will make up the Shared Volume Group.\n") prompt_multiple "$quest" "${cl_list}" "$hlp" selected_pv_list=${answer} log "These unused physical volumes have been selected ${selected_pv_list}" print "${selected_pv_list}" msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 200 "You have selected %s physical volumes to make up the %s\nShared Volume Group.\n" "${selected_pv_list}" "${APPVG}") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 201 "Is this correct\n") yes_no "$msg " "$quest" "y" if [[ $? -ne 0 ]]; then next_state=prompt_vg return 0 fi /usr/bin/dspmsg -s 1 oracle_sa.cat 274 "Running %s, this may take a few minutes....\n" "volume group configuration" # # convert pv name to pvid for cli_mkvg # pvid_list="" for pvname in ${selected_pv_list} do one_pvid=$(/usr/sbin/lspv |/usr/bin/grep $pvname|/usr/bin/awk '{print $2}') pvid_list=$(echo ${pvid_list} $one_pvid) done log "The pvids of selected disks are $pvid_list" # # finally create the vg # cmd="/usr/es/sbin/cluster/cspoc/cli_mkvg -f -n -s 32 -y ${APPVG} ${selected_pv_list}" mkvg_out=$($cmd 2>&1) rc=$? log "$cmd returned $rc\n$mkvg_out" # # check for vg # /usr/sbin/lsvg |/usr/bin/grep -sw $APPVG >>$RUN_LOG 2>&1 grc=$? # # if no vg or both cli_mkvg failed and the failure is valid... if (( ($grc != 0) || ( ($rc != 0) && ($mkvg_rc == 0) ) )); then msg_log "NO_CLEAR" 44 "\ncl_mkvg failed with %s, try again.\n" $rc next_state=prompt_vg return 0 fi if (( $mkvg_rc == 1 )); then # special processing for aix5.3 and IY71500 not installed # A climportvg -L failure has left the VG in the read-only state # varied_on=$(/usr/sbin/lsvg -o | /usr/bin/grep -qsw ${APPVG}) if [[ $? -eq 0 ]]; then # varied on perms_ck if [[ $? -ne 0 ]]; then next_state=prompt_vg return 0 fi fi # varied on fi # mkvg_rc = 1 special handling # ------------------------------------- # # cli_mkvg was successful # varied_on=$(/usr/sbin/lsvg -o | /usr/bin/grep -q -w ${APPVG}) if [[ $? -ne 0 ]]; then # not varied on /usr/es/sbin/cluster/utilities/clvaryonvg ${APPVG} >> ${RUN_LOG} 2>&1 if [[ $? -ne 0 ]]; then # not varied on msg_log "NO_CLEAR" 41 "A problem occurred while trying to vary on the volume group.\n" next_state=prompt_vg return 0 fi fi next_state=prompt_fs return 0 else # didnt select a or s next_state=prompt_vg return 0 fi # auto or smit next_state=prompt_fs return 0 } # end of validate_vg # ------------------------------------------------ # # cli_mkvg will always fail when running aix 5.3 without IY71500 # importvg -L fails leaving the volume group in read only state # running varyoffvg and varyonvg will compenstate for this. # function perms_ck { set -A perms $(LC_ALL=C /usr/sbin/lsvg -L $APPVG |/usr/bin/grep -s PERMISSION) log "VG PERMISSION for $APPVG is ${perms[2]}" if [[ ${perms[2]} = "read-only" ]]; then cmd="/usr/sbin/varyoffvg $APPVG" cmd_out=$($cmd 2>&1) if [[ $? -eq 0 ]]; then log "varyoffvg $APPVG returned\n$cmd_out" fi # varyoffvg rc cmd="/usr/sbin/varyonvg $APPVG" cmd_out=$($cmd 2>&1) if [[ $? -eq 0 ]]; then log "varyonvg $APPVG returned\n$cmd_out" fi # varyonvg rc set -A perms $(LC_ALL=C /usr/sbin/lsvg -L $APPVG |/usr/bin/grep -s PERMISSION) log "VG PERMISSION for $APPVG is ${perms[2]}" # recheck if [[ ${perms[2]} = "read-only" ]]; then msg_log 41 "A problem occurred while trying to vary on the volume group.\n" return 1 fi # recheck fi # perms = read-only return 0 } # end perms_ck #---------------------------- prompt_fs -------------------------------- # # # NAME: prompt_fs # # FUNCTION: # prompts for the file system for use by the assist # # EXECUTION ENVIRONMENT: # lsvg # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function prompt_fs { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=3 # prompt_fs # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 79 "This task will help select the Shared Filesystem.\n") func_header prompt_fs if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 45 "running prompt_fs next_state=validate_fs\n" >&2 fi next_state=validate_fs hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 168 "Select a number which corresponds to the filesystem you wish to use.\nSelecting [new_name] will create new filesystems.\n") list=$(/usr/sbin/lsvg -l $APPVG |/usr/bin/grep -sv $APPVG |/usr/bin/grep -sv "TYPE" |/usr/bin/grep -sv "N/A" |/usr/bin/awk '{print $7}') msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 202 "Select one or more existing filesystems that you wish to use,\n or select [new_name] to create new filesytems for oracle data, commands and installation ") list_cmd="/usr/sbin/lsvg -l $APPVG |/usr/bin/grep -sv $APPVG |/usr/bin/grep -sv "TYPE" |/usr/bin/grep -sv "N/A" |/usr/bin/awk '{print $7}'" echo $list_cmd >>$RUN_LOG echo $list >>$RUN_LOG # check for null list if [[ -n ${list} ]]; then list=$(echo ${list} "[new_name]") prompt_multiple "$msg" "${list}" "$hlp" APPFS=$answer log "The user selected $answer" else APPFS="[new_name]" log "There were no filesystems, using [new_name]" fi update_options_file "APPFS" "${APPFS}" return 0 } # end of function prompt_fs #---------------------------- validate_fs -------------------------------- # # NAME: validate_fs # # FUNCTION: # validates the file system used by the assist # prompts for existing fs or # creates 2 5GB LVs and 2 FS, one for database, one for cmds & install info # # EXECUTION ENVIRONMENT: # lsfs # mklv # smitty cl_lvsjfs # mount # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function validate_fs { # [[ "$VERBOSE_LOGGING" = "high" ]] && set -x task=3 # validate_fs # TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 80 "This task will validate the Shared Filesystem.\n") func_header validate_fs if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 46 "running validate_fs, next_state=config_app_server\n" >&2 fi next_state=config_app_server # # this might be 1 or 2 existing fs # log "Checking for file system ${APPFS} ...\n" newfs=0 rc=0 if [[ ${APPFS} != "[new_name]" ]]; then newfs=1 /usr/sbin/lsfs $APPFS >>$RUN_LOG 2>&1 rc=$? fi if [[ $newfs -eq 1 ]] && [[ $rc -eq 0 ]]; then # found------------------------ # # mount and return # # # fs belongs to appvg, see if it is mounted, note the while loop # rc=0 for one_fs in ${APPFS} do /usr/sbin/mount 2>&1 | grep -q ${one_fs} if [[ $? -ne 0 ]]; then # not mounted log "File system \"${one_fs}\" is not mounted, mounting it." APPLV=$(/usr/sbin/lsfs | /usr/bin/grep $one_fs |/usr/bin/awk '{print $1}') cmd="/usr/sbin/mount $APPLV $one_fs" cmd_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then # problem rc=1 print "$cmd_out" echo $cmd_out >> $RUN_LOG msg_log NO_CLEAR 174 "A problem occurred while trying to mount the filesystem. Additional details\n\ may be found in the log.\nCluster verification may fail if \"%s\" is not mounted.\n" "${one_fs}" fi if [[ $rc -ne 0 ]]; then next_state=prompt_fs return 0 fi fi #is it mounted done # each fs in APPFS return 0 # # the fs was not found or its a new_name # else # not found ------------------------ if [[ $APPFS != "[new_name]" ]]; then # hard to get here since we choose from a list. msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 172 "\nFile system \"%s\" not found. The file system must be defined\nto aix before adding it to the resource group. \n" "${APPFS}") next_state=prompt_fs return 0 fi quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 203 "The assist will create two filesystems one for the database, and one for commands and the home directory. if you have selected two disks for the Volume Group the will be on seperate disks, otherwise they will be on the same disk. Would you like to define the filesystem now\n") if yes_no "" "$quest" "y" then # # create 2 lv and the 2 fs, using 1 or 2 disks, 1 for db, 1 for cmd and ins. # if there is 1 disk, use it for both LV&FS, 2 disk, use 1 for data, 1 for cmd # if there are more than 2 disks, let them pick the allocation # # # get the disk names. # pv_list=$(/usr/sbin/lspv |/usr/bin/grep -sw $APPVG |/usr/bin/awk '{print$1}') echo $pv_list |read pv_data pv_cmd pv_rest if [[ -n $pv_rest ]]; then # # there are more than 2 disks in the VG. # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 210 "Select a physical volume for the data ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 211 "The data and commands can be on seperate disks, or the same disk.\n") prompt_list "$msg" "${pv_list}" "$hlp" pv_data=$answer msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 212 "Select a physical volume for the commands ") prompt_list "$msg" "${pv_list}" "$hlp" pv_cmd=$answer fi if [[ -z $pv_cmd ]]; then msg_log "NO_CLEAR" 204 "Found one physical volume %s in the Volume Group, it will be used\nfor the two filesystems.\n" "$pv_data" pv_cmd=$pv_data fi msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 205 "Choose jfs or jfs2 filesystems ") prompt "$msg" "jfs2" "" "" jfsx=$answer log "User selected $jfsx type filesystem" if [[ $jfsx != "jfs" ]] && [[ $jfsx != "jfs2" ]]; then msg "need to select jfs or jfs2, not $jfsx" log "User chose $jfsx type filesystem" next_state=prompt_fs return 0 fi /usr/bin/dspmsg -s 1 oracle_sa.cat 274 "Running %s, this may take a few minutes....\n" "filesystem configuration" if [[ -z $FS_SIZE ]] || [[ $FS_SIZE -lt 5120 ]]; then FS_SIZE=5120 fi LV_SIZE="${FS_SIZE}M" # create a logical volume for the database large enough for 5GB # Set environ var to allow execution of base AIX command... 710 mklv_out=$(CLUSTER_OVERRIDE="yes" /usr/sbin/mklv -t $jfsx -Yora_data $APPVG $LV_SIZE $pv_data) if [[ $? -ne 0 ]]; then log "mklv -t $jfsx -Yora_data $APPVG $LV_SIZE $pv_data failed.\n$mklv_out" msg_log "NO_CLEAR" 47 "mklv %s $LV_SIZE %s failed. Correct and try again.\n" $APPVG $pv_data >&2 next_state=prompt_fs return 0 else log "mklv -t $jfsx -Yora_data $APPVG $LV_SIZE $pv_data returned 0." fi # get the name of the last (latest) lv, that was just created. data_lv=$(/usr/sbin/lsvg -l $APPVG | /usr/bin/grep -s ora_data | /usr/bin/awk '{ print $1 }' | /usr/bin/tail -1) log "the new lv is $data_lv \n" APPLVdata=$data_lv update_options_file "APPLVdata" "${data_lv}" # # create a logical volume for the cmds large enough for 5GB # Set environ var to allow execution of base AIX command... 710 # mklv_out=$(CLUSTER_OVERRIDE="yes" /usr/sbin/mklv -t $jfsx -Yora_cmd $APPVG $LV_SIZE $pv_cmd) if [[ $? -ne 0 ]]; then log "NO_CLEAR" "mklv -t$jfsx -Yora_cmd $APPVG $LV_SIZE $pv_cmd failed.\n$mklv_out" msg_log "NO_CLEAR" 47 "mklv %s $LV_SIZE %s failed. Try again.\n" $APPVG $pv_cmd >&2 next_state=prompt_fs return 0 else log "mklv -t$jfsx -Yora_cmd $APPVG $LV_SIZE $pv_cmd returned 0." fi # get the name of the last (latest) lv, that was just created. cmd_lv=$(/usr/sbin/lsvg -l $APPVG | /usr/bin/grep -s ora_cmd | /usr/bin/awk '{ print $1 }' | /usr/bin/tail -1) log "the new lv is $cmd_lv" APPLVcmd=$cmd_lv update_options_file "APPLVcmd" "${cmd_lv}" # # Create a lvlog on the cmd pv. Use this name when creating the # two filesystems # Set environ var to allow execution of base AIX command... 710 # cmd="CLUSTER_OVERRIDE=yes /usr/sbin/mklv -t ${jfsx}log -Yora_log $APPVG 1 $pv_cmd" mklv_out=$($cmd) if [[ $? -ne 0 ]]; then log "NO_CLEAR" "$cmd\n$mklv_out" msg_log "NO_CLEAR" 47 "mklv %s %s failed. Try again.\n" "-t ${jfsx}log -Yora_log" $pv_cmd >&2 next_state=prompt_fs return 0 else log "$cmd returned 0." fi set -A lv_log $(/usr/sbin/lsvg -l $APPVG |/usr/bin/grep -s ora_log) ora_loglv=${lv_log[0]} log "VG loglv for $APPVG is ${lv_log[0]}" # format the log file echo "y" | /usr/sbin/logform /dev/$ora_loglv >> $RUN_LOG 2>&1 # # make all the lv superstrict with the chlv command # lv_list=$(/usr/sbin/lsvg -l $APPVG | /usr/bin/tail +3 | /usr/bin/awk '{ print $1 }') # 710 # Set environ var to allow execution of base AIX command... 710 # 710 CLUSTER_OVERRIDE="yes" /usr/sbin/chlv -u 32 -s s $lv_list >> $RUN_LOG 2>&1 # # Make the 2 FS # # # make a new name for datafs # data_fs="/${data_lv}fs" log "Creating the filesystem $data_fs on logical volume $data_lv" /usr/sbin/lsfs $data_fs >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then msg_log "NO_CLEAR" 183 "The filesystem %s on %s exists, use SMIT to create the filesystem.\n" $data_fs $data_lv next_state=prompt_fs return 0 else cmd="/usr/sbin/crfs -v $jfsx -d $data_lv -m $data_fs -p rw -a logname=$ora_loglv" log "$cmd" cmd_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 184 "The crfs command %s failed with this output\n%s\n" "$cmd" "$cmd_out" log "$cmd_out" next_state=prompt_fs return 0 else APPFSdata=$data_fs update_options_file "APPFSdata" "${data_fs}" # now fall through to mount. fi fi # new name ok # # make a new name for cmdfs # cmd_fs="/${cmd_lv}fs" log "Creating the filesystem $cmd_fs on logical volume $cmd_lv" /usr/sbin/lsfs $cmd_fs >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then msg_log "NO_CLEAR" 183 "The filesystem %s on %s exists, use SMIT to create the filesystem.\n" $cmd_fs $cmd_lv next_state=prompt_fs return 0 else cmd="/usr/sbin/crfs -v $jfsx -d $cmd_lv -m $cmd_fs -p rw -a logname=$ora_loglv" cmd_out=$($cmd 2>&1) if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 184 "The crfs command %s failed with this output\n%s\n" "$cmd" "$cmd_out" next_state=prompt_fs return 0 else APPFScmd=$cmd_fs update_options_file "APPFScmd" "${cmd_fs}" # now fall through to mount. fi fi # new name ok else # yes_no define (not) now log "User chose not to create Filesystem now." next_state=prompt_vg return 0 fi # yes_no fi # found ---------------------------------- APPFS="$APPFSdata $APPFScmd" update_options_file "APPFS" "${APPFS}" # # mount the new filesystems # # # fs belongs to appvg, see if it is already mounted, if not, mount. # /usr/sbin/mount 2>&1 | grep -q ${APPFScmd} if [[ $? -ne 0 ]]; then # not mounted log "File system \"${APPFScmd}\" is not mounted, mounting it." full_cmd=$(/usr/sbin/lsfs | /usr/bin/grep $APPFScmd |/usr/bin/awk '{print $1}') /usr/sbin/mount $full_cmd $APPFScmd >>$RUN_LOG 2>&1 if [[ $? -ne 0 ]]; then # problem msg_log NO_CLEAR 174 "A problem occurred while trying to mount the filesystem. Additional details\n\ may be found in the log.\n\ Cluster verification may fail if \"%s\" is not mounted.\n" ${APPFScmd} next_state=prompt_fs return 0 fi fi /usr/bin/chmod 777 ${APPFScmd} >> $RUN_LOG 2>&1 /usr/bin/ls -l ${APPFScmd} >> $RUN_LOG 2>&1 /usr/sbin/mount 2>&1 | grep -q ${APPFSdata} if [[ $? -ne 0 ]]; then # not mounted log "File system \"${APPFSdata}\" is not mounted, mounting it." full_data=$(/usr/sbin/lsfs | /usr/bin/grep $APPFSdata |/usr/bin/awk '{print $1}') /usr/sbin/mount $full_data $APPFSdata >>$RUN_LOG 2>&1 if [[ $? -ne 0 ]]; then # problem msg_log NO_CLEAR 174 "A problem occurred while trying to mount the filesystem. Additional details\n\ may be found in the log.\n\ Cluster verification may fail if \"%s\" is not mounted.\n" ${APPFSdata} next_state=prompt_fs return 0 fi fi /usr/bin/chmod 777 ${APPFSdata} >> $RUN_LOG 2>&1 /usr/bin/ls -l ${APPFSdata} >> $RUN_LOG 2>&1 msg_log "NO_CLEAR" 213 "The data Filesystem on disk %s is %s.\nThe cmd Filesytem on disk %s is %s\n" "${pv_data}" "${APPFSdata}" "${pv_cmd}" "${APPFScmd}" return 0 } # end of validate_fs #---------------------------- unconfigure_assist --------------------------- # # NAME: unconfigure_assist # # FUNCTION: # Gives the user the opportunity to remove any and all # cluster components. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function unconfigure_assist { task= TASK=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 81 "This task will help unconfigure PowerHA SystemMirror components.\n") func_header unconfigure_assist if [[ -n $VERBOSE ]]; then log "================================\n\ Running unconfigure_assist, next_state=prompt_action" fi next_state=prompt_action msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 106 "You have selected to unconfigure the Oracle Assist.\n\ This will prompt you to remove the Volume Group, Filesystem,\n\ application server, resource groups, their resources and the cluster.\n") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 107 "Are you sure you want to continue ") if yes_no "$msg" "$quest" "y" then # ====================== volume group ====================== # # choose a vg that does not have root in the name. # and pvids for each vg must be on both nodes. # prim_vg_list=$(/usr/sbin/lsvg |/usr/bin/grep -v root) sec_pvid_list=$(/usr/es/sbin/cluster/utilities/cl_rsh $short_second /usr/sbin/lspv | /usr/bin/awk '{print $2}') pick_list="" for vg in $prim_vg_list ; do prim_vg_pvid=$(/usr/sbin/lspv |/usr/bin/grep -sw $vg |/usr/bin/awk '{print $2}') not_found=0 for pvid in $prim_vg_pvid ; do out=$(echo $sec_pvid_list |/usr/bin/grep -qsw $pvid) if [[ $? -ne 0 ]]; then not_found=1 fi done if [[ $not_found -eq 0 ]]; then pick_list=$(echo ${pick_list} $vg) fi done if [[ -n ${pick_list} ]]; then # add None to the list list="" list=$(echo ${pick_list} "[None]") msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 182 "\ Select a number from which corresponds to the Shared Volume Group\n\ you wish to delete.\nWARNING:This action will delete any Logical Volumes\n\ and Data on the Volume Group ") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 259 "Removes physical volumes from a volume group. When all physical\n\ volumes are removed from the volume group, the volume group is deleted.\n\ You will be prompted to run exportvg on the remote node when this is completed.") prompt_list "$msg" "${list}" "$hlp" log "\nThe user chose to remove ${answer} \n" rm_vg=$answer if [[ $rm_vg != "[None]" ]]; then # # Remove the shared volume group # print msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 234 "WARNING:This action will delete any Logical Volumes and Data on the Volume Group ") quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 108 "Unconfigure the %s Shared Volume Group " $rm_vg) if yes_no "$msg" "$quest" "y" then # # see if there are any other fs mounted on rm_vg # the vg has to be varied on to umount fs and reducevg # varied_on=$(/usr/sbin/lsvg -o | /usr/bin/grep -qsw ${rm_vg}) if [[ $? -ne 0 ]]; then # not varied on /usr/es/sbin/cluster/utilities/clvaryonvg ${rm_vg} >> ${RUN_LOG} 2>&1 fi mnt_fs=$(/usr/sbin/lsvg -l $rm_vg | /usr/bin/tail +3 | /usr/bin/grep -s -v "N/A" | /usr/bin/awk '{ print $7 }') if [[ -n $mnt_fs ]]; then for one_mnt in $mnt_fs ; do /usr/sbin/umount $one_mnt >> $RUN_LOG 2>&1 done fi # # get the pv for the vg # pv_list=$(/usr/sbin/lspv |/usr/bin/grep -s $rm_vg |/usr/bin/awk '{print $1}') # # see if there is a cluster defined to determine how to delete. # force_rmvg=0 rc=0 rc1=0 rc2=0 echo $pv_list >> $RUN_LOG # the cluster should not be running, ever... cmd="/usr/es/sbin/cluster/cspoc/cli_reducevg -f -R $short_primary $rm_vg $pv_list" cmd_out=$($cmd >> $RUN_LOG 2>&1) rc=$? log "$cmd \n returned $cmd_out \n return code $rc" if [[ $rc != 0 ]]; then # also, if cli_reducevg failed force_rmvg=1 # then try force removal fi rc1=0 rc2=0 rc3=0 if [[ ${force_rmvg} -eq 1 ]]; then # Set env var to allow execution of base AIX command... 710 cmd="CLUSTER_OVERRIDE=yes /usr/sbin/reducevg -df $rm_vg $pv_list" cmd_out=$($cmd >> $RUN_LOG 2>&1) rc=$? # hard to know why it failed, see if it worked log "$cmd returned $cmd_out...$rc" # # remove the VG from the secondary node # clrsh only runs if the cluster is defined # ${TOOLS_DIR}/cllsclstr >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then # lvm dis-allows remote exportvg... rvg=$($TOOLS_DIR/cl_rsh $short_second /usr/sbin/lsvg) log "These are the volume groups on the remote node $rvg" echo $rvg |/usr/bin/grep -qsw $rm_vg rc3=$? if [[ $rc3 -eq 0 ]]; then msg_log "NO_CLEAR" 217 "Please run /usr/sbin/exportvg %s on the remote node.\n" $rm_vg # # see if the user was able to remove the VG # rvg=$($TOOLS_DIR/cl_rsh $short_second /usr/sbin/lsvg) log "These are the volume groups on the remote node $rvg" echo $rvg |/usr/bin/grep -qsw $rm_vg rc3=$? fi else # # cluster is not running, still need to exportvg # there is no way to verify that user did this # rc3=0 log "cluster is not running, still need to exportvg $rm_vg" msg_log "NO_CLEAR" 217 "Please run /usr/sbin/exportvg %s on the remote node.\n" "$rm_vg" fi pvg=$(/usr/sbin/lsvg) log "These are the volume groups on the primary node $pvg" echo $pvg |/usr/bin/grep -qsw $rm_vg rc1=$? if [[ $rc1 -eq 0 ]] || [[ $rc3 -eq 0 ]]; then # rc2 never 0 because lvm wont run exportvg remotely. msg_log "NO_CLEAR" 105 "There was a problem removing the Volume Group.\n" fi fi # is there a cluster fi # remove vg and fs fi # selected None fi # if list is empty # ============== application server ====================== # # remove the application server # print list="" list=$(${TOOLS_DIR}/cllsserv -c 2>> $RUN_LOG) if [[ -n ${list} ]]; then # add None to the list list=$(echo ${list} "[None]") msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 243 "\ Select a number from which corresponds to the Application Server\n\ you wish to delete.") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 260 "The Application server name will be removed from the configuration.") prompt_list "$msg" "${list}" "$hlp" if [[ $answer != "[None]" ]]; then serv_name=$(echo $answer |/usr/bin/awk -F ":" '{print $1}') ${TOOLS_DIR}/clrmserv ${serv_name} >>$RUN_LOG 2>&1 if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 110 "A problem occurred while removing the application server\n" fi fi # not none fi # list not empty # ================ service IP ============================= # # remove the service IP # print msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 236 "Choose a service IP label to unconfigure.") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 261 "This will remove the IP Address/Label from the cluster.") svc_ip_list="" svc_ip_list=$(LC_ALL=C ${TOOLS_DIR}/cllsif -c 2>>$RUN_LOG |/usr/bin/grep -v serial |/usr/bin/grep -sw service |/usr/bin/awk -F":" '{print $1}' | /usr/bin/sort -u) if [[ -n ${svc_ip_list} ]]; then svc_list="" svc_list=$(echo ${svc_ip_list} "[None]") prompt_list "$msg" "$svc_list" "$hlp" if [[ ${answer} != "[None]" ]]; then LC_ALL=C ${TOOLS_DIR}/cllsif -c |/usr/bin/grep -v serial |/usr/bin/grep -sw service | /usr/bin/grep -sw ${answer} >> $RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then # exists ${TOOLS_DIR}/clrmnode -a ${answer} >> $RUN_LOG 2>&1 if [[ $? -ne 0 ]]; then msg_log "NO_CLEAR" 198 "A problem occurred while removing the Service IP Label.\n" fi fi # remove service IP Label fi # if ne None fi # if a label exists # ========================== resource group =================== # # Look for any resource groups defined # print list="" list=$(${TOOLS_DIR}/cllsgrp 2>>$RUN_LOG) if [[ -n ${list} ]]; then rg_list="" rg_list=$(echo ${list} "[None]") msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 244 " Choose a resource group to unconfigure") hlp=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 262 "All information about the selected resource group will be removed\n\ from the ODM.") prompt_list "$msg" "$rg_list" "$hlp" if [[ ${answer} != "[None]" ]]; then # # remove the resource group. # log "Removing ${answer}" ${TOOLS_DIR}/clrmgrp -g $answer >>$RUN_LOG 2>&1 fi else msg_log "NO_CLEAR" 113 "No groups found.\n" fi # ================== cluster ============================= # # remove the cluster. # print ${TOOLS_DIR}/cllsclstr >>$RUN_LOG 2>&1 if [[ $? -eq 0 ]]; then cl_msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 237 "If you choose to unconfigure the cluster, all user-configured PowerHA SystemMirror\n\ information WILL BE DELETED by this operation.") cl_quest=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 114 "Do you wish to unconfigure the cluster") if yes_no "NO_CLEAR" "$cl_msg" "$cl_quest" "n" then log "Removing the $clstr cluster." ${TOOLS_DIR}/cl_rsh $short_second ${TOOLS_DIR}/clrmclstr >>$RUN_LOG ${TOOLS_DIR}/clrmclstr >>$RUN_LOG fi else msg_log "NO_CLEAR" 115 "No cluster found.\n" fi fi # # All or part of the cluster may have been removed, choose next step. # print "" msg_log "NO_CLEAR" 52 "The unconfigure task has completed.\n" next_state=prompt_action return 0 } # end of unconfigure #---------------------------- show_readme --------------------------- # # NAME: show_readme # # FUNCTION: # displays the README file for this plugin # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function show_readme { ${PAGER} ${OSA_README} next_state=prompt_action } #---------------------------- assist_init -------------------------------- # # NAME: assist_init # # FUNCTION: # initializes some stuff for the oracle assist program # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function assist_init { [[ "$VERBOSE_LOGGING" = "high" ]] && set -x # # show header on the top of screen # clear_screen # # Welcome screen # msg=$(/usr/bin/dspmsg -s 1 oracle_sa.cat 118 "This program helps you configure an PowerHA SystemMirror two node cluster and install the \n\ \tOracle Infrastructure Tier software. \n\ There are a few tasks that you must complete before using \n\ this program - please refer to the README file for more information. \n\ From a subsequent screen you may select option 3 to view the README file. \n\n\ You will need to know the hostname of the second node, and the HACMP service \n\ IP address. These must be resolvable before running the assist. \n\n\ Help is available by typing \"h\" at any prompt. You may exit this program at \n\ any time by typing \"x\" at any prompt. \n\ You can remove the configuration created by the oracle assist by \n\ selecting the Unconfigure option 2 on a subsequent screen. \n\n\ Information about this session will be stored in \n\ \t%s\n" $RUN_LOG) msg $msg /usr/bin/dspmsg -s 1 oracle_sa.cat 116 "Oracle Assist Program initializing...\n" # make sure we are root ck_user # Create the directory where we'll do our work if [[ -d ${LOG_DIR} ]]; then if [ -f ${RUN_LOG} ]; then # print "Saving existing ${RUN_LOG} to ${RUN_LOG}.bak" mv -f ${RUN_LOG} ${RUN_LOG}.bak 2>/dev/null fi elif [[ ! -d ${LOG_DIR} ]]; then mkdir -p ${LOG_DIR} 2>${RUN_LOG} || /usr/bin/dspmsg -s 117 "This tool expects to use the directory named \"%s\",\n\ but could not create it. Check path names and permissions.\n" ${LOG_DIR} fi # initialize the session log echo " Program for PowerHA SystemMirror Oracle Infrastructure Tier configuration.\n\ Run date: $(date) on machine $(hostname)\n" >>${RUN_LOG} # # read the options file ck_options_file # # Get Primary and Secondary hostnames # get_node_names # # check the filesystem sizes etc # ck_sizes if [[ $? -ne 0 ]]; then log "ck_sizes failed on $short_prim" ck_ver_fail="yes" exit 1 fi # # The secondary node will be checked after the cluster is defined in # config_basic_cluster # if [[ -n $VERBOSE ]]; then msg_log "NO_CLEAR" 57 "Comleted Software level check.\n" >&2 fi next_state=prompt_action return 0 } # end of assist_init #---------------------------------------------------------------------------- function get_last { start_string=$1 stop_string=$2 srcfile=$3 outfile=$4 cat $srcfile | grep -p "^$start_string" | while read line; do echo "$line" | grep "^$start_string" >/dev/null 2>&1 if [ $? -eq 0 ]; then echo $line > $outfile while read line; do echo $line >> $outfile echo $line | grep "^$stop_string" >/dev/null 2>&1 && break done fi done } #---------------------------- is_valid_arg -------------------------------- # # NAME: is_valid_arg # # FUNCTION: # Determines whether the argument its given is valid (ie. that the # arg exists and that it is not a flag. # # EXECUTION ENVIRONMENT: # Command line parsing. # # RETURNS: 0 if the arg is valid # 1 if the arg is not valid # # OUTPUT: None #------------------------------------------------------------------------------- function is_valid_arg { typeset arg="$1" # If the argument doesn't exist or its first character is a "-" or # there are any embedded flags (strings matching " -") then its not # a valid argument if [[ -z "$arg" ]] || [[ "$arg" = \-*(?) ]]; then return 1 # it isn't valid else echo $arg | grep " -" >/dev/null 2>&1 && return 1 return 0 # it is valid fi } #---------------------------- assist_main ------------------------------- # # NAME: oracle assist # # FUNCTION: # interactive script to configure the oracle assist # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # # OUTPUT: #-------------------assist_main main MAIN ------------------------------------ # # Turn off noclobber option so that existing files may be appended to (for # those who have noclobber turned on). # set +o noclobber # # set traps # exit is trap 0 # segmentation violation is trap 11 # cntrl D&C interupts are trap 2 # 1=hangup, 15=software termination # trap complete_pgm 0 11 trap "" 2 trap user_exit 1 15 # add the PATHs we need PATH=${ASSIST_PATHS}:${PATH} if [[ -n $VERBOSE ]]; then echo $PATH >> $RUN_LOG fi # # Help msg # if [ "$1" = "-h" ] || [ "$1" = "-?" ]; then echo $ASSIST_HELP exit 0 fi # Parse the rest of the args while [ $# != 0 ]; do cmdline_flags="${cmdline_flags}$1" # for adding to use.log log "cmdline flags are $cmdline_flags" case $1 in -v) # verbose mode - display messages VERBOSE=yes ;; -r) # run on remote node and check the prereqs only. REMOTE_ONLY=yes ;; *) /usr/bin/dspmsg -s 1 oracle_sa.cat 120 "Unexpected flag or argument encountered: \"%s\".\n" $1 BAD_ARGS=yes exit 1 ;; esac shift done # Take all the "-" off the list of command line flags cmdline_flags=`echo $cmdline_flags | sed 's/\-//g'` if [[ ${REMOTE_ONLY} = "yes" ]]; then echo " Program for PowerHA SystemMirror Oracle Infrastructure Tier configuration.\n\ Run date: $(date) on machine $(hostname)\n" >>${RUN_LOG} # read the options file ck_options_file ck_sizes rc=$? log "ck_sizes returned $rc" exit $rc fi # call the various functions next_state=assist_init while [[ -n "${next_state}" ]] do prev_state=${state} state=${next_state} next_state="" ${state} done exit 0