#!/bin/bash                                 
#
# Copyright (c) 2006 Mellanox Technologies. All rights reserved.
#
# This Software is licensed under one of the following licenses:
#
# 1) under the terms of the "Common Public License 1.0" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/cpl.php.
#
# 2) under the terms of the "The BSD License" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/bsd-license.php.
#
# 3) under the terms of the "GNU General Public License (GPL) Version 2" a
#    copy of which is available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/gpl-license.php.
#
# Licensee has the right to choose one of the above licenses.
#
# Redistributions of source code must retain the above copyright
# notice and one of the license notices.
#
# Redistributions in binary form must reproduce both the above copyright
# notice, one of the license notices in the documentation
# and/or other materials provided with the distribution.
#
#  $Id: install.sh 9845 2006-10-17 10:04:38Z vlad $
#
# Description: OFED installation script

usage()
{
cat << EOF

    `basename $0` [ -c <packages config_file> ] [ -net <network config_file> ]

EOF
}

unalias -a

cd ${0%*/*}
CWD=`pwd`

INTERACTIVE=1
SET_CONFIG_NET=0
IS_CONFIG_NET=0
CONFIG=""

if [ ! -e ./build_env.sh ]; then
    echo "ERROR: $CWD/build_env.sh file is missing"
    exit 1
fi

while [ $# -gt 0 ]
do
    case $1 in
            -c)
                shift
                CONFIG=$1
                INTERACTIVE=0
            ;;
            -net)
                shift
                CONFIG_NET=$1
            ;;
            *)
                usage
                exit 1
            ;;
    esac
    shift
done
                    
. $CWD/build_env.sh

if [ $INTERACTIVE -eq 1 ]; then
    CONFIG_NET=${CONFIG_NET:-"${PKG_SOURCE_DIR}/ofed_net.conf"}
    touch $CONFIG_NET
    [ -s ${CONFIG_NET} ] && $MV -f ${CONFIG_NET} ${CONFIG_NET}.save
    cat $NULL > ${CONFIG_NET}
    SET_CONFIG_NET=1
else
    if [ -s "$CONFIG_NET" ]; then
        IS_CONFIG_NET=1
    fi
fi

SELECTED_PACKAGES=""
OPENIB_PACKAGES=""
EXTRA_PACKAGES=""
IB_EXTRA_PACKAGES=""

# Remove remaining empty directories and files which are listed in the installation log file
clean()
{

    # Check if some empty directories with installation prefix still exist and remove them
    if [ -d ${STACK_PREFIX} ]; then
        find ${STACK_PREFIX} -type d | sort -r | xargs rmdir > $NULL 2>&1
    fi
    # rmdir ${STACK_PREFIX} > $NULL 2>&1

}

# Remove installed packages in case of an upgrade
rmInstalled()
{
    local RC=0
    local OLD_PREFIX=""
    echo
    echo "Removing previous InfiniBand Software installations"
    echo

    # Check prefix and kernel version using the info file:
    INFO=/etc/infiniband/info
    if [ -x ${INFO} ]; then
           info_prefix=$(${INFO} | grep -w prefix | cut -d '=' -f 2)
           if [ -x ${info_prefix}/uninstall_gen2.sh ] \
                   || [ -x ${info_prefix}/uninstall.sh ]; then
                        yes | ${info_prefix}/uninstall_gen2.sh > $NULL 2>&1 || \
                        yes | ${info_prefix}/uninstall.sh > $NULL 2>&1
                if [ $? -ne 0 ]; then
                    err_echo "Failed to uninstall the software stack from ${info_prefix}"
                    exit 1
                fi
           fi

    fi
        
    MPITESTS_LIST=$(rpm -qa | grep mpitests)
 
    if [ -n "$MPITESTS_LIST" ]; then
        for mpitest_name in $MPITESTS_LIST
        do 
            if ( $RPM -q ${mpitest_name} > $NULL 2>&1 ); then
                ex "$RPM -e ${mpitest_name}"
            fi
        done    
    fi

    MPI_OSU_LIST=$(rpm -qa | grep ${MPI_OSU_MPICH_NAME})

    if [ -n "$MPI_OSU_LIST" ]; then
        for mpi_name in $MPI_OSU_LIST
        do 
            if ( $RPM -q ${mpi_name} > $NULL 2>&1 ); then
                ex "$RPM -e ${mpi_name}"
            fi
        done    
    fi

    OPENMPI_LIST=$(rpm -qa | grep ${OPENMPI_NAME})

    if [ -n "$OPENMPI_LIST" ]; then
        for mpi_name in $OPENMPI_LIST
        do 
            if ( $RPM -q ${mpi_name} > $NULL 2>&1 ); then
                ex "$RPM -e ${mpi_name}"
            fi
        done    
    fi
    
    if [[ ! -z $MTHOME && -d $MTHOME ]]; then
        if [ -e $MTHOME/uninstall.sh ]; then
            echo
            echo "  An old version of the OPENIB driver was detected and will be removed now"
            ex "yes | env MTHOME=$MTHOME $MTHOME/uninstall.sh"
        else
            echo
            warn_echo "Found an MTHOME variable pointing to $MTHOME. Probably some old InfiniBand Software ..."
            echo
        fi    
        let RC++
    elif [ -d /usr/mellanox ]; then
        if [ -e /usr/mellanox/uninstall.sh ]; then
            echo
            echo "  Removing MVAPI..."
            ex "yes | /usr/mellanox/uninstall.sh"
        else
            echo
            warn_echo "Found a /usr/mellanox directory. Probably some old InfiniBand Software ..."
            echo
        fi  
    fi
    
    packs_to_remove=""
    for package in $ALL_PACKAGES $PREV_RELEASE_PACKAGES $IB_KERNEL_UTILS
    do
        if ( $RPM -q ${package} > $NULL 2>&1 ); then
            packs_to_remove="$packs_to_remove ${package}"
            let RC++
        fi
    done    

    if ( $RPM -q ib-verbs > $NULL 2>&1 ); then
        OLD_PREFIX=`$RPM -ql ib-verbs | grep "utils/create_devs" | sed -e 's/\/utils\/create_devs//'`
        NEW_PREFIX=`$RPM -ql ib-verbs | grep "bin/ibv_devinfo" | sed -e 's/\/bin\/ibv_devinfo//'`
        let RC++
    fi    

    if ( $RPM -q libibverbs > $NULL 2>&1 ); then
        GEN2_PREFIX=$($RPM -ql libibverbs | grep "libibverbs.so" | head -1 | sed -e 's/\/lib\/libibverbs.so//' -e 's/\/lib64\/libibverbs.so//')            
    fi

    if [ -n "${packs_to_remove}" ]; then
        ex "$RPM -e $packs_to_remove"
    fi
    

    # Uninstall SilverStorm package
    if [ -e /sbin/iba_config ]; then
        ex /sbin/iba_config -u
    fi

    # Uninstall Topspin package
    topspin_rpms=$($RPM -qa | grep "topspin-ib")
    if [ -n "${topspin_rpms}" ]; then
        ex $RPM -e ${topspin_rpms}
    fi

    # Uninstall Voltaire package
    voltaire_rpms=$($RPM -qa | grep -i "Voltaire" | grep "4.0.0_5")
    if [ -n "${voltaire_rpms}" ]; then
        ex $RPM -e ${voltaire_rpms}
    fi
    
    clean

    if [ $RC -gt 0 ]; then
        let NEED_REBOOT++
    fi
    return 0
}

# Check if RPMs for the selected packages exist
is_rpms()
{
    for package in $OPENIB_PACKAGES
    do
        case "$package" in
        "kernel-ib")
            if ! ( /bin/ls -1 ${RPMS}/${package}-[0-9]*${RPMK_VER}.${build_arch}.rpm > $NULL 2>&1 ); then
                return 1
            fi
            # Check if the kernel-ib RPM includes the required kernel module
            required_kmods=""
            for kmod in $OPENIB_KERNEL_PACKAGES
            do
                if [ "$kmod" == "ib_verbs" ]; then
                    continue
                fi
                if ! ( $RPM -qlp ${RPMS}/${package}-[0-9]*${RPMK_VER}.${build_arch}.rpm | grep "${kmod}.ko" > $NULL 2>&1 ); then
                    return 1
                fi
            done
        ;;
        "kernel-ib-devel")
            if ! ( /bin/ls -1 ${RPMS}/${package}-[0-9]*${RPMK_VER}.${build_arch}.rpm > $NULL 2>&1 ); then
                return 1
            fi
        ;;
        *)
            if ! ( /bin/ls -1 ${RPMS}/${package}-[0-9]*.${build_arch}.rpm > $NULL 2>&1 ); then
                return 1
            fi
        ;;
        esac
                
    done

    for package in $EXTRA_PACKAGES
    do
        case $package in
            mpi_osu)
               for mpi_comp in ${MPI_COMPILER_mpi_osu}
               do
                   [ ! -f ${RPMS}/${MPI_OSU_MPICH_NAME}_${mpi_comp}-${MPI_OSU_MPICH_VER}-${MPI_OSU_MPICH_REL}.${build_arch}.rpm ] && return 1
               done    
            ;;
            openmpi)
#               for mpi_comp in ${MPI_COMPILER_openmpi}
#               do
#                   [ ! -f ${RPMS}/${OPENMPI_NAME}_${mpi_comp}-${OPENMPI_VERSION}.${build_arch}.rpm ] && return 1
#               done    
            ;;
            mpitests)
                if ! ( /bin/ls -1 ${RPMS}/${MPITESTS_NAME}*-${MPITESTS_VERSION}.${build_arch}.rpm > $NULL 2>&1 ); then
                    return 1
                fi
            ;;
            pdsh)
            #   [ ! -f ${RPMS}/${PDSH_NAME}-${PDSH_VERSION}.${build_arch}.rpm ] && return 1
            ;;
            ibutils)
                [ ! -f ${RPMS}/${IBUTILS_NAME}-${IBUTILS_VERSION}.${build_arch}.rpm ] && return 1
                required_libtcl=$($RPM -qp --requires ${RPMS}/${IBUTILS_NAME}-${IBUTILS_VERSION}.${build_arch}.rpm 2> $NULL | grep libtcl | head -1)
                if ! ($RPM -q --provides tcl 2> $NULL | grep -w ${required_libtcl} > $NULL 2>&1 ); then
                    return 1
                fi
            ;;
            oiscsi-iser)
                [ ! -f ${RPMS}/${OISCSI_ISER_NAME}-${OISCSI_ISER_VERSION}.${build_arch}.rpm ] && return 1
            ;;
            ofed-docs)
                [ ! -f ${RPMS}/${DOCS_NAME}-${DOCS_VERSION}.noarch.rpm ] && return 1
            ;;
            ofed-scripts)
                [ ! -f ${RPMS}/${SCRIPTS_NAME}-${SCRIPTS_VERSION}.noarch.rpm ] && return 1
            ;;
            *)
                echo "Unknown package !!!"
                return 1
            ;;
            esac    
    
    done

    return 0
}

# Check the $1 package requirments for running
check_run_req()
{
    local RC=0
    local mode=$2
    local rreq_pack
    local rreq_pack_name
    local rreq_pack_ver
    local rreq_pack_rel
    local curr_pack_ver
    
        for rreq_pack in  `eval echo \$\{${1}_RUN_REQ\}`
        do  
            if ( echo $rreq_pack | grep '_' > $NULL 2>&1 ); then
                rreq_pack_name=`echo $rreq_pack | cut -d '_' -f 1`          
                rreq_pack_ver=`echo $rreq_pack | cut -d '_' -f 2`
                rreq_pack_rel=`echo $rreq_pack | cut -d '_' -f 3`
            else
                rreq_pack_name=$rreq_pack
                rreq_pack_ver=""
                rreq_pack_rel=""
            fi
            
            if ! ( $RPM -q $rreq_pack_name > $NULL 2>&1 ); then
                [ "$mode" == "warn" ] && warn_echo "The $rreq_pack_name package is required to run $1"
                [ "$mode" == "err" ] && err_echo "The $rreq_pack_name package is required to run $1"
                let RC++
            else
                if [ "$rreq_pack_ver" != "" ]; then
                    curr_pack_ver=`$RPM --queryformat "[%{VERSION}]" -q $rreq_pack_name`
                    compare $rreq_pack_ver $curr_pack_ver
                    if [ $? -eq 1 ]; then
                        [ "$mode" == "warn" ] && warn_echo "The $rreq_pack_name >= $rreq_pack_ver package is required  to run $1"
                        [ "$mode" == "err" ] && err_echo "The $rreq_pack_name >= $rreq_pack_ver package is required to run $1"
                        let RC++
                    fi
                fi
            fi
        done
    return $RC    
}

# Check if the package $1 is installed
isInstalled()
{
    if ( $RPM -q $1 > $NULL 2>&1 ); then
        return 0
    fi    
    return 1
}

# Check if the given IP address is valid
is_valid()
{
    perl -e 'if ($#ARGV != 0){exit 2}'  -e 'if ($ARGV[0] =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { exit 0 } else { exit 1 }' $@
    if [ $? -ne 0 ]; then
        return 1
    fi

    local IFS_save
    IFS_save=$IFS
    IFS='.'
    for oct in $@
    do
        if [ $oct -gt 255 ]; then
            IFS=$IFS_save
            return 2
        fi
    done
    IFS=$IFS_save
    
    return 0
}

is_integer()
{
   if [ $# -gt 1 ]; then
        return 2
   fi
   printf "%s\n" $1 |grep -E "^[+-]?[0-9]+$" > /dev/null
   return $?
}

# Configure OpenSM parameters
osmconf()
{
    local OSM_HOST_tmp
    local LAN_INTERFACE_tmp
    local OSM_HOSTS_LIST_tmp
    
         LAN_INTERFACE_tmp=`$IFCONFIG | grep eth | awk '{print$1}' | sort -n | head -1 | tr -d '[:space:]'`
         LAN_INTERFACE=${LAN_INTERFACE:-$LAN_INTERFACE_tmp}
        
         OSM_HOST_tmp=`$IFCONFIG | sed -e "/\($LAN_INTERFACE\).*/{ N; s/.*inet addr:\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/; }" | grep ^[0-9] | head -1`
         echo -n "Enter IP Addresses of all OpenSM Servers in the IB subnet  [${OSM_HOST_tmp} [...]]:"
         read OSM_HOSTS_LIST_tmp

         if [ "${OSM_HOSTS_LIST_tmp}" == "" ]; then
             OSM_HOSTS_LIST=$OSM_HOST_tmp
         else
             for osm_host in ${OSM_HOSTS_LIST_tmp}
             do
                 if ! is_valid $osm_host; then
                     while ! is_valid $osm_host; do
                         echo -n "Enter a valid IP address like [$OSM_HOST_tmp] instead of ${osm_host}:"
                         read osm_host
                         [ "$osm_host" == "" ] && osm_host=$OSM_HOST_tmp
                     done
                     OSM_HOSTS_LIST="${OSM_HOSTS_LIST} ${osm_host}"
                 else
                     OSM_HOSTS_LIST="${OSM_HOSTS_LIST} ${osm_host}"
                 fi
             done
         fi    

    # Clean the previous IBADM configuration in order to prevent IP duplication
    perl -ni -e 'if (/\#\# OpenSM \#\#$/) { $filter = 1 }' -e 'if (!$filter) { print }' -e 'if (/\#\# END OpenSM \#\#$/){ $filter = 0 }' $CONFIG
    
    echo "## OpenSM ##" >> $CONFIG
    echo OSM_HOSTS_LIST=\"$OSM_HOSTS_LIST\" >> $CONFIG
    echo "## END OpenSM ##" >> $CONFIG
    
    return 0
}

