#!/bin/bash
#*****************************************************************************
# Copyright 2004-2008 LSI Corporation.
#
# 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:	mppMkInitrd26p %
#  Instance:		WIC_1
#  %version:		12.1.5 %
#  Description:		
#  %created_by:		bmoger %
#  %date_created:	Mon Sep 08 11:39:27 2008 %

OS_DIST="";
HbaVendor="";
REDHAT_NEED_MODCONF_RESTORE=""
SYS_MODPROBE_FILE=/etc/modprobe.conf
MPP_TMP_MODPROBE_FILE=/tmp/modprobe_conf_mppappend_saved
SYS_MODPROBE_SAVED_FILE=/tmp/modprobe_conf_mpp_saved
MPPAPPENDFILE=/opt/mpp/modprobe.conf.mppappend;
SUSE_MPPAPPENDFILE=/opt/mpp/modprobe.conf.mppappend;
SUSE_MODPROBE_CONF=/etc/modprobe.conf.local
REDHAT_MODPROBE_CONF=/etc/modprobe.conf
SUSE_LPFC_CONF=/etc/modprobe.d/lpfc
SUSE_BFA_CONF=/etc/modprobe.d/bfa
SUSE_QLA_CONF=/etc/modprobe.d/qla
SUSE_SCSI_MOD_CONF=/etc/modprobe.d/scsi_mod
SUSE_NEED_MODCONF_RESTORE=""
SUSE_MODPROBE_LOCAL_MPP_SAVED_FILE=/tmp/modprobe_conf_local_mpp_saved
OLD_MPP_CONF_FILE=/etc/mpp.conf.rpmsave;
NEW_MPP_CONF_FILE=/etc/mpp.conf;
TEMP_MPP_CONF_FILE=/etc/mpp.conf.$$;
SUSE_SYSCONFIG_KERNEL="/etc/sysconfig/kernel"
SUSE_SYSCONFIG_KERNEL_SAVED="/tmp/kernel.orig"
HBA_VENDOR_LIST=""
QLOGIC_COMMON_FIRST_TIME=""
SILVERSTORM_MODULE_OPTS=""
CISCO_IB_MODULE_OPTS=""
MPP_QLA_DRIVER_COMPATIBLITY="http://www.engenio.com/html/partners/compatible_matrix/compatible_matrix.html"

#Value of max luns for ramdisk
MAX_LUNS=512

#Value of max reported luns for ramdisk
MAX_REPORT_LUNS=256

#initialize PRELOAD value to null, This parameter is used to preload modules at mkinitrd
REDHAT_PRELOAD=""

MODULE_LIST_FILE="/tmp/ModuleListFile.mpp"
QLA_MIN_VERSION="8.00.01b4-lsi3"

export LINK_DOWN_TIMEOUT=144

