#!/bin/bash
#*****************************************************************************
# Copyright 2004-2010 NetApp, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation,  version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#*****************************************************************************
#
#  Script %name:    mppUpdate26p %
#  Instance:        WIC_1
#  %version:        8 %
#  Description:        This script is used to update the entries in the device mapping file. Either
#  all or specific entries can be deleted or entries can be made to match what the driver can 
#  currently see.        
#  %created_by:        somasunk %
#  %date_created:    Thu Apr 26 17:28:26 2012 %

# Get all the options from the command line

. /opt/mpp/mppMkInitrdHelper;

while getopts cvd: op 2>/dev/null
do
    case "$op" in
        c) CLEAR_ALL=TRUE;;
        d) MODULE="$OPTARG";;
        v) VERBOSE=TRUE;;
        \?) echo "Usage: $0: [-c] [-v] [-d storageArrayName]"
            exit 2;;
    esac
done


DEVICE_MAP_FILE=/var/mpp/devicemapping
MPP_UTIL_FILE=/usr/sbin/mppUtil
TEMP_DEVICE_MAP_FILE=/tmp/devicemapping.$$
TEMP_DEVICE_LIST=/tmp/deviceList.$$
TEMP_MODULE_LIST=/tmp/moduleList.$$
UNAME=`uname -r`

#kdump support 
if [ -f /etc/redhat-release ]; then 
	DIST=REDHAT
else 
	DIST=SUSE
fi

KDUMP_FLAG=`/bin/rpm -qa | grep kexec-tools | wc -l`
if [ $KDUMP_FLAG = 1 ]; then
    if [ $DIST = SUSE ]; then
        if [ -f /boot/vmlinux-kdump ]; then 
            KDUMP_STATUS=`echo 1`
        else
		    KDUMP_STATUS=`echo 0`
		fi

        if [ $KDUMP_STATUS = 1 ]; then
            KERNEL_DUMP_VER=`ls -la /boot/vmlinux-kdump | sed -e 's/.*vmlinux-//g'`
        fi
    else
        KDUMP_STATUS=`echo 1`
        if [ $KDUMP_STATUS = 1 ]; then
            KERNEL_DUMP_VER=`uname -r`
        fi
    fi
else
    KDUMP_STATUS=`echo 0`
fi

#check if a module name has been given as input

if [ -n "$MODULE" ]
then
    if [ ! -e $DEVICE_MAP_FILE ]
    then
        echo "Error, No Devicemapping ($DEVICE_MAP_FILE) file found." >&2
        exit
    fi
    MODULE_FOUND=`/bin/grep ":$MODULE$" $DEVICE_MAP_FILE`
    # search for the module name in the device mapping file
    if [ -z "${MODULE_FOUND}" ]
    then
        echo "The module "$MODULE" is not present in the MPP persistence mapping list ($DEVICE_MAP_FILE). "
        exit
    else
        # Remove the entry from the device mapping file
        /bin/sed -n "/:$MODULE$/ !p"  $DEVICE_MAP_FILE >>  $TEMP_DEVICE_MAP_FILE
        /bin/mv -f $TEMP_DEVICE_MAP_FILE $DEVICE_MAP_FILE
        echo "The module "$MODULE" was removed from the MPP persistence mapping list ($DEVICE_MAP_FILE)."
        # do not exit here. Makeinitrd image and exit
    fi
elif [ -n "$CLEAR_ALL" ]
then
    if [ ! -e $DEVICE_MAP_FILE ]
    then
        echo "Error, No Devicemapping ($DEVICE_MAP_FILE) file found." >&2
        exit
    fi
    # Remove all the entries from the device mapping file
    /bin/sed '1,$ d' $DEVICE_MAP_FILE >> $TEMP_DEVICE_MAP_FILE
    /bin/mv -f $TEMP_DEVICE_MAP_FILE $DEVICE_MAP_FILE
    echo "All entries have been cleared from the MPP persistence mapping list ($DEVICE_MAP_FILE)."
    # do not exit here. Makeinitrd image and exit
