#! /bin/sh
# chkconfig: - 11 89
# description: iSCSI daemon

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

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

#Timeouts to be used during iscsi shutdown
CONNFAILTIMEOUT=30
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 failure
        elif [ -s $PIDFILE ] && kill -0 `head -n 1 $PIDFILE` >/dev/null ; then
                echo $"iSCSI daemon already running"
		failure
                return $?
        fi

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

        # start
        echo -n $"Starting iSCSI: iscsi"

	# the install script tells us when we need to unload an old module,
	# so that 'make install; rc.iscsi restart' does what people expect.
	if [ -d /tmp -a -e /tmp/.iscsi.unload.module ] ; then
	    rmmod iscsi_sfnet > /dev/null 2>&1
	    rm -f /tmp/.iscsi.unload.module
        fi

        if lsmod | grep -q "^iscsi_sfnet" ; then
            :
        else
            if ! modprobe iscsi_sfnet ; then
                echo $"Could not load module iscsi_sfnet.o"
                return failure
            fi
        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 [ -d /proc/scsi/iscsi ] ; then
	    for hba in /proc/scsi/iscsi/* ; do
		if [ -f $hba ] ; then
		    break
		fi
	    done
	    if [ -f $hba ] ; then
		while read busid targetid lun ip port name ; do
		    case $busid
			in
			\#*) continue ;; #  ignore comments
			'')  continue ;; # ignore empty lines
		    esac
		    
		    break
		    
		done < $hba
	    fi
	fi

	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 > /dev/null 2>/var/log/iscsi.log < /dev/null ) >&- 2>&- <&-
        fi
	success
	return $?
}

stop() {
	# if iSCSI network boot then exit.
	if iscsi_network_boot ; then
	    echo $"Since it is an iSCSI network boot therefore, driver cannot be stopped/restarted"
	    failure
	    return $?
	fi

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

        sync

        # unmount all filesystems on iSCSI devices
	# FIXME: This won't work if the iscsi device is part of a logical volume
        echo -n $" umount"
	if ! iscsi-umountall -t -k; then
		failure
		return 1
	fi 

        sync
        sleep 3

	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

	# shutdown the kernel module
	if [ -d /proc/scsi/iscsi ] ; then
	    echo -n " iscsi"
	    for hba in /proc/scsi/iscsi/* ; do
		echo "shutdown" > $hba
	    done
	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=$?
	;;
 stop)
	stop
	err=$?
	;;
 reload) 
	reload 
	err=0
	;;
 status) 
	status iscsid 
	err=0
	;;
 restart) 
	restart 
	err=0
	;;
 condrestart)
        [ -f /var/lock/subsys/iscsi ] && restart || :
        ;;
 redebug)
        stop
        debug
        ;;
 debug) debug
        ;;
       
 *)
        echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}"
	exit 1
        ;;
esac
echo ""
exit $err
