#!/bin/bash

#/*******************************************************************
# * This file is part of the Emulex HBA Manager remote              *
# * management configuration application for Emulex Fibre           *
# * Channel Host Bus Adapters.                                      *
# * Copyright (c) 2003-2021 Broadcom. All Rights Reserved.          *
# * The term "Broadcom" refers to Broadcom Inc. and/or              *
# * its subsidiaries.                                               *
# *                                                                 *
# * www.broadcom.com                                                *
# *                                                                 *
# * Description:                                                    *
# * Invoked from RMAPI after setting linux driver parameter         *
# * (adding entry to elx-lpfc.conf) to recreate the linux system    *
# * initial ram disk.                                               *
# *                                                                 *
# * The lpfc driver loads so early in the machine boot cycle,       *
# * that it will not receive the new parameter value unless the     *
# * updated elx-lpfc.conf is reinserted into the ram disk.          *
# *                                                                 *
#/*******************************************************************
#

exec_command()
{
    local TEMPFILE
    RETURNVALUE=0
    if [ "$2" = background ] ; then
        TEMPFILE=`mktemp /tmp/elx-lpfc-install.XXXXXX`
        (eval $1 ; echo "RETURNVALUE=$?" >> ${TEMPFILE}) &
        while [ -e ${TEMPFILE} ] && [ ! -s ${TEMPFILE} ] ; do
            sleep 3
            echo -en "."
        done
        . ${TEMPFILE}
        rm -f ${TEMPFILE}
    else
        eval $1
        RETURNVALUE=$?
    fi
    echo -en "\n"
    return ${RETURNVALUE}
}

# Function:  backup_files_to_elx()
#
# Description:
#   Copy each file passed as a parameter to filename.elx.
#
# Parameters:
#   A list of filenames to back up.
#
# Returns:
#   Nothing.
backup_files_to_elx()
{
    for i in $@ ; do
    if [ -e $i ] ; then
        cp -f $i $i.elx
        if [ $? -ne 0 ] ; then
            echo "Error $? copying $i to $i.elx"
        else
            echo "Original ramdisk image $i saved as $i.elx"
        fi
    fi
    done
}