# Check if ETH interface $1 exists
is_eth()
{
    local eth_name=$1
    shift
    
    $IFCONFIG $eth_name > $NULL 2>&1   
    return $?
}


#####################################################################
# Configure Driver Autostart
ipconfig()
{
    local device=$1
          shift
    local target=$1
          shift
    
    # Set the default network configuration
    local IPADDR
    local NETMASK
    local BROADCAST
    local NETWORK
    local ONBOOT ONBOOT_tmp=1
    local LAN_INTERFACE LAN_INTERFACE_tmp
    local INTERFACES INTERFACE ADDRS
    
    
    INTERFACES=`$IFCONFIG | grep eth | awk '{print$1}' | sort -n | tr -s '\n' '\ '`
    for INTERFACE in $INTERFACES
    do
        if ( $IFCONFIG $INTERFACE | grep "inet addr" > $NULL 2>&1 ); then
              LAN_INTERFACE_tmp=$INTERFACE
              break
        fi
    done
    
    
    
   
    #################################################################
    
    local ip=""
    local nm=""
    local nw=""
    local bc=""
     
    if [ $INTERACTIVE -eq 1 ]; then
       echo
       echo "$device configuration:"
    
            if [ -s $NETWORK_CONF_DIR/ifcfg-$device ]; then
                echo
                echo "  The current IPOIB configuration for $device is:"
                echo
                cat $NETWORK_CONF_DIR/ifcfg-$device
                echo
                echo -n "Do you want to change this configuration? [y/N]:"
                if ! get_ans; then
                    return 0
                fi
            fi
            
    
                echo -n "Enter an IP Address:"
                read ip
                while ! is_valid $ip; do
                    echo -n "Enter a valid IPv4 Address:"
                    read ip
                done    
                IPADDR=$ip
                
                echo -n "Enter the Netmask:"
                read nm
                while ! is_valid $nm; do
                    echo -n "Enter a valid Netmask:"
                    read nm
                done    
                NETMASK=$nm
                    
                echo -n "Enter the Network:"
                read nw
                while ! is_valid $nw; do
                    echo -n "Enter a valid Network:"
                    read nw
                done    
                NETWORK=$nw
                
                echo -n "Enter the Broadcast Address:"
                read bc
                while ! is_valid $bc; do
                    echo -n "Enter a valid Broadcast Address:"
                    read bc
                done    
                BROADCAST=$bc
                
                read -p "Start Device On Boot? [Y/n]:" ans
                if ! [[ "$ans" == "" || "$ans" == "y" || "$ans" == "Y" || "$ans" == "yes" ]]; then
                    ONBOOT=0
                else
                    ONBOOT=1    
                fi
    
                
                echo
                echo Selected configuration:
                echo
                echo IPADDR=$IPADDR
                echo NETMASK=$NETMASK
                echo NETWORK=$NETWORK
                echo BROADCAST=$BROADCAST
                if [ $ONBOOT -eq 1 ]; then
                     echo ONBOOT=yes
                else
                     echo ONBOOT=no
                fi
    
                echo
                echo -n "Do you want to save the selected configuration? [Y/n]:"
                read ans
                if ! [[ "$ans" == "" || "$ans" == "y" || "$ans" == "Y" || "$ans" == "yes" ]]; then
                    return 1
                fi    
                
    else # Non-interactive mode
 
        if [ $IS_CONFIG_NET -eq 0 ]; then
            # There is no configuration for IPoIB devices
            return 0
        fi
    
        if [ -e ${target}.rpmsave ]; then
            if ( /usr/bin/diff ${target}.rpmsave ${target} > $NULL 2>&1 ); then
                pass_echo "Used the previous configuration file (${target}.rpmsave) for $device interface"
                return 0
            fi  
        fi

        # Set the Ethernet device for IPoIB configuration
        LAN_INTERFACE=$(grep -w LAN_INTERFACE_${device} ${CONFIG_NET} | cut -d '=' -f 2)
        if [ -n "${LAN_INTERFACE}" ]; then
            if ! is_eth $LAN_INTERFACE; then
                echo "The interface $LAN_INTERFACE does not exist."
                echo "Update ${CONFIG_NET} with a valid Ethernet interface name for LAN_INTERFACE_${device}"
                continue
            fi
        fi
        LAN_INTERFACE=${LAN_INTERFACE:-$LAN_INTERFACE_tmp}
    

        IPADDR_eth=`$IFCONFIG | sed -e "/\($LAN_INTERFACE\).*/{ N; s/.*inet addr:\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/;}" | grep ^[0-9] | head -1`
        NETMASK_eth=`$IFCONFIG | sed -e "/\($LAN_INTERFACE\).*/{ N; s/.*Mask:\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/; }" | grep ^[0-9] | head -1`
        if [ "${NETMASK_eth}" == "" ]; then
            NETMASK_eth=255.0.0.0
        fi
    
        BROADCAST_eth=`$IFCONFIG | sed -e "/\($LAN_INTERFACE\).*/{ N; s/.*Bcast:\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/;}" | grep ^[0-9] | head -1`

        # Set device configuration from the config file
        IPADDR=$(grep -w IPADDR_${device} ${CONFIG_NET} | cut -d '=' -f 2)
        NETMASK=$(grep -w NETMASK_${device} ${CONFIG_NET} | cut -d '=' -f 2)
        NETWORK=$(grep -w NETWORK_${device} ${CONFIG_NET} | cut -d '=' -f 2)
        BROADCAST=$(grep -w BROADCAST_${device} ${CONFIG_NET} | cut -d '=' -f 2)
        ONBOOT=$(grep -w ONBOOT_${device} ${CONFIG_NET} | cut -d '=' -f 2)

#        IPADDR=`eval echo \$\{IPADDR_$device\}`
#        NETMASK=`eval echo \$\{NETMASK_$device\}`
#        NETWORK=`eval echo \$\{NETWORK_$device\}`
#        BROADCAST=`eval echo \$\{BROADCAST_$device\}`
#        ONBOOT=`eval echo \$\{ONBOOT_$device\}`
                   
        if [ -z "${IPADDR}" ]; then
            echo "IPADDR_${device} address is not defined in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi

        if [ -z "${NETMASK}" ]; then
            echo "NETMASK_${device} address should be defined in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi

        if [ -z "${BROADCAST}" ]; then
            echo "BROADCAST_${device} address should be defined in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi
       
        declare -a ipaddr_arr ipaddr_eth_arr 
        declare -a netmask_arr netmask_eth_arr
        declare -a network_arr network_eth_arr
        declare -a broadcast_arr broadcast_eth_arr

        local IFS_save=$IFS
        IFS='.'
        ipaddr_arr=(${IPADDR})
        ipaddr_eth_arr=(${IPADDR_eth})
        netmask_arr=(${NETMASK})
        netmask_eth_arr=(${NETMASK_eth})
        broadcast_arr=(${BROADCAST})
        broadcast_eth_arr=(${BROADCAST_eth})
        IFS=$IFS_save

        for (( n=0 ; n<=3 ; n++ ))
        do
            if [ -z ${ipaddr_eth_arr[$n]} ] || [ -z ${netmask_eth_arr[$n]} ]; then
                break
            else
                network_eth_arr[$n]=$[ ${ipaddr_eth_arr[$n]} & ${netmask_eth_arr[$n]} ]
            fi
        done    

        if [ -z "${NETWORK}" ]; then
            for (( n=0 ; n<=3 ; n++ ))
            do
                if is_integer ${ipaddr_arr[$n]} && is_integer ${netmask_arr[$n]}; then
                    network_arr[$n]=$[ ${ipaddr_arr[$n]} & ${netmask_arr[$n]} ]
                fi
            done
        else
            local IFS_save=$IFS
            IFS='.'
            network_arr=(${NETWORK})
            IFS=$IFS_save
        fi

        for (( n=1 ; n<=4 ; n++ ))
        do
            if [ "${ipaddr_arr[$n-1]}" == "'*'" ]; then
                if [ -z "${ipaddr_eth_arr[$n-1]}" ]; then
                    echo "Cannot determine the IP address of the ${LAN_INTERFACE} interface"
                    break
                fi
                ipaddr_arr[$n-1]=${ipaddr_eth_arr[$n-1]}
            fi
            if [ "${netmask_arr[$n-1]}" == "'*'" ]; then
                if [ -z "${netmask_eth_arr[$n-1]}" ]; then
                    echo "Cannot determine the Netmask of the ${LAN_INTERFACE} interface"
                    break
                fi
                netmask_arr[$n-1]=${netmask_eth_arr[$n-1]}
            fi
            if [ "${network_arr[$n-1]}" == "'*'" ]; then
                if [ -z "${network_eth_arr[$n-1]}" ]; then
                    echo "Cannot determine the Network address of the ${LAN_INTERFACE} interface"
                    break
                fi
                network_arr[$n-1]=${network_eth_arr[$n-1]}
            fi
            if [ "${broadcast_arr[$n-1]}" == "'*'" ]; then
                if [ -z "${broadcast_eth_arr[$n-1]}" ]; then
                    echo "Cannot determine the Broadcast address of the ${LAN_INTERFACE} interface"
                    break
                fi
                broadcast_arr[$n-1]=${broadcast_eth_arr[$n-1]}
            fi
        done

        IPADDR=$(echo -n ${ipaddr_arr[@]} | sed -e 's/\ /./g')
        NETMASK=$(echo -n ${netmask_arr[@]} | sed -e 's/\ /./g')
        NETWORK=$(echo -n ${network_arr[@]} | sed -e 's/\ /./g')
        BROADCAST=$(echo -n ${broadcast_arr[@]} | sed -e 's/\ /./g')

        if ! is_valid ${IPADDR}; then
            echo "The computed IP address [${IPADDR}] is not valid"
            echo "Check the IPADDR_${device} parameter in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi

        if ! is_valid ${NETMASK}; then
            echo "The computed NETMASK [${NETMASK}] is not valid"
            echo "Check the NETMASK_${device} parameter in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi

        if ! is_valid ${NETWORK}; then
            echo "The computed NETWORK [${NETWORK}] is not valid"
            echo "Check the NETWORK_${device} parameter in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi

        if ! is_valid ${BROADCAST}; then
            echo "The computed BROADCAST address [${BROADCAST}] is not valid"
            echo "Check the BROADCAST_${device} parameter in the ${CONFIG_NET} file"
            echo "Skipping $device configuration..."
            continue
        fi


        echo
        echo "IPoIB configuration for $device:"
        echo
        echo IPADDR=$IPADDR
        echo NETMASK=$NETMASK
        echo NETWORK=$NETWORK
        echo BROADCAST=$BROADCAST
        if [ $ONBOOT -eq 1 ]; then
            echo ONBOOT=yes
        else
            echo ONBOOT=no
        fi
    fi    
    
    cat $NULL > $target
    
    if [ "$DISTRIBUTION" == "SuSE" ]; then
        echo BOOTPROTO=\'static\' >> $target
        echo IPADDR=\'${IPADDR}\' >> $target
        echo NETMASK=\'$NETMASK\' >> $target
        echo NETWORK=\'${NETWORK}\' >> $target
        echo BROADCAST=\'${BROADCAST}\' >> $target
        echo REMOTE_IPADDR=\'\' >> $target
        if [ $ONBOOT -eq 1 ]; then
            echo STARTMODE=\'onboot\' >> $target
        else
            echo STARTMODE=\'manual\' >> $target
        fi    
        echo WIRELESS=\'no\' >> $target
    else
        echo DEVICE=$DEVICE >> $target
        echo BOOTPROTO=static >> $target
        echo IPADDR=${IPADDR} >> $target
        echo NETMASK=$NETMASK >> $target
        echo NETWORK=${NETWORK} >> $target
        echo BROADCAST=${BROADCAST} >> $target
        if [ $ONBOOT -eq 1 ]; then
            echo ONBOOT=yes >> $target
        else
            echo ONBOOT=no >> $target    
        fi        
    fi
    
    
    if [ $SET_CONFIG_NET -eq 1 ]; then                                
        echo LAN_INTERFACE_$device=$LAN_INTERFACE >> $CONFIG_NET
        echo IPADDR_$device=$IPADDR >> $CONFIG_NET
        echo NETMASK_$device=$NETMASK >> $CONFIG_NET
        echo NETWORK_$device=$NETWORK >> $CONFIG_NET
        echo BROADCAST_$device=$BROADCAST >> $CONFIG_NET
        echo ONBOOT_$device=$ONBOOT >> $CONFIG_NET
    fi
    
    chown root $target
    chgrp root $target
    chmod ugo=r,u=rw $target

}


