#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2018,2019,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r720 src/43haes/usr/sbin/cluster/cspoc/utilities/cllspvids.sh 1.25 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1999,2015 
# 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/cllspvids.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM
# 
###############################################################################
#
#   COMPONENT_NAME: CSPOC 
#
# Name:
#   cllspvids
#
# Description:
#   Use C-SPOC to acquire a list of free physical volumes known on all of a
#   given list of nodes, suitable for either concurrent or non-concurrent
#   volume groups, as specified.
#
# Arguments:
#
#   cllspvids [-n|-c|-A] [-p] [-r N:M] node_name {node_name ...]
#
#   '-c' implies that the disks should be suitable for a concurrent volume
#	 group
#
#   '-n' implies no such requirement
#
#   '-A' list all disks, including those in use
#
#   '-p' colon separated output
#
#   '-P' pick list formatted output
#
#   '-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.
#
#   '-O' Do not show Oracle raw disks
#
#   '-u' check that UUIDs match to ensure disks are really the same
#
#   '-R' checks specific to repository disk
#
#   The list of node names are those on which the disk(s) must exist
#
# Return Values:
#   return code of 1 set if no disks found matching the criteria
#
#   Otherwise, a list of disks matching the criteria is written to standard
#   out, one per line
#
################################################################################

PROGNAME=${0##*/}
PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)"
export PATH
if [[ -n $_DEBUG ]] && (( $_DEBUG == 9 ))
then
    print "DEBUG $PROGNAME version 1.24"
    if (( $_DEBUG == 9 ))
    then
	export PS4='${PROGNAME}[$LINENO]: '
	set -x
    fi
    db_flag="-d $_DEBUG"
fi

# Check if RBAC is enabled
typeset is_rbac_enabled=""
is_rbac_enabled=$(clodmget -nq "group=LDAPClient and name=RBACConfig" -f value HACMPLDAP 2>/dev/null)

# For a non root user, append the user name to the output file.
[[ -z "$LOGIN" ]] && user_name=$(id -nu 2>/dev/null) || user_name="$LOGIN"
if [[ $user_name != "root" && $is_rbac_enabled == "YES" ]];then
    CL_DATFILE="/var/hacmp/tmp/cllspvids.out"_$user_name
else
    CL_DATFILE="/var/hacmp/tmp/cllspvids.out"
fi

SMIT_PVIDDISKLIST=""
format_flag=""
all_disks=""
RAW_DISKS=""
integer total_lines
integer uniq_pvids
typeset NO_ORACLE=""
typeset UUID_check=""
typeset REPOSITORY=""

#
:   Pick up the type flag and the node list.  Note that type flag is required.
#
while getopts ":cnpPAOur:R" opt
do
    case $opt in 
	c ) :	Anything that will support Enhanced Concurrent Mode
	    GREP_OPT=':C:Y'
	    ;;

	n ) :	Anything 
	    GREP_OPT=""
	    ;;

	p ) :	Colon delimited output
	    format_flag='-c'
	    ;;

	P ) :	Pick list formatted output
	    format_flag='-P'
	    ;;

        r ) :   Pick up the range requirement
            RANGE="-${opt} $OPTARG"
	    ;;

	A ) :	All disks
	    all_disks='-A'
	    ;;

	O ) :	Do not list raw Oracle disks
	    NO_ORACLE='-O'
	    ;;

	u ) :   Check UUIDs in addition to PVIDs to be disks are the same 
	    UUID_check='-u'
	    ;;

	R ) :	Checks specific to repository disk and not to list raw Oracle disks
	    REPOSITORY='-R'
	    NO_ORACLE='-O'
	    ;;

	* )
	    print "cllspvids [-n|-c] [-p | -P] [-u] [-r N:M] node_name [node_name ...]"
	    return -1
	    ;;
    esac
done
shift $(( $OPTIND - 1 ))			    # remove options, leaving node list

#
:   Get a comma separated list of nodes
#
#   Input node list can be either comma, or space separated, or some combination
#   First, get a purely space separated list.  Then generate comma and | separted
#
NODES=$(IFS=, set -- $@ ; print $* )		    # space separated list
CSPOC_NODES=$(IFS=, set -- $NODES; print "$*")	    # comma separated list
FILTER_NODES=$(IFS=\| set -- $NODES; print "$*")    # '|' separated list, for use in egrep below

#
:   Go find all free disks across the given set of nodes
:   Returned file is in the form:
:   node: hdisk:pvid:concurrent_capable:ECM_only:size
:   FREEMAJORS:
#
cl_lspvids -cspoc "-n $CSPOC_NODES $db_flag" $all_disks $NO_ORACLE $UUID_check $RANGE $REPOSITORY > $CL_DATFILE

