#!/usr/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos72V src/bos/kernext/storfwork/dp/dpcom_collect.sh 1.3 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2019,2020 
# 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 
#-------------------------------------------------------------------------------
# This shell script is shipped with devices.common.IBM.storfwork.rte and is 
# installed in /usr/lib/ras/snapscripts/ for RAS data collection (snap). 
# This script gets executed as a part 'snap -a' and 'snap -g' invocations.
#-------------------------------------------------------------------------------


#-------------------------------------------------------------------------------
# Global variables
#-------------------------------------------------------------------------------
export DATE="/usr/bin/date"
export DUMPCTRL="/usr/sbin/dumpctrl"
export CTCTRL="/usr/sbin/ctctrl"
export LIVEDUMPSTART="/usr/bin/livedumpstart"
export DU="/usr/bin/du"
export CP="/usr/bin/cp"

#-------------------------------------------------------------------------------
# Wrapper function to execute commands with timestamp and banner
#-------------------------------------------------------------------------------
function exe_cmd
{
    [[ -n $DPCOM_RAS_DEBUG ]] && set -x

    typeset cmd=$*
    typeset rc
    typeset date_time_now="$(${DATE} +%d-%b-%Y_%H:%M:%S)"

    print -u2 "#-------------------------------------------------------------------------------"
    print -u2 "# ${date_time_now} ->  Executing '${cmd}'"
    print -u2 "#-------------------------------------------------------------------------------"

    eval ${cmd}
    rc=$?
    (( rc != 0 )) && {
        print -u2 "Cmd '${cmd}' failed with rc=${rc}."
        return $rc
    }

    print -u2 ""
    print -u2 ""
    return 0
}

#-------------------------------------------------------------------------------
# Return true(0) if DPCOM is configured
# 
# We ascertain this by checking if a RAS component named 'dpcom' has been
# registered. 
#-------------------------------------------------------------------------------
function dpcom_configured
{
    [[ -n $DPCOM_RAS_DEBUG ]] && set -x

    typeset tmp output

    ${CTCTRL} -q -c dpcom > /dev/null 2>&1
    if [[ $? == 0 ]]
    then
        return 0    # True
    fi

    return 1        # False
}


#-------------------------------------------------------------------------------
# Handle AIX snap's first pass, which requests a size estimate of the
# total expected data to be collected.
#-------------------------------------------------------------------------------
function dpcom_ras_estimate_size
{
    [[ -n $DPCOM_RAS_DEBUG ]] && set -x

    typeset -i dplocal_size=83968 # 82K - current size of 'dp_local_id' structure
    typeset -i dpglobal_trcsz=0
    typeset -i dplocal_trcsz=0
    typeset -i nbytes=0 total_bytes=0
    typeset line output

    # Collection dpcom is configured
    if dpcom_configured
    then
        output=$(LC_ALL=C exe_cmd ${CTCTRL} -q -c dpcom -r)
        rc=$?

        if [[ -z ${output} || $rc != 0 ]] 
        then
            return 1;
        fi
 
        #----------------------------------------------------------------------
        # Sample output from the command ' ctctrl -q -c dpcom -r'

        #---------------------------------------+-------+-------+-------+---------------
        #                                       | Have  |Mem Trc|Sys Trc| Buffer size
        #Component name                         | alias | /level| /level| /Allocated
        #---------------------------------------+-------+-------+-------+---------------
        #dpcom                                  |   NO  |  ON/7 |  ON/3 |     640000/YES
        #   .dplocal0                           |   NO  |  ON/7 |  ON/3 |    6400000/YES
        

        echo "${output}" | \
        while read line
        do
            if [[ $line == *dpcom* ]]   # Line matches the entry for 'dpcom'
            then
                # Remove all chars from the start of 'line' until a space (inclusive)
                line=${line##*[[:space:]]}
                
                # Now, from the end of the 'line', remove until a '/' (inclusive)
                dpglobal_trcsz=${line%%/*}
            elif [[ $line == *dplocal* ]]
            then
                # Remove all chars from the start of 'line' until a space (inclusive)
                line=${line##*[[:space:]]}
                
                # Now, from the end of the 'line', remove until a '/' (inclusive)
                (( dplocal_trcsz += ${line%%/*} ))
            fi
        done

        (( total_bytes = dplocal_size + dpglobal_trcsz + dplocal_trcsz ))

        # Calculate the actual size on disk for 'dpcomdd' and add that to the
        # 'total_bytes'.

        output=$(${DU} -s /usr/lib/drivers/dpcomdd)
        [[ $? != 0 || -z ${output} ]] && return 1

        file_sz=${output%%[[:space:]]*}
        (( total_bytes += file_sz * 512 ))

    fi

    ## print the size estimate in bytes
    echo $total_bytes

    return 0
}

#-------------------------------------------------------------------------------
# Collect SCSI Disk Driver & AIX PCM related RAS data
#-------------------------------------------------------------------------------
function dpcom_ras_dump_data
{
    [[ -n $DPCOM_RAS_DEBUG ]] && set -x
    typeset date_str=$(LC_ALL=C ${DATE} +"%d-%b-%Y_%T")
    typeset output
    typeset ldumpfile

    if dpcom_configured
    then
        exe_cmd "${DUMPCTRL} -c dpcom -r ldmpon ldmplevel=9"
        output=$(exe_cmd "LC_ALL=C ${LIVEDUMPSTART} symptom='dpcom snap livedump ${date_str}' -c dpcom -r log=no")
        
        if [[ $? == 0 ]]
        then
            # Extract the dump file name from the output. For e.g.
            # The dump is in file /var/adm/ras/livedump/nocomp.202009022130.00.DZ.
            ldumpfile=${output##*[[:space:]]} # Strip all but the last word
            ldumpfile=${ldumpfile%.}   # Remove the period after the filename

            # Now copy it to the snap location for dpcom_collect
            exe_cmd "${CP} ${ldumpfile} ${SNAPDIR}"
        fi
        exe_cmd "${CP} /usr/lib/drivers/dpcomdd ${SNAPDIR}"
    fi

    return 0
}

#-------------------------------------------------------------------------------
# Main starts here
#-------------------------------------------------------------------------------
[[ -n $DPCOM_RAS_DEBUG ]] && export PS4='$0 [$LINENO]> ' && set -x
if [ "$PASSNO" = 1 ]; then
    #
    # Report the size estimate through the SCRIPTSIZE environment variable.
    #

    echo "Collecting DPCOM RAS size estimate information..." >> ${SCRIPTLOG}
    dpcom_ras_estimate_size  > $SCRIPTSIZE

elif [ "$PASSNO" = 2 ]; then
    #
    # Handle AIX snap's second pass, which collects the data.
    #

    echo "Collecting DPCOM RAS information..." >> ${SCRIPTLOG}
    
    dpcom_ras_dump_data 
else
    echo "This script must be run under AIX snap." >> $SCRIPTLOG
    exit 1
fi