set_ip()
{
    if ( echo -n $OPENIB_PARAMS | grep without-ipoibconf > $NULL 2>&1 ); then
        # Do not configure IPoIB interfaces
        return 0
    fi
        count_ib_ports
        ports_num=$?

        DEVICES=""
                           
        for (( i=0 ; i < $ports_num ; i++ ))
        do
            DEVICES="$DEVICES ib${i}"
        done    

        # Set default if no IB devices found                                
        [ "$DEVICES" == "" ] && DEVICES="ib0 ib1"
        
        # IP_cnt=1
        
        # echo "NETWORK_CONF_DIR=${NETWORK_CONF_DIR}" >> $CONFIG
        
        if [ $INTERACTIVE -eq 1 ]; then
            echo
            echo "The default IPoIB interface configuration is based on DHCP."
            echo "Note that a special patch for DHCP is required for supporting IPoIB."
            echo "The patch is available under OFED-1.1/docs/dhcp"
            echo "If you do not have DHCP, you must change this configuration in the following steps."
        fi
        
        for DEVICE in $DEVICES
        do
           target=$NETWORK_CONF_DIR/ifcfg-${DEVICE}
           ipconfig $DEVICE $target
           # let IP_cnt++
        done
        
        if [ $INTERACTIVE -eq 1 ]; then
            echo
            pass_echo "IPOIB interface configured successfully"
            echo
        fi
}