else
    # If the -c or -d option have not been used, need to update the devicemapping file
    if [ ! -e $MPP_UTIL_FILE ]
    then
        echo "Error, No mppUtil ($MPP_UTIL_FILE) found." >&2
        exit
    fi

    # get the maximum virtual target Id supported by our driver
    MAX_VIRTUAL_TARGET_IDS=`$MPP_UTIL_FILE -m 2>/dev/null | cut -d= -f2`
    if [ -z $MAX_VIRTUAL_TARGET_IDS  ]
    then
        echo "Error, MaxVirtualTargets=0. Cannot update Devicemapping ($DEVICE_MAP_FILE) file." >&2
        exit
    fi

    if [ -e $DEVICE_MAP_FILE ]
    then
        /bin/cp $DEVICE_MAP_FILE $TEMP_DEVICE_LIST
    else
        /bin/touch $TEMP_DEVICE_LIST
    fi

    if [ ! -e $TEMP_MODULE_LIST ]
    then
        /bin/touch $TEMP_MODULE_LIST
    fi
   

    i=0
    # Loop through all the virtual target Ids
    while [ $i -lt "$MAX_VIRTUAL_TARGET_IDS" ]
    do
        # call mppUtil to see if there exists an array corresponding to this virtual target id  
        MODULE_NAME=`$MPP_UTIL_FILE -g $i 2>/dev/null`
    
        MODULE_PRESENT=`echo $MODULE_NAME | /bin/grep "WWN: "`
        if [ -z "$MODULE_PRESENT" ]
        then
           # echo "No array at this virtual target ID "
            i=`expr $i + 1`
            continue
    fi
        ARRAY_NOT_LABELED_TAG=`echo "$MODULE_NAME" | /bin/grep Array_Module_`
        if [ -n "$ARRAY_NOT_LABELED_TAG" ]
        then
            # The array doesn't have a defined storage array name
            # do nothing
            echo "The storage array corresponding to virtual target ID "$i" does not have"
        echo " a user assigned label."
        else
            # Parse the storage array name from the mppUtil info
            # and place in the module list temp file
            ARRAY_ENTRY=`echo "$MODULE_NAME" | /bin/sed  -n 's/^      ModuleName: //
                   s/SingleController: .*//p ' | /bin/sed 's/  *// '`
            echo "$i:$ARRAY_ENTRY"  >> $TEMP_MODULE_LIST
        fi
        i=`expr $i + 1`
    done

    if [ ! -e $DEVICE_MAP_FILE ]
    then
        /bin/cp $TEMP_MODULE_LIST $DEVICE_MAP_FILE
        echo "New Devicemapping ( $DEVICE_MAP_FILE ) file has been created with latest array entries."
	MAP_FILE_CREATED=TRUE # CR 133100 -Fix
    fi

    # Start nawk script to read storage array names we have discovered using mppUtil
    # and compare to the list already in devicemapping file 
    /bin/gawk -v numElements="$MAX_VIRTUAL_TARGET_IDS" -v tmpList="$TEMP_MODULE_LIST"  -v tmpFile="$TEMP_DEVICE_LIST" -v uname="$UNAME" -v devmapfile="$DEVICE_MAP_FILE" -v verbose="$VERBOSE" '
        BEGIN {
            # read elements from temporary storage array name file
            contentsChanged=0;
            FS=":"
            while ( getline < tmpList > 0) {
                arrayIndex[$1] = $2;
                arrayName[$2] = $1;
                #printf( "array name %d %s", $1, arrayIndex[$1] )
            }
			
            FS=":" # CR 133100 -Fix
            while ( getline < tmpFile > 0) {
                mapFileArrayIndex[$1] = $2;
                mapFileArrayName[$2] = $1;
                #printf( "array name from map file is%d %s", $1, mapFileArrayIndex[$1] )
            }
        }
    
    
        END {
            for ( x in arrayIndex ) {
                contentsChanged=1;
				#CR133100 
				if ( (! (x in mapFileArrayIndex )) && (! (arrayIndex[x] in mapFileArrayName)) ) {    
						printf ("%d:%s\n",x, arrayIndex[x])  >>tmpFile;
				}
            }
        }
    
        {
            FS = ":"
            if ($1 >= numElements)  {
                # nothing to do as the virtual target id is off the range we support
                print "Found a virtual Target ID off limits."
                next;
            }
                # see if there is a match
            if ( $1 in arrayIndex || $2 in arrayName ) {
                # index is present in devicemapping file and in array 
                # found a match, get rid of entries in arrays
                if( $1 == arrayName[$2] && $2 == arrayIndex[$1] ) { 
                    print "Found match for array name",$1":"$2,arrayName[$2]":"arrayIndex[$1]"."
                    delete arrayIndex[arrayName[$2]] ;
                    delete arrayName[$2];
                    next;
                }
                else {
                    if ( $1 in arrayIndex) {
                        if ($2 !=  arrayIndex[$1] && arrayIndex[$1] != "")  {
                            if (verbose) {
                                print "INFO: The array name "arrayIndex[$1]" found corresponding "
                                print "to Virtual Target ID "$1" is different from that present "
                                print "in the Devicemapping (" devmapfile ") file.\n"
                            }
    
                            next; 
                        }
                    }
                    if ( $2 in arrayName) {
                        if ($1 != arrayName[$2] && arrayName[$2] != "" ) {
                            if (verbose) {
                                print "INFO: The array index "arrayName[$2]" found corresponding "
                                print "to array name "$2" is different from that present "
                                print "in the Devicemapping (" devmapfile ") file.\n"
                            }
    
                            next;
                        }
                    }
                }
    
            }
            else  {
                # This means the name is in the devicemapping file but mppUtil did not find the array  
                print "Spurious Entry "$1":"$2", found in Devicemapping (" devmapfile ") file."
                print "If it is not needed, delete this old entry for which the array was not found.\n"
                next;
            }
    
        } ' $TEMP_DEVICE_LIST 
    
	if [ "$MAP_FILE_CREATED" != "TRUE" ] # CR 133100 -Fix
	then
    	/bin/cp $TEMP_DEVICE_LIST $DEVICE_MAP_FILE
	fi