# Condition will be true after hbaCheck is called and before setupDriver.$(OS_DIST)
# createModDep() routine will use the value of MODULE_LIST generated during hbaCheck
if [ -f $MODULE_LIST_FILE ]
then
MODULE_LIST=`cat $MODULE_LIST_FILE`;
else
MODULE_LIST="";
fi
#*****************************************************************************
#  Function:   mppLnx_isIscsiDriverInstalled_fn
#  Description:  Check if an iSCSI software initiator and its user space tools installed
#                on the Linux system. 
#  The function will print "1" for yes and "0" for no
#*****************************************************************************
mppLnx_isIscsiDriverInstalled_fn()
{
   #both open-iscsi and linux-iscsi user space iscsi daemons are named
   #iscsid and installed at /sbin/iscsid.
   #checking if iscsid exists
   if [ -f /sbin/iscsid ]
   then
      echo "1"
   else
      echo "0"
   fi
}
#*****************************************************************************
#  Function:   mppLnx_modLnxIscsiConf_fn
#  Description:  Modify Linux iSCSI software initiator configuration (a.k.a Cisco software 
#         initiator). This function checks the initiator configuration file /etc/iscsi.conf 
#         for the configuration values of ConnFailTimeout and Multipath parameters. If end 
#         users set the ConnFailTimeout to a value other than 0, this function will not try 
#         to modify the ConnFailTimeout value. The Multipath will set to portal. Some versions 
#         of the Cisco software initiator don't support Multipath. If this the case, the function 
#         will skip the modification of Multipath parameter 
#*****************************************************************************
mppLnx_modLnxIscsiConf_fn()
{
	SAVED_ISCSI_CONF=/etc/iscsi.conf.mppsaved
	ORIG_ISCSI_CONF=/etc/iscsi.conf
	TMP_ISCSI_CONF=/tmp/iscsi.conf.tmp

	
	#save the original ORIG_ISCSI_CONF to SAVED_ISCSI_CONF	
	if [ ! -f  ${SAVED_ISCSI_CONF} ]
	then
		#cp the original iscsi.conf to ORIG_ISCSI_CONF and preserve its timestamp	
		cp -p ${ORIG_ISCSI_CONF} ${SAVED_ISCSI_CONF}
	fi
	
	#edit the iscsi.conf file
	cat ${ORIG_ISCSI_CONF} |awk  \
		-v LINK_DOWN_TIMEOUT=${LINK_DOWN_TIMEOUT} \
		-v ORIG_ISCSI_CONF=${ORIG_ISCSI_CONF} \
		-v TMP_ISCSI_CONF=${TMP_ISCSI_CONF} \
	'BEGIN{ 
		#we do modification of the ORIG_ISCSI_CONF in three phases
		# the first phase checking if the ConnFailTimeout and Multipath parameters are configured
		# correctly in the awk BEGIN phase
		# the second phase will parse the ORIG_ISCSI_CONF file and do the modification. The second
		# phase is performed in the awk main body
		# the last phase is to replace the modified content with ORIG_ISCSI_CONF. This phase
		# is done in the awk END phase
		ConnFailTimeout_configured=0;
		Multipath_configured=0;
		ConnFailTimeout_added=0;
		Multipath_added=0;
		printSwitch=1
		# read the iscsi.conf file line by line
		while ( getline theline < ORIG_ISCSI_CONF   > 0)
		{
			if(theline ~ "ConnFailTimeout" && theline !~ /^#/ &&  theline !~ /#[\x20*]ConnFailTimeout/ && theline !~ /#ConnFailTimeout/ )
			{
				#if we found a valid ConnFailTimeout setting, turn on the ConnFailTimeout_configured flag
				# the ConnFailTimeout_configured flag is used in the second phase
				if(theline  ~ "ConnFailTimeout=0")
				{
					#ConnFailTimeout=0 means never timeout.
					ConnFailTimeout_configured = 1;
				}else
				{
					ConnFailTimeout_configured = 2;
				}
					#printf("ConnFailTimeout is configure %s\n",theline)
			}

			if(theline  ~ "Multipath" && theline !~ /^#/ &&  theline !~ /#[\x20*]Multipath/ && theline !~ /#Multipath/ )
			{
				#we see a valid Multipath=? line.
				#Multipath=portal is what we want 
				if(theline ~ "Multipath=no" || theline ~ "Multipath=portalgroup")
				{
					Multipath_configured = 1;
				}else
				{
					Multipath_configured = 2;
				}	
					#printf("Multipath is configured %s \n", theline)
			}

		}
		close(ORIG_ISCSI_CONF)
		
		#if TMP_ISCSI_CONF exists, rm it
		rmTmpFileCmd=sprintf("if [ -f %s ]; then rm %s; fi",TMP_ISCSI_CONF,TMP_ISCSI_CONF)
		system(rmTmpFileCmd)
	} #end of the BEGIN phase
	{ #start of the main phase
		if( ConnFailTimeout_configured == 2 && Multipath_configured == 2)
		{
			#we do not need to do anything
			#ConnFailTimeout and Multipath are configured correct
			# no-op block
		}else
		{
			if ( $0 ~ "ConnFailTimeout" )
			{
				if (ConnFailTimeout_configured == 1)
				{
					if($0 !~ /^#/ &&  $0 !~ /#[\x20*]ConnFailTimeout/ && $0 !~ /#ConnFailTimeout/ )
					{
						printf("ConnFailTimeout=%d\n",LINK_DOWN_TIMEOUT)>>TMP_ISCSI_CONF
						printSwitch=0

					}

				}else if (ConnFailTimeout_configured == 2)
				{
					#no op
				}else if (ConnFailTimeout_added == 0)
				{
					#the first phase does not find a valid ConnFailTimeout
					print $0 >>TMP_ISCSI_CONF
					printf("ConnFailTimeout=%d\n",LINK_DOWN_TIMEOUT)>>TMP_ISCSI_CONF
					ConnFailTimeout_added++
					printSwitch=0
				}
			}

			if ( $0 ~ "Multipath" )
			{
				if( Multipath_configured == 1 )
				{
					if($0 !~ /^#/ &&  $0 !~ /#[\x20*]Multipath/ && $0 !~ /#Multipath/ )
					{

						#we see the Multipath
						#print $0
						printf("Multipath=portal\n")>>TMP_ISCSI_CONF
						printSwitch=0
					}
				}else if( Multipath_configured == 2 )
				{
					#no op
				}else if(Multipath_added == 0)
				{
					print $0 >>TMP_ISCSI_CONF
					printf("Multipath=portal\n")>>TMP_ISCSI_CONF
					Multipath_added++
					printSwitch=0
				}
			} 
			if(printSwitch)
			{
				print $0 >>TMP_ISCSI_CONF
			}else
			{
				printSwitch=1
			}

		}
	}END{
		rplIscsiConfCmd=sprintf("if [ -f %s ]; then cp %s %s; rm %s; fi",TMP_ISCSI_CONF,TMP_ISCSI_CONF,ORIG_ISCSI_CONF,TMP_ISCSI_CONF)
		system(rplIscsiConfCmd)

	} '
}
#*****************************************************************************
#  Function:   mppLnx_modOpenIscsiConf_fn
#  Description: Modify Open-iSCSI software initiator configuration. This function checks 
#        the initiator configuration file /etc/iscsid.conf for the configuration values 
#        of node.session.timeo.replacement_timeout. If end users set the node.session.
#        timeo.replacement_timeout to a value other than 120 (default), this function 
#        will not try to modify the node.session.timeo.replacement_timeout value
#*****************************************************************************
mppLnx_modOpenIscsiConf_fn()
{
	SAVED_ISCSI_CONF=/etc/iscsi/iscsid.conf.mppsaved
	ORIG_ISCSI_CONF=/etc/iscsi/iscsid.conf
	TMP_ISCSI_CONF=/tmp/iscsid.conf.tmp
	
	#save the original ORIG_ISCSI_CONF to SAVED_ISCSI_CONF
	if [ ! -f  ${SAVED_ISCSI_CONF} ]
	then
		#cp the original iscsid.conf to ORIG_ISCSI_CONF and preserve its timestamp
		cp -p ${ORIG_ISCSI_CONF} ${SAVED_ISCSI_CONF}
	fi
	
	#edit the iscsid.conf file
	cat ${ORIG_ISCSI_CONF} |awk  \
		-v LINK_DOWN_TIMEOUT=${LINK_DOWN_TIMEOUT} \
		-v ORIG_ISCSI_CONF=${ORIG_ISCSI_CONF} \
		-v TMP_ISCSI_CONF=${TMP_ISCSI_CONF} \
	'BEGIN{ 
		#we do modification of the ORIG_ISCSI_CONF in three phases
		# the first phase checking if the ReplacementTimeout is configured
		# correctly in the awk BEGIN phase
		# the second phase will parse the ORIG_ISCSI_CONF file and do the modification. The second
		# phase is peformed in the awk main body
		# the last phase is to replace the modified content with ORIG_ISCSI_CONF. This phase
		# is done in the awk END phase
		ReplacementTimeout_configured=0;
		ReplacementTimeout_added=0;
		printSwitch=1
		# read the iscsid.conf file line by line
		while ( getline theline < ORIG_ISCSI_CONF   > 0)
		{
			if(theline ~ "node.session.timeo.replacement_timeout" && theline !~ /^#/ &&  theline !~ /#[\x20*]node.session.timeo.replacement_timeout/ && theline !~ /#node.session.timeo.replacement_timeout/ )
			{
				#if we found a valid ReplacementTimeout setting, turn on the ReplacementTimeout_configured flag
				# the ReplacementTimeout_configured flag is used in the second phase
				if( theline  ~ /node.session.timeo.replacement_timeout *= *120/ )
				{
					ReplacementTimeout_configured = 1;
				}else
				{
					ReplacementTimeout_configured = 2;
				}
				#printf("ReplacementTimeout is configure %s\n",theline)
			}
		}
		close(ORIG_ISCSI_CONF)
		
		#if TMP_ISCSI_CONF exists, rm it
		rmTmpFileCmd=sprintf("if [ -f %s ]; then rm %s; fi",TMP_ISCSI_CONF,TMP_ISCSI_CONF)
		system(rmTmpFileCmd)
	} #end of the BEGIN phase
	{ #start of the main phase
		if( ReplacementTimeout_configured == 2 )
		{
			#we do not need to do anything
			#ReplacementTimeout is configured correctly
			# no-op block
		}else
		{
			if ( $0 ~ "node.session.timeo.replacement_timeout" )
			{
				if (ReplacementTimeout_configured == 1)
				{
					if( $0  ~ /node.session.timeo.replacement_timeout *= *[0-9]/ )
					{
						printf("node.session.timeo.replacement_timeout = %d\n",LINK_DOWN_TIMEOUT)>>TMP_ISCSI_CONF
						printSwitch=0

					}

				}else if (ReplacementTimeout_configured == 2)
				{
					#no op
				}else if (ReplacementTimeout_added == 0)
				{
					#the first phase does not find a valid ReplacementTimeout
					print $0 >>TMP_ISCSI_CONF
					printf("node.session.timeo.replacement_timeout = %d\n",LINK_DOWN_TIMEOUT)>>TMP_ISCSI_CONF
					ReplacementTimeout_added++
					printSwitch=0
				}
			}

			if(printSwitch)
			{
				print $0 >>TMP_ISCSI_CONF
			}else
			{
				printSwitch=1
			}

		}
	}END{
		rplIscsiConfCmd=sprintf("if [ -f %s ]; then cp %s %s; rm %s; fi",TMP_ISCSI_CONF,TMP_ISCSI_CONF,ORIG_ISCSI_CONF,TMP_ISCSI_CONF)
		system(rplIscsiConfCmd)

	} '
}
#*****************************************************************************
#  Function:   mppLnx_modIscsiConf_fn
#  Description: Modify configuration parameters for  Open-iSCSI software initiator or 
#         Linux iSCSI software initiator
#*****************************************************************************
mppLnx_modIscsiConf_fn()
{
	LNX_ISCSI_CONF="/etc/iscsi.conf"
	OPEN_ISCSI_CONF="/etc/iscsi/iscsid.conf"
	if [ -f ${LNX_ISCSI_CONF} ]
	then
		#this is the Cisco software initiator case
		mppLnx_modLnxIscsiConf_fn

	elif [ -f ${OPEN_ISCSI_CONF} ]
	then
		#this is the open iscsi software initiator case
		mppLnx_modOpenIscsiConf_fn
	fi
}
#identify the type of HBA cards on the system.
#check if there are any HBA card from unsupported vendors

checkHBAConfig ()

# This function checks the fibre channel HBA cards on the installation system
# and detect the following situations:
# 1. No supported fibre channel HBA cards on the system
# 2. Mixed supported fibre channel HBA cards co-exist on the system
# 3. Non-supported fibre channel HBA cards on the system
# This function outputs proper warning message to the user if any of the conditions 
# above is detected.
# To include additions models into MPP driver supported HBA cards, please use the following format:
# SupportedHBAModel[HBAVendorID]="HBAModelID1,HBAModelID2,..."

{

   ISCSI_SOFT_INITIATOR=$(mppLnx_isIscsiDriverInstalled_fn)
   # Class Code - 0c04 - Fibre Channel HBA
   # Class Code - 0c06 - Infiniband HCA
   # Class Code - 0100 - SAS HBA
   # Class Code - 0280 - Network Controller, iSCSI TOE card 

   lspci_n=`/sbin/lspci -n | awk '{print $2}'` #DVS 
   lspci_numeric=`expr "$lspci_n" : 'Class'`

   if [ "$lspci_numeric" == "0" ]
   then
        HBAModels=`/sbin/lspci -n | /bin/gawk '/ 0c04:/ || / 0c06:/ || / 0100.*1077.*22../ || / 0100.*1000.*005/ ||/ 0280:/  {print $2 $3 $4 $5 }'` 
   else
        HBAModels=`/sbin/lspci -n | /bin/gawk '/Class 0c04/ || /Class 0c06/ || /Class 0100.*1077.*22../ || /Class 0100.*1000.*005/ ||/Class 0280/  {print $3 $4 $5 $6 }'` #DVS
   fi

   export HBAModels
   echo "$HBAModels" | /bin/gawk \
        -v ISCSI_SOFT_INITIATOR=${ISCSI_SOFT_INITIATOR}\
        'BEGIN {
                NumberOfSupportedHBAModel = 0;
                nonSupportedHBAVendorExists = 0;
                FS=":";

		#FORMAT: SupportedHBAModel[HBAVendorID]="HBAModelID1,HBAModelID2,..."
                SupportedHBAModel["1000"] = "0050,0054,0056,0058,005a,005e,0062,0621,0622,0624,0626,0628,0640,0642,0646";
                SupportedHBAModel["1077"] = "2300,2310,2312,2322,2340,2342,2420,2422,2432,2440,2442,2460,2462,2532,4010,4022,4032,5422,5432,6312,6322";
                SupportedHBAModel["10df"] = "f011,f015,f095,f098,f0a1,f0a5,f0e1,f0e5,f900,f980,fa00,fa01,fc00,fc10,fc20,fc40,fd00,fd11,fd12,fe00,fe11,fe12,f100,f111,f112";
		SupportedHBAModel["1657"] = "0013,0017";		
                SupportedHBAModel["15b3"] = "5a44,6274,6278,6282,634a";
	
                errorMessage[1] = "Unsupported Host Adapter Vendor: Vendor ID";
                errorMessage[2] = "Unsupported Host Adapter Model: Product ID";

        }
        {
                HBAVendorSupported = 0;
                HBAModelSupported = 0;
               	HBAVendor = $2;
               	HBAModel = $3;
			
		if ( match($0,"Class 0100") != 0  && match(HBAVendor, "1077") != 0  && match(HBAModel,"22") != 0 )
		# This is a QLogic 2200 HBA card
		{
			print errorMessage[2],HBAModel;
		}
		else
		{
                	for (i in SupportedHBAModel)
                	{
                        	if ( match(HBAVendor,i) != 0)
                        	{
                                	HBAVendorSupported = 1;
					SupportedVendor[i] ++;

                                	split(SupportedHBAModel[i],a,",");   
                                	for ( j in a )
                                	{
                                        	if (match(HBAModel,a[j]) != 0)
                                        	{
                                                	HBAModelSupported = 1;
                                                	break;
                                        	}
                                	}
                                	if ( HBAModelSupported == 0)
                                	{
                                        	print errorMessage[2],HBAModel;
						UnsupportedModelFromVendor[i] = 1;
                                	}
					break; # break out of vendor check
                        	}
                	}
                	if (HBAVendorSupported == 0)
                	{
                        if ( ISCSI_SOFT_INITIATOR != 1)
                        {
                        	print errorMessage[1],HBAVendor;
                        }
                        	nonSupportedHBAVendorExists = 1;
                	}
		}
        }
        END {
		# configCheckResult value:
		# 0: Good
		# 1: warning needed because:
		# a) Unsupported HBA model exists
		# b) Mixed supported HBA co-exist
		# 2: No supported HBA card
		# 3: only iscsi software initiator is detected
		configCheckResult = 0;
		for (i in SupportedVendor) {
			if (match (i, "1077") != 0)
				VendorName = "QLogic" ;
			if (match (i, "1000") != 0)
				VendorName = "LSI";
			if (match (i, "10df") != 0)
				VendorName = "Emulex";
			if (match (i, "1657") != 0)
				VendorName = "Brocade";
			if (match (i, "15b3") != 0)
				VendorName = "Supported";
                        SupportedVendors++;
			print "Detected", SupportedVendor[i], VendorName, "Host Adapter Port(s) on the system";
		}
		if ( SupportedVendors == 0)
		{
			if(ISCSI_SOFT_INITIATOR == 1)
			{
				#we did not find any supported HBAs but a software iSCSI initiator is installed
				#on the system. Set configCheckResult=3. The hbaCheck code will ask end users
				#if they would like to continue
				configCheckResult = 3;
			}else
			{
    			print "There is no MPP supported Host Adapter card on your system.";
    			print "MPP driver supports Qlogic 23xx/24xx/4xxx HBA cards or LSI FC929X or LSI SAS 3800x or Emulex LP952/LP982/LP9002/LP9002DC/LP9802/LP9802DC/LP1050/LP10000/LP10000DC/LP11000 HBA cards";
				configCheckResult = 2;
			}
		}	
		else
		{
			if ( SupportedVendors > 1 )
			{
            			print "Host Adapters from different supported vendors co-exists on your system.";
				configCheckResult = 1;
			}	
                	for (i in UnsupportedModelFromVendor)
			{
				if (match (i, "1077") != 0)
					VendorName = "QLogic" ;
				if (match (i, "1000") != 0)
					VendorName = "LSI";
				if (match (i, "10df") != 0)
					VendorName = "Emulex";
				if (match (i, "1657") != 0)
					VendorName = "Brocade";
				if (match (i, "15b3") != 0)
					VendorName = "Supported";
				print "Unsupported model from Vendor", VendorName, " exists.";
				configCheckResult = 1;
			}
			if ( nonSupportedHBAVendorExists == 1)
			{
    	    			print "Host Adapter from unsupported vendor detected.";
				configCheckResult = 1;
			}
		}
		print configCheckResult>"/tmp/checkResultFile.mpp";
        } ' ;
}

ModuleNameCheck()
{

   if [ "$#" -gt "0" ]
   then
       MPP_RAMDISK_KERNEL_VERSION="$1"
   else
       MPP_RAMDISK_KERNEL_VERSION="$(uname -r)"
   fi
   
   export MPP_RAMDISK_KERNEL_VERSION
   
   /sbin/depmod -a ${MPP_RAMDISK_KERNEL_VERSION}
   
   #if HBAModels is empty, we don't need to keep going
   if [ "XXX${HBAModels}" == "XXX" ]
   then
      return
   fi
   
   echo "$HBAModels" > /tmp/HBAModel.mpp
   PCIMAP_MPP=`/bin/gawk ' { print $1,":",$2,":",$3; } ' /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/modules.pcimap`;
   MODULE_LIST=`echo "$PCIMAP_MPP" | /bin/gawk -v HBAFile="/tmp/HBAModel.mpp" '
        BEGIN {
                FS=":";
                MODULE_LIST="";
                i=0;
                while ( getline < HBAFile > 0) {
                      VendorId[i] = "0x0000"$2;
                      split($3, device, "(");
                      DeviceId[i] = "0x0000"device[1];  
                      i++;
                }
        }
        END {
                print MODULE_LIST ;
        }
        {
                HBAVendor = $2;
                HBAModel = $3;
                HBAModuleName = $1;

                for (i in VendorId)
                {
                        if ( match(HBAVendor,VendorId[i]) != 0)
                        {
                        	if (match(HBAModel,DeviceId[i]) != 0)
                               {
                               		if(match(MODULE_LIST, HBAModuleName) == 0)
                                       {
                                       		MODULE_LIST = MODULE_LIST HBAModuleName;
                                       }
                            	}
                        }
                }       
        } '`

   export $MODULE_LIST;
   echo "$MODULE_LIST" > $MODULE_LIST_FILE;

   rm /tmp/HBAModel.mpp
  
}


############################################
# Check qla driver's version number
# If it is lower than the min vesion number, return 0
# otherwise, return 1
############################################
mppLnx_check_qla_version()
{
   #get the current qla driver's version number
      QLA_VERSION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/qla2xxx/qla2xxx.ko | grep version|awk '{print $2}')
   export QLA_VERSION=${QLA_VERSION}
   #the version has the format 8.00.01bxx-xxx
   echo ${QLA_VERSION} |awk -F'.' -v QLA_MIN_VERSION="${QLA_MIN_VERSION}" '
   {
      release_n=$1
      major_n=$2
      minor_and_build=$3
      build_num_index=index(minor_and_build,"b")
      build_num_dash=index(minor_and_build,"-")
      if(build_num_dash == 0)
      {
         #the version number has no -xxxx
         build_num_len=length(minor_and_build)-build_num_index -1
      }
      else
      {
         build_num_len=build_num_dash - build_num_index  -1
      }
      if(build_num_index == 0)
      {
         #the version doesnot have build number
         build_n = 0
         minor_n = minor_and_build
      }
      else
      {
         build_n=substr(minor_and_build,build_num_index+1,build_num_len)
         minor_n=substr(minor_and_build,0,build_num_index-1)
      }

      split(QLA_MIN_VERSION,certified_qla,".");
      min_release_n=certified_qla[1]
      min_major_n=certified_qla[2]
      min_minor_and_build=certified_qla[3]
      min_build_num_index=index(min_minor_and_build,"b")
      min_build_num_dash=index(min_minor_and_build,"-")
      if(min_build_num_dash == 0)
      {
         build_num_len=length(min_minor_and_build)-min_build_num_index -1
      }
      else
      {
         build_num_len=min_build_num_dash - min_build_num_index  -1
      }
      min_build_n=substr(min_minor_and_build,min_build_num_index+1,build_num_len)
      min_minor_n=substr(min_minor_and_build,0,min_build_num_index-1)
   }
END{
   if(release_n > min_release_n)
   {
      #higher release
      print 1
   }
   else if(release_n < min_release_n)
   {
      #lower release
      print 0
   }
   else if ( major_n > min_major_n)
   {
      #same release but higher major
      print 1
   }
   else if ( major_n < min_major_n)
   {
      #same release but lower major
      print 0
   }
   else if( minor_n > min_minor_n)
   {
      #same release and major but higher minor
      print 1
   }
   else if( minor_n < min_minor_n)
   {
      #same release and major but lower minor
      print 0
   }
   else
   {
      #same release, major and minor
      print 1
   }
   }
'
}


################################################
#warning the user if the qla driver's version is lower 
#than the certified version
#
###############################################
mppLnx_qla_version_warning()
{
   QLA_VERSION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/qla2xxx/qla2xxx.ko|grep version|awk '{print $2}')
   export QLA_VERSION=${QLA_VERSION}
   QLA_VERSION_WARNING_MSG="Warning : Qlogic HBA driver ${QLA_VERSION} Does not meet minimum requirement of MPP.
          Check ${MPP_QLA_DRIVER_COMPATIBLITY} for Compatibility.
	  After HBA driver is installed, please run \"mppUpdate\" and reboot your system. "

DO_WARNING=$(mppLnx_check_qla_version)
if [ ${DO_WARNING} -lt 1 ]
then
   echo "${QLA_VERSION_WARNING_MSG}"
fi

}