#####################################################################
# HCA driver and ULP RPMs installation
openib()
{
    local rpms_to_install=""
    local kernel_rpms_to_install=""
    local tools_rpms_to_install=""


    for package in $OPENIB_PACKAGES
    do
        package_var=$(echo $package | sed -e 's/-/_/g')
        
#        if ! check_run_req ${package_var} err; then
#                exit 2
#        fi    
        rpm=""
        case "$package" in
                "kernel-ib"|"kernel-ib-devel")
                    if ( /bin/ls -1 ${RPMS}/${package}-[0-9]*${RPMK_VER}.${build_arch}.rpm > $NULL 2>&1 ); then
                        rpm=$(/bin/ls -1 ${RPMS}/${package}-[0-9]*${RPMK_VER}.${build_arch}.rpm 2> $NULL)
                        kernel_rpms_to_install="$kernel_rpms_to_install $rpm"
                    else
                        echo "${package} RPM not found under ${RPMS}"
                    fi
                ;;
                *)
                    if ( /bin/ls -1 ${RPMS}/${package}-[0-9]*.${build_arch}.rpm > $NULL 2>&1 ); then
                        rpm=$(/bin/ls -1 ${RPMS}/${package}-[0-9]*.${build_arch}.rpm 2> $NULL)
                        case "$package" in
                            ipoibtools|srptools|mstflint|tvflash)
                                tools_rpms_to_install="$tools_rpms_to_install $rpm"
                            ;;
                            *)
                                rpms_to_install="$rpms_to_install $rpm"
                            ;;
                        esac
                    else
                        echo "${package} RPM not found under ${RPMS}"
                    fi
                ;;
        esac
        rpms_to_install=$(echo $rpms_to_install | tr -s ' ' '\n' | sort -n | uniq | tr -s '\n' ' ')
        kernel_rpms_to_install=$(echo $kernel_rpms_to_install | tr -s ' ' '\n' | sort -n | uniq | tr -s '\n' ' ')
        tools_rpms_to_install=$(echo $tools_rpms_to_install | tr -s ' ' '\n' | sort -n | uniq | tr -s '\n' ' ')
    
    done

    # Added '--force' parameter in order to avoid conflict with the 
    #   kernel-ib-devel rpm package
    # Added '--nodeps' parameter to get rid of dependencies issue with 
    #   kernel.org kernels installad from sources and not as an RPM
    if [ -n "${kernel_rpms_to_install// /}" ]; then
        ex "$RPM -ihv --force --nodeps ${kernel_rpms_to_install}"
    fi

    if [ -n "${rpms_to_install// /}" ]; then
        ex "$RPM -ihv ${rpms_to_install}"
    fi

    if [ -n "${tools_rpms_to_install// /}" ]; then
        ex "$RPM -ihv ${tools_rpms_to_install}"
    fi

    return 0
}