#
: Change the ownership of output file, for a non root user.
#
[[ $user_name != "root" ]] && chown $user_name $CL_DATFILE

#
:   If there were any free disks found, select for commonality and concurrency
#
if [[ -s $CL_DATFILE ]]
then
    if [[ -z $all_disks ]]
    then
	#
	:   If we are building a pick list for disk allocation, filter out
	:   repository, back up repository, and tie breaker disks
	#
	#   Because of the inconsistency in ODM structure, the PVIDs 
	#   sometimes come out as space separated, and sometimes as
	#   new line separated.  We turn them into a single string 
	#   with a '|' separator, to use in the egrep -v command 
	#   below, meaning skip all of these.
	#
        filter_pvids=$(/usr/es/sbin/cluster/utilities/clodmget -f repository -n HACMPsircol)

        ba_repos_pvids=$(/usr/es/sbin/cluster/utilities/clodmget -f backup_repository -n HACMPsircol)
        if [[ -n $ba_repos_pvids ]]
        then
            filter_pvids=${filter_pvids:+${filter_pvids}"|"}$ba_repos_pvids
        fi

        tie_breaker=$(/usr/es/sbin/cluster/utilities/clodmget -q "policy = tiebreaker" -f value -n HACMPsplitmerge)
        if [[ -n $tie_breaker ]]
        then
            filter_pvids=${filter_pvids:+${filter_pvids}"|"}$tie_breaker
        fi

	disk_pvids=$(/usr/es/sbin/cluster/utilities/clodmget -q "name = DISK" -f value -n HACMPresource)
	if [[ -n $disk_pvids ]]
	then
            filter_pvids=${filter_pvids:+${filter_pvids}"|"}$disk_pvids
	fi

	if [[ -n $filter_pvids ]]
	then
	    #
	    :	Remove those disks which are used for some other purpose
	    #
	    filter_pvids=$(print "${filter_pvids}" | paste -s -d'|' - | tr ' ' '|')
	    egrep -v $filter_pvids $CL_DATFILE > ${CL_DATFILE}.1
	    #
	    : Change the ownership of output file, for a non root user.
	    #
	    [[ $user_name != "root" ]] && chown $user_name ${CL_DATFILE}.1
	    mv -f ${CL_DATFILE}.1 ${CL_DATFILE}
	fi
    fi

    #
    :	Trim off the free major number information,
    :	perform any concurrency selection,
    :	select disks only from nodes of interest,
    :	and pass the rest to cl_pviddisklist to give the common PVID, 
    :	HDISK and node information.  Lines are of the form
    :	node[,node,node]: hdisk:pvid
    :	meaning that pvid is known as that hdisk on that list of nodes.
    #
    if ! SMIT_PVIDDISKLIST=$(grep -v 'FREEMAJORS'  $CL_DATFILE | \
			     grep "$GREP_OPT" | \
			     egrep -w "$FILTER_NODES" | \
			     cl_pviddisklist $format_flag $UUID_check $CSPOC_NODES)
    then
	#
	:   Any error return code cl_pviddisklist is passed back, generally 
	:   indicating no disks found
	#
	print "$SMIT_PVIDDISKLIST"		# any error msg
	exit 1
    fi
fi

#
:   Check to make sure we have some output
#
if [[ -z $SMIT_PVIDDISKLIST ]]
then
    #
    :	No output from cl_pviddisklist - let the user know
    #
    msg_line=$(dspmsg -s 43 cspoc.cat 6 "No free disks found.");
    printf '# %s\n' "${msg_line}"
    msg_line=$(dspmsg -s 43 cspoc.cat 42 "Check each node to see if any disks need to have PVIDs allocated.");
    printf '# %s\n' "${msg_line}"
    exit 1

else 
    #
    :   Print out any disks we found
    #
    if [[ $format_flag == '-P' ]]
    then
	#
	:   If using new pick list format, see if disk names are unique
	#
	total_lines=$(print "$SMIT_PVIDDISKLIST" | wc -l)
	uniq_pvids=$(print "$SMIT_PVIDDISKLIST" | cut -f2 -d '(' | cut -f1 -d ')' | sort -u | wc -l)
	if (( $total_lines == $uniq_pvids ))
	then
	    #
	    :	Since hdisk names are unique over $CSPOC_NODES, sort 
	    :	output by hdisk name for improved output look
	    #
	    print "$SMIT_PVIDDISKLIST" | sort -n -b -t' ' -k1.6,1
	else
	    print "$SMIT_PVIDDISKLIST"
	fi
    else
	print "$SMIT_PVIDDISKLIST"
    fi
    exit 0
fi
