#!/bin/bash

#/*******************************************************************
# * This file is part of the Emulex OneCommand Manager remote       *
# * management configuration application for Emulex Fibre           *
# * Channel Host Bus Adapters.                                      *
# * Copyright (C) 2003-2016 Emulex.  All rights reserved.           *
# *                                                                 *
# * www.emulex.com                                                  *
# *                                                                 *
# * Description:                                                    *
# * Invoked from RMAPI after setting linux driver parameter         *
# * (adding entry to modprobe.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 modprobe.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
        
        if [ ${RH_VERSION_MAJOR} -ge 6 ]; then
            INITRDFILE="/boot/initramfs-${UNAME}.img"
        else
            INITRDFILE="/boot/initrd-${UNAME}.img"
        fi
        
        backup_files_to_elx ${INITRDFILE}
        echo -n "Creating ramdisk ."
        if [ ${RH_VERSION_MAJOR} -ge 6 ]; then
            exec_command "/sbin/dracut -f ${INITRDFILE} ${UNAME}" background
        else
            exec_command "/sbin/mkinitrd --allow-missing -f ${INITRDFILE} ${UNAME}" background
        fi
        if [ $? -ne 0 ] ; then
            echo "Could not create ramdisk image.  Restoring original ramdisk ..."
            cp -f /boot/initrd-${UNAME}.img.elx /boot/initrd-${UNAME}.img
            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} = "suse" ]; then
        # Configure ramdisk configuration file for SuSE Linux Enterprise Server.
        if [ ${ARCH} = "ppc64" ] || [ ${ARCH} = "ppc64le" ]; then
            INITRDFILE="/boot/initrd"
            SLES_KERNEL_IMAGE=vmlinux
        else
            INITRDFILE="/boot/initrd /boot/initrd.shipped"
            SLES_KERNEL_IMAGE=vmlinuz
        fi
        backup_files_to_elx ${INITRDFILE}

        echo -n "Creating ramdisk ."
        
        if [ -x /sbin/mkinitrd ]; then
            exec_command "/sbin/mkinitrd -i initrd-${UNAME} -k ${SLES_KERNEL_IMAGE}-${UNAME} >/dev/null 2>&1" background
        else
            exec_command "/sbin/mk_initrd -i initrd-${UNAME} -k ${SLES_KERNEL_IMAGE}-${UNAME} >/dev/null 2>&1" background
        fi
        if [ $? -ne 0 ]; then
            echo "Could not create ramdisk image.  Restoring original ramdisk ..."
            cp -f /boot/initrd.shipped.elx /boot/initrd.shipped && cp -f /boot/initrd.elx /boot/initrd
            if [ $? -eq 0 ] ; then
                echo "Original ramdisks restored."
            else
                echo "Original ramdisks could not be restored - error $?"
            fi
            echo ""
            echo "Please run uninstall to remove any partially"
            echo "installed components of the Emulex driver and utility applications."
            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
    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 ]; then
    DISTRIBUTION=suse
elif [ -f /etc/debian_version ]; then
    DISTRIBUTION=debian
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