oiscsi-iser()
{
    local rpm_cnt=0

#    if ! check_run_req oiscsi_iser err; then
#        return 2
#    fi    

    if [ -f ${RPMS}/${OISCSI_ISER_NAME}-${OISCSI_ISER_VERSION}.${build_arch}.rpm ]; then
        ex "$RPM -Uhv ${RPMS}/${OISCSI_ISER_NAME}-${OISCSI_ISER_VERSION}.${build_arch}.rpm"
    else
        err_echo "${OISCSI_ISER_NAME}-${OISCSI_ISER_VERSION}.${build_arch}.rpm not found under ${RPMS}."
    fi    

    return 0

}

ofed-docs()
{
    if [ -f ${RPMS}/${DOCS_NAME}-${DOCS_VERSION}.noarch.rpm ]; then
        ex "$RPM -Uhv ${RPMS}/${DOCS_NAME}-${DOCS_VERSION}.noarch.rpm"
    else
        err_echo "${DOCS_NAME}-${DOCS_VERSION}.noarch.rpm not found under ${RPMS}."
    fi    


    return 0
}

ofed-scripts()
{
    if [ -f ${RPMS}/${SCRIPTS_NAME}-${SCRIPTS_VERSION}.noarch.rpm ]; then
        ex "$RPM -Uhv ${RPMS}/${SCRIPTS_NAME}-${SCRIPTS_VERSION}.noarch.rpm"
    else
        err_echo "${SCRIPTS_NAME}-${SCRIPTS_VERSION}.noarch.rpm not found under ${RPMS}."
    fi    


    return 0
}

ibutils()
{
    local rpm_cnt=0

#    if ! check_run_req ibutils err; then
#        return 2
#    fi    

    if [ -f ${RPMS}/${IBUTILS_NAME}-${IBUTILS_VERSION}.${build_arch}.rpm ]; then
        ex "$RPM -Uhv --nodeps ${RPMS}/${IBUTILS_NAME}-${IBUTILS_VERSION}.${build_arch}.rpm" 
    else
        err_echo "${IBUTILS_NAME}-${IBUTILS_VERSION}.${build_arch}.rpm not found under ${RPMS}."
    fi    

    return 0

}

# OSU MPI RPM installation (the MPI_COMPILER_mpi_osu variable should contain the list of compilers)
mpi_osu()
{
    local rpm_cnt=0
    
#    if ! check_run_req mpi_osu err; then
#        return 2
#    fi    
    
    for mpi_comp in ${MPI_COMPILER_mpi_osu}
    do
        OSU_RPM=${MPI_OSU_MPICH_NAME}_${mpi_comp}-${MPI_OSU_MPICH_VER}-${MPI_OSU_MPICH_REL}.${build_arch}.rpm
    
        if [ -f ${RPMS}/${OSU_RPM} ]; then
            ex "$RPM -Uhv ${RPMS}/${OSU_RPM}"
            let rpm_cnt++
        else
            echo "${RPMS}/${OSU_RPM} not found"
        fi
        if [ "$mpitests" == "y" ]; then
            MPITESTS_RPM=${MPITESTS_NAME}_${MPI_OSU_MPICH_NAME}_${mpi_comp}-${MPITESTS_VERSION}.${build_arch}.rpm
            if [ -f ${RPMS}/${MPITESTS_RPM} ]; then
                ex "$RPM -Uhv ${RPMS}/${MPITESTS_RPM}"
                let rpm_cnt++
            fi  
        fi
    done        
    
    if [ $rpm_cnt -eq 0 ]; then
        err_echo "OSU MPI RPMs are not installed"
        return 1
    fi    
    
    return 0
}

