Blame etc/initd/initd.suse

Packit eace71
#!/bin/bash
Packit eace71
#
Packit eace71
# /etc/init.d/iscsi
Packit eace71
#
Packit eace71
### BEGIN INIT INFO
Packit eace71
# Provides:          iscsi
Packit eace71
# Required-Start:    $network
Packit eace71
# Should-Start:      iscsitarget multipathd
Packit eace71
# Required-Stop:     $network
Packit eace71
# Should-Stop:       multipathd
Packit eace71
# Default-Start:     3 5
Packit eace71
# Default-Stop:      
Packit eace71
# Short-Description: iSCSI initiator daemon
Packit eace71
# Description:       The iSCSI initator is used to create and
Packit eace71
#                    manage iSCSI connections to an iSCSI Target.
Packit eace71
#
Packit eace71
### END INIT INFO
Packit eace71
Packit eace71
CONFIG_FILE=/etc/iscsi/iscsid.conf
Packit eace71
DAEMON=/sbin/iscsid
Packit eace71
ISCSIADM=/sbin/iscsiadm
Packit eace71
BRCM_ISCSIUIO=/sbin/brcm_iscsiuio
Packit eace71
ARGS="-c $CONFIG_FILE -n"
Packit eace71
Packit eace71
# Source LSB init functions
Packit eace71
. /etc/rc.status
Packit eace71
Packit eace71
# Reset status of this service
Packit eace71
rc_reset
Packit eace71
Packit eace71
DM_MAJOR=$(sed -n 's/\(.*\) device-mapper/\1/p' /proc/devices)
Packit eace71
Packit eace71
iscsi_login_all_nodes()
Packit eace71
{
Packit eace71
	echo -n "Setting up iSCSI targets: "
Packit eace71
	$ISCSIADM -m node --loginall=automatic 2> /dev/null
Packit eace71
	if [ $? == 21 ] ; then
Packit eace71
	    rc_failed 6
Packit eace71
	fi
Packit eace71
	rc_status -v
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Try to load all required modules prior to startup
Packit eace71
#
Packit eace71
iscsi_load_transport_modules()
Packit eace71
{
Packit eace71
    loaded=$(sed -n "/^iscsi_tcp/p" /proc/modules)
Packit eace71
    if [ -z "$loaded" ] ; then
Packit eace71
	modprobe iscsi_tcp
Packit eace71
	if [ $? = 0 ] ; then
Packit eace71
	    echo -n " tcp"
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
Packit eace71
    for iface in /etc/iscsi/ifaces/*; do
Packit eace71
	[ -f "$iface" ] || continue
Packit eace71
	[ "$iface" = "iface.example" ] && continue
Packit eace71
	# Check if the iface has been configured
Packit eace71
	result=$(sed '/#.*/D;/iface.iscsi_ifacename/D;/iface.hwaddress/D;/iface.transport_name/D' $iface)
Packit eace71
	if [ "$result" ] ; then
Packit eace71
	    mod=$(sed -n 's/iface.transport_name *= *\(.*\)/\1/p' $iface)
Packit eace71
	    loaded=$(sed -n "/^$mod/p" /proc/modules)
Packit eace71
	    if [ -z "$loaded" ] ; then
Packit eace71
		modprobe $mod
Packit eace71
		if [ $? = 0 ] ; then
Packit eace71
		    echo -n " $mod"
Packit eace71
		fi
Packit eace71
	    fi
Packit eace71
	fi
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Set a temporary startmode for ifdown
Packit eace71
#
Packit eace71
iscsi_modify_if_startmode()
Packit eace71
{
Packit eace71
    local ifname=$1
Packit eace71
    local tmp_ifcfg=/dev/.sysconfig/network/if-$ifname
Packit eace71
Packit eace71
    if [ -e "$tmp_ifcfg" ] ; then
Packit eace71
	. $tmp_ifcfg
Packit eace71
	if [ "$startmode" ] ; then
Packit eace71
	    return
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
    : disabling shutdown on $ifname
Packit eace71
    echo "startmode=nfsroot" >> $tmp_ifcfg
Packit eace71
}
Packit eace71
Packit eace71
iscsi_get_ifacename_from_session()
Packit eace71
{
Packit eace71
    local session=$1
Packit eace71
    local ifacename
Packit eace71
Packit eace71
    ifacename=$(iscsiadm -m session -r ${session##.*/session} 2> /dev/null | \
Packit eace71
	sed -n 's/iface.iscsi_ifacename = \(.*\)/\1/p')
Packit eace71
    if [ -z "$ifacename" ] ; then
Packit eace71
	# Check for iBFT
Packit eace71
	ifacename=$(iscsiadm -m fw 2> /dev/null)
Packit eace71
	if [ -n "$ifacename" ] ; then
Packit eace71
	    ifacename="fw"
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
    echo $ifacename
Packit eace71
}
Packit eace71
Packit eace71
iscsi_get_hwaddress_from_iface()
Packit eace71
{
Packit eace71
    local iface=$1
Packit eace71
    local hwaddress
Packit eace71
Packit eace71
    hwaddress=$(iscsiadm -m iface -I "$iface" 2> /dev/null | sed -n 's/iface.hwaddress = \(.*\)/\1/p')
Packit eace71
    [ "$hwaddress" = "<empty>" ] && hwaddress=
Packit eace71
Packit eace71
    echo $hwaddress
Packit eace71
}
Packit eace71
Packit eace71
iscsi_get_ifname_from_iface()
Packit eace71
{
Packit eace71
    local iface=$1
Packit eace71
    local ifname
Packit eace71
Packit eace71
    ifname=$(iscsiadm -m iface -I "$iface" 2> /dev/null | sed -n 's/iface.net_ifacename = \(.*\)/\1/p')
Packit eace71
    [ "$ifname" = "<empty>" ] && ifname=
Packit eace71
Packit eace71
    echo $ifname
Packit eace71
}
Packit eace71
Packit eace71
iscsi_get_ipaddr_from_iface()
Packit eace71
{
Packit eace71
    local iface=$1
Packit eace71
    local ipaddr
Packit eace71
Packit eace71
    ipaddr=$(iscsiadm -m iface -I "$iface" 2> /dev/null | sed -n 's/iface.ipaddress = \(.*\)/\1/p')
Packit eace71
    [ "$ipaddr" = "<empty>" ] && ipaddr=
Packit eace71
Packit eace71
    echo $ipaddr
Packit eace71
}
Packit eace71
Packit eace71
iscsi_get_ifname_from_firmware()
Packit eace71
{
Packit eace71
    local hwaddress
Packit eace71
Packit eace71
    hwaddress=$(iscsiadm -m fw 2> /dev/null | sed -n 's/iface.net_ifacename = \(.*\)/\1/p')
Packit eace71
Packit eace71
    echo $hwaddress
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# cxgb3i is using the HWAddress to select
Packit eace71
# the correct interface
Packit eace71
#
Packit eace71
iscsi_get_ifname_from_hwaddress()
Packit eace71
{
Packit eace71
    local hwaddress=$1
Packit eace71
Packit eace71
    for if in /sys/class/net/*; do
Packit eace71
	[ -e "$if" ] || continue
Packit eace71
	read mac < $if/address
Packit eace71
	[ "$mac" = "$hwaddress" ] || continue
Packit eace71
	echo ${if##*/}
Packit eace71
	break
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
iscsi_get_ifname_from_ipaddr()
Packit eace71
{
Packit eace71
    local ipaddr=$1
Packit eace71
    local ifname
Packit eace71
Packit eace71
    ifname=$(ip addr show to $ipaddr | sed -n 's/[0-9]*: \([^ :]*\): .*/\1/p')
Packit eace71
    return $ifname
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Handle 'default' interface:
Packit eace71
# It is basically impossible to determine via which
Packit eace71
# interface the iSCSI traffic will flow, so we take
Packit eace71
# the easy option and ignore _all_ active interfaces
Packit eace71
# during shutdown
Packit eace71
#
Packit eace71
iscsi_modify_all_interfaces()
Packit eace71
{
Packit eace71
    ip link show up | sed -n '/.*LOOPBACK.*/d;s/[0-9]*: \(.*\): .*/\1/p' | while read ifname; do
Packit eace71
	iscsi_modify_if_startmode $ifname
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Check iface setting and disable
Packit eace71
# affected network interfaces
Packit eace71
#
Packit eace71
iscsi_check_interface()
Packit eace71
{
Packit eace71
    local session=$1
Packit eace71
    local i h n
Packit eace71
Packit eace71
    i=$(iscsi_get_ifacename_from_session $session)
Packit eace71
    [ -z "$i" ] && continue
Packit eace71
    if [ "$i" = "default" ] ; then
Packit eace71
	iscsi_modify_all_interfaces
Packit eace71
    elif [ "$i" = "fw" ] ; then
Packit eace71
	n=$(iscsi_get_ifname_from_firmware)
Packit eace71
    else
Packit eace71
	n=$(iscsi_get_ifname_from_iface $i)
Packit eace71
	if [ -z "$n" ] ; then
Packit eace71
	    h=$(iscsi_get_hwaddress_from_iface $i)
Packit eace71
	    if [ -n "$h" ] ; then
Packit eace71
		n=$(iscsi_get_ifname_from_hwaddress $h)
Packit eace71
	    fi
Packit eace71
	fi
Packit eace71
	if [ -z "$n" ] ; then
Packit eace71
	    h=$(iscsi_get_ipaddr_from_iface $i)
Packit eace71
	    if [ -n "$h" ] ; then
Packit eace71
		n=$(iscsi_get_ifname_from_ipaddr $h)
Packit eace71
	    fi
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
    if [ "$n" ] ; then
Packit eace71
	iscsi_modify_if_startmode $n
Packit eace71
    fi
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Check if device 'dev' is mounted
Packit eace71
# Returns the mount point on success
Packit eace71
#
Packit eace71
iscsi_check_if_mounted()
Packit eace71
{
Packit eace71
    local dev=$1
Packit eace71
    local d m t o x p
Packit eace71
Packit eace71
    cat /proc/mounts | sed -ne '/^\/dev\/.*/p' | while read d m t o x; do 
Packit eace71
	if [ -L "$d" ] ; then
Packit eace71
	    d=$(readlink -f $d)
Packit eace71
	fi
Packit eace71
	[ -b "$d" ] || continue
Packit eace71
Packit eace71
	b=$(ls -l $d | sed -n 's/.* \([0-9]*\), \([0-9]*\) .*/\1:\2/p')
Packit eace71
	p=$(cd -P /sys/dev/block/$b ; echo $PWD)
Packit eace71
Packit eace71
	if [ -z "$p" ] ; then
Packit eace71
	    d=${d##/dev}
Packit eace71
	    p="/sys/block${d%%[0-9]*}"
Packit eace71
	fi
Packit eace71
Packit eace71
	[ ! -d ${p} ] && continue
Packit eace71
Packit eace71
	if [ -e $p/partition ] ; then
Packit eace71
	    p=$(cd -P $p/../; echo $PWD)
Packit eace71
	fi
Packit eace71
	if [ "$dev" = "${p##*/}" ] ; then
Packit eace71
	    echo $m
Packit eace71
	fi
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Unwind block device stack
Packit eace71
# 
Packit eace71
# Stops unwinding if either no more 'holders'
Packit eace71
# are found or if a device is mounted
Packit eace71
# 
Packit eace71
# Unmounts top-level device and deconfigures
Packit eace71
# all devices down the stack
Packit eace71
#
Packit eace71
# Root fs is not unmounted
Packit eace71
#
Packit eace71
iscsi_unwind_stack()
Packit eace71
{
Packit eace71
    local p=$1
Packit eace71
    local d=${p##*/}
Packit eace71
    local u
Packit eace71
    local m
Packit eace71
Packit eace71
    if [ ! -d ${p} ] ; then
Packit eace71
	return;
Packit eace71
    fi
Packit eace71
Packit eace71
    m=$(iscsi_check_if_mounted $d)
Packit eace71
    if [ -z "$m" ] ; then
Packit eace71
	for s in $p/holders/* ; do
Packit eace71
	    [ -e $s ] || continue
Packit eace71
	    p=$(cd -P $s; echo $PWD)
Packit eace71
	    u=$(iscsi_unwind_stack $p)
Packit eace71
	    if [ "$u" ] ; then
Packit eace71
		echo -n "$u "
Packit eace71
	    fi
Packit eace71
	done
Packit eace71
    else
Packit eace71
	if [ "$m" = "/" ] ; then
Packit eace71
	    echo -n "$d "
Packit eace71
	    return 1
Packit eace71
	fi
Packit eace71
	if ! umount $m ; then
Packit eace71
	    echo -n "$d "
Packit eace71
	    return 1
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
Packit eace71
    if [ "${d#dm-}" != "$d" ] ; then
Packit eace71
	if ! dmsetup remove -j $DM_MAJOR -m ${d#dm-} 2> /dev/null ; then
Packit eace71
	    echo -n "$d "
Packit eace71
	    return 1
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
Packit eace71
    if [ "${d#md}" != "$d" ] ; then
Packit eace71
	if ! mdadm --manage /dev/$d --stop 2> /dev/null ; then
Packit eace71
	    echo -n "$d "
Packit eace71
	    return 1
Packit eace71
	fi
Packit eace71
    fi
Packit eace71
    return 0
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Return all targets for a given session
Packit eace71
#
Packit eace71
iscsi_get_target()
Packit eace71
{
Packit eace71
    local session=$1
Packit eace71
    local d
Packit eace71
Packit eace71
    for d in $session/device/target* ; do
Packit eace71
	[ -e "$d" ] || continue
Packit eace71
	echo "$d"
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Checks all devices presented by a target
Packit eace71
# and tries to umount them.
Packit eace71
# Skip unmounting for the root fs.
Packit eace71
# Stops on the first device which could not be unmounted
Packit eace71
# and returns the mount device of that device.
Packit eace71
#
Packit eace71
iscsi_check_target()
Packit eace71
{
Packit eace71
    local t=$1
Packit eace71
    local d b m
Packit eace71
Packit eace71
    for d in $t/* ; do
Packit eace71
	[ -d $d/block ] || continue
Packit eace71
	for b in $d/block/sd* ; do
Packit eace71
	    [ -d "$b" ] || continue
Packit eace71
	    m=$(iscsi_unwind_stack $b)
Packit eace71
	    if [ -n "$m" ] ; then
Packit eace71
		echo $m
Packit eace71
		return 1
Packit eace71
	    fi
Packit eace71
	done
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
#
Packit eace71
# Check all sessions for mounted devices
Packit eace71
# and shutdown the session if the affected
Packit eace71
# devices could be umounted cleanly.
Packit eace71
# If umount fails disable shutdown on all
Packit eace71
# affected network interfaces
Packit eace71
#
Packit eace71
iscsi_stop_sessions()
Packit eace71
{
Packit eace71
    local t m s i
Packit eace71
Packit eace71
    i=0
Packit eace71
    for session in /sys/class/iscsi_session/session* ; do
Packit eace71
	[ -e "$session" ] || continue;
Packit eace71
	[ -e $session/device ] || continue
Packit eace71
	t=$(iscsi_get_target $session)
Packit eace71
	m=$(iscsi_check_target $t)
Packit eace71
	s=${session##*/session}
Packit eace71
	if [ -z "$m" ] ; then
Packit eace71
	    iscsiadm -m session -r ${s} -u
Packit eace71
	    i=$(( $i + 1 ))
Packit eace71
	else
Packit eace71
	    iscsi_check_interface $s
Packit eace71
	fi
Packit eace71
    done
Packit eace71
    echo $i
Packit eace71
}
Packit eace71
Packit eace71
iscsi_list_all_nodes()
Packit eace71
{
Packit eace71
    # Check for active sessions
Packit eace71
    if $ISCSIADM -m session > /dev/null; then
Packit eace71
	return 0
Packit eace71
    fi
Packit eace71
    echo "Active connections:"
Packit eace71
    $ISCSIADM -m session | while read proto num PORTAL TARGET ; do
Packit eace71
	PORTAL=${PORTAL%,*}
Packit eace71
	echo -e "\t$TARGET at $PORTAL"
Packit eace71
    done
Packit eace71
}
Packit eace71
Packit eace71
case "$1" in
Packit eace71
    start)
Packit eace71
	if checkproc $DAEMON ; then
Packit eace71
	    RETVAL=0
Packit eace71
	else
Packit eace71
	    echo -n "Starting iSCSI initiator service: "
Packit eace71
	    iscsi_load_transport_modules
Packit eace71
	    if grep -q bnx2i /proc/modules && [ -x $BRCM_ISCSIUIO ] ; then
Packit eace71
		startproc $BRCM_ISCSIUIO
Packit eace71
	    fi
Packit eace71
	    startproc $DAEMON $ARGS
Packit eace71
	    RETVAL=$?
Packit eace71
	    rc_status -v
Packit eace71
	fi
Packit eace71
	if [ "$RETVAL" == "0" ]; then
Packit eace71
	    iscsi_login_all_nodes
Packit eace71
	fi
Packit eace71
	;;
Packit eace71
    stop)
Packit eace71
	n=$(iscsi_stop_sessions)
Packit eace71
	echo -n "Stopping iSCSI initiator service: "
Packit eace71
	if [ "$n" ] && [ "$n" != "0" ] ; then
Packit eace71
	    m=$(iscsiadm -m session 2> /dev/null)
Packit eace71
	    if [ -z "$m" ] ; then
Packit eace71
		killproc -KILL $DAEMON
Packit eace71
		RETVAL=$?
Packit eace71
		if grep -q bnx2i /proc/modules && [ -x $BRCM_ISCSIUIO ]; then
Packit eace71
		    killproc -KILL $BRCM_ISCSIUIO
Packit eace71
		fi
Packit eace71
 		RETVAL=$?
Packit eace71
	    else
Packit eace71
		RETVAL=1
Packit eace71
	    fi
Packit eace71
	    rc_failed $RETVAL
Packit eace71
	    rc_status -v
Packit eace71
	else
Packit eace71
	    # umounting failed, leave initiator running
Packit eace71
	    rc_status -s
Packit eace71
	fi
Packit eace71
	;;
Packit eace71
    status)
Packit eace71
	echo -n "Checking for iSCSI initiator service: "
Packit eace71
	if checkproc $DAEMON ; then
Packit eace71
	    rc_status -v
Packit eace71
	    iscsi_list_all_nodes
Packit eace71
	else
Packit eace71
	    rc_failed 3
Packit eace71
	    rc_status -v
Packit eace71
	fi
Packit eace71
	;;
Packit eace71
    restart|reload)
Packit eace71
	$0 stop
Packit eace71
	RETVAL=$?
Packit eace71
	if [ "$RETVAL" != "0" ]; then
Packit eace71
		echo "Stopping iSCSI initiator service failed, not starting"
Packit eace71
		exit $RETVAL
Packit eace71
	fi
Packit eace71
	sleep 1
Packit eace71
	$0 start
Packit eace71
	;;
Packit eace71
    *)
Packit eace71
	echo "Usage: $0 {start|stop|status|restart|reload}"
Packit eace71
	exit 1
Packit eace71
	;;
Packit eace71
esac
Packit eace71
rc_exit
Packit eace71