#! /bin/sh
# chkconfig: - 13 87
# description: iSCSI daemon

# Source function library.
[ -f /etc/init.d/functions ] || exit 0
. /etc/init.d/functions

[ -f /etc/sysconfig/iscsi ] && . /etc/sysconfig/iscsi

BASEDIR=/
PIDFILE=/var/run/iscsid.pid

#Timeouts to be used during iscsi startup
STARTUPTIMEOUT=${STARTUPTIMEOUT:-5}
ESTABLISHTIMEOUT=${ESTABLISHTIMEOUT:-30}

#Timeouts to be used during iscsi shutdown
CONNFAILTIMEOUT=${CONNFAILTIMEOUT:-30}
DISKCOMMANDTIMEOUT=${DISKCOMMANDTIMEOUT:-5}

iscsi_network_boot()
{
	mtab=/etc/mtab
	iscsirootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' $mtab)
	
	tmp="/dev/inbpdisk"
	
	dev=$(echo $tmp |sed -e "s/\//\\\\\//g")
	partnr=$(echo $iscsirootfs | sed -e "s/$dev//g")
	
	tmp=$tmp$partnr
	
	if [ ! $tmp = $iscsirootfs ] ; then
	    return 1
	else
	    return 0
	fi
}

start() {
        # Do sanity checks before we start..
        if [ ! -e /etc/iscsi.conf ]; then
		echo
                echo "Error: configuration file /etc/iscsi.conf is missing!"
		echo "The iSCSI driver has not been correctly installed and cannot start."
                return 1
        elif [ -s $PIDFILE ] && kill -0 `head -n 1 $PIDFILE` >/dev/null ; then
                echo "iSCSI daemon already running"
                return 1
        fi

        grep -Eq '^[^#]' /etc/iscsi.conf
        if [ $? -ne 0 ] ; then
            echo "Error: Configuration file is empty, unable to start the driver"
            return 1
        fi

	if [ ! -f /var/lib/iscsi/bindings ] ; then
	    if [ -e /etc/iscsi.bindings ] ; then
		echo
		echo "Changing the name and location of /etc/iscsi.bindings file to /var/lib/iscsi/bindings"
		if [ ! -d /var/lib/iscsi ] ; then
			mkdir -p /var/lib/iscsi
		fi
		mv /etc/iscsi.bindings /var/lib/iscsi/bindings
	    elif [ -e /var/iscsi/bindings ] ; then
		echo
		echo "Changing the name and location of /var/iscsi/bindings file to /var/lib/iscsi/bindings"
		if [ ! -d /var/lib/iscsi ] ; then
			mkdir -p /var/lib/iscsi
		fi
		mv /var/iscsi/bindings /var/lib/iscsi/bindings
	    fi
	fi

        if [ ! -f /etc/initiatorname.iscsi ] ; then
            echo "Error: InitiatorName file /etc/initiatorname.iscsi is missing!"
            return 1
        fi

        # see if we need to generate a unique iSCSI InitiatorName
	# this should only happen if the 
        if grep -q "^GenerateName=yes" /etc/initiatorname.iscsi ; then
	    if [ ! -x ${BASEDIR}sbin/iscsi-iname ] ; then
		echo "Error: ${BASEDIR}sbin/iscsi-iname does not exist, driver was not successfully installed"
		return 1
	    fi 
	    # Generate a unique InitiatorName and save it
	    INAME=`${BASEDIR}sbin/iscsi-iname`
	    if [ "$INAME" != "" ] ; then
		echo "## DO NOT EDIT OR REMOVE THIS FILE!" > /etc/initiatorname.iscsi
		echo "## If you remove this file, the iSCSI daemon will not start." >> /etc/initiatorname.iscsi
		echo "## If you change the InitiatorName, existing access control lists" >> /etc/initiatorname.iscsi
		echo "## may reject this initiator.  The InitiatorName must be unique">> /etc/initiatorname.iscsi
		echo "## for each iSCSI initiator.  Do NOT duplicate iSCSI InitiatorNames." >> /etc/initiatorname.iscsi
		printf "InitiatorName=$INAME\n"  >> /etc/initiatorname.iscsi

	    else
		echo "Error: failed to generate an iSCSI InitiatorName, driver cannot start."
		echo
		return 1
	    fi
        fi

	# make sure there is a valid InitiatorName for the driver
        if ! grep -q "^InitiatorName=[^ \t\n]" /etc/initiatorname.iscsi ; then
	    echo "Error: /etc/initiatorname.iscsi does not contain a valid InitiatorName."
	    echo "The iSCSI driver has not been correctly installed and cannot start."
            return 1
	fi

        # start
        echo -n "Starting iSCSI: iscsi"

        if ! modprobe iscsi_sfnet ; then
            echo "Could not load module iscsi_sfnet.o"
            return 1
        fi

	# By default, we try to load the scsi disk driver module.
	# If SCSI support is in modules, sd_mod won't get loaded
	# until after a /dev/sd* device is opened.  This means no 
	# messages about disks will be logged until a disk device 
	# is opened.  Worse, mounting by label won't work, since
	# it relies on /proc/partitions, which won't get updated
	# until the SCSI disk driver is loaded, creating a circular
	# dependency.  To work around these problems, we try to load 
	# the disk driver here.  If you're not using SCSI disks, 
	# you can comment this out.
	modprobe sd_mod > /dev/null 2>&1

        echo -n " iscsid"

	if [ "$DEBUG_ISCSI" ] ; then
	    if [ -e /proc/scsi/scsi ] ; then
		# log SCSI error handling
#		echo "scsi log scan 5" > /proc/scsi/scsi
		echo "scsi log timeout 3" > /proc/scsi/scsi
		echo "scsi log error 5" > /proc/scsi/scsi
	    fi
	    if [ -e /proc/sys/kernel/sysrq ] ; then
		# enable magic SysRq
		echo "1" > /proc/sys/kernel/sysrq
	    fi	
	    if [ -d /proc/scsi/iscsi ] ; then
		# turn on some useful kernel module debug messages by default
		for hba in /proc/scsi/iscsi/* ; do
		    echo "log sense always" > $hba
#		    echo "log login on" > $hba
		    echo "log init on" > $hba
#		    echo "log queue on" > $hba
#		    echo "log flow on" > $hba
		    echo "log retry on" > $hba
		    echo "log eh on" > $hba
#		    echo "log alloc on" > $hba
		done
            fi
	    iscsid -d $DEBUG_ISCSI
        else
	    # if this was actually a daemon, I wouldn't have to do this
	    iscsid 2>&-


	    # check to make sure it actually started
	    sleep $STARTUPTIMEOUT

	    if ! status iscsid &>/dev/null 
	    then
	        failure
		return 1
	    fi

        fi
	# sleep another 5 seconds to allow time to detect devices
	sleep $ESTABLISHTIMEOUT

	# Make sure the K*iscsi scripts get called
        if [ -d /var/lock/subsys ] ; then
            touch /var/lock/subsys/iscsi
        fi

	[ $? ] && success || failure
	return $?
}

stop() {
	# if iSCSI network boot then exit.
	if iscsi_network_boot ; then
	    echo "driver cannot be stopped/restarted since it is an iSCSI network boot."
	    return 1
	fi

        if [ ! -d /proc/scsi/iscsi ]; then
            echo "iscsi driver not loaded"
            return 1;
        fi

        echo -n "Stopping iSCSI:"
        for hba in /proc/scsi/iscsi/* ; do
            echo "connfailtimeout - - $CONNFAILTIMEOUT" > $hba
            echo "diskcommandtimeout - - $DISKCOMMANDTIMEOUT" > $hba
        done

        sync

	id=$(pidofproc iscsid)
	if [ -n "$id" ] ; then
		echo -n " iscsid"
		kill $id 2> /dev/null ;
		if [ -n "$(pidofproc iscsid)" ] ; then
 		   sleep 2; kill -9 $id 2>/dev/null
		fi
		sleep 2
		if [ -n  "$(pidofproc iscsid)" ] ; then
		   failure
		   return 1
		fi
		rm -f $PIDFILE
	fi

        # remove the kernel module
        if ! rmmod iscsi_sfnet; then
            echo "Unable to remove iscsi kernel driver - devices may still be in use"
            return 1
        fi

        rm -f /var/lock/subsys/iscsi
	success
	return $?
}

reload() {
    if [ -f $PIDFILE ] ; then
        kill -HUP `head -1 $PIDFILE`
    fi
}

restart() {
    stop
    echo ""
    start
}

debug() {
    DEBUG_ISCSI=5
    export DEBUG_ISCSI
    start
}

case "$1" in
 start)
	start
	err=$?
        echo ""
	;;
 stop)
	stop
	err=$?
        echo ""
	;;
 reload) 
	reload 
	err=0
        echo ""
	;;
 status) 
	status iscsid
	err=$?
	;;
 restart) 
	restart
        echo ""
	err=$?
	;;
 condrestart)
        [ -f /var/lock/subsys/iscsi ] && restart || :
        err=$?
        ;;
 redebug)
        stop && debug
        err=$?
        ;;
 debug) debug
        echo ""
        err=$?
        ;;
       
 *)
        echo "Usage: $0 {start|stop|restart|reload|status|condrestart}"
	exit 1
        ;;
esac
exit $err