# Function:  create_ramdisk()
#
# Description:
#   Creates a ramdisk image for the currently running kernel.
#
# Parameters:
#   none.
#
# Returns:
#   Nothing.
create_ramdisk()
{
    UNAME=$(uname -r)
    ARCH=$(uname -m)
    
    if [ ${DISTRIBUTION} = "redhat" ] || [ ${DISTRIBUTION} = "asianux" ] || [ ${DISTRIBUTION} = "powerkvm" ]; then
        # Configure ramdisk for Red Hat Linux, Asian Linux, or PowerKVM
        if [ ${DISTRIBUTION} = "redhat" ]; then
            RH_VERSION_MAJOR=$(cat /etc/redhat-release | sed "s/[^0-9\.]//g" | awk -F. '{print $1}')
        elif [ ${DISTRIBUTION} = "asianux" ]; then
            RH_VERSION_MAJOR=$(cat /etc/asianux-release | sed "s/[^0-9\.]//g" | awk -F. '{print $1}')
        else
            #Treat powerkvm like RHEL7
            RH_VERSION_MAJOR=7
        fi
        
        INITRDFILE="/boot/initramfs-${UNAME}.img"
        
        if [ -f /usr/bin/dracut ]; then
            DRACUT_BIN="/usr/bin/dracut"
        elif [ -f /sbin/dracut ]; then
            DRACUT_BIN="/sbin/dracut"
        else
            DRACUT_BIN="dracut"
        fi
        
        backup_files_to_elx ${INITRDFILE}
        echo -n "Creating ramdisk ."
        
        exec_command "${DRACUT_BIN} -f ${INITRDFILE} ${UNAME}" background
        if [ $? -ne 0 ]; then
            echo "Could not create ramdisk image.  Restoring original ramdisk..."
            cp -f ${INITRDFILE}.elx ${INITRDFILE}
            CP_STATUS=$?
            
            if [ $CP_STATUS -eq 0 ] ; then
                echo "Original ramdisk restored."
            else
                echo "Original ramdisk could not be restored - error $CP_STATUS"
            fi
            exit 1
        fi
    elif [ ${DISTRIBUTION} = "suse" ]; then
        # Configure ramdisk configuration file for SuSE Linux Enterprise Server.
        INITRDFILE="/boot/initrd-${UNAME}"
		
        # SLES 15 SP0/SP1, SLES 12 SP4/SP5
        if [ -f /usr/bin/dracut ]; then
            DRACUT_BIN="/usr/bin/dracut"
        elif [ -f /sbin/dracut ]; then
            DRACUT_BIN="/sbin/dracut"
        else
            DRACUT_BIN="dracut"
        fi
        
        backup_files_to_elx ${INITRDFILE}
        
        echo -n "Creating ramdisk ."
        
        exec_command "${DRACUT_BIN} -qf ${INITRDFILE} ${UNAME}" background
        if [ $? -ne 0 ]; then
            echo "Could not create ramdisk image.  Restoring original ramdisk..."
            cp -f ${INITRDFILE}.elx ${INITRDFILE}
            CP_STATUS=$?
            
            if [ $CP_STATUS -eq 0 ] ; then
                echo "Original ramdisk restored."
            else
                echo "Original ramdisk could not be restored - error $CP_STATUS"
            fi
            exit 1
        fi
    elif [ ${DISTRIBUTION} = "debian" ]; then
        # Configure ramdisk for Debian.
        INITRDFILE="/boot/initrd.img-${UNAME}"
        backup_files_to_elx ${INITRDFILE}
        echo -n "Creating ramdisk ."
        exec_command "sudo update-initramfs -u -v -k ${UNAME}" background
        if [ $? -ne 0 ]; then
            echo "Could not create ramdisk image.  Restoring original ramdisk ..."
            cp -f ${INITRDFILE}.elx ${INITRDFILE}
            echo "Original ramdisk restored."
            echo ""
            echo "Please run uninstall to remove any partially"
            echo "installed components of the Emulex driver and utility applications."
            exit 1
        fi
    elif [ ${DISTRIBUTION} = "xenserver" ]; then
        XS_VERSION_MAJOR=$(cat /etc/redhat-release | sed "s/[^0-9\.]//g" | awk -F. '{print $1}')
        INITRDFILE="/boot/initrd-${UNAME}.img"
        
        backup_files_to_elx ${INITRDFILE}
        echo -n "Creating ramdisk ."
        if [ -x /bin/mkinitrd ]; then
            MKINITRD_CMD="/bin/mkinitrd"
        elif [ -x /sbin/mkinitrd ]; then
            MKINITRD_CMD="/sbin/mkinitrd"
        else
            MKINITRD_CMD="mkinitrd"
        fi
        
        exec_command "${MKINITRD_CMD} --allow-missing -f ${INITRDFILE} ${UNAME}" background
        
        if [ $? -ne 0 ] ; then
            echo "Could not create ramdisk image.  Restoring original ramdisk ..."
            cp -f ${INITRDFILE}.elx ${INITRDFILE}
            echo "Original ramdisk restored."
            echo ""
            echo "Please run uninstall to remove any partially"
            echo "installed components of the Emulex driver and utility applications."
            exit 1
        fi
    elif [[ ${DISTRIBUTION} = "openEuler" ]]; then       
        INITRDFILE="/boot/initramfs-${UNAME}.img"

        if [ -f /usr/bin/dracut ]; then
            DRACUT_BIN="/usr/bin/dracut"
        else
            DRACUT_BIN="dracut"
        fi

        backup_files_to_elx ${INITRDFILE}
        echo -n "Creating ramdisk ."

        exec_command "${DRACUT_BIN} -f ${INITRDFILE} ${UNAME}" background
        if [ $? -ne 0 ]; then
            echo "Could not create ramdisk image.  Restoring original ramdisk..."
            cp -f ${INITRDFILE}.elx ${INITRDFILE}
            CP_STATUS=$?

            if [ $CP_STATUS -eq 0 ] ; then
                echo "Original ramdisk restored."
            else
                echo "Original ramdisk could not be restored - error $CP_STATUS"
            fi
            exit 1
        fi
    fi

    return 0
}

print_help()
{
    echo ""
    echo "  The following option must be used:"
    echo ""
    echo "   --createramdisk   - Create a new ramdisk image.  Use this option after"
    echo "                        you have modified driver parameters in the"
    echo "                        /etc/modprobe.conf file."
    echo ""
}

if [ $# -eq 0 ] ; then
    print_help
    exit 1
fi

echo "Determining distribution type..."

# Check for XenServer before checking for Red Hat
if [ -f /etc/xensource-inventory ]; then
    DISTRIBUTION=xenserver
elif [ -f /etc/asianux-release ]; then
    DISTRIBUTION=asianux
elif [ -f /etc/redhat-release ]; then
    DISTRIBUTION=redhat
elif [ -f /etc/ibm_powerkvm-release ]; then
    DISTRIBUTION=powerkvm
elif [[ -f /etc/SuSE-release || -f /etc/SUSE-brand ]]; then
    DISTRIBUTION=suse
elif [ -f /etc/debian_version ]; then
    DISTRIBUTION=debian
elif [ -f /etc/openEuler-release ]; then
    DISTRIBUTION=openEuler
else
    echo ""
    echo "Unable to determine distribution type"
    exit 1
fi

if [ "$1" = "--createramdisk" ]; then
    create_ramdisk
else
    print_help
    exit 1
fi
 
exit 0
