#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r721 src/43haes/usr/sbin/cluster/events/utils/cl_update_vg_odm_ts.sh 1.13 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2013,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/usr/sbin/cluster/events/utils/cl_update_vg_odm_ts.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM # #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================ ################################################################################ # # Name: update_vg_odm_ts # # Function: Given a volume group, check to see if any disk in the volume # group has a time stamp different from the time stamp for the # volume group in ODM. If so, update the ODM time stamp to match # that of the disk. # # Then, update the time stamp in the ODMs of any other nodes in # the resource group that owns this volume group. # # # Input: Volume group name, optionally followed by node list # # If only the volume group name is given, the time stamps are # updated on the nodes in the resource group containing the volume # group. # If a node list is given, the volume group time stamps are updated # on all nodes in the list. The node list is a list of PowerHA # node names, either space or comma separated. # # # Output: return code = 0 - volume group time stamp successfully updated # return code = 1 - no volume group name provided # return code = 2 - cannot read volume group VGID from ODM # return code = 3 - cannot read current volume group time stamp # from ODM # # Notes: This routine only updates the volume group timestamps in ODM on # the various nodes. It does not do a true synchronization of the # volume group metadata. It is intended to deal with the fact # that, varying off a volume group updates the time stamps, and # only recent versions of LVM automatically propagate that change # to other nodes. Updating these time stamps across the cluster # avoids problem reports on the next verify and sync, and possibly # long recovery times. # ################################################################################# if [[ $VERBOSE_LOGGING == 'high' ]] then PS4_TIMER=true set -x version='1.13' fi ################################################################################# # # Name: lspv_in_vg # # Function: Given the name of a volume group, find the names of the hdisks in # that volume group by direct query of CuAt. # # This direct query of CuAt avoids LVM locking and other overhead # that is significant with very large numbers of disks and volume # groups. # # Input: Volume group name # # Output: hdisk names in the volume group written to stdout, one per line # ################################################################################# function lspv_in_vg { if [[ $VERBOSE_LOGGING == 'high' ]] then PS4_FUNC='lspv_in_vg' set -x fi typeset vg_name=$1 clodmget -q "name = $vg_name and attribute = pv" -f value -n CuAt | while read pvid ; do # : Find the name of the disk with PVID $pvid # clodmget -q "value = $pvid and attribute = pvid" -f name -n CuAt done } ################################################################################ # # MAIN Main main # # o_flag="" f_flag="" while getopts ':of' option do case $option in o ) : Local timestamps should be good, since volume group was : just varyied on or off o_flag=TRUE ;; f ) : Update timestamps clusterwide, even if LVM support is in : place f_flag=TRUE ;; * ) : dspmsg -s 4 cspoc.cat 26 "$PROGNAME: Invalid option [$option].\n" $PROGNAME $option return 1 ;; esac done shift $((OPTIND - 1)) vg_name=$1 if [[ -z $vg_name ]] then print "cl_update_vg_odm_ts []" return 1 # Bad input - missing volume group name fi shift node_list=$* PATH=$(/usr/es/sbin/cluster/utilities/cl_get_path all) if [[ -z $f_flag ]] then ################################################################################ : Check to see if this update is necessary - some LVM levels automatically : update volume group timestamps clusterwide. # # Complex check below needed to catch various versions of LVM efix # if instfix -iqk IV74100 > /dev/null 2>&1 || instfix -iqk IV74883 > /dev/null 2>&1 || instfix -iqk IV74698 > /dev/null 2>&1 || instfix -iqk IV74246 > /dev/null 2>&1 then # : LVM APAR installed which makes timestamp update unnecessary # return 0 fi if ( $(emgr -l -L IV74883 2>/dev/null >&2) || $(emgr -l -L IV74698 2>/dev/null >&2) || $(emgr -l -L IV74246 2>/dev/null >&2) ) then # : LVM efix installed which makes timestamp update unnecessary # return 0 fi # : Each of the V, R, M and F fields are padded to fixed length, : to allow reliable comparisons. E.g., maximum VRMF is : 99.99.999.999 # typeset -li V R M F typeset -Z2 V # two digit version typeset -Z2 R # two digit release typeset -Z3 M # three digit modification typeset -Z3 F # three digit fix typeset -li lvm_lvl6=601008015 # minimum lvm level needed for # automatic timestamp update typeset -li lvm_lvl7=701003046 # minimum lvl level, AIX 7 typeset -li VRMF=0 # : Here try and figure out what level of LVM is installed # lslpp -lcqOr bos.rte.lvm | cut -f3 -d':' | IFS=. read V R M F VRMF=$V$R$M$F # get the LVM level if (( $V == 6 && $VRMF >= $lvm_lvl6 )) || (( $VRMF >= $lvm_lvl7 )) then # : LVM at a level in which timestamp update is unnecessary # return 0 fi ################################################################################ fi found_new_ts="" # : Try to update the volume group ODM time stamp on every other node : in the resource group that owns $vg_name # if [[ -z $node_list ]] then # : We were not given a node list. The node list is derived from : the resource group that the volume group is in. # group_name=$(/usr/es/sbin/cluster/utilities/clodmget -q "name like *VOLUME_GROUP and value = $vg_name" -f group -n HACMPresource) if [[ -n $group_name ]] then # : Find all other cluster nodes in the resource group that owns : the volume group $vg_name # node_list=$(/usr/es/sbin/cluster/utilities/clodmget -q "group = $group_name" -f nodes -n HACMPgroup) fi fi # : Check to see if the volume group is known locally # if [[ -z $(odmget -q "name = $vg_name and PdDvLn = logical_volume/vgsubclass/vgtype" CuDv) ]] then # : Volume group $vg_name is not defined on this node # if [[ -n $node_list ]] then # : If the vg is not visible on the local node, then delegate : this work to some other node in the node_list # LOCALNODENAME=${LOCALNODENAME:-$LOCAL_NODE} LOCALNODENAME=${LOCALNODENAME:-$(get_local_nodename 2> /dev/null)} if [[ -n $LOCALNODENAME ]] then node_list=$(print "$node_list" | tr ' ' '\n' | tr ',' '\n' | grep -v -w -x $LOCALNODENAME | paste -s -d' ' -) fi if [[ -n $node_list ]] then print -- "$node_list" | read node rest /usr/es/sbin/cluster/sbin/cl_on_node -cspoc "-f -n $node" "/usr/es/sbin/cluster/events/utils/cl_update_vg_odm_ts $vg_name \"$node_list\"" fi fi return 0 # # The astute reader will note that if this routine is # called with no node list, for a volume group not known # locally, no effort is made to check other nodes. # fi # : Get the vgid for volume group $vg_name # if ! vgid=$(getlvodm -v $vg_name) then return 2 # Cannot get volume group VGID from ODM fi # : Get the volume group timestamp for $vg_name : as currently saved in ODM # if ! current_odm_ts=$(getlvodm -T $vgid) then return 3 # Cannot get volume group time stamp from ODM fi if [[ $o_flag != "TRUE" ]] then typeset -E24 E_current_odm_ts # digits for significance typeset -E24 E_disk_ts # digits for significance # : We only have to check the volume group time stamps against : the disk time stamps if the volume group is not currently : on line. # if ! lsvg -o -L | grep -x -q -w $vg_name then # : Volume group $vg_name is not on line # # : Examine all the disk in volume group $vg_name : looking for one with a timestamp different from : what is currently in ODM # for vg_disk in $(lspv_in_vg $vg_name) do if disk_ts=$(lqueryvg -Tp $vg_disk) then if [[ $disk_ts != $current_odm_ts ]] then # : Turn the timestamps into large positive integers, : since these are 'ticks since epoch'. # E_disk_ts=16#0${disk_ts} (( $E_disk_ts < 0 )) && (( E_disk_ts = - $E_disk_ts )) E_current_odm_ts=16#0${current_odm_ts} (( $E_current_odm_ts < 0 )) && (( E_current_odm_ts = - $E_current_odm_ts )) if (( $E_disk_ts > $E_current_odm_ts )) then # : Disk $vg_disk has a larger - more recent - time : stamp than the ODM timestamp for $vg_name # current_odm_ts=$disk_ts found_new_ts="true" fi fi fi done if [[ -n $found_new_ts ]] then # : Update CuAt, and the copy in the boot image for the local node # putlvodm -T $current_odm_ts $vgid && /usr/sbin/savebase > /dev/null fi fi fi # : Is an update necessary? # if [[ -n $node_list ]] then LOCALNODENAME=${LOCALNODENAME:-$LOCAL_NODE} LOCALNODENAME=${LOCALNODENAME:-$(get_local_nodename 2> /dev/null)} if [[ -n $LOCALNODENAME ]] then # : Skip the local node, since we have done that above. # node_list=$(print "$node_list" | tr ' ' '\n' | tr ',' '\n' | grep -v -w -x $LOCALNODENAME | paste -s -d, -) else # : Make sure we have a comma separated list # node_list=$(print "$node_list" | tr ' ' '\n' | tr ',' '\n' | paste -s -d, -) fi # : Update the time stamp on all those other nodes on which the : volume group is currently varied off. LVM will take care of : the others. # if [[ -n $node_list ]] then _CSPOC_CALLED_FROM_SMIT=true cl_on_node -cspoc "-f -n $node_list" "lsvg -o | grep -qx $vg_name || /usr/sbin/putlvodm -T $current_odm_ts $vgid && /usr/sbin/savebase > /dev/null" fi fi return 0