#!/usr/bin/sh
#############################################################
#  Copyright (c) 2002-2023, Dell Inc. or its subsidiaries. All Rights Reserved.
#
#  To configure PowerPath in a Boot-From-SAN setup on RHEL7, RHEL8, RHEL9, SLES12, SLES15, OL7, OL8 and OL9.
#############################################################

#-----------------------------------------------------
##    Variables
#-----------------------------------------------------

REDHAT=/etc/redhat-release
SLES_12=/etc/os-release
SLES=/etc/SuSE-release
SCRIPT_NAME=$(basename $0)
FSTAB=/etc/fstab
TMP_MENU_LST=/etc/opt/emcpower/.tmp/tmp_${SCRIPT_NAME}_menu.lst
RH7SL12_GRUB_DEFAULT=/etc/default/grub
TMP_RH7SL12_GRUB_DEFAULT=/etc/opt/emcpower/.tmp/${SCRIPT_NAME}_default_grub
TMP_FSTAB=/etc/opt/emcpower/.tmp/tmp_${SCRIPT_NAME}_fstab
TMP1_FSTAB=/etc/opt/emcpower/.tmp/tmp1_${SCRIPT_NAME}_fstab
LVM=/etc/lvm/lvm.conf
TMP_LVM=/etc/opt/emcpower/.tmp/tmp_${SCRIPT_NAME}_lvm.conf
TMP1_LVM=/etc/opt/emcpower/.tmp/tmp1_${SCRIPT_NAME}_lvm.conf
PP_BFS_DONE=/etc/emc/.${SCRIPT_NAME}_done
TMP_PP_ADD_LUN=/etc/opt/emcpower/.tmp/tmp_${SCRIPT_NAME}_add_lun
DATE=bkp_${SCRIPT_NAME}_$1_$(date "+%b%d%Y_%Hh%Mm%Ss")
MIN_BOOT_SIZE=22000
ACTION=no
PP_BOOT_LUN=no
STATUS=no
GRUB1=no
UEFI=no
NDU_LOCK_FILE=/etc/opt/emcpower/.ndu_lock


#-----------------------------------------------------
##    Usage of the script
#-----------------------------------------------------

USAGE()
{
    echo "---------------------------"
    echo ""
    echo "Usage:"
    echo "  ${SCRIPT_NAME} <operation>"
    echo ""
    echo "  where <operation> is one of the following:"
    echo "    config"
    echo "    remove"
    echo "    help"
    echo ""
    echo "---------------------------"
}       

#-----------------------------------------------------
##    HEADER
#-----------------------------------------------------
HEADER()
{
    echo "$1" | awk '{
    i=72;k=1
    for(k=1;k<i;k++)printf("-")
    printf("\n")}'
}

#-----------------------------------------------------
##   ERROR HEADER
#-----------------------------------------------------
ERROR_HEADER()
{
    echo
    echo "$1" | awk '{
    i=72;k=1
    for(k=1;k<i;k++)printf("*")
    printf("\n")}'
}

#-----------------------------------------------------
##   Cleanup and exit
#-----------------------------------------------------
CLEANUP()
{
    # Cleanup temp files from the system.
    for tmp_files in $TMP_FSTAB $TMP1_FSTAB \
                     $TMP_LVM $TMP1_LVM $TMP_PP_ADD_LUN \
                     $TMP_MENU_LST $TMP_RH7SL12_GRUB_DEFAULT
    do

        if [ -f $tmp_files ]; then
            rm -f $tmp_files
        fi

    done
}

ERROR_EXIT()
{
    # Exit the script for any error.
    CLEANUP 
    exit 1
}

#-----------------------------------------------------
##   Messages to System log
#-----------------------------------------------------
PP_LOGGER()
{
    msg=$*
    type logger > /dev/null 2>&1

    if [ $? -eq 0 ]; then
        logger -t $SCRIPT_NAME ${msg}
    fi
}


#-----------------------------------------------------
##    Audit Messages
#-----------------------------------------------------
AUDIT_MESSAGE()
{
    if [[ $ACTION == "remove" || $ACTION == "config" ]]; then
        PP_LOGGER info: cmd=${SCRIPT_NAME}: ${ACTION} \
                        \(user ID real=$(id -u) effective=$(id -g)\)
    fi
}

