#! /bin/bash
#
# Start, Stop, Restart the QLogic VNIC service
#
# Handles loading, unloading of the VNIC driver and triggers creation
# of the VNIC interfaces by invoking qlgc_vnic_parser.pl, which parses the
# VNIC configuration file and creates the VNIC interfaces.
#
# Copyright (c) 2007 QLogic, Inc.  All rights reserved.
#
# This software is available to you under a choice of one of two
# licenses.  You may choose to be licensed under the terms of the GNU
# General Public License (GPL) Version 2, available from the file
# COPYING in the main directory of this source tree, or the
# OpenIB.org BSD license below:
#
#     Redistribution and use in source and binary forms, with or
#     without modification, are permitted provided that the following
#     conditions are met:
#
#      - Redistributions of source code must retain the above
#        copyright notice, this list of conditions and the following
#        disclaimer.
#
#      - Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials
#        provided with the distribution.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#
# config: /etc/infiniband/qlogic_vnic.cfg (or /etc/sysconfig/ics_inic.cfg)
# pidfile: /var/lock/subsys/ics_inic

PATH=$PATH:/sbin:/usr/bin
if [ -e /etc/profile.d/ofed.sh ]; then
        . /etc/profile.d/ofed.sh
fi

MODULE_IB=qlgc_vnic
MODULE_HCA=ib_mthca
MODULE_UMAD=ib_umad
CONFIG_FILE=/etc/infiniband/qlogic_vnic.cfg
DIR_PROC=/tmp
CHECK_LOAD=/tmp/qlogic.mod_ib
SCRIPT="qlgc_vnic_parser.pl -v"
UDEV=/dev/infiniband/umad0	
DEL=/sys/class/infiniband_qlgc_vnic/interfaces/delete_vnic
DIR=/sys/class/infiniband_qlgc_vnic/interfaces/


if [ -z "${BOOTUP:-}" ]; then
  if [ -f /etc/sysconfig/init ]; then
      . /etc/sysconfig/init
  else
    # This all seem confusing? Look in /etc/sysconfig/init,
    # or in /usr/doc/initscripts-*/sysconfig.txt
    BOOTUP=color
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \\033[0;39m"
    LOGLEVEL=1
  fi
  if [ "$CONSOLETYPE" = "serial" ]; then
      BOOTUP=serial
      MOVE_TO_COL=
      SETCOLOR_SUCCESS=
      SETCOLOR_FAILURE=
      SETCOLOR_WARNING=
      SETCOLOR_NORMAL=
  fi
fi

if [ "${BOOTUP:-}" != "verbose" ]; then
   INITLOG_ARGS="-q"
else
   INITLOG_ARGS=
fi


test -f  || exit 0

echo_success() {
  echo -n $@
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
  echo -n "[  "
  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
  echo -n $"OK"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo -n "  ]"
  echo -e "\r"
  return 0
}

echo_failure() {
  echo -n $@
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
  echo -n "["
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo -n $"FAILED"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo -n "]"
  echo -e "\r"
  return 1
}

echo_log() {
	logger $@ -p user.err
	echo "Please refer to /var/log/messages"	
}

print_status()
{
	if [ $1 -eq 0 ]
	then
		echo_log "Success"
	else
		echo_log "Failure"
	fi
	echo_log ""
}

load_module()
{
	
	if lsmod | grep "^$*" >/dev/null 2>&1 ; then
		return 0;
	fi		
	# try to silently load
	modprobe $* >/dev/null 2>&1
	res=$?
	echo  $* >> $CHECK_LOAD
	
	if [ $res != 0 ]
	then
		# if fails, try again and log failures
		modprobe $* 2>&1|logger -s -p kern.err
		res=$?
	fi
	return $res
}

function load_modules()
{
	load_module $MODULE_IB $RESOURCES
		res=$?
	if [ $res != 0 ] ; then
		modprobe -r $MODULE > /dev/null 2>&1
		return 1
	fi
	load_module $MODULE_UMAD $RESOURCES
		res=$?
	if [ $res != 0 ] ; then
		modprobe -r $MODULE_UMAD > /dev/null 2>&1
		return 1
	fi
	load_module $MODULE_HCA $RESOURCES
		res=$?
	if [ $res != 0 ] ; then
		modprobe -r $MODULE_HCA > /dev/null 2>&1
		return 1
	fi	
	return 0
}

function remove_modules()
{
	modprobe -r $MODULE_IB
    # Unload hisax modules
	if [  -f $CHECK_LOAD ] ; then
		if lsmod | grep "^$MODULE_HCA" >/dev/null 2>&1 ; then
			if cat $CHECK_LOAD | grep "^$MODULE_HCA" >/dev/null 2>&1 ; then
				modprobe -r $MODULE_HCA
			fi
		fi

		if lsmod | grep "^$MODULE_UMAD" >/dev/null 2>&1 ; then
			if cat $CHECK_LOAD | grep "^$MODULE_UMAD" >/dev/null 2>&1 ; then
				modprobe -r $MODULE_UMAD
			fi
		fi
	fi
	echo_success		
		
}

function load_config()
{
    if [ ! -d $DIR_PROC ]
    then
        echo 
        echo "** ERROR ** Unable to access $CONFIG_PROC. Make sure"
	echo "you do not have the $DIR_PROC directory open, and retry."
        echo
        remove_modules
        return 1
    fi
    cat $CONFIG_FILE > $CONFIG_PROC
    return 0
}

function start()
{
# load modules
    echo -n "Starting Virtual NIC"
    if load_modules ; then
 	echo_success
	echo -n "Creating  QLogic VNIC interfaces"
        # load the configuration
	if [ -e $UDEV ] ; then
	   true
	else
	   udevstart		
	fi

	  $SCRIPT > /dev/null 2>&1
	     res=$?	
	    	 
	    if [ $res = 127 ]; then
		echo_failure	
		echo_log "Cannot execute $SCRIPT"
		return
	    fi
	    if [ $res != 0 ]; then
		if [ $res == 2 ]; then
			echo_success
			echo "Created Virtual interfaces but with errors"
			echo "Please refer to /var/log/messages"
			return
		fi
		echo_failure
		echo_log "$0: Error in configuring QLogic VNIC"
	    else
		echo_success
	    fi  			
            touch /var/lock/subsys/ql_vnic
     else
	echo_failure
	echo_error "$0: Loading kernel modules failed"
	
    fi
}

function stop()
{
	echo -n "Stopping Virtual NIC" 
	remove_modules	
	rm -f /var/lock/subsys/ql_vnic
	rm -f $CONFIG_PROC		
	rm -f $CHECK_LOAD	
}

function restart()
{
	stop
	start
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    *)
       echo_log $"Usage: $0 {start|stop|restart}"
       exit 1
esac

exit 0