#######################################
#Check the supported module parameters in the lpfc driver module
# and return the proper module options
############################################
mppLnx_lpfc_opts()
{
    LPFC_DRIVER=$1

    LPFC_NODEV_TMO_OPTION="lpfc_nodev_tmo"
    HAS_LPFC_NODEV_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/lpfc/${LPFC_DRIVER}.ko | grep -c ${LPFC_NODEV_TMO_OPTION})	
    if [  ${HAS_LPFC_NODEV_OPTION} -gt 0 ]
    then
        echo "lpfc_nodev_tmo=60"
    else
        #the lpfc driver doesn't support this option. Put a no-op command
    	:
    fi

}                                 

#######################################
#######################################
#Check the supported module parameters in the bfa driver module
# and return the proper module options
############################################
mppLnx_bfa_opts()
{
    BFA_DRIVER=$1

    BFA_NODEV_TMO_OPTION="rport_del_timeout"
    HAS_BFA_NODEV_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/${BFA_DRIVER}.ko | grep -c ${BFA_NODEV_TMO_OPTION})	
    if [  ${HAS_BFA_NODEV_OPTION} -gt 0 ]
    then
        echo "rport_del_timeout=60"
    else
        #the bfa driver doesn't support this option. Put a no-op command
    	:
    fi

}                                 

#######################################
#Check the supported module parameters in the qla2xxx driver module
# and return the proper module options
############################################
mppLnx_qla_opts()
{
   NOT_READY_OPTION="ql2xprocessnotready"
   if [ "$1" == "qla4xxx" ]
   then
      FAILOVER_OPTION="ql4xfailover"
      RETRY_COUNT_OPTION="ql4xcmdretrycount"
      QLA_DRIVER_KO="qla4xxx/qla4xxx.ko"
      PORT_DOWN_OPTION="ql4xkeepalive"
      PORT_DOWN_VALUE="144"
   else
      FAILOVER_OPTION="ql2xfailover"
      RETRY_COUNT_OPTION="ql2xretrycount"
      QLA_DRIVER_KO="qla2xxx/qla2xxx.ko"
      PORT_DOWN_OPTION="qlport_down_retry"
      PORT_DOWN_VALUE="70"
   fi

   RETURN_RESULT=""

   #check if the qla module supports FAILOVER_OPTION
   HAS_FAILOVER_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/${QLA_DRIVER_KO}|grep -c ${FAILOVER_OPTION})
   if [ ${HAS_FAILOVER_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${FAILOVER_OPTION}=0 "
   fi

   #check if the qla module supports RETRY_COUNT_OPTION
   HAS_RETRY_COUNT_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/${QLA_DRIVER_KO}|grep -c ${RETRY_COUNT_OPTION})
   if [ ${HAS_RETRY_COUNT_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${RETRY_COUNT_OPTION}=3 "
   fi

   #check if the qla module supports NOT_READY_OPTION
   HAS_NOT_READY_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/${QLA_DRIVER_KO}|grep -c ${NOT_READY_OPTION})
   if [ ${HAS_NOT_READY_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${NOT_READY_OPTION}=0 "
   fi

   #check if the qla module supports PORT_DOWN_OPTION
   HAS_PORT_DOWN_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/${QLA_DRIVER_KO}|grep -c ${PORT_DOWN_OPTION})
   if [ ${HAS_PORT_DOWN_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${PORT_DOWN_OPTION}=${PORT_DOWN_VALUE} "
   fi

   echo ${RETURN_RESULT}
}
#######################################
#Check the supported module parameters in the Mellanox driver module
# and return the proper module options
############################################
mppLnx_mellanox_opts()
{
   MELLANOX_DRIVER=$1
   QUEUE_DEPTH="max_cmds_per_lun"

   RETURN_RESULT=""

   #check if the Mellanox ib_srp module supports max_cmds_per_lun
   HAS_QUEUE_DEPTH_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/infiniband/${MELLANOX_DRIVER}.ko|grep -c ${QUEUE_DEPTH})
   if [ ${HAS_QUEUE_DEPTH_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${QUEUE_DEPTH}=32 "
   fi

   echo ${RETURN_RESULT}
}
#######################################
#Check the supported module parameters in the Silverstorm driver module
# and return the proper module options
############################################
mppLnx_silverstorm_opts()
{

   SILVERSTORM_DRIVER=$1
   QUEUE_DEPTH="ScsiQDepth"
   SCSI_RETURN_NOCONNECT="ScsiReturnNoConnect"
   SRP_MAX_LUNS="SrpMaxLuns"
   SRP_ADAPTER_REGISTER_NOWAIT="SrpAdapterRegisterNoWait"
   RETURN_RESULT=""

   #check if the Silverstorm ics_srp module supports ScsiQDepth
   HAS_QUEUE_DEPTH_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/iba/${SILVERSTORM_DRIVER}.ko|grep -c ${QUEUE_DEPTH})
   if [ ${HAS_QUEUE_DEPTH_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${QUEUE_DEPTH}=32 "
   fi
   HAS_SCSI_RETURN_NOCONNECT=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/iba/${SILVERSTORM_DRIVER}.ko|grep -c ${SCSI_RETURN_NOCONNECT})
   if [ ${HAS_SCSI_RETURN_NOCONNECT} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${SCSI_RETURN_NOCONNECT}=1 "
   fi
   HAS_SRP_ADAPTER_REGISTER_NOWAIT=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/iba/${SILVERSTORM_DRIVER}.ko|grep -c ${SRP_ADAPTER_REGISTER_NOWAIT})
   if [ ${HAS_SRP_ADAPTER_REGISTER_NOWAIT} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${SRP_ADAPTER_REGISTER_NOWAIT}=1 "
   fi
   HAS_SRP_MAX_LUNS=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/iba/${SILVERSTORM_DRIVER}.ko|grep -c ${SRP_MAX_LUNS})
   if [ ${HAS_SRP_MAX_LUNS} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${SRP_MAX_LUNS}=256"
   fi

   echo ${RETURN_RESULT}


}
#######################################
#Check the supported module parameters in the cisco IB HCA driver module
# and return the proper module options
############################################
mppLnx_cisco_ib_opts()
{

   CISCO_IB_DRIVER=$1
   QUEUE_DEPTH="max_cmds_per_lun"
   CONNECT_TIMEOUT="connect_timeout"
   COMMAND_RETRY_THRESHOLD="command_retry_threshold"
   MAX_LUNS="max_luns"
   RETURN_RESULT=""

   #check if the cisco ib ts_srp_host module supports max_cmds_per_lun
   HAS_QUEUE_DEPTH_OPTION=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/ib/${CISCO_IB_DRIVER}.ko|grep -c ${QUEUE_DEPTH})
   if [ ${HAS_QUEUE_DEPTH_OPTION} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${QUEUE_DEPTH}=32 "
   fi

   HAS_CONNECT_TIMEOUT=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/ib/${CISCO_IB_DRIVER}.ko|grep -c ${CONNECT_TIMEOUT})
   if [ ${HAS_CONNECT_TIMEOUT} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${CONNECT_TIMEOUT}=60 "
   fi

   HAS_COMMAND_RETRY_THRESHOLD=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/ib/${CISCO_IB_DRIVER}.ko|grep -c ${COMMAND_RETRY_THRESHOLD})
   if [ ${HAS_COMMAND_RETRY_THRESHOLD} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${COMMAND_RETRY_THRESHOLD}=0 "
   fi

   HAS_MAX_LUNS=$(/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/ib/${CISCO_IB_DRIVER}.ko|grep -c ${MAX_LUNS})
   if [ ${HAS_MAX_LUNS} -gt 0 ]
   then
      RETURN_RESULT="${RETURN_RESULT} ${MAX_LUNS}=256"
   fi

   echo ${RETURN_RESULT}


}
##############################################################
# identify OS distribution and HBA vendor
#
# This function changes the global environment variables "OS_DIST",
# "HbaVendor" and "HBA_VENDOR_LIST".
##############################################################
identifyOSAndHBAVendor ()
{
	# Change system configuration file
	if [ -f /etc/SuSE-release ]
	then
		OS_DIST="SUSE"
	else
		OS_DIST="REDHAT"
	fi
}

#######################################################
# Function name:mppLnx_rh_qla_drv_dep
#
# Descriptions: Add qla driver's module dependency to the modprobe.conf file
#              so that the qla drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_qla_drv_dep()
{
    
    #Execute the following for only ONCE for various qlogic drivers , example qla2300, qla2400
    if [ "XX${QLOGIC_COMMON_FIRST_TIME}" == "XX" ]
    then
        QLA_MODULE_OPTIONS=$(mppLnx_qla_opts $1)
        mppLnx_qla_version_warning >&2
        if [ "$1" == "qla4xxx" ]
        then
           echo "options qla4xxx ${QLA_MODULE_OPTIONS}"
        else
           echo "options qla2xxx ${QLA_MODULE_OPTIONS}"
        fi
        QLOGIC_COMMON_FIRST_TIME="TRUE"
        export QLOGIC_COMMON_FIRST_TIME
    fi

#Execute the following for various qlogic drivers , example qla2300, qla2400
echo "alias scsi_hostadapter96 $1" 


}
#######################################################
# Function name:mppLnx_rh_lpfc_drv_dep
#
# Descriptions: Add emulex driver's module dependency to the modprobe.conf file
#              so that the emulex drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_lpfc_drv_dep()
{
   lpHostDriver=$1;
   LPFC_MODULE_OPTIONS=$(mppLnx_lpfc_opts ${lpHostDriver})

   if [ "XX${LPFC_MODULE_OPTIONS}" != "XX" ]
   then 
      echo "options ${lpHostDriver} ${LPFC_MODULE_OPTIONS}"
   else
      echo "#${lpHostDriver} driver: no special module options"
   fi

   echo "alias scsi_hostadapter97 $1" 

}
#######################################################
# Function name:mppLnx_rh_bfa_drv_dep
#
# Descriptions: Add bfa driver's module dependency to the modprobe.conf file
#              so that the emulex drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_bfa_drv_dep()
{
   bfaHostDriver=$1;
   BFA_MODULE_OPTIONS=$(mppLnx_bfa_opts ${bfaHostDriver})

   if [ "XX${BFA_MODULE_OPTIONS}" != "XX" ]
   then 
      echo "options ${bfaHostDriver} ${BFA_MODULE_OPTIONS}"
   else
      echo "#${bfaHostDriver} driver: no special module options"
   fi

   echo "alias scsi_hostadapter92 $1" 

}
#######################################################
# Function name:mppLnx_rh_mellanox_drv_dep
#
# Descriptions: Add Mellanox driver's module dependency to the modprobe.conf file
#              so that the mellanox drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_mellanox_drv_dep()
{
    echo "alias scsi_hostadapter95 $1"

    MELLANOX_MODULE_OPTIONS=$(mppLnx_mellanox_opts $1)
    if [ "$MELLANOX_MODULE_OPTIONS" != "" ]
    then
   	echo "options $1  ${MELLANOX_MODULE_OPTIONS}"
    fi

}
#######################################################
# Function name:mppLnx_rh_silverstorm_drv_dep
#
# Descriptions: Add SilverStorm  driver's module dependency to the modprobe.conf file
#              so that the silverstorm drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_silverstorm_drv_dep()
{
    echo "alias scsi_hostadapter94 $1"

    SILVERSTORM_MODULE_OPTIONS=$(mppLnx_silverstorm_opts $1)
    if [ "$SILVERSTORM_MODULE_OPTIONS" != "" ]
    then
   	echo "options $1  ${SILVERSTORM_MODULE_OPTIONS}"
    fi

}
#######################################################
# Function name:mppLnx_rh_cisco_ib_drv_dep
#
# Descriptions: Add Cisco IB  driver's module dependency to the modprobe.conf file
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_cisco_ib_drv_dep()
{
    echo "alias scsi_hostadapter93 $1"

    CISCO_IB_MODULE_OPTIONS=$(mppLnx_cisco_ib_opts $1)
    if [ "$CISCO_IB_MODULE_OPTIONS" != "" ]
    then
   	echo "options $1  ${CISCO_IB_MODULE_OPTIONS}"
    fi

}

#######################################################
# Function name:mppLnx_rh_mpt_drv_dep
#
# Descriptions: Add lsi driver's module dependency to the modprobe.conf file
#              so that the lsi drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for RedHat AS4 distribution
#######################################################
mppLnx_rh_mpt_drv_dep()
{
   mptHostDriver=$1;
echo "alias scsi_hostadapter98 $1" 

}

#######################################################
# Function name:mppLnx_rh_hba_drv_dep
#
# Descriptions: go over the supported HBA drivers detected in this system
#               and work on its driver module dependency. The driver dependency 
#               module probe configuration parameters will be reported to the
#               standard output
# Notes: This function is for RedHat AS4 distribution
######################################################
mppLnx_rh_hba_drv_dep()
{
    for hba_module in ${MODULE_LIST}
    do
       case ${hba_module} in

          qla2xxx)
              mppLnx_rh_qla_drv_dep qla2xxx
              ;;
          qla2400)
              mppLnx_rh_qla_drv_dep qla2400
              ;;
          qla2300)
              mppLnx_rh_qla_drv_dep qla2300
              ;;
          qla2200)
              mppLnx_rh_qla_drv_dep qla2200
              ;;
          qla4xxx)
              mppLnx_rh_qla_drv_dep qla4xxx
              ;;
          mptbase)
              mppLnx_rh_mpt_drv_dep mptscsih
              ;;
          mptsas)
              mppLnx_rh_mpt_drv_dep mptsas
              ;;
          mptspi)
              mppLnx_rh_mpt_drv_dep mptspi
              ;;
          mptfc)
              mppLnx_rh_mpt_drv_dep mptfc
              ;;
          lpfc)
              mppLnx_rh_lpfc_drv_dep lpfc
              ;;
          lpfcdd)
              mppLnx_rh_lpfc_drv_dep lpfcdd
              ;;
          bfa)
              mppLnx_rh_bfa_drv_dep bfa
              ;;
          mod_thh | mod_rhh)
                  # same module name is used for mellanox and cisco in modules.pcimap
                  # mod_thh handles pci-x cards and mod_rhh handles pci-express cards 
              cisco_ib_modinfo=`/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/ib/ts_srp_host.ko 2> /dev/null`
              if [ "XX${cisco_ib_modinfo}" = "XX" ]
              then
                  # this is mellanox HCA driver, build these modules into mpp initrd
              mppLnx_rh_mellanox_drv_dep ib_srp
                  REDHAT_PRELOAD="--preload=${hba_module} --preload=ib_tavor --preload=ib_useraccess"
              else
                  # this is Cisco IB HCA driver, DO NOT build modules into mpp initrd
                  # allow cisco's rc.d scripts to load their drivers 
                  if [ "XX${CISCO_IB_MODULE_OPTS}" == "XX" ]
                  then
    		    CISCO_IB_MODULE_OPTS=$(mppLnx_cisco_ib_opts "ts_srp_host")
              	    export CISCO_IB_MODULE_OPTS
                  fi
              fi
              ;;
          ib_mthca)
              ;;
	  mlx4_core)
	      ;;
          mt23108vpd | mt25218vpd)
               # mt23108vpd handles pci-x cards and mt25218vpd handles pci-express cards
