#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2018,2019,2020,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_replace_repository.sh 1.21.1.6 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2012,2016 # 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 # @(#) 7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_replace_repository.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM #============================================================================ # # Name: KLIB_HACMP_replace_repository # # Description: This is the main, FPATH function that is invoked by clmgr # to manually replace the current primary/active repository. # # Inputs: See the "devDoc()" function, below. # # Outputs: The properties hash is populated. The only other outputs are # any error messages that might be needed. # # Returns: Zero if no errors are detected. Otherwise, an appropriate # non-zero value is returned. Refer to the "RETURN" section # of the "devDoc()" function, below, for the standard return # code values/meanings for clmgr. # #============================================================================ function KLIB_HACMP_replace_repository { . $HALIBROOT/log_entry "$0()" "$CL" : version=@(#) 7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_replace_repository.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM : INPUTS: $* typeset new_repository=${1//\"/} typeset site=${2//\"/} typeset refnode=${3//\"/} [[ $CLMGR_LOGGING == 'med' ]] && set +x # Only trace param values #=================================== : Declare and initialize variables #=================================== typeset -A properties typeset -i rc=$RC_UNKNOWN i=0 typeset BACKUPS="" REM="" IDENTIFIERS="" REFNODE="" typeset OLD_REPOS_NAME="" OLD_REPOS_PVID="" OLD_REPOS_UUID="" typeset NEW_REPOS_NAME="" NEW_REPOS_PVID="" NEW_REPOS_UUID="" typeset current_repository="" NODES="" siteOpt="" LSPV_OUT="" typeset node_list="" #================================================================ : Check for a defined cluster. No need to continue without one. #================================================================ CL=$LINENO isClusterDefined (( $? != RC_SUCCESS )) && rc=$RC_MISSING_DEPENDENCY #================================================================== : See if there is a replacement disk specified. If not, check for : a pre-defined list of backups, and use one of those instead. #================================================================== if (( $rc == RC_UNKNOWN )); then if [[ $new_repository == *([[:space:]]) ]]; then if [[ $site == *([[:space:]]) ]]; then print "$0()[$LINENO]($SECONDS): clodmget -n -f backup_repository HACMPsircol" >>$CLMGR_TMPLOG BACKUPS=$(clodmget -n -f backup_repository HACMPsircol) else print "$0()[$LINENO]($SECONDS): clodmget -n -q name=${site}_sircol -f backup_repository HACMPsircol" >>$CLMGR_TMPLOG BACKUPS=$(clodmget -n -q name=${site}_sircol -f backup_repository HACMPsircol) fi print "$0()[$LINENO]($SECONDS): clodmget RC: $? ($BACKUPS)" >>$CLMGR_TMPLOG if [[ $BACKUPS != *([[:space:]]) ]]; then new_repository=${BACKUPS%%,*} new_repository=${new_repository##+([[:space:]])} new_repository=${new_repository%%+([[:space:]])*} fi : Automatic Repository Replacement: $new_repository fi if [[ $new_repository == *([[:space:]]) ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 423 "\nERROR: a replacement disk was not specified, nor are any backup repository disks defined.\n\n" 1>&2 rc=$RC_MISSING_INPUT log_return_msg "$rc" "$0()" "$LINENO" return $? fi fi #================================================================ : Since this is a destructive operation, seek confirmation from : the customer before proceeding. #================================================================ if (( ! CLMGR_FORCE )) && [[ $CLMGR_GUI != "SMIT" ]]; then typeset MSG=$(cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 440 '\n***Warning: this operation will destroy any information currently stored on "%1$s". Are you sure you want to proceed? (y/n)\n' "$new_repository") print -n -- "${MSG%%*([[:space:]])} " typeset -l char=$(dd if=/dev/tty bs=3 count=1 2>/dev/null) if [[ $char != y* ]]; then log_return_msg "$RC_SUCCESS" "$0()" "$LINENO" return $? fi fi #================= : Validate input #================= if (( $rc == RC_UNKNOWN )); then if [[ $new_repository != *([[:space:]]) ]]; then #Getting the new_repository to the hdisk name #as new_repository can be in the UUID or pvid #format and chdev needs hdisk name to work. LC_ALL=C lspv -u|grep -w $new_repository |awk '{print $1 " " $2}' | read new_rep_disk_name new_pvid #============================================================ : Allocating pvid to the specified disk if pvid is "none". #============================================================ if [[ $new_pvid == "none" ]]; then chdev -a pv=yes -l $new_rep_disk_name > /dev/null if (( $? != 0 )) || [[ $(LC_ALL=C lspv -u| grep -w $new_repository | awk '{ print $2 }') == "none" ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1168 'ERROR: Failed to allocate PVID to "%1\$s". Manual intervention is needed to allocate PVID.\n' "$new_repository" 1>&2 rc=$RC_ERROR log_return_msg "$rc" "$0()" "$LINENO" fi fi # : Check for whether or not a site was specified, and whether or : not one was needed. This test should come before the call to : KLIB_HACMP_is_known_repository. It has been modified to not : fail in an ugly fashion, but it is still not going to be able : to produce good results without the site value being correct. # if [[ $CLUSTER_TYPE == "LC" ]] then if [[ $site == *([[:space:]]) ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 250 "\nERROR: a linked cluster requires one repository disk per site. Please use the SITE option to indicate within which site you intended to replace the repository.\n\n" 1>&2 rc=$RC_MISSING_INPUT fi else if [[ $site != *([[:space:]]) ]] then if [[ $CLUSTER_TYPE == "SC" ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 254 "\nERROR: a stretched cluster only requires one repository disk for the entire cluster, not per site. The SITE option is not appropriate for this environment.\n\n" 1>&2 rc=$RC_INCORRECT_INPUT else cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 255 "\nERROR: a cluster without sites only requires one repository disk for the entire cluster. The SITE option is not appropriate for this environment.\n\n" 1>&2 rc=$RC_INCORRECT_INPUT fi fi fi if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then if [[ $site == *([[:space:]]) ]]; then CL=$LINENO KLIB_HACMP_is_known_repository "$new_repository" else CL=$LINENO KLIB_HACMP_is_known_repository "$new_repository" "$site" fi typeset -i cmd_rc=$? if (( $cmd_rc == RC_SUCCESS )); then #======================================= : If it is a backup disk, this is okay #======================================= typeset -A props CL=$LINENO KLIB_HACMP_get_repository_attributes "$new_repository" props $site if [[ ${props[BACKUP]} == 0 ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 416 '\nERROR: an attempt was made to add "%1$s" as a repository, but it is already being used as a repository disk.\n\n' "$new_repository" 1>&2 rc=$RC_INCORRECT_INPUT fi fi #======================================================================= # Check if tie-breaker disk is choosen as a repository disk to replace #======================================================================= typeset tie_breaker_disk=$(clodmget -n -q policy=tiebreaker -f value HACMPsplitmerge) typeset new_repository_pvid=$(LC_ALL=C lspv -u| grep -w $new_repository | awk '{ print $2 }') if [[ $tie_breaker_disk == $new_repository_pvid ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1179 "\nERROR: \"%1\$s\" is configured as a tie-breaker disk and cannot be chosen as a repository disk.\n\n" "$new_repository" 1>&2 rc=$RC_INCORRECT_INPUT fi fi fi fi if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then if [[ $CLUSTER_TYPE == "LC" ]]; then CL=$LINENO KLIB_HACMP_is_known_site $site >/dev/null if (( $? != RC_SUCCESS )); then rc=$RC_NOT_FOUND dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$site" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 157 "Available Sites:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_sites available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" else #================================================ : Verify given node $refnode is part of site $site #================================================ if [[ -n $refnode ]] then node_list=$(clodmget -n -q name=$site -f nodelist HACMPsite) echo $node_list|grep -wq $refnode if (( $? != 0 )) then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1320 "\nERROR: Node \"%1\$s\" is not part of site \"%2\$s\".\n\n" "$refnode" "$site" 1>&2 rc=$RC_INCORRECT_INPUT fi fi fi fi fi #================================================== : Check Availability of 4KDisk Capability #================================================== typeset -i caa_4KDisk_available=0 typeset -i flag=0 caa_4kdisk_capability=$(LC_ALL=C cl_get_capabilities -i 4KDISK 2>&1) if (( $? == 0 )) && [[ -n $caa_4kdisk_capability ]] then flag=$(echo $caa_4kdisk_capability | awk -F':' '{print $NF}') if (( $flag == 1 ));then caa_4KDisk_available=1 fi fi #================================================== : Verify disks block size #================================================== if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then nodes=$refnode if [[ $site == *([[:space:]]) ]]; then if [[ -z $refnode ]]; then nodes=$(clodmget -n -q object=COMMUNICATION_PATH -f name HACMPnode) fi else #============================= : Site "$site" was specified #============================= if [[ -z $refnode ]]; then nodes=$(clodmget -n -q name=$site -f nodelist HACMPsite) fi fi node=$(echo $nodes | awk '{print $1}') if [[ node != $LOCAL_NODE ]]; then new_repository=$($CLRSH $node LC_ALL=C lspv -u| grep -w $new_repository | awk '{print $1}') blk_size=$($CLRSH $node /usr/es/sbin/cluster/events/utils/cl_querypv -b $new_repository 2>>$CLMGR_TMPLOG) else new_repository=$(LC_ALL=C lspv -u| grep -w $new_repository | awk '{print $1}') blk_size=$(cl_querypv -b $new_repository 2>>$CLMGR_TMPLOG) fi if [[ -z $blk_size ]]; then print "$0()($SECONDS): cl_querypv -b $new_repository. The block size of disk $new_repository is NULL.This is due to failure in cl_queryp v." >>$CLMGR_TMPLOG cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1218 "\nERROR: The block size of disk %1\$s is NULL.\n\ This is due to failure in cl_querypv.\n\n" "$new_repository" 1>&2 rc=$RC_INCORRECT_INPUT elif (( $blk_size == 4096 && caa_4KDisk_available == 0 )); then print "$0()($SECONDS): cl_querypv -b $new_repository. The block size of disk $new_repository is $blk_size, but CAA does not support \n\ 4KDISK on this AIX level. Please redefine the disk using a supported block size." >>$CLMGR_TMPLOG cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1222 "\nERROR: The block size of disk %1\$s is %2\$d, but CAA does not support \n\ 4KDISK on this AIX level. Please redefine the disk using a supported block size.\n\n" "$new_repository" "$blk_size" 1>&2 rc=$RC_INCORRECT_INPUT elif (( caa_4KDisk_available == 1 && $blk_size != 4096 && $blk_size != 512 )); then print "$0()($SECONDS): cl_querypv -b $new_repository. The block size of disk $new_repository is $blk_size, but CAA supports \n\ disks with a block size of 4K and 512 bytes. Please redefine the disk using a supported block size." >>$CLMGR_TMPLOG cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1223 "\nERROR: The block size of disk %1\$s is %2\$d, but CAA supports \n\ disks with a block size of 4K and 512 bytes. Please redefine the disk using a supported block size.\n\n" "$new_repository" "$blk_size" 1>&2 rc=$RC_INCORRECT_INPUT elif (( $blk_size != 512 && caa_4KDisk_available == 0 )); then print "$0()($SECONDS): cl_querypv -b $new_repository. The block size of disk $new_repository is $blk_size. CAA only supports disks with a block size of 512 bytes." >>$CLMGR_TMPLOG cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1217 "\nERROR: The block size of disk %1\$s is %2\$d. CAA only supports \n\ disks with a block size of 512bytes.\n\n" "$new_repository" "$blk_size" 1>&2 rc=$RC_INCORRECT_INPUT fi fi #========================================================== : Perform the replacement if no errors have been detected #========================================================== if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then NODES=$refnode if [[ $site == *([[:space:]]) ]]; then if [[ -z $refnode ]]; then NODES=$(clodmget -n -q object=COMMUNICATION_PATH -f name HACMPnode) fi current_repository=$(clodmget -n -f repository HACMPsircol) #================================================================== : Verify that the stored information matches the real information. : Sometimes the PVID of the repository gets changes by CAA. #================================================================== if [[ -n $refnode && $refnode != $LOCAL_NODE ]]; then LSPV_OUT=$($CLRSH $refnode /usr/sbin/lspv | /usr/bin/grep -w caavg_private) else LSPV_OUT=$(lspv | grep -w caavg_private) fi if [[ -n $LSPV_OUT ]]; then print -- "$LSPV_OUT" | read JUNK NEW_REPOS_PVID JUNK if [[ -n $NEW_REPOS_PVID && $NEW_REPOS_PVID != $current_repository ]]; then print "$0()[$LINENO]($SECONDS): The CAA repository PVID has changed from \"$current_repository\" to \"$NEW_REPOS_PVID\". Updating the HACMPsircol ODM to reflect this change." >>$CLMGR_TMPLOG print "$0()[$LINENO]($SECONDS): echo \"HACMPsircol: repository=$NEW_REPOS_PVID id=0\" | odmchange -o HACMPsircol" >>$CLMGR_TMPLOG print "HACMPsircol: repository=$NEW_REPOS_PVID\nid=0" | odmchange -o HACMPsircol print "$0()[$LINENO]($SECONDS): New HACMPsircol stanza is:" >>$CLMGR_TMPLOG odmget HACMPsircol >>$CLMGR_TMPLOG print >>$CLMGR_TMPLOG # Since an ODM was updated, set the cluster "change" flag print "HACMPcluster: handle=0" | odmchange -o HACMPcluster current_repository=$NEW_REPOS_PVID fi else current_repository="" fi else #============================= : Site "$site" was specified #============================= if [[ -z $refnode ]]; then NODES=$(clodmget -n -q name=$site -f nodelist HACMPsite) fi current_repository=$(clodmget -n -q name=${site}_sircol -f repository HACMPsircol) siteOpt=" -S $site" #================================================================== : Verify that the stored information matches the real information. : Sometimes the PVID of the repository gets changes by CAA. #================================================================== if [[ -n $refnode && $refnode != $LOCAL_NODE ]]; then LSPV_OUT=$($CLRSH $refnode /usr/sbin/lspv | /usr/bin/grep -w caavg_private) elif [[ " $NODES " != *\ $LOCAL_NODE\ * ]]; then LSPV_OUT=$($CLRSH ${NODES%%+([[:space:]])*} /usr/sbin/lspv | /usr/bin/grep -w caavg_private) else LSPV_OUT=$(lspv | grep -w caavg_private) fi if [[ -n $LSPV_OUT ]]; then print -- "$LSPV_OUT" | read JUNK NEW_REPOS_PVID JUNK if [[ -n $NEW_REPOS_PVID && $NEW_REPOS_PVID != $current_repository ]]; then print "$0()[$LINENO]($SECONDS): The CAA repository PVID for site \"$site\" has changed from \"$current_repository\" to \"$NEW_REPOS_PVID\". Updating the HACMPsircol ODM to reflect this change." >>$CLMGR_TMPLOG print "$0()[$LINENO]($SECONDS): echo \"HACMPsircol: repository=$NEW_REPOS_PVID\" | odmchange -o HACMPsircol -q \"name=${site}_sircol\"" >>$CLMGR_TMPLOG print "HACMPsircol: repository=$NEW_REPOS_PVID" | odmchange -o HACMPsircol -q "name=${site}_sircol" print "$0()[$LINENO]($SECONDS): New HACMPsircol stanza is:" >>$CLMGR_TMPLOG odmget -q "name=${site}_sircol" HACMPsircol >>$CLMGR_TMPLOG print >>$CLMGR_TMPLOG # Since an ODM was updated, set the cluster "change" flag print "HACMPcluster: handle=0" | odmchange -o HACMPcluster current_repository=$NEW_REPOS_PVID fi else current_repository="" fi fi NODES=$(CL=$LINENO trim "$NODES") if [[ -n $current_repository ]]; then #============================================================ : See if the current repository still exists. Under certain : error conditions, the disk can be completely gone, which : will cause failures, and an early exit. However, that is : not desirable if a rebuild from the repository cache is : possible/intended. #============================================================ if [[ " $NODES " == *\ $LOCAL_NODE\ * ]]; then CL=$LINENO KLIB_HACMP_is_known_physical_volume "$current_repository" 2>>$CLMGR_TMPLOG else if [[ -n $refnode ]]; then REFNODE=$refnode else REFNODE=${NODES%% *} fi CL=$LINENO KLIB_HACMP_is_known_physical_volume "$current_repository" "$REFNODE" 2>>$CLMGR_TMPLOG fi if (( $? == RC_SUCCESS )); then #===================================================== : Get the various identifiers for the old repository #===================================================== IDENTIFIERS="" CL=$LINENO getDiskData "$current_repository" "$NODES" IDENTIFIERS true rc=$? if (( $rc == RC_SUCCESS )); then print -- "$IDENTIFIERS" |\ IFS=: read OLD_REPOS_NAME OLD_REPOS_PVID OLD_REPOS_UUID REFNODE REM else log_return_msg "$rc" "$0()" "$LINENO" return $? fi fi fi #===================================================== : Get the various identifiers for the new repository #===================================================== IDENTIFIERS="" CL=$LINENO getDiskData "$new_repository" "$NODES" IDENTIFIERS true rc=$? if (( $rc == RC_ERROR )); then rc=$RC_NOT_FOUND # No such disk found dspmsg -s $CLMGR_SET $CLMGR_MSGS 153 "Available Physical Volumes:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_physical_volume available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" elif (( $rc == RC_SUCCESS )); then print -- "$IDENTIFIERS" |\ IFS=: read NEW_REPOS_NAME NEW_REPOS_PVID NEW_REPOS_UUID REFNODE REM # REPOS_MIN_SIZE is set in func_include CL=$LINENO verify_disk "$NEW_REPOS_PVID" "$REFNODE" $REPOS_MIN_SIZE cmd_rc=$? (( $cmd_rc != RC_SUCCESS )) && rc=$cmd_rc fi if (( $rc != RC_SUCCESS )); then log_return_msg "$rc" "$0()" "$LINENO" return $? fi if [[ -z $NEW_REPOS_NAME || \ -z $NEW_REPOS_PVID ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 441 "\nERROR: could not determine the name and PVID of the replacement repository disk. Unable to proceed.\n\n" 1>&2 log_return_msg "$RC_ERROR" "$0()" "$LINENO" return $? fi if (( $rc == RC_SUCCESS || $rc == RC_UNKNOWN )); then if /usr/lib/cluster/incluster then #=============================================== : Make sure the required information was found #=============================================== if [[ -z $OLD_REPOS_NAME || \ -z $OLD_REPOS_PVID ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 424 "\nERROR: could not determine the name and PVID of the current repository disk. Unable to proceed.\n\n" 1>&2 log_return_msg "$RC_ERROR" "$0()" "$LINENO" return $? fi #============================================================== : Ask CAA to do the actual, physical replacement. The chrepos : command does not support remote site management, though. So : if this is a linked cluster, chrepos *must* be invoked on a : node within the site that it is being modified. #============================================================== # "NODES" is set to the either all nodes within the cluster, # for stretched or standard clusters, or else for linked # clusters to the nodes withing the specified site. #============================================================== if [[ " $NODES " == *\ $LOCAL_NODE\ * ]]; then #========================================================== : Scrub disk "$NEW_REPOS_NAME" on $LOCAL_NODE to eliminate : any possible interference from a former repository. #========================================================== print "$0()[$LINENO]($SECONDS): CAA_FORCE_ENABLED=true rmcluster -f -r $NEW_REPOS_NAME" >>$CLMGR_TMPLOG CAA_FORCE_ENABLED=true rmcluster -f -r $NEW_REPOS_NAME >>$CLMGR_TMPLOG 2>&1 print "$0()[$LINENO]($SECONDS): rmcluster RC: $?" >>$CLMGR_TMPLOG print "$0()[$LINENO]($SECONDS): chrepos -r -$OLD_REPOS_NAME,+$NEW_REPOS_NAME" >>$CLMGR_TMPLOG chrepos -r -$OLD_REPOS_NAME,+$NEW_REPOS_NAME 2>>$CLMGR_TMPLOG else #======================================================== : Scrub disk "$NEW_REPOS_NAME" on $REFNODE to eliminate : any possible interference from a former repository. #======================================================== print "$0()[$LINENO]($SECONDS): $CLRSH $REFNODE CAA_FORCE_ENABLED=true /usr/sbin/rmcluster -f -r $NEW_REPOS_NAME" >>$CLMGR_TMPLOG $CLRSH $REFNODE CAA_FORCE_ENABLED=true /usr/sbin/rmcluster -f -r $NEW_REPOS_NAME >>$CLMGR_TMPLOG 2>&1 print "$0()[$LINENO]($SECONDS): rmcluster RC: $?" >>$CLMGR_TMPLOG print "$0()[$LINENO]($SECONDS): $CLRSH $REFNODE /usr/sbin/chrepos -r -$OLD_REPOS_NAME,+$NEW_REPOS_NAME" >>$CLMGR_TMPLOG $CLRSH $REFNODE /usr/sbin/chrepos -r -$OLD_REPOS_NAME,+$NEW_REPOS_NAME 2>>$CLMGR_TMPLOG fi rc=$? print "$0()[$LINENO]($SECONDS): chrepos RC: $rc" >>$CLMGR_TMPLOG elif [[ -f /etc/cluster/clrepos_cache ]]; then if ! /usr/lib/cluster/clras dumprepos >/dev/null 2>&1 then #================================================== : Scrub disk "$NEW_REPOS_NAME" to eliminate any : possible interference from a former repository. #================================================== print "$0()[$LINENO]($SECONDS): CAA_FORCE_ENABLED=true rmcluster -f -r $NEW_REPOS_NAME" >>$CLMGR_TMPLOG CAA_FORCE_ENABLED=true rmcluster -f -r $NEW_REPOS_NAME >>$CLMGR_TMPLOG 2>&1 print "$0()[$LINENO]($SECONDS): rmcluster RC: $?" >>$CLMGR_TMPLOG #========================================================== : The node does not think it is in a cluster... but there : is a repository disk cache. This means a standard repos : replacement will not be possible, because the original : repository disk cannot be read/copied. In this case, an : attempt must be made to rebuild it from the cache file. #========================================================== print "$0()[$LINENO]($SECONDS): chrepos -c $NEW_REPOS_NAME" >>$CLMGR_TMPLOG chrepos -c $NEW_REPOS_NAME 2>>$CLMGR_TMPLOG rc=$? print "$0()[$LINENO]($SECONDS): chrepos RC: $rc" >>$CLMGR_TMPLOG if (( $rc == RC_SUCCESS )); then #==================================================== : Re-init the CAA cluster on all remote nodes that : are currently up. This helps ensure that when the : newly rebuilt repository will be accepted by the : remote, live nodes. The nodes that are still down, : however, will require the following command to be : run manually when they are brought back up, since : communication with the other nodes will no longer : be possible. #==================================================== for node in $(clnodename); do [[ $node == $LOCAL_NODE ]] && continue print "$0()[$LINENO]($SECONDS): $CLRSH $node \"CAA_FORCE_ENABLED=true /usr/sbin/clusterconf -fu\"" >>$CLMGR_TMPLOG $CLRSH $node "CAA_FORCE_ENABLED=true /usr/sbin/clusterconf -fu" >>$CLMGR_TMPLOG 2>&1 print "$0()[$LINENO]($SECONDS): clusterconf RC: $?" >>$CLMGR_TMPLOG done if [[ -n $OLD_REPOS_NAME ]]; then #================================================ : Make an attempt to clean up the old disk, but : only if the needed information is available. #================================================ print "$0()[$LINENO]($SECONDS): CAA_FORCE_ENABLED=true rmcluster -fr $OLD_REPOS_NAME" >>$CLMGR_TMPLOG CAA_FORCE_ENABLED=true rmcluster -fr $OLD_REPOS_NAME >>$CLMGR_TMPLOG 2>&1 print "$0()[$LINENO]($SECONDS): rmcluster RC: $?" >>$CLMGR_TMPLOG fi #====================================== : Tell this node to join the cluster, : using the newly rebuilt repository #====================================== print "$0()[$LINENO]($SECONDS): clusterconf" >>$CLMGR_TMPLOG clusterconf >>$CLMGR_TMPLOG 2>&1 cmd_rc=$? if [[ $cmd_rc == RC_SUCCESS ]]; then print "$0()[$LINENO]($SECONDS): clusterconf RC: $cmd_rc" >>$CLMGR_TMPLOG else print "$0()[$LINENO]($SECONDS): WARNING: clusterconf failed with RC: $cmd_rc \n clusterconf request has been queued and will be retired by clcomd,\n proceeding with rest of the operation. " >>$CLMGR_TMPLOG fi #=============================================== : Send a PROD to other nodes to rejoin cluster #=============================================== print "$0()[$LINENO]($SECONDS): clusterconf -p" >>$CLMGR_TMPLOG clusterconf -p >>$CLMGR_TMPLOG 2>&1 print "$0()[$LINENO]($SECONDS): clusterconf RC: $?" >>$CLMGR_TMPLOG fi fi fi if (( $rc == RC_SUCCESS )); then #=============================================================== : Under certain conditions, when chrepos runs, it can reassign : the PVID of a disk, so it will be different from what it was : before the chrepos. This can happen, for example, when a disk : has been damaged somehow, then repaired. Our testers use dd : to simulate it. To counter this, the CAA team recommended : re-reading the repository PVID, post-chrepos. #=============================================================== if [[ -n $REFNODE && $REFNODE != $LOCAL_NODE ]]; then LSPV_OUT=$($CLRSH $REFNODE /usr/sbin/lspv | /usr/bin/grep -w caavg_private) else LSPV_OUT=$(lspv | grep -w caavg_private) fi if [[ -n $LSPV_OUT ]]; then print -- "$LSPV_OUT" | read JUNK NEW_REPOS_PVID JUNK fi fi fi if (( $rc == RC_SUCCESS || $rc == RC_UNKNOWN )); then #================================================== : Replace the repository in the SystemMirror ODMs #================================================== print "$0()[$LINENO]($SECONDS): clmanagerepos -X -d $NEW_REPOS_PVID -n $REFNODE$siteOpt" >>$CLMGR_TMPLOG clmanagerepos -X -d $NEW_REPOS_PVID -n $REFNODE$siteOpt rc=$? print "clmanagerepos RC: $rc" >>$CLMGR_TMPLOG # Always log command result # : Add the previous active repository as a new backup repository : only if needed information is available. # if (( $rc == RC_SUCCESS )); then if [[ -n $OLD_REPOS_PVID ]]; then if [[ -n $site ]]; then OLD_BACKUP_REPOS=$(clodmget -n -q name=${site}_sircol -f backup_repository HACMPsircol) else OLD_BACKUP_REPOS=$(clodmget -n -f backup_repository HACMPsircol) fi typeset -i NB_OLD_BACKUP_REPOS=$(echo $OLD_BACKUP_REPOS | wc -w) NB_OLD_BACKUP_REPOS=${NB_OLD_BACKUP_REPOS:-0} typeset -i NB_BACKUP_REPOS=$((NB_OLD_BACKUP_REPOS + 1)) #================================================== : There must not be over $MAX_NB_OF_BACKUP_REPOSITORIES #================================================== if (( $NB_BACKUP_REPOS > $MAX_NB_OF_BACKUP_REPOSITORIES )); then if [[ $CLUSTER_TYPE == "LC" ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1445 '\nWarning: a linked cluster cannot have more than "%1$d" backup repositories per site (there were "%2$d" backup repositories) Hence primary repository disk will replace with new repository disk but not added to backup repositories list.\n\n' "$MAX_NB_OF_BACKUP_REPOSITORIES" "${NB_OLD_BACKUP_REPOS}" 1>&2 else cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1446 '\nWarning: a no-site cluster or a stretched cluster cannot have more than "%1$d" backup repositories (there were "%2$d" backup repositories) Hence primary repository disk will replace with new repository disk but not added to backup repositories list.\n\n' "$MAX_NB_OF_BACKUP_REPOSITORIES" "${NB_OLD_BACKUP_REPOS}" 1>&2 fi else print "$0()[$LINENO]($SECONDS): clmanagerepos -a -d $OLD_REPOS_PVID -n $REFNODE$siteOpt" >>$CLMGR_TMPLOG clmanagerepos -a -d $OLD_REPOS_PVID -n $REFNODE$siteOpt cmd_rc=$? print "clmanagerepos RC: $rc" >>$CLMGR_TMPLOG # Always log command result (( rc |= $cmd_rc )) fi fi fi if (( $rc == RC_SUCCESS )); then # Since an ODM was updated, set the cluster "change" flag print "HACMPcluster: handle=0" | odmchange -o HACMPcluster fi fi fi if (( $rc != RC_SUCCESS )); then if (( $rc != RC_MISSING_INPUT )); then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 725 '\nERROR: could not change the active repository disk to "%1$s". Please try with another disk.\n\n' "$new_repository" 1>&2 fi rc=$RC_ERROR elif /usr/lib/cluster/incluster then print cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 483 'New repository "%1$s" (%2$s) is now active and configuration has been updated.\n' "$NEW_REPOS_NAME" "$NEW_REPOS_PVID" cl_dspmsg -s 32 scripts 62 "Please use 'clmgr query repository' command on each node to verify new repository information.\n" print fi #======================================================================= : If a user input error was detected, provide some helpful suggestions #======================================================================= if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \ [[ $CLMGR_GUI == *([[:space:]]) ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \ "replace repository -h" "REPOSITORY:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_replace_repository()" #============================================================================ # # Name: devDoc # # Description: This is a never-to-be-called, wrapper function that all the # clmgr FPATH functions implement in order to hide embedded # syntax from trace logging. This information is implemented # in POD format, and can be viewed in a number of ways using # POD tools. Some viewing suggestions for this function's POD- # formatted information are: # # perldoc # pod2text -c # pod2text -c --code # pod2html # # However, the more important use for this information is that # it is parsed by clmgr to display the syntax for this file's # operation. The information in the "SYNOPSIS" section is used # for this purpose. This feature was originally implemented # using the man page information. However, in a code review it # was pointed out that this approach had to be changed because # customers do not have to install the man pages! Therefore, a # built-in dependency on man page information would break the # automatic help feature of clmgr. So the SYNPOSIS section must # be used instead. # # IMPORTANT: As a result of this, it is imperative that the # information in this SYNOPSIS be kept in sync # with the man page information, which is owned # by the IDD team. # # Inputs: None. # # Outputs: None. # # Returns: n/a (not intended to be invoked) # #============================================================================ function devDoc { : <<'=cut' >/dev/null 2>&1 =head1 NAME KLIB_HACMP_replace_repository =head1 SYNOPSIS clmgr replace repository [ ] \ [ SITE= ] \ [ NODE= ] NOTE: if no disk is specified, the backup list will be used. NOTE: the alias for "repository" is "rp". =head1 DESCRIPTION Attempts to replace the current, active repository disk with the specified new disk. =head1 ARGUMENTS 1. new_repository [OPTIONAL] [string] The name of the new repository disk. This value may be the device name, PVID, or UUID. Any appropriate, required format conversion will be done automatically. If nothing is specified here, an attempt is made to use the first backup repository disk, if defined. 2. site [OPTIONAL] [string] The label of the site that this repository supports. This is only needed/valid for a linked cluster environment. 3. refnode [OPTIONAL] [string] The label of node to use as a reference for resolving the specified disk names. This is only useful if device names are specified instead of PVIDs. If no node is provided, and effort is made to automatically find a suitable reference node. =head1 RETURN 0: no errors were detected; the operation appears to have been successful 1: a general error has occurred 2: a specified resource does not exist, or could not be found 3: some required input was missing 4: some detected input was incorrect in some way 5: a required dependency does not exist 6: a specified search failed to match any data =cut } # End of "devDoc()" #============================================================================== # The following, comment block attempts to enforce coding standards when this # file is edited via emacs or vim. This block _must_ appear at the very end # of the file, or the editor will not find it, and it will be ignored. #============================================================================== # Local Variables: # indent-tabs-mode: nil # tab-width: 4 # End: #============================================================================== # vim: tabstop=4 shiftwidth=4 expandtab #==============================================================================