#-----------------------------------------------------
##    Messages
#-----------------------------------------------------
MESSAGES()
{
    # Info and error messages use by the script.
    case $1 in
    msg_phase1)
        AUDIT_MESSAGE
        HEADER
        echo "PHASE 1: VERIFICATION PHASE"
        HEADER
        PP_LOGGER info: PHASE 1: VERIFICATION PHASE.
    ;;

    msg_phase2_config)
        HEADER
        echo "PHASE 2: CONFIGURATION PHASE"
        HEADER
        PP_LOGGER info: PHASE 2: CONFIGURATION PHASE.
    ;;

    msg_pp_not_installed)
        ERROR_HEADER
        echo "ERROR: PowerPath is not installed." 
        ERROR_HEADER
        PP_LOGGER error: PowerPath is not installed.
        ERROR_EXIT
    ;;

    msg_pp_not_running)
        ERROR_HEADER
        echo "ERROR: PowerPath is not running."
        ERROR_HEADER
        PP_LOGGER error: PowerPath is not running.
        ERROR_EXIT
    ;;

    msg_phase2_remove)
        HEADER
        echo "PHASE 2: REMOVAL PHASE"
        HEADER
        PP_LOGGER info: PHASE 2: REMOVAL PHASE.
    ;;

    msg_not_supported_kernel)
        AUDIT_MESSAGE
        ERROR_HEADER
        echo "ERROR: The script ${SCRIPT_NAME} is NOT supported on this kernel."
        ERROR_HEADER
        PP_LOGGER error: The script ${SCRIPT_NAME} is NOT supported on this kernel.
    ;;

    msg_not_supported_config)
        ERROR_HEADER
        echo "ERROR: Not a supported PowerPath Boot-From-SAN configuration."
        ERROR_HEADER
        PP_LOGGER error: Not a supported PowerPath Boot-From-SAN configuration.
        ERROR_EXIT
    ;;

    msg_check_fstab)
         ERROR_HEADER
         echo "ERROR: Either /etc/fstab file is missing"
         echo "       or ${boot_par} entry is not found." 
         ERROR_HEADER
         PP_LOGGER error: Either \/etc\/fstab file is missing or ${boot_par} entry is not found.
         ERROR_EXIT
    ;;

    msg_check_boot_size)
         ERROR_HEADER
         echo "ERROR: Please ensure enough space in ${boot_par}."
         ERROR_HEADER
         PP_LOGGER error: Please ensure enough space in ${boot_par}.
         ERROR_EXIT
    ;;

    msg_boot_partition_not_mounted)
         ERROR_HEADER
         echo "ERROR: ${boot_par} partition is not mounted. Please mount ${boot_par} partition and try again."
         ERROR_HEADER
         PP_LOGGER error: Please ensure ${boot_par} is mounted.
         ERROR_EXIT
    ;;

    msg_lvm_file_not_found)
         ERROR_HEADER
         echo "ERROR: \'${LVM}\' file not found."
         ERROR_HEADER
         PP_LOGGER error: \'${LVM}\' file not found.
         ERROR_EXIT
    ;;

    msg_lvm_filter_not_found)
         ERROR_HEADER
         echo "ERROR: \'filter\' not found in ${LVM}."
         ERROR_HEADER
         PP_LOGGER error: \'filter\' not found in ${LVM}.
         ERROR_EXIT
    ;;

    msg_lvm_use_devicesfile_not_found)
         ERROR_HEADER
         echo "ERROR: \'use_devicesfile\' parameter not found in ${LVM}."
         ERROR_HEADER
         PP_LOGGER error: \'use_devicesfile\' parameter not found in ${LVM}.
         ERROR_EXIT
    ;;

    msg_lvm_multipath_component_detection_not_found)
         ERROR_HEADER
         echo "ERROR: \'multipath_component_detection\' parameter not found in ${LVM}."
         ERROR_HEADER
         PP_LOGGER error: \'multipath_component_detection\' parameter not found in ${LVM}.
         ERROR_EXIT
    ;;

    msg_check_boot_in_use)
         ERROR_HEADER
         echo "ERROR: /boot is in use."
         ERROR_HEADER
         PP_LOGGER error: \/boot is in use.
         ERROR_EXIT
    ;;

    msg_remove_device)
         ERROR_HEADER
         echo "ERROR: LUN(s) in use, can't proceed."
         ERROR_HEADER
         PP_LOGGER error: LUN\(s\) in use, can\'t proceed.
         ERROR_EXIT
    ;;

    msg_fstab_update_umount)
         ERROR_HEADER
         echo "ERROR: ${boot_par} in use, can't umount."
         ERROR_HEADER
         PP_LOGGER error: ${boot_par} in use, can\'t umount. 
    ;;

    msg_fstab_update_umount2)
         ERROR_HEADER
         echo "ERROR: ${boot_par2} in use, can't umount."
         ERROR_HEADER
         PP_LOGGER error: ${boot_par2} in use, can\'t umount. 
    ;;

    msg_fstab_update_mount2)
         ERROR_HEADER
         echo "ERROR: Failed to mount ${boot_par2}"
         ERROR_HEADER
         PP_LOGGER error: Failed to mount ${boot_par2}.
    ;;

    msg_fstab_update_mount)
         ERROR_HEADER
         echo "ERROR: Failed to mount ${boot_par}"
         ERROR_HEADER
         PP_LOGGER error: Failed to mount ${boot_par}.
    ;;

    msg_fstab_update_failed)
         ERROR_HEADER
         echo "ERROR: Failed to update ${FSTAB}."
         ERROR_HEADER
         PP_LOGGER error: Failed to update ${FSTAB}.
    ;;

    msg_lvm_update)
         ERROR_HEADER
         echo "ERROR: Failed to update ${LVM}."
         ERROR_HEADER
         PP_LOGGER error: Failed to update ${LVM}.
    ;;

    msg_pp_bfs_configured)
         AUDIT_MESSAGE
         ERROR_HEADER
         echo "ERROR: PowerPath is already configured."
         ERROR_HEADER
         PP_LOGGER error: PowerPath is already configured.
         ERROR_EXIT
    ;;

    msg_pp_bfs_not_configured)
         AUDIT_MESSAGE
         ERROR_HEADER
         echo "ERROR: PowerPath is not configured on Boot-From-SAN."
         ERROR_HEADER
         PP_LOGGER error: PowerPath is not configured on Boot-From-SAN.
         ERROR_EXIT
    ;;

    msg_incorrect_input)
         ERROR_HEADER
         echo "ERROR: Invalid option."
         ERROR_HEADER
    ;;

    msg_rollback)
         HEADER
         echo "INFO: ROLLBACK STARTED"
         HEADER
         PP_LOGGER info: ROLLBACK STARTED.
    ;;

    msg_ctrl_c_rollback)
         ERROR_HEADER
         echo "ERROR: Interrupt signal Ctrl + C identified."   
         echo "       Starting rollback."
         ERROR_HEADER
         PP_LOGGER error: Ctrl + C Interpreted, proceeding rollback.
    ;;

    msg_rollback_success)
         HEADER
         echo "INFO: Restored Original Configuration."
         echo "      Please fix above error and try again."
         HEADER
         PP_LOGGER info: Restored Original Configuration. Please fix the error and try again.
         ERROR_EXIT
    ;;

    msg_ctrl_c_no_change)
         HEADER
         echo "INFO: No changes made to the system files." 
         HEADER
         PP_LOGGER info: No changes made to the system files.
         ERROR_EXIT
    ;;

    msg_insufficient_permission)
         AUDIT_MESSAGE
         HEADER
         echo "ERROR: Insufficient user privilege." 
         HEADER
         PP_LOGGER error: Insufficient user privilege \(user ID real=$(id -u) effective=$(id -g)\).
         ERROR_EXIT
    ;;

    msg_ppme_present)
         HEADER
         echo "ERROR: PowerPath migrations are present." 
         echo "       Please cleanup the migrations and then reissue the ${SCRIPT_NAME}."
         HEADER
         PP_LOGGER error: PowerPath migrations are present. Please cleanup the migrations and then reissue the ${SCRIPT_NAME}.
         ERROR_EXIT
    ;;

    msg_success)
        HEADER
        echo "INFO: Successfully Completed."
        PP_LOGGER info: Successfully Completed.
        HEADER
        CLEANUP
    ;;

    esac
}

#-----------------------------------------------------
##   Rollback Stages
#-----------------------------------------------------
ROLLBACK_STAGE1()
{
    # Rollback the default ramdisk image file.
    if [[ $ACTION == "config" ]]; then
        if [[ ${VERSION} == "SLES12" || ${VERSION} == "SLES15" || ${VERSION} == "RHEL8" || ${VERSION} == "RHEL9" ]]; then
            mv -f ${initramfs}_${DATE}  ${initramfs}
        fi
    fi
}

ROLLBACK_STAGE2()
{

    # Rollback the fstab file.
    echo "   Reverting ${FSTAB}"
    mv -f ${FSTAB}_${DATE} ${FSTAB}
  
    umount ${boot_par} > /dev/null 2>&1
    if [[ ${UEFI} == "yes" ]]; then
        umount ${boot_par2} > /dev/null 2>&1
        mount ${boot_par2} > /dev/null 2>&1
    fi
    mount ${boot_par} > /dev/null 2>&1

    ROLLBACK_STAGE1
}

ROLLBACK_STAGE3()
{

    # Rollback the lvm.conf file.
    echo "   Reverting ${LVM}"
    mv -f ${LVM}_${DATE} ${LVM}
    vgscan -v  > /dev/null 2>&1
    lvmdiskscan  > /dev/null 2>&1

    ROLLBACK_STAGE2
}

#-----------------------------------------------------
##   Rollback MAIN
#-----------------------------------------------------

ROLLBACK()
{
    # Script detected error during configuration, 
    # hence rolling back the original configuration

    MESSAGES msg_rollback

    case $STAGE in
    STAGE1)
        ROLLBACK_STAGE1
    ;;
    STAGE2)
        ROLLBACK_STAGE2
    ;;
    STAGE3)
        ROLLBACK_STAGE3
    ;;
    esac

    MESSAGES msg_rollback_success

}

#-----------------------------------------------------
##   Ctrl + C Rollback
#-----------------------------------------------------
CTRL_C()
{
    # Script detected Ctrl + C configuration, 
    # hence rolling back the original configuration.
    MESSAGES msg_ctrl_c_rollback

    if [[ $STAGE != "" ]]; then
        ROLLBACK
    else
        MESSAGES msg_ctrl_c_no_change 
    fi

}

#-----------------------------------------------------
##   Host Configuration Verification SUB Functions
#-----------------------------------------------------
#-----------------------------------------------------
##   PowerPath Verification 
#-----------------------------------------------------
CHECK_POWERPATH()
{
    lsmod | grep -w emcp > /dev/null 2>&1

    if [ $? -ne 0 ]; then
        rpm -qa | grep EMCpower.LINUX > /dev/null 2>&1

        if [ $? -ne 0 ]; then
            echo "Failed" 
            STATUS="Failed:msg_pp_not_installed"
        else
            echo "Failed" 
            STATUS="Failed:msg_pp_not_running"
        fi

    else
        echo "Installed"
    fi
}