#              mppLnx_rh_silverstorm_drv_dep ics_srp
#              REDHAT_PRELOAD="--preload=mt23108vpd --preload=mst"
	      
              if [ "XX${SILVERSTORM_MODULE_OPTS}" == "XX" ]
              then
    		SILVERSTORM_MODULE_OPTS=$(mppLnx_silverstorm_opts "ics_srp")
              	export SILVERSTORM_MODULE_OPTS
              fi
              ;;
          lpfcdfc)
               #do nothing. This is the lpfc ioctl driver. It also registred as a pci driver
               ;;
          *)
              echo "Detected unsupported HBA - ${hba_module}" >&2
              ;;
      esac
    done

}

#######################################################
# Function name:mppLnx_redhat_module_dep
#
# Descriptions: Create HBA driver dependency module options for 
#               building a mpp ramdisk in a correct module loading order
# Notes: This function is for RedHat AS4 distribution
######################################################
mppLnx_redhat_module_dep()
{

   COMMON_PREFIX="### BEGIN OF MPP Driver Changes ###
options scsi_mod max_report_luns=$MAX_REPORT_LUNS max_luns=$MAX_LUNS
alias scsi_hostadapter99 mppVhba"


   COMMON_POSTFIX="## END OF MPP Driver Changes ###"

   echo "${COMMON_PREFIX}" >${MPPAPPENDFILE}

   mppLnx_rh_hba_drv_dep >>${MPPAPPENDFILE}

   echo "${COMMON_POSTFIX}" >>${MPPAPPENDFILE}

   #During the mppUpdate time, the following comments has been appended to the 
   #/etc/modprobe.conf file. We don't want to append it again

   HAS_MPP_COMMENTS=$(grep -c "### BEGIN MPP Driver Comments ###" /etc/modprobe.conf)
   
   if [ ${HAS_MPP_COMMENTS} = 0 ]
   then

   echo "### BEGIN MPP Driver Comments ###" >> ${REDHAT_MODPROBE_CONF}
echo "remove mppUpper if [ \`ls -a /proc/mpp | wc -l\` -gt 2 ]; then echo -e \"Please Unload Physical HBA Driver prior to unloading mppUpper.\"; else /sbin/modprobe -r --ignore-remove mppUpper; fi">> ${REDHAT_MODPROBE_CONF}
if [ "XX${SILVERSTORM_MODULE_OPTS}" != "XX" ]
then
    echo "options ics_srp ${SILVERSTORM_MODULE_OPTS}" >> ${REDHAT_MODPROBE_CONF}
fi
if [ "XX${CISCO_IB_MODULE_OPTS}" != "XX" ]
then
    echo "options ts_srp_host ${CISCO_IB_MODULE_OPTS}" >> ${REDHAT_MODPROBE_CONF}
fi
echo "# Additional config info can be found in /opt/mpp/modprobe.conf.mppappend.
# The Above config info is needed if you want to make "mkinitrd" manually.
# Please read the Readme file that came with MPP driver for building RamDisk manually.
# Edit the '/etc/modprobe.conf' file and run 'mppUpdate' to create Ramdisk dynamically.
### END MPP Driver Comments ###" >> ${REDHAT_MODPROBE_CONF};

    fi
}
#######################################################
# Function name:mppLnx_suse_qla_drv_dep
#
# Descriptions: Add qla driver's module dependency to the modprobe.conf file
#              so that the qla drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSe SLES9 distribution
#######################################################
mppLnx_suse_qla_drv_dep()
{
    # SuSE system with Qlogic adapter

    #Execute the following for only ONCE for various qlogic drivers , example qla2300, qla2400
    if [ "XX${QLOGIC_COMMON_FIRST_TIME}" == "XX" ]
    then
        QLA_MODULE_OPTIONS=$(mppLnx_qla_opts $1)
        mppLnx_qla_version_warning >&2
        if [ "$1" == "qla4xxx" ]
        then
           echo "options qla4xxx ${QLA_MODULE_OPTIONS}"
        else
           echo "options qla2xxx ${QLA_MODULE_OPTIONS}"
        fi
        QLOGIC_COMMON_FIRST_TIME="TRUE"
        export QLOGIC_COMMON_FIRST_TIME
    fi

}
#######################################################
# Function name:mppLnx_suse_mellanox_drv_dep
#
# Descriptions: Add Mellanox driver's module dependency to the modprobe.conf file
#              so that the mellanox drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSE SLES9  distribution
#######################################################
mppLnx_suse_mellanox_drv_dep()
{
    # SuSE system with Mellanox Infiniband adapter
    MELLANOX_MODULE_OPTIONS=$(mppLnx_mellanox_opts $1)
    if [ "$MELLANOX_MODULE_OPTIONS" != "" ]
    then
   	echo "options $1 ${MELLANOX_MODULE_OPTIONS}"
    fi
}
#######################################################
# Function name:mppLnx_suse_silverstorm_drv_dep
#
# Descriptions: Add SilverStorm driver's module dependency to the modprobe.conf file
#              so that the silverstorm drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSE SLES9  distribution
#######################################################
mppLnx_suse_silverstorm_drv_dep()
{
    # SuSE system with SilverStorm Infiniband adapter
    SILVERSTORM_MODULE_OPTIONS=$(mppLnx_silverstorm_opts $1)
    if [ "$SILVERSTORM_MODULE_OPTIONS" != "" ]
    then
   	echo "options $1 ${SILVERSTORM_MODULE_OPTIONS}"
    fi
}
#######################################################
# Function name:mppLnx_suse_cisco_ib_drv_dep
#
# Descriptions: Add Cisco IB driver's module dependency to the modprobe.conf.local file
# Notes: This function is for SuSE SLES9  distribution
#######################################################
mppLnx_suse_cisco_ib_drv_dep()
{
    # SuSE system with Cisco IB Infiniband adapter
    CISCO_IB_MODULE_OPTIONS=$(mppLnx_cisco_ib_opts $1)
    if [ "$CISCO_IB_MODULE_OPTIONS" != "" ]
    then
   	echo "options $1 ${CISCO_IB_MODULE_OPTIONS}"
    fi
}
#######################################################
# Function name:mppLnx_suse_lpfc_drv_dep
#
# Descriptions: Add emulex driver's module dependency to the modprobe.conf file
#              so that the emulex drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSe SLES9 distribution
#######################################################
mppLnx_suse_lpfc_drv_dep()
{
  lpHostDriver=$1;
  LPFC_MODULE_OPTIONS=$(mppLnx_lpfc_opts ${lpHostDriver})

  if [ "XX${LPFC_MODULE_OPTIONS}" != "XX" ]
  then 
     echo "options ${lpHostDriver} ${LPFC_MODULE_OPTIONS}"
  else
    echo "#${lpHostDriver} driver: no special module options"
  fi
}