fi

identifyOSAndHBAVendor
ModuleNameCheck;
createModDep;

if [ -f /etc/redhat-release ]; then
	RHEL6_FLAG=`if [ -f /etc/redhat-release ]; then cat /etc/redhat-release | grep -c 'release 6'; else echo 0; fi`;
fi

if [ "${RHEL6_FLAG}" == "0" ]; #CR173298
then
        makeMPPInitrdImage 
else
        echo "MPP: Running dracut <$MPP_RAMDISK_KERNEL_VERSION> <$MPP_RAMDISK_KERNEL_VERSION>"
        dracut -f /boot/mpp-${MPP_RAMDISK_KERNEL_VERSION}.img ${MPP_RAMDISK_KERNEL_VERSION}
fi
if [ $KDUMP_STATUS = 1 ]; then
	if [ "${RHEL6_FLAG}" == "0" ]; #CR173298
	then
		makeMPPInitrdImage $KERNEL_DUMP_VER
	else
		echo "MPP: Running dracut <$KERNEL_DUMP_VER> <$KERNEL_DUMP_VER>"
		dracut -f /boot/mpp-${KERNEL_DUMP_VER}.img ${KERNEL_DUMP_VER}
	fi
	if [ $DIST = SUSE ]; then
		cp -f /boot/mpp-$KERNEL_DUMP_VER.img /boot/initrd-$KERNEL_DUMP_VER
	else 
		cp -f /boot/mpp-$KERNEL_DUMP_VER.img /boot/initrd-${KERNEL_DUMP_VER}kdump.img
	fi
fi

if [ "${RHEL6_FLAG}" == "1" ];
then
        /bin/rm -f /etc/modprobe.d/mppmodules.conf
fi

/bin/rm -f $TEMP_DEVICE_LIST
/bin/rm -f $TEMP_MODULE_LIST
exit 0;