# Open MPI RPM installation (the MPI_COMPILER_openmpi variable should contain the list of compilers)
openmpi()
{
    local rpm_cnt=0
    
#    if ! check_run_req openmpi err; then
#        return 2
#    fi    

    need_openmpi_build=0
    for mpi_comp in ${MPI_COMPILER_openmpi}
    do
        [ ! -f ${RPMS}/${OPENMPI_NAME}_${mpi_comp}-${OPENMPI_VERSION}.${build_arch}.rpm ] && need_openmpi_build=1
    done  

    if [ $need_openmpi_build -eq 1 ]; then
        if [[ -z $OPENMPI_NAME || -z $OPENMPI_VERSION ]]; then
            err_echo "Failed to identify the Open MPI RPM version"
            return 1
        fi
    
        if ! check_build_req openmpi err; then
            return 2
        fi    
    
        echo
        echo "Building the Open MPI RPM. Please wait..."
        echo
    
        for mpi_comp in ${MPI_COMPILER_openmpi}
        do
            echo "Using the ${mpi_comp} compiler"
            OPENMPI_RPM=${OPENMPI_NAME}_${mpi_comp}-${OPENMPI_VERSION}.${build_arch}.rpm
            case ${mpi_comp} in
                pathscale)
                    COMP_OPTIONS="CC=pathcc"
                    if [ $is_pathCC -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS CXX=pathCC"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                    fi
                    if [ $is_pathf90 -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS F77=pathf90 FC=pathf90"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77 --disable-mpi-f90"
                    fi
                ;;
                intel)
                    COMP_OPTIONS="CC=icc"
                    if [ $is_icpc -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS CXX=icpc"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                    fi
                    if [ $is_ifort -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS F77=ifort FC=ifort"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77 --disable-mpi-f90"
                    fi
                ;;
                pgi)
                    COMP_OPTIONS="CC=pgcc"
                    if [ $is_pgCC -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS CXX=pgCC"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                    fi
                    if [ $is_pgf77 -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS FC=pgf77"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77"
                    fi
                    if [ $is_pgf90 -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS FC=pgf90"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f90"
                    fi
                ;;
                gcc)
                    COMP_OPTIONS="CC=gcc"
                    if [ $is_gpp -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS CXX=g++"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                    fi
                    if [ $is_gfortran -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS F77=gfortran FC=gfortran"
                    elif [ $is_gcc_g77 -eq 1 ]; then
                        COMP_OPTIONS="$COMP_OPTIONS F77=g77 --disable-mpi-f90"
                    else
                        COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77 --disable-mpi-f90"
                    fi
                ;;
                *)
                    COMP_OPTIONS="CC=${mpi_comp} --disable-mpi-f77 --disable-mpi-f90"
                ;;
            esac
            
            case ${ARCH} in
                ppc64)
                    COMP_OPTIONS="$COMP_OPTIONS --with-wrapper-ldflags=\"-g -O2 -m64 -L/usr/lib64\" --with-wrapper-cflags=-m64 --with-wrapper-cxxflags=-m64 --with-wrapper-fflags=-m64 --with-wrapper-fcflags=-m64 LDFLAGS=\"-m64 -L/usr/lib64\" CFLAGS=-m64 CXXFLAGS=-m64 FFLAGS=-m64"
                ;;
                *)
                ;;
            esac

            ex rpmbuild --rebuild \
                    --define \'_topdir ${RPM_DIR}\' \
                    --define \'_name ${OPENMPI_NAME}_${mpi_comp}\' \
                    --define \'_prefix ${STACK_PREFIX}/mpi/${mpi_comp}/${OPENMPI_NAME}-${OPENMPI_VERSION}\' \
                    --define \'configure_options --with-openib=${STACK_PREFIX} ${COMP_OPTIONS}\' \
                    --define \'_mandir %{_prefix}/share/man\' \
                    --define \'_defaultdocdir ${STACK_PREFIX}/mpi/${mpi_comp}/${OPENMPI_NAME}-${OPENMPI_VERSION}\' \
                    --define \'root_path ${BUILD_ROOT}\' \
                    $OPENMPI_SRC_RPM
            
            ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${OPENMPI_RPM} $RPMS"
            ex "$RPM -Uhv ${RPMS}/${OPENMPI_RPM}"
            let rpm_cnt++
            if [ "$mpitests" == "y" ]; then
                echo
                echo "Building the mpitests RPM over Open MPI using the ${mpi_comp} compiler. Please wait..."
                echo
                MPITESTS_RPM=${MPITESTS_NAME}_${OPENMPI_NAME}_${mpi_comp}-${MPITESTS_VERSION}.${build_arch}.rpm
                ex rpmbuild --rebuild \
                    --define \'_topdir ${RPM_DIR}\' \
                    --define \'_name ${MPITESTS_NAME}_${OPENMPI_NAME}_${mpi_comp}\' \
                    --define \'path_to_mpihome ${STACK_PREFIX}/mpi/${mpi_comp}/${OPENMPI_NAME}-${OPENMPI_VERSION}\' \
                    --define \'root_path ${BUILD_ROOT}\' \
                    $MPITESTS_SRC_RPM
                ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${MPITESTS_RPM} $RPMS"
                ex "$RPM -Uhv ${RPMS}/${MPITESTS_RPM}"
                let rpm_cnt++
            fi
        done
    
    else
            for mpi_comp in ${MPI_COMPILER_openmpi}
            do
                OPENMPI_RPM=${OPENMPI_NAME}_${mpi_comp}-${OPENMPI_VERSION}.${build_arch}.rpm
            
                if [ -f ${RPMS}/${OPENMPI_RPM} ]; then
                    ex "$RPM -Uhv ${RPMS}/${OPENMPI_RPM}"
                    let rpm_cnt++
                else
                    echo "${RPMS}/${OPENMPI_RPM} not found"
                fi
                if [ "$mpitests" == "y" ]; then
                    MPITESTS_RPM=${MPITESTS_NAME}_${OPENMPI_NAME}_${mpi_comp}-${MPITESTS_VERSION}.${build_arch}.rpm
                    if [ -f ${RPMS}/${MPITESTS_RPM} ]; then
                        ex "$RPM -Uhv ${RPMS}/${MPITESTS_RPM}"
                        let rpm_cnt++
                    fi  
                fi
            done
    fi        

    if [ $rpm_cnt -eq 0 ]; then
        err_echo "Open MPI RPMs are not installed"
        return 1
    fi    

    return 0
}


#
#   Remove a previously installed stack (if one exists)
#   Install the new stack RPMs. Also copy Documentation and useful scripts
#
make_install()
{
    
    if [[ -n "$OPENIB_PACKAGES" || -n "$EXTRA_PACKAGES" ]]; then
            rmInstalled
    fi                

    echo
    echo "Installing ${PACKAGE} software into $STACK_PREFIX"
    echo

    ex_silent "mkdir -p $STACK_PREFIX"

    if [ ! -e $STACK_PREFIX/uninstall.sh ]; then
        ex_silent "$CP $PKG_SOURCE_DIR/uninstall.sh $STACK_PREFIX/uninstall.sh"
        perl -ni -e "s@(STACK_PREFIX=).*@\$1${STACK_PREFIX}@; print" $STACK_PREFIX/uninstall.sh
    fi
            
    if [ -n "$OPENIB_PACKAGES" ]; then
            # install openib RPMs
            openib
    fi        
    
    for package in $EXTRA_PACKAGES
    do
    case $package in
        mpitests)
        # Nothing to be done: RPM created/installed from OSU/Open MPI
        ;;
        *)
        $package
        ;;
        esac
    done
    
    return 0
}