#######################################################
# Function name:mppLnx_suse_bfa_drv_dep
#
# Descriptions: Add bfa driver's module dependency to the modprobe.conf file
#              so that the emulex drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSe SLES9 distribution
#######################################################
mppLnx_suse_bfa_drv_dep()
{
  bfaHostDriver=$1;
  BFA_MODULE_OPTIONS=$(mppLnx_bfa_opts ${bfaHostDriver})

  if [ "XX${BFA_MODULE_OPTIONS}" != "XX" ]
  then 
     echo "options ${bfaHostDriver} ${BFA_MODULE_OPTIONS}"
  else
    echo "#${bfaHostDriver} driver: no special module options"
  fi
}


#######################################################
# Function name:mppLnx_suse_mpt_drv_dep
#
# Descriptions: Add lsi driver's module dependency to the modprobe.conf file
#              so that the lsi drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSe SLES9 distribution
#######################################################
mppLnx_suse_mpt_drv_dep()
{
  #nothing to do for now
  echo "#mpt driver is handled by mpp installation"
}

#######################################################
# Function name:mppLnx_suse_mptsas_drv_dep
#
# Descriptions: Add lsi sas driver's module dependency to the modprobe.conf file
#              so that the lsi sas drivers could be built into the mpp ramdisk
#              in a correct loading order
# Notes: This function is for SuSe SLES9 distribution
#######################################################
mppLnx_suse_mptsas_drv_dep()
{
  #nothing to do for now
  echo "#mpt sas driver is handled by mpp installation"
}

#########################################################
# Function name:mppLnx_suse_hba_drv_dep
#
# Descriptions: go over the supported HBA drivers detected in this system
#               and work on its driver module dependency. The driver dependency 
#               module probe configuration parameters will be reported to the
#               standard output
# Notes: This function is for SuSe SLES9 distribution
######################################################
mppLnx_suse_hba_drv_dep()
{
    for hba_module in ${MODULE_LIST}
    do
       case ${hba_module} in
          qla2xxx)
              mppLnx_suse_qla_drv_dep qla2xxx
              ;;
          qla2400)
              mppLnx_suse_qla_drv_dep qla2400
              ;;
          qla2300)
              mppLnx_suse_qla_drv_dep qla2300
              ;;
          qla2200)
              mppLnx_suse_qla_drv_dep qla2200
              ;;
          qla4xxx)
              mppLnx_suse_qla_drv_dep qla4xxx
              ;;
          mptbase)
              mppLnx_suse_mpt_drv_dep mptscsih
              ;;
          mptsas)
              mppLnx_suse_mpt_drv_dep mptsas
              ;;
          mptfc)
              mppLnx_suse_mpt_drv_dep mptfc
              ;;
          mptspi)
              mppLnx_suse_mpt_drv_dep mptspi
              ;;
          lpfc)
              mppLnx_suse_lpfc_drv_dep lpfc
              ;;
          lpfcdd)
              mppLnx_suse_lpfc_drv_dep lpfcdd
              ;;
          bfa)
              mppLnx_suse_bfa_drv_dep bfa
              ;;
          mod_thh | mod_rhh)
                  # same module name is used for mellanox and cisco in modules.pcimap
                  # mod_thh handles pci-x cards and mod_rhh handles pci-express cards 
              cisco_ib_modinfo=`/sbin/modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/ib/ts_srp_host.ko 2> /dev/null`
              if [ "XX${cisco_ib_modinfo}" = "XX" ]
              then
                  # this is mellanox HCA driver, build mellanox modules into mpp initrd
              mppLnx_suse_mellanox_drv_dep ib_srp
              else
                  # this is Cisco IB HCA driver, DO NOT build modules into mpp initrd
                  # allow cisco's rc.d scripts to load their drivers 
                  if [ "XX${CISCO_IB_MODULE_OPTS}" == "XX" ]
                  then
                    CISCO_IB_MODULE_OPTS=$(mppLnx_cisco_ib_opts "ts_srp_host")
                    export CISCO_IB_MODULE_OPTS
                  fi
              fi
              ;;
          ib_mthca)
              ;;
	  mlx4_core)
	      ;;
          mt23108vpd | mt25218vpd)
                  # mt23108vpd handles pci-x cards and mt25218vpd handles pci-express cards
#              mppLnx_suse_silverstorm_drv_dep ics_srp
              if [ "XX${SILVERSTORM_MODULE_OPTS}" == "XX" ]
              then
    		SILVERSTORM_MODULE_OPTS=$(mppLnx_silverstorm_opts "ics_srp")
              	export SILVERSTORM_MODULE_OPTS
              fi
              ;;
          lpfcdfc)
               #do nothing. This is the lpfc ioctl driver. It also registred as a pci driver
               ;;
          *)
              echo "Detected unsupported HBA - ${hba_module}" >&2
              ;;
      esac
    done

}

#######################################################
# Function name:mppLnx_suse_module_dep
#
# Descriptions: Create HBA driver dependency module options for 
#               building a mpp ramdisk in a correct module loading order
# Notes: This function is for SuSe SLES9 distribution
######################################################
mppLnx_suse_module_dep()
{
    COMMON_PREFIX="### BEGIN OF MPP Driver Changes ###
options scsi_mod max_report_luns=$MAX_REPORT_LUNS max_luns=$MAX_LUNS"
    COMMON_POSTFIX="## END OF MPP Driver Changes ###"

    echo "${COMMON_PREFIX}"   >${SUSE_MPPAPPENDFILE}
    mppLnx_suse_hba_drv_dep  >>${SUSE_MPPAPPENDFILE}
    echo "${COMMON_POSTFIX}" >>${SUSE_MPPAPPENDFILE}
		
    #During the mppUpdate time, the following comments has been appended to the 
    #/etc/sysconfig/kernel file. We don't want to append it again

    HAS_MPP_COMMENTS=$(grep -c "### BEGIN MPP Driver Comments ###" ${SUSE_SYSCONFIG_KERNEL})
   
    if [ ${HAS_MPP_COMMENTS} = 0 ]
    then
    		
	echo " ### BEGIN MPP Driver Comments ###
# Additional config info can be found in /opt/mpp/kernel.suseinitrd and modprobe.conf.local
# The Above config info is needed if you want to make "mkinitrd" manually.
# Please read the Readme file that came with MPP driver for building RamDisk manually.
# Edit the '/etc/sysconfig/kernel' file and run 'mppUpdate' to create Ramdisk dynamically.
### END MPP Driver Comments ###" >> ${SUSE_SYSCONFIG_KERNEL};

    fi
    
    #During the mppUpdate time, the following comments has been appended to the 
    #/etc/modprobe.conf.local file. We don't want to append it again

    HAS_MPP_COMMENTS=$(grep -c "### BEGIN MPP Driver Comments ###" ${SUSE_MODPROBE_CONF})
   
    if [ ${HAS_MPP_COMMENTS} = 0 ]
    then
   		
echo "### BEGIN MPP Driver Comments ###" >> ${SUSE_MODPROBE_CONF}
if [ "XX${SILVERSTORM_MODULE_OPTS}" != "XX" ]
then
    echo "options ics_srp ${SILVERSTORM_MODULE_OPTS}" >> ${SUSE_MODPROBE_CONF}
fi
if [ "XX${CISCO_IB_MODULE_OPTS}" != "XX" ]
then
    echo "options ts_srp_host ${CISCO_IB_MODULE_OPTS}" >> ${SUSE_MODPROBE_CONF}
fi
echo "remove mppUpper if [ \`ls -a /proc/mpp | wc -l\` -gt 2 ]; then echo -e \"Please Unload Physical HBA Driver prior to unloading mppUpper.\"; else /sbin/modprobe -r --ignore-remove mppUpper; fi">> ${SUSE_MODPROBE_CONF}
echo "# Additional config info can be found in /opt/mpp/kernel.suseinitrd and modprobe.conf.local
# The Above config info is needed if you want to make "mkinitrd" manually.
# Please read the Readme file that came with MPP driver for building RamDisk manually.
# Edit the '/etc/sysconfig/kernel' file and run 'mppUpdate' to create Ramdisk dynamically.
### END MPP Driver Comments ###" >> ${SUSE_MODPROBE_CONF};

    fi


}

####################################################################
# createModDep: create module dependency among MPP upper level module,
# MPP virtual HBA driver module, sg and sd modules and
# low level physical HBA driver module.
#####################################################################
createModDep ()
{
    if [ "$#" -gt "0" ]
    then
        MPP_RAMDISK_KERNEL_VERSION="$1"
    else
        MPP_RAMDISK_KERNEL_VERSION="$(uname -r)"
    fi
   
    export MPP_RAMDISK_KERNEL_VERSION

    if [ "$OS_DIST" = REDHAT ]
    then

        mppLnx_redhat_module_dep

    else

        mppLnx_suse_module_dep

    fi
}

#
# fucntion to change MPP driver configurable parameter file
#
modifyMPPCfgFile ()
{
	# If there is no Scsi2-Scsi3 translation key associated with this host,
	# run genunuqueid program to generate an 8-byte random number
	# and record it in mpp.conf for future use
	S2ToS3KeyExists=0
	
	if [ -f $OLD_MPP_CONF_FILE ]
	then
   		S2ToS3KeyExists=`grep -c S2ToS3Key $OLD_MPP_CONF_FILE`
	fi

	if [ $S2ToS3KeyExists = 0 ]
	# This is fresh installation. Generate the key.
	then
   		# we do not have the key yet
   		S2ToS3Key=`/opt/mpp/genuniqueid`
	else
   		# This is re-installation. Copy the old key to configuration file
   		S2ToS3Key=`/bin/grep S2ToS3Key $OLD_MPP_CONF_FILE | /bin/gawk '{split($1,key,"="); print key[2]}'`
	fi

	echo -n "S2ToS3Key=">>$NEW_MPP_CONF_FILE
	echo $S2ToS3Key >>$NEW_MPP_CONF_FILE
	echo "">> $NEW_MPP_CONF_FILE
}

