#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 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/usr/sbin/cluster/cspoc/utilities/clgetpvid.sh 1.28 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1999,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/cspoc/utilities/clgetpvid.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 #================================================ # # Component: hacmp.cspoc # # Function: returns a list of the known disks not currently in a volume # group, along with an indication of whether they can support a # concurrent mode volume group # # returns the size of the disk # # '-r' gives a range of disk sizes, in megabytes, of the form 'N:M' # if either is left off, there is no limit on that end of the # range. E.g., "-r 1000:64000" says the disk must be between # 1 and 64 GB, as returned by "bootinfo -s", while "-r 1000:" # would mean all disks larger than 1GB, and "-r :64000" would # mean all disks less than 64 GB. # # '-A' returns information on all disks, including those in a # volume group # # '-u' adds the disk UUID to the output # # '-R' checking associated with potential repository disks # # returns a list of the free major numbers for logical volumes # # If a free disk does not have a PVID associated with it, and it is # not in use as a raw disk, a PVID is assigned. # # Output is of the form: # # hdisk4:00c48bb0d1f9c3d5:C:Y:5120 # hdisk6:00c48bb052afaeae:C:Y:140013 # hdisk11:00c48bb04bd88346:C:Y:10240 # FREEMAJORS:53... # # Origins: 27 # # Arguments: None # # Environment:None # ############################################################################# # : Load the "CL_PVID_ASSIGNMENT" from the environment file, if : present, allowing for any unexpected leading whitespace. # typeset TAB=$'\t' typeset INDENT="$TAB " eval $(grep -w '^[$INDENT]*CL_PVID_ASSIGNMENT' /etc/environment) PROGNAME=${0##*/} PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)" if [[ $VERBOSE_LOGGING == "high" ]] then set -x version='1.28' fi integer DISK_SIZE=0 integer MIN_SIZE=0 integer MAX_SIZE=0 integer NO_ORACLE=0 integer ALL_DISKS=0 integer ADD_UUID=0 integer REPOSITORY=0 typeset ineligible_disk_criteria="" # : Directory to hold work files # if [[ -d /var/hacmp/log/ksh93_tmp ]] then TMPDIR='/var/hacmp/log/ksh93_tmp' else TMPDIR='/var/hacmp/log' fi # : Common classification of disk types # if [[ -x /usr/sbin/gsclvmd ]]; then # : If the group services CLVM daemon is present, : pretty much anything can be used in a concurrent : volume group # CONCURRENT="C" ENHANCE_CONCURRENT_ONLY="Y" else # : Anything else cannot be used in a concurrent volume group # CONCURRENT="N" ENHANCE_CONCURRENT_ONLY="N" fi # : This script uses the following temporary work files # rm -f ${TMPDIR}/clgetpvid_[1-7].$$ # 1 - all hdisks and their UUIDs, sorted by UUID # 2 - all UUIDs for defined RAW_DISKs, sorted by UUID # 3 - hdisks and UUIDs for RAW_DISKs, sorted by hdisk name # 4 - lspv output, sorted by hdisk name # 5 - returned disk information # 6 - all hdisks and their UUIDs, sorted by hdisk name # 7 - all hdisks minus any raw disks # : Check for a specified size range # while getopts ':Ar:OuR' option do case $option in r ) print $OPTARG | IFS=: read MIN_SIZE MAX_SIZE # : Disks must be between $MIN_SIZE and $MAX_SIZE # ;; O ) : Do not list any Oracle raw disks NO_ORACLE=1 ;; A ) : Look at all known disks ALL_DISKS=1 ;; u ) : Append disk UUID to returned information ADD_UUID=1 LC_ALL=C /usr/es/sbin/cluster/utilities/cl_get_rdisks | sort -b -k2,2 > ${TMPDIR}/clgetpvid_1.$$ ;; R ) : Repository disk checks NO_ORACLE=1 REPOSITORY=1 ;; * ) : Invalid operand return 1 ;; esac done # # Disks that are not to be managed by AIX LVM/associated with different # storage management can, in some cases, be identified based on criteria # given in the cl_disk_tags.lst file. # if [[ -s /usr/es/sbin/cluster/etc/cl_disk_tags.lst ]] then # : Disks that match the criteria mentioned in the file should not be considered : for adding PVID automatically. # ineligible_disk_criteria=${TMPDIR}/clgetpvid_idc.$$ grep -v '^#' /usr/es/sbin/cluster/etc/cl_disk_tags.lst | sort -b -k1,1 | cut -f1,2 -d' ' > $ineligible_disk_criteria fi # : Check if vpath is installed and get list of vpath disks # if [[ -x /usr/sbin/lsvpcfg ]] then lsvpcfg > ${TMPDIR}/lsvpcfg.out.$$ 2>> ${TMPDIR}/lsvpcfg.err fi # : If there are defined raw disks - which are known only by their UUID - they are : not available as free disks, and should not have a PVID assigned. # if (( ! ALL_DISKS )) # if we don't want everything then # : First, get a list of all hdisks and their UUIDs, sorted by UUID # if (( ! ADD_UUID )) # Not already collected above then LC_ALL=C /usr/es/sbin/cluster/utilities/cl_get_rdisks | sort -b -k2,2 > ${TMPDIR}/clgetpvid_1.$$ fi # : Get a list of all the UUIDs for defined RAW_DISKs known to PowerHA : sorted by UUID # /usr/es/sbin/cluster/utilities/clodmget -q "name = RAW_DISK" -f value -n HACMPresource | sort -b > ${TMPDIR}/clgetpvid_2.$$ if [[ -s ${TMPDIR}/clgetpvid_1.$$ && -s ${TMPDIR}/clgetpvid_2.$$ ]] then # : If the above two operations found anything, get a list of : hdisks and their corresponding UUIDs, sorted by hdisk name : for all defined RAW_DISKs # join -1 2 ${TMPDIR}/clgetpvid_1.$$ ${TMPDIR}/clgetpvid_2.$$ | cut -f2 -d' ' | sort -b -k1,1 > ${TMPDIR}/clgetpvid_3.$$ fi fi if [[ -s ${TMPDIR}/clgetpvid_3.$$ ]] # If there are RAW_DISKs known on this node then # : Get a list of physical volumes known on this node, sorted by hdisk name # lspv -L | sort -b -k1,1 > ${TMPDIR}/clgetpvid_4.$$ # : Finally, use the join command to remove from the list generated by lspv : all those disks which are RAW_DISKs # join -v 2 -1 1 -2 1 ${TMPDIR}/clgetpvid_3.$$ ${TMPDIR}/clgetpvid_4.$$ >${TMPDIR}/clgetpvid_7.$$ else # : No defined RAW_DISKs present, or want them all, so just use lspv output # lspv -L >${TMPDIR}/clgetpvid_7.$$ fi typeset -i caa_4KDisk_available=0 if (( $REPOSITORY )) then #================================================== : Check 4KDisk Capability Availability #================================================== if LC_ALL=C cl_get_capabilities -q -i 4KDISK then caa_4KDisk_available=1 fi fi sort -r ${TMPDIR}/clgetpvid_7.$$ | while read DISK PVID VG rest do valid_flag="TRUE" if [[ "None" != $VG ]] && (( ! ALL_DISKS )) then # : Skip disks that are already in a volume group # continue elif [[ "none" == $PVID ]] && (( ! ALL_DISKS )) then # : If the device does not have a PVID assigned, see if one : can be assigned. This is only done in the case where the : actual PVID on the platter is not already present in CuAt, : which would be the case for a disk that is part of a : multipath object. # # : Recognized values for CL_PVID_ASSIGNMENT are "false", "no", : "disable", or zero. Any other value preserved the default : behavior, allowing PVIDs to be automatically assigned, as : needed. # if [[ -n $CL_PVID_ASSIGNMENT && $CL_PVID_ASSIGNMENT == @(f|F|n|N|d|D|0)* ]] then : The customer has explicitly disabled automatic PVID assignment continue fi if ! On_disk_PVID=$(VERBOSE_LOGGING="" /usr/es/sbin/cluster/events/utils/cl_querypv $DISK 2>>${TMPDIR}/clgetpvid.err) then continue # Cannot read disk, assign PVID won't work elif [[ -z $On_disk_PVID ]] then continue # Cannot read disk, assign PVID won't work else if [[ -z $(odmget -q "attribute = pvid and value = $On_disk_PVID" CuAt) ]] then # : There is something on the disk - might just be zeros : See if the disk is ineligible for PVID assignment : before doing so. # if [[ -n $ineligible_disk_criteria ]] then # : Check to see if this disk has a flag on it that makes : it ineligible for PVID assignment. # lquerypv -h /dev/${DISK} | join -1 1 -2 1 -o 2.1,1.2,2.6 $ineligible_disk_criteria - |\ while read field_offset field_content xlate ; do xlate=${xlate##\|} if [[ $xlate == ${field_content}* ]] then # : Disk ${DISK} is ineligible for PVID assignment : because the field at offset 0x${field_offset} : has value $xlate which matches the criteria : $field_content from cl_disk_tags.lst # valid_flag="FALSE" break fi done # # The careful reader will note that the above algorithm # assumes that the field to be searched for starts on a # 16 byte boundary, and is no more than 16 bytes long, # and is a character - as opposed to hex - string. This # works, as of this writing, for disks used by Oracle ASM (R) # fi if [[ $valid_flag == "TRUE" ]] then # : This is an eligible disk, try assigning a PVID # chdev -l $DISK -a pv=yes >/dev/null 2>>${TMPDIR}/clgetpvid.err PVID=$(/usr/es/sbin/cluster/utilities/clodmget -q "name = $DISK and attribute = pvid" -f value -n CuAt) PVID=${PVID:-none} PVID=${PVID%0000000000000000} # : Now, try that test again # if [[ "none" == $PVID ]]; then # : Skip disks that do not have a PVID assigned # continue else # : Record newly assigned pvid disks list # PVID_ASSIGNED_DISKS=${PVID_ASSIGNED_DISKS:+$PVID_ASSIGNED_DISKS, }$DISK fi else # : This is an ineligible disk and should not be assigned a PVID # continue fi else # : Skip disks if "On_disk_PVID" is already assigned to : another device, i.e. part of a multipath object # continue fi fi fi if [[ -s ${TMPDIR}/lsvpcfg.out.$$ && # We have vpath configuration information, and $DISK != @(vpath*) && # this disk is not a vpath, and $(grep -w "$DISK" ${TMPDIR}/lsvpcfg.out.$$ | cut -d'(' -f 2 | cut -d')' -f 1 | grep -w "pv") ]] # the corresponding vpath is a physical volume then # : Skip disks that have PVID on a vpath and hdisk # continue fi # : Pick up the size of the disk while we are at it : Skip any disk that does not meet the size requirements # /usr/sbin/bootinfo -s $DISK 2>/dev/null | read DISK_SIZE DISK_SIZE=${DISK_SIZE:-0} if (( $MIN_SIZE != 0 && $DISK_SIZE < $MIN_SIZE )) then continue elif (( $MAX_SIZE != 0 && $DISK_SIZE > $MAX_SIZE )) then continue fi # : Checks for potential repository disks. : Skip any disks with block size other than 512 bytes. # if (( $REPOSITORY )) then VERBOSE_LOGGING="" blk_size=$(cl_querypv -b $DISK 2>>${TMPDIR}/clgetpvid.err) # Skip any disks with block size other than 512 bytes and 4K as CAA only supports disk with 512 and 4K block size. if (( caa_4KDisk_available != 1 && $blk_size != 512 )) then continue elif (( caa_4KDisk_available == 1 && $blk_size != 512 && $blk_size != 4096 )) then continue fi fi # : If requested, do not list any Oracle ASM disks # if (( NO_ORACLE )); then if [[ -n $ineligible_disk_criteria ]] then # : Check to see if this disk has a flag on it that makes : it ineligible for PVID assignment. # typeset -i ORACLE=0 lquerypv -h /dev/${DISK} | join -1 1 -2 1 -o 2.1,1.2,2.6 $ineligible_disk_criteria - |\ while read field_offset field_content xlate ; do xlate=${xlate##\|} if [[ $xlate == ${field_content}* ]] then ORACLE=1 break fi done (( ORACLE )) && continue fi fi # : Pass back the collected data # if (( ! ADD_UUID )) then print "${DISK}:${PVID}:${CONCURRENT}:${ENHANCE_CONCURRENT_ONLY}:${DISK_SIZE}" else print "${DISK}:${PVID}:${CONCURRENT}:${ENHANCE_CONCURRENT_ONLY}:${DISK_SIZE}" >> ${TMPDIR}/clgetpvid_5.$$ fi done if [[ -n $PVID_ASSIGNED_DISKS ]] then # : Logging pvid assignment details to cspoc.log # MSG="One or more disks were assigned PVID. They are $PVID_ASSIGNED_DISKS" CSPOC_DIR=$(clodmget -q "name = cspoc.log" -f value -n HACMPlogs) typeset DATE=$(LC_ALL=C date +'%D %T') typeset LHOST=$(get_local_nodename) print -- "$DATE $LHOST: $MSG" >> $CSPOC_DIR/cspoc.log logger -p user.info "$DATE $LHOST: $MSG" fi if (( ADD_UUID )) then # : As requested, add the UUID, if present, for each disk to the output # sort -b -k1,1 ${TMPDIR}/clgetpvid_1.$$ | sed 's/ */:/' > ${TMPDIR}/clgetpvid_6.$$ if [[ -s ${TMPDIR}/clgetpvid_5.$$ ]] then sort -t: -b -k1,1 ${TMPDIR}/clgetpvid_5.$$ | join -t: -1 1 -2 1 -a 1 - ${TMPDIR}/clgetpvid_6.$$ fi fi # : Clean up work files, if not saved for debugging # if [[ $VERBOSE_LOGGING != 'high' ]] then rm -f ${TMPDIR}/lquerypv.out rm -f $ineligible_disk_criteria rm -f ${TMPDIR}/lsvpcfg.out.$$ rm -f ${TMPDIR}/clgetpvid_[1-7].$$ fi # : And also pass back the free major numbers # print -- "FREEMAJORS:$(lvlstmajor)"