# Uninstall Software
uninstall()
{
    local RUN_CLEAN=0
    local no_count=0
    local RC=0

    # Get the list of installed packages and select packages to uninstall
    if isInstalled ib-verbs || isInstalled openib || isInstalled libibverbs || isInstalled "kernel-ib"; then
        echo -n "Do you want to remove all ${PACKAGE} software? [y/N]:"
        if ! get_ans; then
            echo
            echo "Checking for installed ${PACKAGE} Software..."
            echo

            packs_to_remove=""
            for package in $ALL_PACKAGES $PREV_RELEASE_PACKAGES
            do
                if [ "X${package}" == "Xmpi_osu" ]; then
                    MPI_OSU_LIST=$(rpm -qa | grep ${MPI_OSU_MPICH_NAME})
                    for mpi in ${MPI_OSU_LIST}
                    do
                        echo -n "Remove ${mpi} [y/N]?"
                        if get_ans; then
                            packs_to_remove="$packs_to_remove ${mpi}"
                            let RC++
                        else
                            let no_count++
                        fi        
                    done
                elif [ "X${package}" == "Xopenmpi" ]; then
                    OPENMPI_LIST=$(rpm -qa | grep ${OPENMPI_NAME})
                    for mpi in $OPENMPI_LIST
                    do 
                        echo -n "Remove ${mpi} [y/N]?"
                        if get_ans; then
                            packs_to_remove="$packs_to_remove ${mpi}"
                            let RC++
                        else
                            let no_count++
                        fi        
                    done    
                else
                    if ( $RPM -q ${package} > $NULL 2>&1 ); then
                        echo -n "Remove ${package} [y/N]?"
                        if get_ans; then
                            packs_to_remove="$packs_to_remove ${package}"
                            let RC++
                        else
                            let no_count++
                        fi        
                    fi
                fi
            done    
            
            if [ $no_count -eq 0 ]; then
                RUN_CLEAN=1
            fi
    
        else # All ${PACKAGE} Software selected to be removed
                echo -n "Are you sure? [y/N]:"
                if get_ans; then
                    # Set all packages to be removed
                    packs_to_remove=""
                    for package in $ALL_PACKAGES $PREV_RELEASE_PACKAGES $IB_KERNEL_UTILS
                    do
                        if [ "X${package}" == "Xmpi_osu" ]; then
                            MPI_OSU_LIST=$(rpm -qa | grep ${MPI_OSU_MPICH_NAME})
                            for mpi in ${MPI_OSU_LIST}
                            do
                                 packs_to_remove="$packs_to_remove ${mpi}"
                                 let RC++
                            done
                        elif [ "X${package}" == "Xopenmpi" ]; then
                            OPENMPI_LIST=$(rpm -qa | grep ${OPENMPI_NAME})
                            for mpi in $OPENMPI_LIST
                            do 
                                packs_to_remove="$packs_to_remove ${mpi}"
                                let RC++
                            done    
                        else
                            if ( $RPM -q ${package} > $NULL 2>&1 ); then
                                 packs_to_remove="$packs_to_remove ${package}"
                                 let RC++
                            fi
                        fi
                    done
                    RUN_CLEAN=1
                else
                    return 1
                fi
        fi
    else
        warn_echo There are no ${PACKAGE} packages installed
        getch
        return 1
    fi  
      
    # Run Uninstall
    
    if [ -n "${packs_to_remove}" ]; then   
        ex $RPM -e ${packs_to_remove}
    fi
    
    if [ $RUN_CLEAN -eq 1 ]; then
        clean
    fi

    if [ $RC -gt 0 ]; then
        echo
        pass_echo "$RC packages were removed successfully"
        echo
        getch
    else 
        echo
        warn_echo "No packages selected to be removed"
        getch    
    fi    

    return 0
}

#
# Edit /etc/infiniband/openib.conf
# It is possible to redefine the default values of modules' on-boot load parameters.
# This can be done by defining the new values in the ${PACKAGE}.conf file when running unattended installation,
# or by exporting those variables in the shell before running an interactive installation
#
set_config_openib()
{
    local OPENIB_CONF="/etc/infiniband/openib.conf"

    if [ ! -e ${OPENIB_CONF} ]; then
        return 1
    fi

    # Define OPENIB_ONBOOT="yes" or "no" (default "yes")
    if [ ! -z "${OPENIB_ONBOOT}" ]; then
        case "${OPENIB_ONBOOT}" in
            yes|no)
                perl -ni -e "s@^(ONBOOT=).*@\${1}${OPENIB_ONBOOT}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define IPOIB_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${IPOIB_LOAD}" ]; then
        case "${IPOIB_LOAD}" in
            yes|no)
                perl -ni -e "s@^(IPOIB_LOAD=).*@\${1}${IPOIB_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define UCM_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${UCM_LOAD}" ]; then
        case "${UCM_LOAD}" in
            yes|no)
                perl -ni -e "s@^(UCM_LOAD=).*@\${1}${UCM_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define RDMA_CM_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${RDMA_CM_LOAD}" ]; then
        case "${RDMA_CM_LOAD}" in
            yes|no)
                perl -ni -e "s@^(RDMA_CM_LOAD=).*@\${1}${RDMA_CM_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define RDMA_UCM_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${RDMA_UCM_LOAD}" ]; then
        case "${RDMA_UCM_LOAD}" in
            yes|no)
                perl -ni -e "s@^(RDMA_UCM_LOAD=).*@\${1}${RDMA_UCM_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define MTHCA_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${MTHCA_LOAD}" ]; then
        case "${MTHCA_LOAD}" in
            yes|no)
                perl -ni -e "s@^(MTHCA_LOAD=).*@\${1}${MTHCA_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define IPATH_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${IPATH_LOAD}" ]; then
        case "${IPATH_LOAD}" in
            yes|no)
                perl -ni -e "s@^(IPATH_LOAD=).*@\${1}${IPATH_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define ISER_LOAD="yes" or "no" (default "yes")
    if [ ! -z "${ISER_LOAD}" ]; then
        case "${ISER_LOAD}" in
            yes|no)
                perl -ni -e "s@^(ISER_LOAD=).*@\${1}${ISER_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

#    # Define RDS_LOAD="yes" or "no" (default "yes")
#    if [ ! -z "${RDS_LOAD}" ]; then
#        case "${RDS_LOAD}" in
#            yes|no)
#                perl -ni -e "s@^(RDS_LOAD=).*@\${1}${RDS_LOAD}@; print" ${OPENIB_CONF}
#            ;;
#        esac
#    fi

    # Define SDP_LOAD="yes" or "no" (default "no")
    if [ ! -z "${SDP_LOAD}" ]; then
        case "${SDP_LOAD}" in
            yes|no)
                perl -ni -e "s@^(SDP_LOAD=).*@\${1}${SDP_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

    # Define SRP_LOAD="yes" or "no" (default "no")
    if [ ! -z "${SRP_LOAD}" ]; then
        case "${SRP_LOAD}" in
            yes|no)
                perl -ni -e "s@^(SRP_LOAD=).*@\${1}${SRP_LOAD}@; print" ${OPENIB_CONF}
            ;;
        esac
    fi

}

# Edit /etc/opensm.conf
set_config_opensm()
{
        # Edit /etc/opensm.conf
    if [ ! -z "${OSM_HOSTS_LIST}" ]; then
        for OPENSM_HOST in ${OSM_HOSTS_LIST}
        do
                if [[ -n "`$IFCONFIG | grep -w $OPENSM_HOST`"  || -n "`grep -rw $OPENSM_HOST ${NETWORK_CONF_DIR}`" ]]; then
                    perl -ni -e "s@^(ONBOOT=).*@\${1}yes@; print" /etc/opensm.conf
                    
#                    # Enlarge QP1 size on OpenSM server
#                    if [ -e /etc/modules.conf ]; then
#                            perl -ni -e "s@^(options ib_mad ib_outs_mad_recv_entries=).*@\${1}15000@; print" /etc/modules.conf
#                    fi
#                    
#                    if [ -e /etc/modprobe.conf ]; then
#                            perl -ni -e "s@^(options ib_mad ib_outs_mad_recv_entries=).*@\${1}15000@; print" /etc/modprobe.conf
#                    fi
                    
                    break
                else
                    perl -ni -e "s@^(ONBOOT=).*@\${1}no@; print" /etc/opensm.conf
                fi
        done
        
        perl -ni -e "s@^(OSM_HOSTS=).*@\${1}\"${OSM_HOSTS_LIST}\"@; print" /etc/opensm.conf
    fi
    
    return 0
}