######################################################################
#The function mppLnx_redhat_suseModConf will merge lpfc, qla and scsi_mod module options
#in the /etc/modprobe.conf, /etc/modprobe.conf.local, /etc/modprobe.d and mpp required module options
#the final module options will be stored in /tmp/modprobe_conf_mppappend_saved
######################################################################
mppLnx_suse_mergeModConf()
{
   rm -f ${MPP_TMP_MODPROBE_FILE}
echo " " |awk -v SYS_MODPROBE_FILE="${SYS_MODPROBE_FILE}" -v MPP_MODPROBE_FILE="${MPPAPPENDFILE}" \
  -v MPP_TMP_MODPROBE_FILE="${MPP_TMP_MODPROBE_FILE}"  -v SUSE_MODPROBE_CONF="${SUSE_MODPROBE_CONF}" \
  -v SYS_MODPROBE_SAVED_FILE="${SYS_MODPROBE_SAVED_FILE}"  -v SUSE_MODPROBE_LOCAL_MPP_SAVED_FILE="${SUSE_MODPROBE_LOCAL_MPP_SAVED_FILE}" -v SUSE_LPFC_CONF="${SUSE_LPFC_CONF}" \
  -v SUSE_SCSI_MOD_CONF="${SUSE_SCSI_MOD_CONF}" -v SUSE_QLA_CONF="${SUSE_QLA_CONF}" -v SUSE_BFA_CONF="${SUSE_BFA_CONF}" '
#susedirOptions are options collected from /etc/modprobe.d
#suselocalOptions are options collected from /etc/modprobe.conf.local
#mppOptions are options collected from mpp generated options modprobe.conf.mppappend
#userOptions are options collected from /etc/modprobe.conf
    function mergeOptions(susedirOptions, suselocalOptions, mppOptions, userOptions,merged_option, allkey)
    {
        for (key in userOptions)
        {
            allkey[key]=1
        }
        for (suselocalkey in suselocalOptions)
        {
            allkey[suselocalkey]=1
        }
        for(susedirkey in susedirOptions)
        {
            allkey[susedirkey]=1
        }
        for(mppkey in mppOptions)
        {
            allkey[mppkey]=1
        }
        merged_option=""

        for(key in allkey)
        {
#suselocalOptions (/etc/modprobe.conf.local) is given a high priority
#checking values are available for which all options
            if ((suselocalOptions[key] && userOptions[key])||(suselocalOptions[key] && susedirOptions[key])|| (suselocalOptions[key] && mppOptions[key]))
            {
                printf("Warning:Duplicate module options detected.\n") > "/dev/stderr"
                printf("Option in /etc/modprobe.conf.local ( %s%s ) takes precedence\n", key,suselocalOptions[key]) > "/dev/stderr"
                merged_option=merged_option " " key suselocalOptions[key]
            }
#susedirOptions (/etc/modprobe.d) is given a second priority
#checking values are available for which all options
            else if ((susedirOptions[key] && userOptions[key])|| (susedirOptions[key] && mppOptions[key]))
            {
                printf("Warning:Duplicate module options detected.\n") > "/dev/stderr"
                printf("Option in /etc/modprobe.d ( %s%s ) takes precedence\n", key,susedirOptions[key]) > "/dev/stderr"
                merged_option=merged_option " " key susedirOptions[key]
            }
#userOptions (/etc/modprobe.conf) is given a third priority
#checking values are available for which all options
            else if (userOptions[key]  && mppOptions[key])
            {
                printf("Warning:Duplicate module options detected.\n") > "/dev/stderr"
                printf("Option in /etc/modprobe.conf ( %s%s ) takes precedence\n", key,userOptions[key]) > "/dev/stderr"
                merged_option=merged_option " " key userOptions[key]
            }
#if only option is available at only one location
            else if (suselocalOptions[key])
            {
                merged_option= merged_option " " key suselocalOptions[key]
            }
            else if (userOptions[key])
            {
               merged_option= merged_option " " key userOptions[key]
            }
            else if (susedirOptions[key])
            {
              merged_option= merged_option " " key susedirOptions[key]
            }
            else if ( mppOptions[key])
            {
                merged_option= merged_option " " key mppOptions[key]
            }
        }
        printf("the merged options %s\n",merged_options)
        return  merged_option
    }
BEGIN{
    #
    #read the /etc/modprobe.conf.local file and get module options for lpfc, bfa, qla and scsi_mod
    #the module options are saved in hash arrays
    #
    while ( getline theline < SUSE_LPFC_CONF   > 0)
    {
        #do not touch lines start with #
        if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
        {
            #lpfc options
            if(theline ~  /[^ ]*options *lpfc/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse lpfc key= %s value = %s\n",kvpair[1], kvpair[2])
                        susedir_lpfcoptions[kvpair[1]]="=" kvpair[2]
                        needMerge["lpfc"]++;
                    }
                }
            }
         }
    }#while

    while ( getline theline < SUSE_BFA_CONF   > 0)
    {
        #do not touch lines start with #
        if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
        {
            #bfa options
            if(theline ~  /[^ ]*options *bfa/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse bfa key= %s value = %s\n",kvpair[1], kvpair[2])
			if ( (kvpair[1] != "") && (match(kvpair[1],"os_name") == 0) && ( match(kvpair[1],"os_patch") == 0 ))
			{
                        susedir_bfaoptions[kvpair[1]]="=" kvpair[2] 
                        needMerge["bfa"]++;
                    }
                }
            }
         }
         }
    }#while

    while ( getline theline < SUSE_QLA_CONF   > 0)
    {

        #do not touch lines start with #
        if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
        {
            #qla options
            if(theline ~  /[^ ]*options *qla2xxx/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse qla key= %s value = %s\n",kvpair[1], kvpair[2])
                        susedir_qla2options[kvpair[1]]="=" kvpair[2]
                        needMerge["qla2"]++;
                    }
                }
            }
            if(theline ~  /[^ ]*options *qla4xxx/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse qla key= %s value = %s\n",kvpair[1], kvpair[2])
                        susedir_qla4options[kvpair[1]]="=" kvpair[2]
                        needMerge["qla4"]++;
                    }
                }
            }
        }
    }#while

    while ( getline theline < SUSE_SCSI_MOD_CONF   > 0)
    {
        if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
        {
            #scsi_mod options
            if(theline ~  /[^ ]*options *scsi_mod/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse scsi_mod key= %s value = %s\n",kvpair[1], kvpair[2])
                        susedir_scsi_modoptions[kvpair[1]]="=" kvpair[2]
                        needMerge["scsi_mod"]++;
                    }
                }
            }
        }
    }#while

    while ( getline theline < SUSE_MODPROBE_CONF   > 0)
    {

        #do not touch lines start with #
        if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
        {
            #qla options
            if(theline ~  /[^ ]*options *qla2xxx/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        suselocal_qla2options[kvpair[1]]="=" kvpair[2]
                        needMerge["qla2"]++;
                    }
                }
            }
            #qla options
            if(theline ~  /[^ ]*options *qla4xxx/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        suselocal_qla4options[kvpair[1]]="=" kvpair[2]
                        needMerge["qla4"]++;
                    }
                }
            }

            #lpfc options
            if(theline ~  /[^ ]*options *lpfc/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse lpfc key= %s value = %s\n",kvpair[1], kvpair[2])
                        suselocal_lpfcoptions[kvpair[1]]="=" kvpair[2]
                        needMerge["lpfc"]++;
                    }
                }
            }
	    #bfa options
            if(theline ~  /[^ ]*options *bfa/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
			if ( (kvpair[1] != "") && (match(kvpair[1],"os_name") == 0) && ( match(kvpair[1],"os_patch") == 0 ))
			{
                        printf("suse bfa key= %s value = %s\n",kvpair[1], kvpair[2])
                        suselocal_bfaoptions[kvpair[1]]="=" kvpair[2] 
                        needMerge["bfa"]++;
                    	}
                    }
                }
            }


            #scsi_mod options
            if(theline ~  /[^ ]*options *scsi_mod/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        printf("suse local scsi key= %s value = %s\n",kvpair[1], kvpair[2])
                        suselocal_scsi_modoptions[kvpair[1]]="=" kvpair[2]
                        needMerge["scsi_mod"]++;
                    }
                }
            }
        } #if not comments
    }#while


    #
    #read the /etc/modprobe.conf file and get module options for lpfc, bfa, qla and scsi_mod
    #the module options are saved in hash arrays
    #
    while ( getline theline < SYS_MODPROBE_FILE   > 0)
    {
            #do not touch lines start with #
            if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
            {
                    #qla options
                    if(theline ~  /[^ ]*options *qla2xxx/)
                    {
                            fcnt=split(theline, linefields)
                                    for(i=1; i <=fcnt; i++)
                                    {
                                            if(linefields[i] ~ "=")
                                            {
                                                    split(linefields[i], kvpair,"=")
                                                            user_qla2options[kvpair[1]]="=" kvpair[2]
                                                            needMerge["qla2"]++;
                                            }
                                    }
                    }
                    if(theline ~  /[^ ]*options *qla4xxx/)
                    {
                            fcnt=split(theline, linefields)
                                    for(i=1; i <=fcnt; i++)
                                    {
                                            if(linefields[i] ~ "=")
                                            {
                                                    split(linefields[i], kvpair,"=")
                                                            user_qla4options[kvpair[1]]="=" kvpair[2]
                                                            needMerge["qla4"]++;
                                            }
                                    }
                    }

                    #lpfc options
                    if(theline ~  /[^ ]*options *lpfc/)
                    {
                            fcnt=split(theline, linefields)
                                    for(i=1; i <=fcnt; i++)
                                    {
                                            if(linefields[i] ~ "=")
                                            {
                                                    split(linefields[i], kvpair,"=")
                                                            printf("user lpfc key= %s value = %s\n",kvpair[1], kvpair[2])
                                                            user_lpfcoptions[kvpair[1]]="=" kvpair[2]
                                                            needMerge["lpfc"]++;
                                            }
                                    }
                    }

	    	    #bfa options
	    	    if(theline ~  /[^ ]*options *bfa/)
	    	    {
	    	        fcnt=split(theline, linefields)
	    	    	    for(i=1; i <=fcnt; i++)
	    	    	    {
	    	    		    if(linefields[i] ~ "=")
	    	    		    {
	    	    			    split(linefields[i], kvpair,"=")
	    	    				    printf("user bfa key= %s value = %s\n",kvpair[1], kvpair[2])
	    	    				    if ( (kvpair[1] != "") && (match(kvpair[1],"os_name") == 0) && ( match(kvpair[1],"os_patch") == 0 ))
	    	    				    {
	    	    					    user_bfaoptions[kvpair[1]]="=" kvpair[2]
	    	    						    needMerge["bfa"]++;
	    	    				    }
	    	    		    }
	    	    	    }
	    	    }

                    #scsi_mod options
                    if(theline ~  /[^ ]*options *scsi_mod/)
                    {
                            fcnt=split(theline, linefields)
                                    for(i=1; i <=fcnt; i++)
                                    {
                                            if(linefields[i] ~ "=")
                                            {
                                                    split(linefields[i], kvpair,"=")
                                                            printf("user scsi key= %s value = %s\n",kvpair[1], kvpair[2])
                                                            user_scsi_modoptions[kvpair[1]]="=" kvpair[2]
                                                            needMerge["scsi_mod"]++;
                                            }
                                    }
                    }
            } #if not comments
    }#while

    #
    #if we need to perform the module option mergence, read the /opt/mpp/modprobe.conf.mppappend
    #and get the mpp driver default option settings
    #
    if(needMerge["qla2"] || needMerge["qla4"] || needMerge["lpfc"] || needMerge["bfa"] || needMerge["scsi_mod"])
    {
        while ( getline theline < MPP_MODPROBE_FILE     > 0)
        {

            if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
            {
    		#qla options
                if(theline ~  /[^ ]*options *qla2xxx/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_qla2options[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }
                if(theline ~  /[^ ]*options *qla4xxx/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_qla4options[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }


                #the lpfc options
                if(theline ~  /[^ ]*options *lpfc/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_lpfcoptions[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }

		#the bfa options
		if(theline ~  /[^ ]*options *bfa/)
		{
			fcnt=split(theline, linefields)
				for(i=1; i <=fcnt; i++)
				{
					if(linefields[i] ~ "=")
					{
						split(linefields[i], kvpair,"=")
							if ( (kvpair[1] != "") && (match(kvpair[1],"os_name") == 0) && ( match(kvpair[1],"os_patch") == 0 ))
							{
								printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
									mpp_bfaoptions[kvpair[1]]="=" kvpair[2]
							}
					}
				}
		}

                if(theline ~  /[^ ]*options *scsi_mod/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_scsi_modoptions[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }
            }#if not comments
        }#if need merge
   }#while
}
END{
    # this awk script has no main body
    #check duplicated options

    if(needMerge["qla2"])
    {
        qla2tmp= mergeOptions(susedir_qla2options, suselocal_qla2options,mpp_qla2options,user_qla2options,qla2tmp,qlaAllkey)
        qla2Options="options qla2xxx " qla2tmp
    }

    if(needMerge["qla4"])
    {
        qla4tmp= mergeOptions(susedir_qla4options, suselocal_qla4options,mpp_qla4options,user_qla4options,qla4tmp,qlaAllkey)
        qla4Options="options qla4xxx " qla4tmp
    }

    #lpfc
    if(needMerge["lpfc"])
    {
        lpfctmp= mergeOptions(susedir_lpfcoptions, suselocal_lpfcoptions,mpp_lpfcoptions,user_lpfcoptions,lpfctmp,lpfcAllkey)
        lpfcOptions="options lpfc " lpfctmp
        printf("the lpfcoptions %s\n",lpfcOptions)
    }


    #bfa
    if(needMerge["bfa"])
    {
        bfatmp= mergeOptions(susedir_bfaoptions, suselocal_bfaoptions,mpp_bfaoptions,user_bfaoptions,bfatmp,bfaAllkey)
        bfaOptions="options bfa " bfatmp
        printf("the bfaoptions %s\n",bfaOptions)
    }


    #scsi mod
    if(needMerge["scsi_mod"])
    {
        scsiModtmp=mergeOptions(susedir_scsi_modoptions, suselocal_scsi_modoptions,mpp_scsi_modoptions,user_scsi_modoptions,scsiModtmp,scsiModAllkey)
        scsiModOptions="options scsi_mod " scsiModtmp
    }


    # we get all options merged.
    # 1. if we need to merge, save the original modprobe.conf to a safe place
    # 2. parse mpp modprobe.conf.append file and replace the options with the merged options
    # 3. remove the module options from the modprobe.conf before we start building ramdisk

    if ( qla2Options || qla4Options || lpfcOptions || bfaOptions || scsiModOptions )
    {

        #copy the origical modprobe.conf file to a safe place
        cpCmd="cp -p /etc/modprobe.conf " SYS_MODPROBE_SAVED_FILE
        system(cpCmd)

        cpCmd="cp -p /etc/modprobe.conf.local " SUSE_MODPROBE_LOCAL_MPP_SAVED_FILE
        system(cpCmd)

        #build sed command string. The sed command is used to remove related module options
        #from /etc/modprobe.conf file. RedHat does not allow multiple line module options for
        # the same module
        if ( qla2Options)
        {
            qla2SedCmd=" -e  \x27/[^ ]*options *qla2xxx/d\x27 "
        }
        if ( qla4Options)
        {
            qla4SedCmd=" -e  \x27/[^ ]*options *qla4xxx/d\x27 "
        }
        if(lpfcOptions)
        {
            lpfcSedCmd=" -e  \x27/[^ ]*options *lpfc/d\x27 "
        }
        if(bfaOptions)
        {
            bfaSedCmd=" -e  \x27/[^ ]*options *bfa/d\x27 "
        }
        if(scsiModOptions)
        {
            scsiModSedCmd=" -e  \x27/[^ ]*options *scsi_mod/d\x27 "
        }
        sedCmd="sed " qla2SedCmd qla4SedCmd lpfcSedCmd bfaSedCmd scsiModSedCmd " " SYS_MODPROBE_SAVED_FILE  ">/etc/modprobe.conf"
        system(sedCmd)

        #paring the mpp modprobe.conf.mppappend file and replace the module options with
        #the merged options

        #close the file first because it is opened in BEGIN block
        close(MPP_MODPROBE_FILE)

        #read line by line.The merged modprobe.conf.mppappend is saved in MPP_TMP_MODPROBE_FILE
        while ( getline theline < MPP_MODPROBE_FILE     > 0)
        {

            if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
            {
                if(theline ~  /[^ ]*options *qla2xxx/ && qla2Options)
                {
                    print qla2Options >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *qla4xxx/ && qla4Options)
                {
                    print qla4Options >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *lpfc/ && lpfcOptions)
                {
                    print lpfcOptions >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *bfa/ && bfaOptions)
                {
                    print bfaOptions >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *scsi_mod/ && scsiModOptions)
                           {
                    print scsiModOptions >>MPP_TMP_MODPROBE_FILE
                }else
                {
                    print theline >>MPP_TMP_MODPROBE_FILE
                }
            }else
            {
                print theline >>MPP_TMP_MODPROBE_FILE
            }
        }
  print "NEEDED"
    }#if need mergence
} #end of the awk
'
} #end of the function



######################################################################
#The function mppLnx_redhat_mergeModConf will merge lpfc, bfa,  qla and scsi_mod module options
#in the /etc/modprobe.con and mpp required module options
#the final module options will be stored in /opt/mpp/modprobe.conf.mppappend
######################################################################
mppLnx_redhat_mergeModConf()
{
   rm -f ${MPP_TMP_MODPROBE_FILE}
echo " " |awk -v SYS_MODPROBE_FILE="${SYS_MODPROBE_FILE}" -v MPP_MODPROBE_FILE="${MPPAPPENDFILE}" \
   -v MPP_TMP_MODPROBE_FILE="${MPP_TMP_MODPROBE_FILE}"  -v SYS_MODPROBE_SAVED_FILE="${SYS_MODPROBE_SAVED_FILE}" '
    function mergeOptions(mppOptions, userOptions,merged_option, allkey)
    {
        for (key in userOptions)
        {
            for(mppkey in mppOptions)
            {
                allkey[key]=1
                allkey[mppkey]=1
            }
        }
        merged_option=""

        for(key in allkey)
        {
            if (mppOptions[key]  && userOptions[key])
            {
                printf("Warning: Duplicate module options detected.\n") >"/dev/stderr"
                printf("         Option in /etc/modprobe.conf ( %s%s ) takes precedence over MPP default setting ( %s%s ).\n", key,userOptions[key],key,mppOptions[key]) >"/dev/stderr"
                merged_option=merged_option " " key  userOptions[key]
            }else
            {
                if(mppOptions[key])
                {
                    merged_option=merged_option " " key  mppOptions[key]
                }else
                {
                    merged_option= merged_option " " key userOptions[key]
                }
            }
        }
        return  merged_option
    }
BEGIN{
    #
    #read the /etc/modprobe.conf file and get module options for lpfc, qla and scsi_mod
    #the module options are saved in hash arrays
    #
    while ( getline theline < SYS_MODPROBE_FILE   > 0)
    {
        
        #do not touch lines start with #
        if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
        {

            #qla2 options
            if(theline ~  /[^ ]*options *qla2xxx/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        user_qla2options[kvpair[1]]="=" kvpair[2]
                        needMerge["qla2"]++;
                    }
                }
            }

            #qla4 options
            if(theline ~  /[^ ]*options *qla4xxx/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        user_qla4options[kvpair[1]]="=" kvpair[2]
                        needMerge["qla4"]++;
                    }
                }
            }

            
            #lpfc options
            if(theline ~  /[^ ]*options *lpfc/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        #printf("user lpfc key= %s value = %s\n",kvpair[1], kvpair[2])
                        user_lpfcoptions[kvpair[1]]="=" kvpair[2]
                        needMerge["lpfc"]++;
                    }
                }
            }

            #bfa options
            if(theline ~  /[^ ]*options *bfa/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
			if ( (kvpair[1] != "") && (match(kvpair[1],"os_name") == 0) && ( match(kvpair[1],"os_patch") == 0 ))
			{
                        	#printf("user bfa key= %s value = %s\n",kvpair[1], kvpair[2])
                        	user_bfaoptions[kvpair[1]]="=" kvpair[2]
                        	needMerge["bfa"]++;
                    	}
                    }
                }
            }



            #scsi_mod options
            if(theline ~  /[^ ]*options *scsi_mod/)
            {
                fcnt=split(theline, linefields)
                for(i=1; i <=fcnt; i++)
                {
                    if(linefields[i] ~ "=")
                    {
                        split(linefields[i], kvpair,"=")
                        #printf("user scsi key= %s value = %s\n",kvpair[1], kvpair[2])
                        user_scsi_modoptions[kvpair[1]]="=" kvpair[2]
                        needMerge["scsi_mod"]++;
                    }
                }
            }
        } #if not comments
    }#while

    #
    #if we need to perform the module option mergence, read the /opt/mpp/modprobe.conf.mppappend
    #and get the mpp driver default option settings
    #
    if(needMerge["qla2"] || needMerge["qla4"] || needMerge["lpfc"] || needMerge["bfa"] || needMerge["scsi_mod"])
    {
        while ( getline theline < MPP_MODPROBE_FILE     > 0)
        {

            if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
            {
                #qla2 options
                if(theline ~  /[^ ]*options *qla2xxx/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            #printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_qla2options[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }

                #qla4 options
                if(theline ~  /[^ ]*options *qla4xxx/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            #printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_qla4options[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }


                #the lpfc options
                if(theline ~  /[^ ]*options *lpfc/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            #printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_lpfcoptions[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }

                #the bfa options
                if(theline ~  /[^ ]*options *bfa/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
			    if ( (kvpair[1] != "") && (match(kvpair[1],"os_name") == 0) && ( match(kvpair[1],"os_patch") == 0 ))
			    {
                            	#printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            	mpp_bfaoptions[kvpair[1]]="=" kvpair[2]
                            }
                        }
                    }
                }


                if(theline ~  /[^ ]*options *scsi_mod/)
                {
                    fcnt=split(theline, linefields)
                    for(i=1; i <=fcnt; i++)
                    {
                        if(linefields[i] ~ "=")
                        {
                            split(linefields[i], kvpair,"=")
                            #printf("mpp key= %s value = %s\n",kvpair[1], kvpair[2])
                            mpp_scsi_modoptions[kvpair[1]]="=" kvpair[2]
                        }
                    }
                }
            }#if not comments
        }#if need merge
   }#while
}
END{
    # this awk script has no main body
    #check duplicated options

    if(needMerge["qla2"])
    {
        qla2tmp= mergeOptions(mpp_qla2options,user_qla2options,qla2tmp,qlaAllkey)
        qla2Options="options qla2xxx " qla2tmp
    }

    if(needMerge["qla4"])
    {
        qla4tmp= mergeOptions(mpp_qla4options,user_qla4options,qla4tmp,qlaAllkey)
        qla4Options="options qla4xxx " qla4tmp
    }


    #lpfc
    if(needMerge["lpfc"])
    {
        lpfctmp= mergeOptions(mpp_lpfcoptions,user_lpfcoptions,lpfctmp,lpfcAllkey)
        lpfcOptions="options lpfc " lpfctmp
    }

    #bfa
    if(needMerge["bfa"])
    {
        bfatmp= mergeOptions(mpp_bfaoptions,user_bfaoptions,bfatmp,bfaAllkey)
        bfaOptions="options bfa " bfatmp
    }


    #scsi mod
    if(needMerge["scsi_mod"])
    {
        scsiModtmp=mergeOptions(mpp_scsi_modoptions,user_scsi_modoptions,scsiModtmp,scsiModAllkey)
        scsiModOptions="options scsi_mod " scsiModtmp
    }


    # we get all options merged. 
    # 1. if we need to merge, save the original modprobe.conf to a safe place
    # 2. parse mpp modprobe.conf.append file and replace the options with the merged options
    # 3. remove the module options from the modprobe.conf before we start building ramdisk
   
    if ( qla2Options || qla4Options || lpfcOptions || bfaOptions || scsiModOptions )
    {

        #copy the origical modprobe.conf file to a safe place
        cpCmd="cp -p /etc/modprobe.conf " SYS_MODPROBE_SAVED_FILE
        system(cpCmd)


        #build sed command string. The sed command is used to remove related module options
        #from /etc/modprobe.conf file. RedHat does not allow multiple line module options for
        # the same module
        if ( qla2Options)
        {
            qla2SedCmd=" -e  \x27/[^ ]*options *qla2xxx/d\x27 "
        }
        if ( qla4Options)
        {
            qla4SedCmd=" -e  \x27/[^ ]*options *qla4xxx/d\x27 "
        }
        if(lpfcOptions)
        {
            lpfcSedCmd=" -e  \x27/[^ ]*options *lpfc/d\x27 "
        }
        if(bfaOptions)
        {
            bfaSedCmd=" -e  \x27/[^ ]*options *bfa/d\x27 "
        }
        if(scsiModOptions)
        {
            scsiModSedCmd=" -e  \x27/[^ ]*options *scsi_mod/d\x27 "
        }
        sedCmd="sed " qla2SedCmd qla4SedCmd lpfcSedCmd bfaSedCmd scsiModSedCmd " " SYS_MODPROBE_SAVED_FILE  ">/etc/modprobe.conf"
        system(sedCmd)


        #paring the mpp modprobe.conf.mppappend file and replace the module options with 
        #the merged options
        
        #close the file first because it is opened in BEGIN block
        close(MPP_MODPROBE_FILE)

        #read line by line.The merged modprobe.conf.mppappend is saved in MPP_TMP_MODPROBE_FILE
        while ( getline theline < MPP_MODPROBE_FILE     > 0)
        {

            if (theline !~ /^#/ &&  theline !~ /#[\x20*]options/ && theline !~ /#options/)
            {
                if(theline ~  /[^ ]*options *qla2xxx/ && qla2Options)
                {
                    print qla2Options >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *qla4xxx/ && qla4Options)
                {
                    print qla4Options >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *lpfc/ && lpfcOptions)
                {
                    print lpfcOptions >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *bfa/ && bfaOptions)
                {
                    print bfaOptions >>MPP_TMP_MODPROBE_FILE
                } else if(theline ~  /[^ ]*options *scsi_mod/ && scsiModOptions)
                           {
                    print scsiModOptions >>MPP_TMP_MODPROBE_FILE
                }else
                {
                    print theline >>MPP_TMP_MODPROBE_FILE
                }
            }else
            {
                print theline >>MPP_TMP_MODPROBE_FILE
            }
        }
        print "NEEDED"
    }#if need mergence
} #end of the awk
'
} #end of the function