#-----------------------------------------------------
##   LUN ID and NICE NAME
#-----------------------------------------------------
LUN_ID()
{
    unset device_all

    for device in $@ ; do
       emcp_lun=$(powermt display dev=$device | grep emcpower |\
                awk -F "=" '{ print $NF }')

       powermt display dev=${emcp_lun} | egrep '^VNX|^CLARiiON|^XtremIO|^Ess|^VPLEX|^Unity|^SC' > /dev/null 2>&1
       if [[ $? == 0 ]]; then
           dev_name=$(powermt display dev=${emcp_lun} | awk -F "[" '/^Logical/ { print $2 }' |\
                      sed -e 's/\]//g')
           device_all="${emcp_lun}:${dev_name} ${device_all}"
       else
           dev_name=$(powermt display dev=${emcp_lun} | awk -F "=" '/^Logical/ { print $2 }')
           length=${#dev_name}

           if (( ${length} <= 8 )); then
               device_all="${emcp_lun}:${dev_name} ${device_all}"
           else
               device_all="${emcp_lun}:${dev_name:(-8)} ${device_all}"
           fi

       fi

    done
}

#-----------------------------------------------------
##   Verification of Boot LUN
#-----------------------------------------------------
CHECK_BOOT_LUN()
{
    if [[ ${UEFI} == "yes" ]]; then
        boot_par=/boot/efi
        mount | grep ${boot_par} > /dev/null 2>&1
    else
        boot_par=/boot
        mount | grep ${boot_par} > /dev/null 2>&1
    fi

    if [ $? -ne 0 ]; then
        echo "Failed"
        STATUS="Failed:msg_boot_partition_not_mounted"
    else

        boot_lun=$(df -h ${boot_par} | grep ${boot_par} |  awk '{ print $1 }' |\
                 awk -F "/" '{ print $NF }' |\
                 sed 's/[1-9]//g')  > /dev/null 2>&1

        if [ $? -ne 0 ]; then
            echo "Failed" 
            STATUS="Failed:msg_not_supported_config"
        else
            powermt display dev=$boot_lun > /dev/null 2>&1

            if [ $? -ne 0 ]; then
                echo "Failed"
                STATUS="Failed:msg_not_supported_config"
            else
                LUN_ID $boot_lun

                if [[ $device_all == "${boot}: " ]]; then
                    unset emcp_lun
                    emcp_lun=$(powermt display dev=$boot_lun |\
                             grep emcpower | awk -F "=" '{ print $NF }')
                    echo $emcp_lun
                else
                    echo $device_all
                fi

            fi

        fi
    fi
}

#-----------------------------------------------------
##   Verification of Root LUN
#-----------------------------------------------------
CHECK_LVM_LUN()
{

    vg_lv=$(mount | grep 'on / type' | awk '{ print $1 }')  > /dev/null 2>&1
    lvdisplay $vg_lv  2>/dev/null > /dev/null 2>&1
    if [[ $? == 0 ]]; then
        vg_name=$(lvdisplay $vg_lv  2>/dev/null | grep 'VG Name' |\
                  awk '{ print $NF }')  > /dev/null 2>&1
        devices=$(pvs  2>/dev/null | grep $vg_name | awk '{ print $1 }' |\
                  sed 's/[0-9]//g' | awk -F '/' '{ print $NF }' | sort -u )  > /dev/null 2>&1

        for pv_emcp_dev in $devices
        do
            powermt display dev=$pv_emcp_dev  > /dev/null 2>&1

           if [[ $? == 0 ]]; then
               if [[ $PP_LVM_LUN == "" ]]; then
                   PP_LVM_LUN=$(powermt display dev=$pv_emcp_dev |\
                                grep emcpower | awk -F "=" '{ print $NF "$"}')
               else
                   PP_LVM_LUN="${PP_LVM_LUN} $(powermt display dev=$pv_emcp_dev |\
                                grep emcpower | awk -F "=" '{ print $NF "$" }')"
               fi
           fi

        done

        pv_devices=$(echo $PP_LVM_LUN | sed 's/\$/ /g') > /dev/null 2>&1
        LUN_ID $pv_devices
        lvm_count=0
        echo $pv_devices | grep "\<${emcp_lun}\>" > /dev/null 2>&1

        if [[ $? != 0 ]]; then
            lvm_count=1
        fi

        for count in ${pv_devices}
        do
            lvm_count=$(expr $lvm_count + 1)
        done

        if [[ $device_all == "${boot}: " ]]; then
            unset emcp_lun
            emcp_lun=$(powermt display dev=$boot_lun |\
                       grep emcpower | awk -F "=" '{ print $NF }')
            echo $emcp_lun
        else
            echo $device_all
        fi

        PP_LVM_LUN=$(echo $PP_LVM_LUN | sed 's/ /\|/g')  > /dev/null 2>&1
    else
        echo "Failed" 
        STATUS="Failed:msg_not_supported_config"
    fi

}

#-----------------------------------------------------
##   Verification of additional LUNs on the system
#-----------------------------------------------------

CHECK_LUNS()
{
    num_device=$(powermt display dev=all | grep emcpower | wc -l)

    if [[ $num_device > $lvm_count ]]; then
         echo "Available" 
         STATUS="Available"
    elif [[ $num_device == $lvm_count ]]; then
         echo "Not Available"
    else
         echo "Available" 
         STATUS="Available"
    fi
}

#-----------------------------------------------------
##   Verification PPME migration
#-----------------------------------------------------
CHECK_PPME()
{
    if [ -f /sbin/powermig ]; then
        powermig info -all | grep "No migrations found." > /dev/null 2>&1

        if [ $? -ne 0 ]; then
            echo "Available"      
            STATUS="Failed:msg_ppme_present"
        else
            echo "No migration"
        fi

    else
        echo "No migration"
    fi
}

#-----------------------------------------------------
##   fstab Verification for /boot entry
#-----------------------------------------------------
CHECK_FSTAB()
{
    if [ -f $FSTAB ]; then
        cat $FSTAB | grep -v "^[ \t]*#" | grep "${boot_par}[[:space:]]" > /dev/null 2>&1

        if [ $? -eq 0 ]; then
            echo "${boot_par} found" 
        else
            echo "Failed" 
            STATUS="Failed:msg_check_fstab"
        fi

    else
        echo "Failed" 
        STATUS="Failed:msg_check_fstab"
    fi

}

#-----------------------------------------------------
##   Verify /boot Device Open
#-----------------------------------------------------
CHECK_BOOT_IN_USE()
{

    fuser /boot > /dev/null 2>&1

    if [ $? -eq 0 ]; then
        STATUS="Failed:msg_check_boot_in_use"
    fi

}

#-------------------------------------------------------------------------------------------
## LVM Filter Verification:
#  This function validates the global_filter available in the lvm.conf for SLES12, SLES15,
#  RHEL7, RHEL8 and RHEL9.
#-------------------------------------------------------------------------------------------
CHECK_LVM_FILTER()
{
    if [ -f $LVM ]; then
        cat $LVM | grep "global_filter[ \t]*=" > /dev/null 2>&1
        lvm_check_filter=$?
        if [ $lvm_check_filter -eq 0 ]; then
            echo "Filter found"
        else
            echo "Failed"
            STATUS="Failed:msg_lvm_filter_not_found"
        fi

    else
        echo "Failed"
        STATUS="Failed:msg_lvm_file_not_found"
    fi
}

#-------------------------------------------------------------------------
## LVM Devices file Verification:
#  This function validates the 'use_devicesfile' parameter is available in
#  the lvm.conf and its current status. Applicable for RHEL9 and OL9 only.
#-------------------------------------------------------------------------
CHECK_LVM_DEVICES_FILE()
{
    if [ -f $LVM ]; then
        cat $LVM | grep ".*use_devicesfile.*=.*[0-9]" > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            lvmdevices > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                echo "Enabled"
            else
                echo "Disabled"
            fi
        else
            echo "Failed"
            STATUS="Failed:msg_lvm_use_devicesfile_not_found"
        fi
    else
        echo "Failed"
        STATUS="Failed:msg_lvm_file_not_found"
    fi

}

#-----------------------------------------------------
##   Call Messages 
#-----------------------------------------------------
CALL_MESSAGES()
{

    if [[ ${STATUS%%:*} == Failed ]]; then
        EXIT=${STATUS##*:}
        MESSAGES $EXIT
    fi

}

#-----------------------------------------------------
##   Host Configuration Verification Main Function
#-----------------------------------------------------
CONFIG_CHECK()
{

    echo -n "   Verifying PowerPath ........................... "
    CHECK_POWERPATH
    CALL_MESSAGES

    if [[ ${UEFI} == "yes" || ${sles_without_separate_boot} != "yes" ]]; then
        echo -n "   Verifying Boot LUN ............................ "
        CHECK_BOOT_LUN
        CALL_MESSAGES
    fi

    # REVISIT - Various LVM changes has been observed from latest OSes, even with their minor versions.
    #         : with multiple paths to boot LUN enables 'multipath_component_detection' feature in the LVM
    #           this leads to abrupt outputs from the LVM commands. So disable it internally to get expected
    #           expected results from LVM commands until PP filters in place.
    #
    #         : In case of RHEL9/OL9 SRDF A/P,R2(failover from R1) disable 'use_devicesfile' as well.
    num_paths=$(powermt display dev=$emcp_lun | grep sd | grep active | awk '{ print $3 }' | wc -l )
    if [ $num_paths -gt 1 ]; then
        DISABLE_MULTIPATH_COMPONENT_DETECTION
        if [[ ${VERSION} == "RHEL9"  ]]; then
            DISABLE_USE_OF_DEVICES_FILE
        fi
    fi

    echo -n "   Verifying Root LVM LUN(s) ..................... "
    CHECK_LVM_LUN
    CALL_MESSAGES

    # REVISIT - Various LVM changes has been observed from latest OSes, even with their minor versions.
    #         : at this stage disable 'multipath_component_detection' feature as PP filter will be added.
    #
    #         : In case of RHEL9/OL9 SRDF A/P,R2(failover from R1) enable back 'use_devicesfile' as well.
    num_paths=$(powermt display dev=$emcp_lun | grep sd | grep active | awk '{ print $3 }' | wc -l )
    if [ $num_paths -gt 1 ]; then
        ENABLE_MULTIPATH_COMPONENT_DETECTION
        if [[ ${VERSION} == "RHEL9"  ]]; then
            ENABLE_USE_OF_DEVICES_FILE
        fi
    fi

    echo -n "   Verifying PPME Migrations ..................... "
    CHECK_PPME
    CALL_MESSAGES

    if [[ ${UEFI} == "yes" || ${sles_without_separate_boot} != "yes" ]]; then
        echo -n "   Verifying $FSTAB .......................... "
        CHECK_FSTAB
        CALL_MESSAGES

        CHECK_BOOT_IN_USE
        if [[ ${STATUS%%:*} == Failed ]]; then
            EXIT=${STATUS##*:}
            echo "   Verifying ${boot_par} ............................... Failed"
            MESSAGES $EXIT
        fi
    fi

    echo -n "   Verifying $LVM ................... "
    CHECK_LVM_FILTER
    CALL_MESSAGES

    if [[ ${VERSION} == "RHEL9" ]]; then
        echo -n "   Verifying LVM devices file .................... "
        CHECK_LVM_DEVICES_FILE
        CALL_MESSAGES
    fi

}

#-----------------------------------------------------
##    Boot LUN and additional LUN(s) verification 
#-----------------------------------------------------
LUNS_CHECK()
{
#    num_device=$(powermt display dev=all | grep emcpower | wc -l)
    partition=$(df -h ${boot_par} | grep "${boot_par}" |  awk '{ print $1 }' |\
              awk -F "/" '{ print $NF }' |\
              sed 's/[a-z]//g') > /dev/null 2>&1
    boot_lun=$(df -h ${boot_par} | grep "${boot_par}" |  awk '{ print $1 }' |\
              awk -F "/" '{ print $NF }' |\
              sed 's/[1-9]//g')  > /dev/null 2>&1

        PP_BOOT_LUN=$(powermt display dev=$boot_lun | grep emcpower |\
                    awk -F "=" '{ print $NF }')  > /dev/null 2>&1
}

#-----------------------------------------------------
##    FSTAB Modification 
#-----------------------------------------------------
FSTAB_UPDATE()
{

    if [ -f $FSTAB ]; then
        cp $FSTAB ${FSTAB}_${DATE}
        cp $FSTAB $TMP_FSTAB
        fstab_boot=$(cat $TMP_FSTAB | grep -v "^[ \t]*#" |\
                   grep "${boot_par}" | awk '{ print $1 }')
        cat $TMP_FSTAB | grep "###${SCRIPT_NAME} for ${boot_par} ###"  > /dev/null 2>&1
         
        if [ $? -ne 0 ]; then
            # Comment out existing /boot enrty.
            sed -i "s%^${fstab_boot}.*%###${SCRIPT_NAME} for ${boot_par} ###$(date)###\n#& \n########\n& %" $TMP_FSTAB
        fi

        boot_par2_parse=""
        if [[ ${UEFI} == "yes" && ${sles_without_separate_boot} != "yes" ]]; then
            boot_par2="/boot "
            cat $TMP_FSTAB | grep "${boot_par2}" > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                boot_par2_parse=$(echo ${boot_par2} | sed 's_/_\\/_g')
                fstab_boot2=$(cat $TMP_FSTAB | grep -v "^[ \t]*#" | grep "${boot_par2}" | awk '{ print $1 }')
                partition2=$(df -h ${boot_par2} | grep "/boot" |  awk '{ print $1 }' |\
                            awk -F "/" '{ print $NF }' | sed 's/[a-z]//g') > /dev/null 2>&1
                uuid2=$(blkid $fstab_boot2 | sed -ne 's:\(.*\) \(UUID=.*\) \(.*\):\2:p' | awk '{ print $1 }' | sed 's/"//g')
                cat $TMP_FSTAB | grep "###${SCRIPT_NAME} for ${boot_par2} ###"  > /dev/null 2>&1
                if [ $? -ne 0 ]; then
                    sed -i "s%^${fstab_boot2}.*%###${SCRIPT_NAME} for ${boot_par2} ###$(date)###\n#& \n########\n& %" $TMP_FSTAB
                fi
            fi
        fi

        if [[ $ACTION == "config" ]]; then
            echo $fstab_boot | grep -v emcpower > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                # Replace boot entry with PowerPath Pseudo device.
                boot_par_parse=$(echo ${boot_par} | sed 's_/_\\/_g')
                cat $TMP_FSTAB | sed -e "/${boot_par_parse} / s%^${fstab_boot}%\/dev\/${PP_BOOT_LUN}${partition}%g" > $TMP1_FSTAB
                sed -i "/${boot_par_parse} /  s%defaults%nofail%"  $TMP1_FSTAB
                if [ "${boot_par2_parse}" != "" ]; then
                    cp -f $TMP1_FSTAB $TMP_FSTAB
                    cat $TMP_FSTAB | sed -e "/${boot_par_parse2} / s%^${fstab_boot2}%\/dev\/${PP_BOOT_LUN}${partition2}%g" > $TMP1_FSTAB
                    sed -i "/${boot_par2_parse} /  s%defaults%nofail%"  $TMP1_FSTAB
                fi
            fi

        elif [[ $ACTION == "remove" ]]; then
            echo $fstab_boot | grep emcpower > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                # Replace boot entry with fileystem UUID.
                uuid=$(blkid $fstab_boot |\
                     sed -ne 's:\(.*\) \(UUID=.*\) \(.*\):\2:p' |\
                     awk '{ print $1 }' | sed 's/"//g')
                boot_par_parse=$(echo ${boot_par} | sed 's_/_\\/_g')
                cat $TMP_FSTAB | sed -e "/${boot_par_parse} /  s%^${fstab_boot}%${uuid}%g" > $TMP1_FSTAB
                sed -i "/${boot_par_parse} /  s%nofail%defaults%"  $TMP1_FSTAB
                if [ "${boot_par2_parse}" != "" ]; then
                    cp -f $TMP1_FSTAB $TMP_FSTAB
                    cat $TMP_FSTAB | sed -e "/${boot_par_2parse} /  s%^${fstab_boot2}%${uuid2}%g" > $TMP1_FSTAB
                    sed -i "/${boot_par2_parse} /  s%nofail%defaults%"  $TMP1_FSTAB
                fi
            fi

        fi

        sleep 1
        if [ -f $TMP1_FSTAB ]; then
            cp $TMP1_FSTAB $FSTAB
        elif [ -f $TMP_FSTAB ]; then
            cp $TMP_FSTAB $FSTAB
        fi

        # If mount points already unmounted due to some reason, set err=-1 
        # to skip 'umount(s)' and then 'mount(s)' will take care  
        err=-1
        sd_boot_part=-1
        sd_efi_boot_part=-1
        emcpower_boot_lun=no
        emcpower_efi_boot_lun=no

        for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
            if [[ $ACTION == "config" ]]; then
                mount | grep ${boot_par} | grep "/dev/sd*"> /dev/null 2>&1
                if [ $? -eq 0 ]; then
                    umount ${boot_par} > /dev/null 2>&1
                    err=$?
                else
                    err=0
                    break
                fi
             elif [[ $ACTION == "remove" ]]; then
                 mount | grep ${boot_par} | grep "/dev/emcpower*"> /dev/null 2>&1
                if [ $? -eq 0 ]; then
                    if [[ ${UEFI} == "yes" ]]; then
                        sd_efi_boot_part=$(df -h | grep ${boot_par} | awk '{print $1}' | sed -e 's/.*\(.\)$/\1/')
                    else
                        sd_boot_part=$(df -h | grep ${boot_par} | grep "/dev/emcpower*" | awk '{print $1}' | sed -e 's/.*\(.\)$/\1/')
                    fi
                    emcpower_boot_lun=$(df -h ${boot_par} | grep ${boot_par} |  awk '{ print $1 }' |\
                                      awk -F "/" '{ print $NF }' |\
                                      sed 's/[1-9]//g')  > /dev/null 2>&1
                    umount ${boot_par} > /dev/null 2>&1
                    err=$?
                else
                    err=0
                    break
                fi
             fi
        done
        if [ $err -gt 0 ]; then
            STATUS="Failed:msg_fstab_update_umount"
        fi

        if [[ "${boot_par2_parse}" != "" && ${STATUS%%:*} != Failed ]]; then
            for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
                if [[ $ACTION == "config" ]]; then
                    mount | grep ${boot_par2} | grep "/dev/sd*"> /dev/null 2>&1
                    if [ $? -eq 0 ]; then
                        umount ${boot_par2} > /dev/null 2>&1
                        err=$?
                    else
                        err=0
                        break
                    fi
                elif [[ $ACTION == "remove" ]]; then
                    mount | grep ${boot_par2} | grep "/dev/emcpower*"> /dev/null 2>&1
                    if [ $? -eq 0 ]; then
                        sd_boot_part=$(df -h | grep ${boot_par2} | awk '{print $1}' | sed -e 's/.*\(.\)$/\1/')
                        emcpower_efi_boot_lun=$(df -h ${boot_par2} | grep ${boot_par2} |  awk '{ print $1 }' |\
                                      awk -F "/" '{ print $NF }' |\
                                      sed 's/[1-9]//g')  > /dev/null 2>&1
                        umount ${boot_par2} > /dev/null 2>&1
                        err=$?
                    else
                        err=0
                        break
                    fi
                fi
            done
            if [ $err -gt 0 ]; then
                STATUS="Failed:msg_fstab_update_umount2"
            fi
        fi

        err_umount=-1
        err_mount=-1
        if [[ "${boot_par2_parse}" != "" && ${STATUS%%:*} != Failed ]]; then
            for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
                if [[ $ACTION == "config" ]]; then
                    sleep 5
                    mount | grep ${boot_par2} | grep "/dev/emcpower*"> /dev/null 2>&1
                    if [ $? -ne 0 ]; then
                        umount ${boot_par2} > /dev/null 2>&1
                        err_umount=$?
                        sleep 1
                        systemctl daemon-reload
                        mount ${boot_par2} > /dev/null 2>&1
                        err_mount=$?
                    else
                        err_umount=0
                        err_mount=0
                        break;
                    fi
                elif [[ $ACTION == "remove" ]]; then
                    mount | grep ${boot_par2} | grep "/dev/sd*"> /dev/null 2>&1
                    if [ $? -ne 0 ]; then
                        umount ${boot_par2} > /dev/null 2>&1
                        err_umount=$?
                        sleep 1
                        systemctl daemon-reload
                        for sd_dev in `powermt display dev=$emcpower_efi_boot_lun | grep sd* | grep active | awk '{ print $3 }'`; do
                            sd_lun="$sd_dev$sd_boot_part"
                            mount /dev/$sd_lun > /dev/null 2>&1
                            if [ $? -eq 0 ]; then
                                err_mount=$?
                                break
                            else
                                err_mount=$?
                            fi
                        done
                    else
                        err_umount=0
                        err_mount=0
                        break;
                    fi
                fi
            done
            if [ $err_umount -gt 0 ]; then
                STATUS="Failed:msg_fstab_update_umount2"
            elif [ $err_mount -gt 0 ]; then
                STATUS="Failed:msg_fstab_update_mount2"
            fi
        fi

        if [[ ${STATUS%%:*} != Failed ]]; then
            for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
                if [[ $ACTION == "config" ]]; then
                    sleep 5
                    mount | grep ${boot_par} | grep "/dev/emcpower*"> /dev/null 2>&1
                    if [ $? -ne 0 ]; then
                        umount ${boot_par} > /dev/null 2>&1
                        err_umount=$?
                        sleep 1
                        systemctl daemon-reload
                        mount ${boot_par} > /dev/null 2>&1
                        err_mount=$?
                    else
                        err_umount=0
                        err_mount=0
                        break;
                    fi
                elif [[ $ACTION == "remove" ]]; then
                    mount | grep ${boot_par} | grep "/dev/sd*"> /dev/null 2>&1
                    if [ $? -ne 0 ]; then
                        umount ${boot_par} > /dev/null 2>&1
                        err_umount=$?
                        sleep 1
                        systemctl daemon-reload
                        for sd_dev in `powermt display dev=$emcpower_boot_lun | grep sd* | grep active | awk '{ print $3 }'`; do
                            if [[ ${UEFI} == "yes" ]]; then
                                sd_lun="$sd_dev$sd_efi_boot_part"
                            else
                                sd_lun="$sd_dev$sd_boot_part"
                            fi
                            mount /dev/$sd_lun > /dev/null 2>&1
                            if [ $? -eq 0 ]; then
                                err_mount=$?
                                break
                            else
                                err_mount=$?
                            fi
                        done
                    else
                        err_umount=0
                        err_mount=0
                        break;
                    fi
                fi
            done
            if [ $err_umount -gt 0 ]; then
                STATUS="Failed:msg_fstab_update_umount"
            elif [ $err_mount -gt 0 ]; then
                STATUS="Failed:msg_fstab_update_mount"
            fi
        fi

        sleep 1
        if [[ ${STATUS%%:*} != Failed ]]; then
            echo "Done"
        else
            echo "Failed"
        fi

    else
        echo "Failed"
        STATUS="Failed:msg_fstab_update_failed"
    fi
}

FSTAB_UPDATE_MAIN()
{

    STAGE=STAGE2
    echo -n "   Updating $FSTAB ........................... "
    FSTAB_UPDATE

    if [[ ${STATUS%%:*} == Failed ]]; then
        EXIT=${STATUS##*:}
        MESSAGES $EXIT
        ROLLBACK
    fi
}

#-----------------------------------------------------
##   LVM Filter modification 
#-----------------------------------------------------
LVM_UPDATE()
{

    if [ -f $LVM ]; then
        cp $LVM ${LVM}_${DATE}
        cp $LVM $TMP_LVM
        cat $TMP_LVM | grep "###${SCRIPT_NAME}###"  > /dev/null 2>&1

        if [[ $ACTION == "config" ]]; then

            cat $TMP_LVM | grep "^[ \t]*global_filter[ \t]*=" |\
                grep "\"a/emcpower.\*/\"[ \t]*,[ \t]*\"r/sd.\*/\"[ \t]*,[ \t]*\"r/disk.\*/\"[ \t]*,[ \t]*\"r/nvme.\*/\"[ \t]*,[ \t]*\"r/scini.\*/\""  > /dev/null 2>&1
            if [ $? -ne 0 ]; then
                sed -i '0,/^[ \t]*#[ \t]*global_filter[ \t]*=/ { s//    global_filter =/ }' $TMP_LVM
                # Update lvm filter with emcpower device for rhel7, sles12 and sles15.
                cat $TMP_LVM | grep "^[ \t]*global_filter[ \t]*=[ \t]*\[[ \t]*\]"> /dev/null 2>&1
                if [ $? -eq 0 ]; then
                    cat $TMP_LVM | sed -e '/^[ \t]*global_filter[ \t]*=/ {
                                        s%# %%g
                                        s%#%%g
                                        s%\[[ \t]*\]%\[ \"a/emcpower.\*/\", \"r/sd.\*/\", \"r/disk.\*/\", \"r/nvme.\*/\", \"r/scini.\*/\" \]%g
                                        s%\"a/sd.\*/\"%\"a/emcpower.\*/\", \"r/sd.\*/\", \"r/disk.\*/\", \"r/nvme.\*/\", \"r/scini.\*/\"%g
                                        s%\"r|/dev/.\*/by-path/.\*|\"%%g
                                        s%\"r|/dev/.\*/by-id/.\*|\"%%g
                                        s%\"r|/dev/.\*/by-name/.\*|\"%%g
                                        s%\"a|/dev/sd.\*|\"%%g
                                        s%\"a/.\*/\"%%g
                                        s%,[ \t]*,[ \t]*,%,%g
                                        s%,[ \t]*,%,%g
                                        s%\[ [ \t]*,%\[ %g
                                        s%,[ \t]*\]% \]%g
                                        }'  > $TMP1_LVM
                else 
                    cp -f $TMP_LVM $TMP1_LVM
                fi

                cat $TMP1_LVM | grep "^[ \t]*global_filter[ \t]*=" |\
                                grep "\"a/emcpower.\*/\"[ \t]*,[ \t]*\"r/sd.\*/\"[ \t]*,[ \t]*\"r/disk.\*/\"[ \t]*,[ \t]*\"r/nvme.\*/\"[ \t]*,[ \t]*\"r/scini.\*/\""  > /dev/null 2>&1
                if [ $? -ne 0 ]; then
                    #sed -i "s%^[ \t]*global_filter[ \t]*=.*%    ###${SCRIPT_NAME} config###$(date)###\n    ##& \n    ########\n& %" $TMP_LVM
                    # Overwrite lvm filter, if the lvm filter is failed to update above.
                    cat $TMP_LVM | sed -e '/^[ \t]*global_filter[ \t]*=/  {
                        s%\[.*\]%\[ \"a/emcpower.\*/\", \"r/sd.\*/\", \"r/disk.\*/\", \"r/nvme.\*/\", \"r/scini.\*/\" \]%g
                        }'  > $TMP1_LVM
                fi

            fi

        elif [[ $ACTION == "remove" ]]; then
            # Update lvm filter for rhel7, sles12 and sles15
            cat $TMP_LVM |  sed -e '/^[ \t]*global_filter[ \t]*=/  {
                s%\"a/emcpower.*/\"[ \t]*,[ \t]*\"r/sd.\*/\"[ \t]*,[ \t]*\"r/disk.\*/\"%\"r/emcpower.\*/\", \"a/sd.\*/\, \"r/nvme.\*/\", \"r/scini.\*/\"%g
                s%\"r/sd.\*/\"%%g
                s%\"r|/dev/sd.\*|\"%%g
                s%,[ \t]*,[ \t]*,%,%g
                s%,[ \t]*,%,%g
                s%\[ [ \t]*,%\[ %g
                s%,[ \t]*\]% \]%g
                }'  > $TMP1_LVM
            cat $TMP1_LVM | grep "^[ \t]*global_filter" |\
                grep "\"r/emcpower.\*/\", \"a/sd.\*/\",  \"r/nvme.\*/\", \"r/scini.\*/\"" > /dev/null 2>&1
            if [ $? -ne 0 ]; then
                #sed -i "s%^[ \t]*global_filter[ \t]*=.*%    ###${SCRIPT_NAME} remove###$(date)###\n    ##& \n    ########\n& %" $TMP_LVM
                # Overwrite lvm filter, if the lvm filter is failed to update above.
                cat $TMP_LVM |  sed -e '/^[ \t]*global_filter[ \t]*=/  s%\[.*\]%\[ \"r/emcpower.\*/\", \"a/sd.\*/\", \"r/nvme.\*/\", \"r/scini.\*/\" \]%g'  > $TMP1_LVM
            fi

        fi

        if [ -f $TMP1_LVM ]; then
            cp $TMP1_LVM $LVM
        elif [ -f $TMP_LVM ]; then
            cp $TMP_LVM $LVM
        fi

        if [[ $skip_lvm_commands_during_host_bootup == "no" ]]; then
            vgscan -v  > /dev/null 2>&1
            vgscanvalue=$?
            lvmdiskscan  > /dev/null 2>&1
            lvmdiskscanvalue=$?

            sleep 2
            if [[ $vgscanvalue != 0 && $lvmdiskscanvalue != 0 ]]; then
                echo "Failed"
                STATUS="Failed:msg_lvm_update"
            else
                echo Done
            fi
        fi

    else
        echo "Failed"
        STATUS="Failed:msg_lvm_update"
    fi

}

LVM_UPDATE_MAIN()
{

    STAGE=STAGE3
    echo -n "   Updating $LVM .................... "
    LVM_UPDATE

    if [[ ${STATUS%%:*} == Failed ]]; then
        EXIT=${STATUS##*:}
        MESSAGES $EXIT
        ROLLBACK
    fi

}

#-----------------------------------------------------
##   Creating initramfs
#-----------------------------------------------------
INITRAMFS_CREATE()
{
    initrd_error=0

    if [ -f $initramfs ]; then
        cp -f $initramfs ${initramfs}_${DATE}
    fi

        # OS issue Workaround: PPLI-1933, Boot from SAN host does not boot up as symlink to the boot partition of the format 
        # /dev/disk/by-path/fc-<FC_INITIATOR_WWPN>-<FC_TARGET_WWPN>-lun-1-part1 is not available when initrd loads. Hence move these 
        # files to a temporary folder so that it cannot be used by dracut to create a finished hook with that type of symlink.
        mkdir /etc/opt/emcpower/.tmp/ppbfs_dracut_tmp 
        mv -f /dev/disk/by-path/fc-* /etc/opt/emcpower/.tmp/ppbfs_dracut_tmp/  > /dev/null 2>&1
        dracut -f -v $initramfstmp $(uname -r) > /etc/opt/emcpower/.tmp/emcpbfs_linux_dracut_logs 2>&1
        initrd_error=$?
        if [ ${initrd_error} -eq 0 ]; then
            if [[ $sles_without_separate_boot == "yes" ]]; then
                mv -f $initramfstmp /boot > /dev/null 2>&1
            else
                mount ${boot_par} > /dev/null 2>&1
                mount | grep ${boot_par} > /dev/null 2>&1
                if [ $? -ne 0 ]; then
                    STATUS="Failed:msg_boot_partition_not_mounted"
                    rm -f $initramfstmp > /dev/null 2>&1
                else
                    mv -f $initramfstmp /boot > /dev/null 2>&1
                fi
            fi
        fi
        mv -f /etc/opt/emcpower/.tmp/ppbfs_dracut_tmp/* /dev/disk/by-path/  > /dev/null 2>&1
        rmdir /etc/opt/emcpower/.tmp/ppbfs_dracut_tmp

    if [ ${initrd_error} -eq 0 ] && [ -f $initramfs ]; then
        echo Done
    else
        echo "Failed"
        STATUS="Failed:msg_initramfs_create"
    fi
}

INITRAMFS_CREATE_MAIN()
{
    STAGE=STAGE1

    if [[ $ACTION == "config" ]]; then
        # Initramfs/Initrd name with PowerPath.
        if [[ ${VERSION} == "RHEL8" || ${VERSION} == "RHEL9"  ]]; then
            initramfs="/boot/initramfs-$(uname -r).img"
            initramfstmp="/tmp/initramfs-$(uname -r).img"
        elif [[ ${VERSION} == "SLES12" || ${VERSION} == "SLES15" ]]; then
            initramfs="/boot/initrd-$(uname -r)"
            initramfstmp="/tmp/initrd-$(uname -r)"
        fi

        # Disable os-prober utility which runs during initrd creation.
        cat $RH7SL12_GRUB_DEFAULT | grep "GRUB_DISABLE_OS_PROBER.*=.*true" > /dev/null 2>&1 
        if [ $? -ne 0 ]; then
            cp $RH7SL12_GRUB_DEFAULT $TMP_RH7SL12_GRUB_DEFAULT
            cat $TMP_RH7SL12_GRUB_DEFAULT | grep "GRUB_DISABLE_OS_PROBER.*=.*false" > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                cat $TMP_RH7SL12_GRUB_DEFAULT | grep "GRUB_DISABLE_OS_PROBER.*=.*false" | sed -i "/GRUB_DISABLE_OS_PROBER.*=.*false/ s%false%true%g" $TMP_RH7SL12_GRUB_DEFAULT > /dev/null 2>&1
            else
                sed -i  "\$aGRUB_DISABLE_OS_PROBER=true" $TMP_RH7SL12_GRUB_DEFAULT > /dev/null 2>&1
            fi
            cp -f $TMP_RH7SL12_GRUB_DEFAULT $RH7SL12_GRUB_DEFAULT
        fi
    fi

    echo -n "   Creating $initramfs ... "
    INITRAMFS_CREATE

    if [[ ${STATUS%%:*} == Failed ]]; then
        EXIT=${STATUS##*:}
        MESSAGES $EXIT
        ROLLBACK
    fi
}

SET_DEFAULT_BOOT_ENTRY()
{
    if [[ (${VERSION} == "RHEL7" || ${VERSION} == "RHEL8" || ${VERSION} == "RHEL9") && ${UEFI} == "yes" ]]; then
        MENU_LST=/boot/efi/EFI/redhat/grub.cfg
    elif [[ -f /boot/grub2/grub.cfg || ${UEFI} == "yes" ]]; then
        MENU_LST=/boot/grub2/grub.cfg
    else
        MENU_LST=/boot/grub/menu.lst
    fi

    cp $MENU_LST $TMP_MENU_LST

    grub_default=$(cat $RH7SL12_GRUB_DEFAULT | grep ^GRUB_DEFAULT | awk -F "=" '{ print $NF }')
    if [[ ${grub_default} != saved ]]; then
        cp $RH7SL12_GRUB_DEFAULT $TMP_RH7SL12_GRUB_DEFAULT
        sed -i "/^GRUB_DEFAULT=/ s/$grub_default/saved/" $TMP_RH7SL12_GRUB_DEFAULT > /dev/null 2>&1

        cp -f $TMP_RH7SL12_GRUB_DEFAULT $RH7SL12_GRUB_DEFAULT
            
        grub2-mkconfig -o $MENU_LST > /dev/null 2>&1
    fi
        
    grub2-set-default 0 > /dev/null 2>&1
}

#-----------------------------------------------------
##   Miscellaneous Function 
#-----------------------------------------------------
MISC()
{
    if [[ $ACTION == "remove" ]]; then
        # Update lvm filter for removel of r/emcpower entry.

        cat $LVM | sed -e '/^[ \t]*global_filter[ \t]*=/ {
                   s%global_filter%# global_filter%g
                   s%\"r/emcpower.\*/\", \"a/sd.\*/\", \"r/nvme.\*/\", \"r/scini.\*/\"%%g
                   }'  > $TMP_LVM
        cp -f $TMP_LVM $LVM
        if [[ $skip_lvm_commands_during_host_bootup == "no" ]]; then
            vgscan -v  > /dev/null 2>&1
            lvmdiskscan  > /dev/null 2>&1
        fi

    fi
}

ENABLE_USE_OF_DEVICES_FILE()
{
    lvmdevices 2>&1 | grep -i "Devices file not enabled." > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        cp $LVM $TMP_LVM

        sed -i -e "/use_devicesfile.*=.*0/  s%use_devicesfile%# use_devicesfile%g"  $TMP_LVM > /dev/null 2>&1
        sed -i -e "/use_devicesfile.*=.*0/  s% #%#%g"                               $TMP_LVM > /dev/null 2>&1

        cp -f $TMP_LVM $LVM
        rm -f $TMP_LVM
    fi
}

DISABLE_USE_OF_DEVICES_FILE()
{
    lvmdevices > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        cp $LVM $TMP_LVM

        sed -i -e "/#.*use_devicesfile.*=.*[0-9]\|use_devicesfile.*=.*[0-9]/  s%#%%g"  $TMP_LVM > /dev/null 2>&1
        sed -i -e "/use_devicesfile.*=.*[1-9]/ s%[1-9]%0%g"  $TMP_LVM > /dev/null 2>&1

        cp -f $TMP_LVM $LVM
        rm -f $TMP_LVM
    fi
}

# Configure LVM to ignore PV on multiple native devices, default by OS.
ENABLE_MULTIPATH_COMPONENT_DETECTION()
{
    grep "multipath_component_detection.*=.*0" $LVM > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        cp $LVM $TMP_LVM
        grep "multipath_component_detection.*=.*0" $TMP_LVM > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            sed -i -e "/multipath_component_detection.*=.*0/  s%0%1%g"  $TMP_LVM > /dev/null 2>&1
            sed -i -e "/multipath_component_detection.*=.*1/  s%multipath_component_detection%# multipath_component_detection%g"  $TMP_LVM > /dev/null 2>&1
            sed -i -e "/multipath_component_detection.*=.*1/  s% #%#%g"  $TMP_LVM > /dev/null 2>&1
            cp -f $TMP_LVM $LVM
        fi
        rm -f $TMP_LVM
    fi
}

# Configure LVM to NOT ignore PV on multiple native devices.
DISABLE_MULTIPATH_COMPONENT_DETECTION()
{
    grep "#.*multipath_component_detection.*=.*[0-9]\|multipath_component_detection.*=.*[1-9]" $LVM > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        cp $LVM $TMP_LVM
        grep "#.*multipath_component_detection.*=.*[0-9]\|multipath_component_detection.*=.*[1-9]" $TMP_LVM > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            sed -i -e "/#.*multipath_component_detection.*=.*[0-9]\|multipath_component_detection.*=.*[1-9]/  s%#%%g" $TMP_LVM > /dev/null 2>&1
            sed -i -e "/multipath_component_detection.*=.*[1-9]/  s%[1-9]%0%g"  $TMP_LVM > /dev/null 2>&1
            cp -f $TMP_LVM $LVM
        fi
        rm -f $TMP_LVM
    fi
}

#-----------------------------------------------------
##   Check PowerPath non disruptive upgrade
#-----------------------------------------------------
# During PowerPath non disruptive upgrade, avoid any PowerPath user commands/scripts
# being executed by checking NDU_LOCK_FILE marker file created.
if [[ -f ${NDU_LOCK_FILE} && ${PP_NDU_IN_PROGRESS} -ne 1 ]]; then
    echo "Warning: PowerPath non disruptive upgrade is in progress."
    echo "Please retry after the upgrade is complete."
    exit 1
fi

#-----------------------------------------------------
##   Check root authorization
#-----------------------------------------------------
if [[ $(whoami) != "root" ]]; then
    MESSAGES msg_insufficient_permission 
fi

#-----------------------------------------------------
##   Linux Kernels Distribution Check
#-----------------------------------------------------

if [ -f ${REDHAT} ]; then
    VERSION=RHEL$(cat ${REDHAT} \
            | sed 's/^.*release \([0-9]\)[0-9.]*.*/\1/') > /dev/null 2>&1
elif [ -f ${SLES_12} ]; then
    cat ${SLES_12} | grep "SUSE Linux Enterprise Server 15" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
       VERSION=SLES15
    fi
    cat ${SLES_12} | grep "SUSE Linux Enterprise Server 12" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
       VERSION=SLES12
    fi
elif [ -f ${SLES} ]; then
    VERSION=SLES$(cat ${SLES} | awk '/^VERSION/ {version=$NF} 
                                END {print version}') > /dev/null 2>&1
fi

#-----------------------------------------------------
##   Setting up the grub file
#-----------------------------------------------------

if [ -d /sys/firmware/efi ]; then
    UEFI=yes
fi

#-------------------------------------------------------------
##   SLES OS install without separate /boot standard partition
#-------------------------------------------------------------

sles_without_separate_boot="no"
if [[ ${VERSION} == "SLES12" || ${VERSION} == "SLES15" ]]; then
    if [ -f $FSTAB ]; then
        cat $FSTAB | grep -v "^[ \t]*#" | grep "/boot[[:space:]]" > /dev/null 2>&1
        if [ $? -ne 0 ]; then
            sles_without_separate_boot="yes"
        fi
    fi
fi

skip_lvm_commands_during_host_bootup="no"

#-----------------------------------------------------
##   MAIN Function
#-----------------------------------------------------

case $VERSION in
RHEL9|RHEL8|RHEL7|SLES12|SLES15)

    if [[ $1 == "config" || $1 == "remove"  ]]; then
        powermt config > /dev/null 2>&1
    fi

    if [[ $1 == "config" ]]; then
        if (( $# >= 2 )); then
                MESSAGES msg_incorrect_input
                USAGE
                ERROR_EXIT
        fi

        CLEANUP
        ACTION=$1

        if [ ! -f $PP_BFS_DONE ]; then
            MESSAGES msg_phase1
            CONFIG_CHECK 
            MESSAGES msg_phase2_${ACTION}
            trap CTRL_C SIGHUP SIGINT SIGTERM 
            if [[ ${UEFI} == "yes" || ${sles_without_separate_boot} != "yes" ]]; then
                LUNS_CHECK
            fi
            if [[ ${VERSION} == "SLES12" || ${VERSION} == "SLES15" || ${VERSION} == "RHEL8" || ${VERSION} == "RHEL9"  ]]; then
                if [[ ${VERSION} == "RHEL9"  ]]; then
                    DISABLE_USE_OF_DEVICES_FILE
                    echo "   LVM devices file .............................. Disabled"
                fi
                INITRAMFS_CREATE_MAIN
            fi
            SET_DEFAULT_BOOT_ENTRY
            if [[ ${UEFI} == "yes" || ${sles_without_separate_boot} != "yes" ]]; then
                FSTAB_UPDATE_MAIN
            fi
            LVM_UPDATE_MAIN 
            touch $PP_BFS_DONE
            MESSAGES msg_success
        else
            MESSAGES msg_pp_bfs_configured
        fi
    elif [[ $1 == "remove" ]]; then
        if (( $# >= 2 )); then
                MESSAGES msg_incorrect_input
                USAGE
                ERROR_EXIT
        fi

        CLEANUP
        ACTION=$1

        if [ -f $PP_BFS_DONE ]; then
            MESSAGES msg_phase1
            CONFIG_CHECK 
            MESSAGES msg_phase2_${ACTION}
            trap CTRL_C SIGHUP SIGINT SIGTERM 
            if [[ ${UEFI} == "yes" || ${sles_without_separate_boot} != "yes" ]]; then
                FSTAB_UPDATE_MAIN
            fi
            if [[ ${VERSION} == "RHEL9"  ]]; then
                ENABLE_USE_OF_DEVICES_FILE
                echo "   LVM devices file .............................. Enabled"
            fi
            LVM_UPDATE_MAIN 
            MISC 
            rm -f $PP_BFS_DONE
            MESSAGES msg_success
        else
            MESSAGES msg_pp_bfs_not_configured
        fi
    elif [[ $1 == "default_lvm_filter" ]]; then
    # REVISIT - root VG's /var mount not recognized during host bootup.
    #         : Below changes are added to fix above issue which lead NVMe daemon 'emcpnvmecfgd' not up after host reboot.
        ACTION="remove"
        skip_lvm_commands_during_host_bootup="yes"
        LVM_UPDATE_MAIN
        CLEANUP
        MISC
        CLEANUP
        rm -f /etc/lvm/lvm.conf_bkp_emcpbfs_linux_default_lvm_filter* > /dev/null 2>&1
    elif [[ $1 == "powerpath_lvm_filter" ]]; then
    # REVISIT - root VG's /var mount not recognized during host bootup.
    #         : Below changes are added to fix above issue which lead NVMe daemon 'emcpnvmecfgd' not up after host reboot.
        ACTION="config"
        skip_lvm_commands_during_host_bootup="yes"
        LVM_UPDATE_MAIN
        CLEANUP
        rm -f /etc/lvm/lvm.conf_bkp_emcpbfs_linux_powerpath_lvm_filter* > /dev/null 2>&1
    elif [[ $1 == "help" ]]; then
        USAGE
    else
        USAGE
    fi
;;

*)
    MESSAGES msg_not_supported_kernel
;;

esac