# Set configuration parameters and perform basic checks
pre_install()
{
        check_user
        
       # Check STACK_PREFIX for existing RPMs
        if [ -e ${RPMS}/ib-verbs-${OPENIB_VER}-${RPMK_VER}.${build_arch}.rpm ]; then
            STACK_PREFIX=`$RPM -qlp ${RPMS}/ib-verbs-${OPENIB_VER}-${RPMK_VER}.${build_arch}.rpm | grep "utils/create_devs" | sed -e 's/\/utils\/create_devs//'`
            . $CWD/build_env.sh    
        fi

        prefchk=$(/bin/ls -1 ${RPMS}/libibverbs-[0-9]*.${build_arch}.rpm  2> $NULL | head -1)
        if [[ -n "${prefchk}" && -e ${prefchk} ]]; then
            RPM_STACK_PREFIX=$($RPM -qlp ${prefchk} | grep "libibverbs.so" | head -1 | sed -e 's@/lib.*/libibverbs.so.*@@')
        else
            RPM_STACK_PREFIX=$STACK_PREFIX
        fi
        
        # Check for InfiniBand software of other vendors
        local vendors="iview_fm|ibhost-hpc"
        local vrpms=""
        
        vrpms=$($RPM -qa | grep -E "${vendors}")
        if [ -n "$vrpms" ]; then
            echo
            err_echo "You must remove the following InfiniBand software before continuing:"
            echo
            echo "$vrpms"
            echo
            exit 9
        fi
    
}

# Run interactive installation mode
interactive()
{
           local ans_inst=""
           show_menu "main_menu"
            
                read ans_inst
                case $ans_inst in
                        2)   
                             if ! select_packages; then
                                 interactive
                             fi    
                             set_package_deps
                             check_run_dependencies        
                          
                             if isInstalled "thca-linux" || isInstalled "openib" || isInstalled "ib-verbs" ||
                                isInstalled "libibverbs" || isInstalled "kernel-ib"; then
                                     echo
                                     warn_echo "This installation program will remove any previously installed IB packages on your machine."
                                     echo
                                     read -p "Do you want to continue? [Y/n]:" ans_r
                                     if ! [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                         return 1
                                     fi
                             fi
                             
                             # Check if all required RPM packages exist
                             # If not, run build.sh script with the created configuration file
                             if ! is_rpms; then
                                
                                     echo
                                     pass_echo "Preparing to build the ${PACKAGE} RPMs:"
                                     echo

                                     include_ifcfg

                                     echo
                                     echo "RPM build process requires a temporary directory."
                                     echo
                                     read -p "Please enter the temporary directory [${BUILD_ROOT}]:"
                                     BUILD_ROOT=${REPLY:-$BUILD_ROOT}
             
                                     if [ "${BUILD_ROOT}" != "${BUILD_ROOT_DFT}" ]; then
                                            BUILD_ROOT=${BUILD_ROOT}/${PACKAGE}
                                     fi
                                     
                                     [ -d $BUILD_ROOT ] && ex_silent "$RM -rf $BUILD_ROOT"
                                     
                                     check_space_req "$BUILD_SPACE_REQ" "$BUILD_ROOT"
                                     
                                     echo
                                     read -p "Please enter the ${PACKAGE} installation directory [${STACK_PREFIX}]:"
                                     STACK_PREFIX=${REPLY:-$STACK_PREFIX}
             
                                     # Set  parameters with new values
                                     . $CWD/build_env.sh
                                     
                                     check_space_req "$RUN_SPACE_REQ" "$STACK_PREFIX"
             
                                     # Update CONFIG file
                                     perl -ni -e "s@(BUILD_ROOT=).*@\$1${BUILD_ROOT}@; print" $CONFIG
                                     perl -ni -e "s@(STACK_PREFIX=).*@\$1${STACK_PREFIX}@; print" $CONFIG
                                     
                                     ${CWD}/build.sh -c $CONFIG
                                     if [ $? -ne 0 ]; then
                                         exit 1
                                     fi
                                     
                                     if [ "${BUILD_ROOT}" != "${BUILD_ROOT_DFT}" ]; then
                                         read -p  "Do you want to remove the temporary build directory $BUILD_ROOT [Y/n]?" ans_r
                                         if [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                             $RM -rf $BUILD_ROOT
                                         fi
                                     fi    
                             else
                                    # Check STACK_PREFIX for existing RPMs
                                    if [ -n "${RPM_STACK_PREFIX}" ]; then
                                       STACK_PREFIX="${RPM_STACK_PREFIX}"
                                    fi
                                    . $CWD/build_env.sh    
                                     
                                    echo   
                                    echo
                                    echo "The default installation directory for ${PACKAGE} Software is ${STACK_PREFIX}"
                                    read -p "Do you want to continue? [Y/n]:" ans_r
                                    if ! [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                        return 1
                                    fi
                                
                             fi
                             
                             if make_install; then

                                    # Set ipoib configuration
                                    if isInstalled kernel-ib && ( echo "$OPENIB_KERNEL_PACKAGES" | grep ipoib > $NULL 2>&1 ) && [ $INCLUDE_IFCFG -eq 1 ]; then 
                                        read -p  "Do you want to configure IPoIB interfaces [Y/n]?" ans_r
                                        if [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                            echo
                                            pass_echo "Configuring IPoIB:"
                                            echo
                                    
                                            set_ip
                                        fi
                                    fi                                       
                                    
                                    # Set OpenSM configuration
                                    if isInstalled opensm && ( echo "$OPENIB_PACKAGES" | grep "opensm" > $NULL 2>&1 ); then
                                        read -p  "Do you want to configure OpenSM [Y/n]?" ans_r
                                        if [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                            echo
                                            pass_echo "Configuring OpenSM:"
                                            echo

                                            osmconf
                                            set_config_opensm
                                        fi
                                    fi    

                                    pass_echo "Installation finished successfully..."
                                    getch
                                    
                             fi
                        ;;
                        3)
                            echo
                            showInstalled
                            echo
                            getch
        
                        ;;
                        4)
                            if ! isInstalled kernel-ib; then
                                echo
                                err_echo "You need to install the InfiniBand Software first! "
                                echo
                                getch
                                return 1
                            fi
                            
                            if isInstalled kernel-ib; then
                                set_ip
                            fi

                            if isInstalled opensm; then
                                osmconf
                                set_config_opensm
                            fi
                                
                            getch
                        ;;
                        5)
                            echo
                            uninstall
                            let NEED_REBOOT++
                        ;;
                        1)
                            view_readme
                        ;;
                        6)
                            ${CWD}/build.sh
                            if [ $? -ne 0 ]; then
                                exit 1
                            fi
                        ;;    
                        Q|q)
                            close_log    
                            exit 0
                        ;;
                        *)
                            return 1
                        ;;
                esac

}

# Run unattended installation mode
unattended()
{
        check_space_req "$RUN_SPACE_REQ" "$STACK_PREFIX"
        select_packages
        set_package_deps
        check_run_dependencies
        
        # Check if all required RPM packages exist
        # If not, run the build.sh script with the created configuration file
        if ! is_rpms || [ "X${RPM_STACK_PREFIX}" != "X${STACK_PREFIX%*/}" ]; then
           ${CWD}/build.sh -c $CONFIG
           if [ $? -ne 0 ]; then
               exit 1
           fi
           # Reread the config file (needed if the config file was changed by build.sh )
           . $CONFIG
        fi
        if make_install; then
            if isInstalled kernel-ib && ( echo "$OPENIB_KERNEL_PACKAGES" | grep ipoib > $NULL 2>&1 ); then
                set_ip
            fi
    
            if isInstalled opensm && ( echo "$OPENIB_PACKAGES" | grep opensm > $NULL 2>&1 ); then
                set_config_opensm
            fi
            pass_echo "Installation finished successfully..."

        fi

}

###
### Main
###

main()
{
        
        pre_install
        
        if [ $INTERACTIVE -eq 1 ]; then
            interactive
        else
            unattended
        fi
        
        set_config_openib
        
        if [ "$RPM_DIR" == "$RPM_DIR_DFT" ]; then
            ex_silent "$RM -rf $RPM_DIR"
        fi
        return 0
}

open_log
while true
do
    main
    if [ $INTERACTIVE -eq 0 ]; then
        exit 0
    fi    
done    