#
# function to change system module configuration file before making RAMdisk image
#
changeCfgFile ()
{
    if [ $1 = SUSE ]; then
	    IS_SLES10=$(echo "${MPP_RAMDISK_KERNEL_VERSION}"|grep -c 2.6.16)
        if [ ${IS_SLES10} != 0 ]
        then
             retVal=$(mppLnx_suse_mergeModConf)
             if [ "XX${retVal}" == "XX" ]
             then
                 /bin/cat $SUSE_MPPAPPENDFILE >> /etc/modprobe.conf.local
             else
                 SUSE_NEED_MODCONF_RESTORE=${retVal}
                 /bin/rm -f $MPPAPPENDFILE
                 /bin/sed '/options lpfc/d' /etc/modprobe.conf.local > /tmp/modprobe.conf.tmp
                 /bin/cp /tmp/modprobe.conf.tmp /etc/modprobe.conf.local
                 /bin/sed '/options bfa/d' /etc/modprobe.conf.local > /tmp/modprobe.conf.tmp
                 /bin/cp /tmp/modprobe.conf.tmp /etc/modprobe.conf.local
                 /bin/sed '/options scsi_mod/d' /etc/modprobe.conf.local > /tmp/modprobe.conf.tmp
                 /bin/cp /tmp/modprobe.conf.tmp /etc/modprobe.conf.local
                 /bin/sed '/options qla2xxx/d' /etc/modprobe.conf.local > /tmp/modprobe.conf.tmp
                 /bin/cp /tmp/modprobe.conf.tmp /etc/modprobe.conf.local
                 /bin/sed '/options qla4xxx/d' /etc/modprobe.conf.local > /tmp/modprobe.conf.tmp
                 /bin/cp /tmp/modprobe.conf.tmp /etc/modprobe.conf.local
                 /bin/mv ${MPP_TMP_MODPROBE_FILE} ${MPPAPPENDFILE}
                 /bin/cat $MPPAPPENDFILE >> /etc/modprobe.conf.local
             fi
         else
                /bin/cat $SUSE_MPPAPPENDFILE >> /etc/modprobe.conf.local
         fi
    else
        retV=$(mppLnx_redhat_mergeModConf)
        if [ "XX${retV}" == "XX" ]
        then
            /bin/cat $MPPAPPENDFILE >> /etc/modprobe.conf
        else
            REDHAT_NEED_MODCONF_RESTORE=${retV}
            /bin/rm -f $MPPAPPENDFILE
            /bin/mv ${MPP_TMP_MODPROBE_FILE} ${MPPAPPENDFILE}
            /bin/cat $MPPAPPENDFILE >> /etc/modprobe.conf
        fi

    fi


    if [ $1 = SUSE ]; then

        #check to see if "scsi mid level" is compiled as module
        info=$(modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/scsi_mod.ko 2> /dev/null) 
        scsi_module="$?"

        #check to see if "sg" is compiled as module
        info=$(modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/sg.ko 2> /dev/null)
        sg_module="$?"

        #check to see if "sd" is compiled as module
        info=$(modinfo /lib/modules/${MPP_RAMDISK_KERNEL_VERSION}/kernel/drivers/scsi/sd_mod.ko 2> /dev/null)
        sd_module="$?"


        #get rid off trailing spaces. SLES 10 has another variable DOMU_INITRD_MODULES
        str=$(grep INITRD_MODULES ${SUSE_SYSCONFIG_KERNEL} |grep -v DOMU_INITRD_MODULES| /bin/sed -e 's/\" *$/\"/'| grep "^INITRD_MODULES") 

        #remove scsi_mod if already present
        str=${str/"scsi_mod"/}

        #remove sd_mod if already present
        str=${str/"sd_mod"/}

        #remove sg if already present
        str=${str/"sg"/}

        #add mppUpper at the begining of the list
        str=${str/"="\"/"=\"mppUpper "}

        if [ $sg_module -eq 0 ]; then 
            #add sg at the begining of the list
            str=${str/"="\"/"=\"sg "}
        fi

        if [ $sd_module -eq 0 ]; then
            #add sd_mod at the begining of the list
            str=${str/"="\"/"=\"sd_mod "}
        fi


        if [ $scsi_module -eq 0 ]; then
            #add scsi_mod at the begining of the list
            str=${str/"="\"/"=\"scsi_mod "}
        fi

        #add mppVhba at the end of the list
        str=${str/%"\""/" mppVhba\""}

        #get rid off leading space
        cat ${SUSE_SYSCONFIG_KERNEL} |/bin/sed 's/^[ ^/t]*//'| /bin/sed  -e "/^INITRD_MODULES.*=/s/^.*$/$str/g" > /tmp/kernel.temp

        #
        #Before we touch the kernel configure file, save a copy and preserve its file attributes
        #
        /bin/cp -p ${SUSE_SYSCONFIG_KERNEL} ${SUSE_SYSCONFIG_KERNEL_SAVED}

        /bin/cp /tmp/kernel.temp ${SUSE_SYSCONFIG_KERNEL} || mppLnx_error 2 "Copy operation failed"
        /bin/cp ${SUSE_SYSCONFIG_KERNEL} /opt/mpp/kernel.suseinitrd || mppLnx_error 2 "Copy operation failed"
        /bin/rm /tmp/kernel.temp
    fi
}

# function to restore system module configuration file after making RAMdisk image
restoreCfgFile ()
{
	/bin/sed '/BEGIN OF MPP/,/END OF MPP/d' /etc/modprobe.conf > /tmp/modprobe.conf.restored
	/bin/cp /tmp/modprobe.conf.restored /etc/modprobe.conf || mppLnx_error 2 "Copy operation failed"
	/bin/rm /tmp/modprobe.conf.restored
	if [ $1 = SUSE ]; then
		#/bin/sed '
		#/INITRD_MODULES/s/mppUpper//g;s/mppVhba//g
		#' /etc/sysconfig/kernel > /tmp/kernel.restored
		#/bin/cp /tmp/kernel.restored /etc/sysconfig/kernel || mppLnx_error 2 "Copy operation failed"
		#/bin/rm /tmp/kernel.restored

                IS_SLES10=$(echo "${MPP_RAMDISK_KERNEL_VERSION}"|grep -c 2.6.16)
                if [ ${IS_SLES10} != 0 ]
                then
                    if [ "XX${SUSE_NEED_MODCONF_RESTORE}" != "XX" ]
                    then
                         /bin/cp -p ${SYS_MODPROBE_SAVED_FILE} ${SYS_MODPROBE_FILE}
                         /bin/rm -f ${SYS_MODPROBE_SAVED_FILE}
                         /bin/cp -p ${SUSE_MODPROBE_LOCAL_MPP_SAVED_FILE} ${SUSE_MODPROBE_CONF}
                         /bin/rm -f ${SUSE_MODPROBE_LOCAL_MPP_SAVED_FILE}
                    fi
                fi
                # restore the suse sysconfig kernel file from the previous saved place
                /bin/rm -f ${SUSE_SYSCONFIG_KERNEL}
                /bin/cp -p ${SUSE_SYSCONFIG_KERNEL_SAVED} ${SUSE_SYSCONFIG_KERNEL}
                /bin/rm -f ${SUSE_SYSCONFIG_KERNEL_SAVED}
		
		/bin/sed '/BEGIN OF MPP Driver Changes/,/END OF MPP Driver Changes/d' /etc/modprobe.conf.local > /tmp/modprobe.conf.restored
		/bin/cp /tmp/modprobe.conf.restored /etc/modprobe.conf.local || mppLnx_error 2 "Copy operation failed"
		/bin/rm /tmp/modprobe.conf.restored
    else
        #redhad case
        if [ "XX${REDHAT_NEED_MODCONF_RESTORE}" != "XX" ]
        then
            /bin/cp -p ${SYS_MODPROBE_SAVED_FILE} ${SYS_MODPROBE_FILE}
            /bin/rm -f ${SYS_MODPROBE_SAVED_FILE}
        fi
	fi
}

mppLnx_error ()
{
	echo "$2";
	restoreCfgFile $OS_DIST;
	exit $1;
}

makeMPPInitrdImage ()
{
    if [ "$#" -gt "0" -a ! -z "$1" ]
    then
        KERNEL_VER="$1"
    else
        KERNEL_VER=`uname -r`
    fi
    if  [ -z $MPP_RAMDISK_KERNEL_VERSION ]
    then
    	MPP_RAMDISK_KERNEL_VERSION=$KERNEL_VER
   	export MPP_RAMDISK_KERNEL_VERSION
    fi


    mppImgName=mpp-$KERNEL_VER.img
	
	# Change system configuration file
	if [ -f /etc/SuSE-release ]
	then
		OS_DIST="SUSE"
	else
		OS_DIST="REDHAT"
	fi
	changeCfgFile $OS_DIST
		

	# call mkinitrd so that the changed devicemapping file is put into the new ramdisk. This is different for SuSE and RedHat.
	echo Creating new MPP initrd image...
	if [ -f /etc/redhat-release ]  
	then
   	    if [ `uname -m` = ia64 ]
   	    then
		mppImgDir=/boot/efi/efi/redhat
   	    else
		mppImgDir=/boot
   	    fi
      	    /opt/mpp/mppmkinitrd $REDHAT_PRELOAD -f $mppImgDir/$mppImgName $KERNEL_VER || return 1;
	elif [ "$OS_DIST" = SUSE ]
	then
   	    if [ `uname -m` = ppc64 ]
   	    then
		/opt/mpp/mppmkinitrd -i $mppImgName -k vmlinux-$KERNEL_VER || return 1;
            else
	        if [ -f /boot/vmlinuz-"$KERNEL_VER" ]
	        then
		    /opt/mpp/mppmkinitrd -i $mppImgName -k vmlinuz-$KERNEL_VER || return 1;
                else
		    /opt/mpp/mppmkinitrd -i $mppImgName -k vmlinuz || return 1;
                fi
            fi
            if [ `uname -m` = ia64 ] && [ -d /boot/efi/efi/SuSE ]
            then
               cp -f /boot/$mppImgName /boot/efi/efi/SuSE
            fi

	else
		echo Your kernel ${KERNEL_VER} is not a RedHat AS or SuSE SLES distribution || return 1;
	fi

	# restore system configuration file
	restoreCfgFile $OS_DIST

	if [ -f  $MODULE_LIST_FILE ]
	then
		rm $MODULE_LIST_FILE
	fi

	if [ -f /tmp/checkResultFile.mpp ]
	then
		rm /tmp/checkResultFile.mpp
	fi
}
