[Pkg-iscsi-maintainers] [SCM] Debian Open-iSCSI Packaging branch, upstream-mnc, updated. 2.0-872-193-gde2c0e7

Mike Christie michaelc at cs.wisc.edu
Sat Apr 7 15:43:24 UTC 2012


The following commit has been merged in the upstream-mnc branch:
commit c44bdb5af6ac232adde2390990e96220d642e43d
Author: Mike Christie <michaelc at cs.wisc.edu>
Date:   Sun Jun 26 17:52:13 2011 -0500

    Update SUSE init script
    
    From Hannes Reinecke
    
    Rework the iSCSI shutdown logic to tear down the block device
    stack correctly.
    
    Signed-off-by: Hannes Reinecke <hare at suse.de>
    [fix merge issues]
    Mike Christie

diff --git a/etc/initd/initd.suse b/etc/initd/initd.suse
index cc0baa9..a1c515a 100644
--- a/etc/initd/initd.suse
+++ b/etc/initd/initd.suse
@@ -5,20 +5,22 @@
 ### BEGIN INIT INFO
 # Provides:          iscsi
 # Required-Start:    $network
-# Should-Start:
-# Required-Stop:     
-# Should-Stop:
+# Should-Start:      iscsitarget multipathd
+# Required-Stop:     $network
+# Should-Stop:       multipathd
 # Default-Start:     3 5
 # Default-Stop:      
-# Short-Description: Starts and stops the iSCSI client initiator
-#                    
+# Short-Description: iSCSI initiator daemon
+# Description:       The iSCSI initator is used to create and
+#                    manage iSCSI connections to a iSCSI Target.
+#
 ### END INIT INFO
 
-PID_FILE=/var/run/iscsi.pid
 CONFIG_FILE=/etc/iscsi/iscsid.conf
 DAEMON=/sbin/iscsid
 ISCSIADM=/sbin/iscsiadm
-ARGS="-c $CONFIG_FILE -p $PID_FILE"
+BRCM_ISCSIUIO=/sbin/brcm_iscsiuio
+ARGS="-c $CONFIG_FILE -n"
 
 # Source LSB init functions
 . /etc/rc.status
@@ -26,6 +28,8 @@ ARGS="-c $CONFIG_FILE -p $PID_FILE"
 # Reset status of this service
 rc_reset
 
+DM_MAJOR=$(sed -n 's/\(.*\) device-mapper/\1/p' /proc/devices)
+
 iscsi_login_all_nodes()
 {
 	echo -n "Setting up iSCSI targets: "
@@ -36,58 +40,349 @@ iscsi_login_all_nodes()
 	rc_status -v
 }
 
-iscsi_logout_all_nodes()
+#
+# Try to load all required modules prior to startup
+#
+iscsi_load_transport_modules()
 {
-	echo -n "Closing all iSCSI connections: "
-	# Logout from all sessions marked automatic
-	if ! $ISCSIADM -m node --logoutall=automatic 2> /dev/null; then
-		if [ $? == 21 ] ; then
-		    RETVAL=6
-		else
-		    RETVAL=1
+    loaded=$(sed -n "/^iscsi_tcp/p" /proc/modules)
+    if [ -z "$loaded" ] ; then
+	modprobe iscsi_tcp
+	if [ $? = 0 ] ; then
+	    echo -n " tcp"
+	fi
+    fi
+
+    for iface in /etc/iscsi/ifaces/*; do
+	[ -f "$iface" ] || continue
+	[ "$iface" = "iface.example" ] && continue
+	# Check if the iface has been configured
+	result=$(sed '/#.*/D;/iface.iscsi_ifacename/D;/iface.hwaddress/D;/iface.transport_name/D' $iface)
+	if [ "$result" ] ; then
+	    mod=$(sed -n 's/iface.transport_name *= *\(.*\)/\1/p' $iface)
+	    loaded=$(sed -n "/^$mod/p" /proc/modules)
+	    if [ -z "$loaded" ] ; then
+		modprobe $mod
+		if [ $? = 0 ] ; then
+		    echo -n " $mod"
 		fi
-		rc_failed $RETVAL
+	    fi
 	fi
-	rc_status -v
+    done
+}
 
-	# Not sure whether this is still needed
-	sleep 1
-	return ${RETVAL:-0}
+#
+# Set a temporary startmode for ifdown
+#
+iscsi_modify_if_startmode()
+{
+    local ifname=$1
+    local tmp_ifcfg=/dev/.sysconfig/network/if-$ifname
+
+    if [ -e "$tmp_ifcfg" ] ; then
+	. $tmp_ifcfg
+	if [ "$startmode" ] ; then
+	    return
+	fi
+    fi
+    : disabling shutdown on $ifname
+    echo "startmode=nfsroot" >> $tmp_ifcfg
 }
 
-iscsi_umount_all_luns()
+iscsi_get_ifacename_from_session()
 {
-    local d m dev p s
+    local session=$1
+    local ifacename
 
-    cat /proc/mounts | sed -ne '/^\/dev\/.*/p' | while read d m t o x; do 
-	if [ "$m" = "/" ] ; then 
-	    continue;
+    ifacename=$(iscsiadm -m session -r ${session##.*/session} 2> /dev/null | \
+	sed -n 's/iface.iscsi_ifacename = \(.*\)/\1/p')
+    if [ -z "$ifacename" ] ; then
+	# Check for iBFT
+	ifacename=$(iscsiadm -m fw 2> /dev/null)
+	if [ -n "$ifacename" ] ; then
+	    ifacename="fw"
+	fi
+    fi
+    echo $ifacename
+}
+
+iscsi_get_hwaddress_from_iface()
+{
+    local iface=$1
+    local hwaddress
+
+    hwaddress=$(iscsiadm -m iface -I "$iface" 2> /dev/null | sed -n 's/iface.hwaddress = \(.*\)/\1/p')
+    [ "$hwaddress" = "<empty>" ] && hwaddress=
+
+    echo $hwaddress
+}
+
+iscsi_get_ifname_from_iface()
+{
+    local iface=$1
+    local ifname
+
+    ifname=$(iscsiadm -m iface -I "$iface" 2> /dev/null | sed -n 's/iface.net_ifacename = \(.*\)/\1/p')
+    [ "$ifname" = "<empty>" ] && ifname=
+
+    echo $ifname
+}
+
+iscsi_get_ipaddr_from_iface()
+{
+    local iface=$1
+    local ipaddr
+
+    ipaddr=$(iscsiadm -m iface -I "$iface" 2> /dev/null | sed -n 's/iface.ipaddress = \(.*\)/\1/p')
+    [ "$ipaddr" = "<empty>" ] && ipaddr=
+
+    echo $ipaddr
+}
+
+iscsi_get_ifname_from_firmware()
+{
+    local hwaddress
+
+    hwaddress=$(iscsiadm -m fw 2> /dev/null | sed -n 's/iface.net_ifacename = \(.*\)/\1/p')
+
+    echo $hwaddress
+}
+
+#
+# cxgb3i is using the HWAddress to select
+# the correct interface
+#
+iscsi_get_ifname_from_hwaddress()
+{
+    local hwaddress=$1
+
+    for if in /sys/class/net/*; do
+	[ -e "$if" ] || continue
+	read mac < $if/address
+	[ "$mac" = "$hwaddress" ] || continue
+	echo ${if##*/}
+	break
+    done
+}
+
+iscsi_get_ifname_from_ipaddr()
+{
+    local ipaddr=$1
+    local ifname
+
+    ifname=$(ip addr show to $ipaddr | sed -n 's/[0-9]*: \([^ :]*\): .*/\1/p')
+    return $ifname
+}
+
+#
+# Handle 'default' interface:
+# It is basically impossible to determine via which
+# interface the iSCSI traffic will flow, so we take
+# the easy option and ignore _all_ active interfaces
+# during shutdown
+#
+iscsi_modify_all_interfaces()
+{
+    ip link show up | sed -n '/.*LOOPBACK.*/d;s/[0-9]*: \(.*\): .*/\1/p' | while read ifname; do
+	iscsi_modify_if_startmode $ifname
+    done
+}
+
+#
+# Check iface setting and disable
+# affected network interfaces
+#
+iscsi_check_interface()
+{
+    local session=$1
+    local i h n
+
+    i=$(iscsi_get_ifacename_from_session $session)
+    [ -z "$i" ] && continue
+    if [ "$i" = "default" ] ; then
+	iscsi_modify_all_interfaces
+    elif [ "$i" = "fw" ] ; then
+	n=$(iscsi_get_ifname_from_firmware)
+    else
+	n=$(iscsi_get_ifname_from_iface $i)
+	if [ -z "$n" ] ; then
+	    h=$(iscsi_get_hwaddress_from_iface $i)
+	    if [ -n "$h" ] ; then
+		n=$(iscsi_get_ifname_from_hwaddress $h)
+	    fi
 	fi
+	if [ -z "$n" ] ; then
+	    h=$(iscsi_get_ipaddr_from_iface $i)
+	    if [ -n "$h" ] ; then
+		n=$(iscsi_get_ifname_from_ipaddr $h)
+	    fi
+	fi
+    fi
+    if [ "$n" ] ; then
+	iscsi_modify_if_startmode $n
+    fi
+}
+
+#
+# Check if device 'dev' is mounted
+# Returns the mount point on success
+#
+iscsi_check_if_mounted()
+{
+    local dev=$1
+    local d m t o x p
+
+    cat /proc/mounts | sed -ne '/^\/dev\/.*/p' | while read d m t o x; do 
 	if [ -L "$d" ] ; then
 	    d=$(readlink -f $d)
 	fi
-	dev=${d##/dev}
+	[ -b "$d" ] || continue
+
+	b=$(ls -l $d | sed -n 's/.* \([0-9]*\), \([0-9]*\) .*/\1:\2/p')
+	p=$(cd -P /sys/dev/block/$b ; echo $PWD)
+
+	if [ -z "$p" ] ; then
+	    d=${d##/dev}
+	    p="/sys/block${d%%[0-9]*}"
+	fi
+
+	[ ! -d ${p} ] && continue
+
+	if [ -e $p/partition ] ; then
+	    p=$(cd -P $p/../; echo $PWD)
+	fi
+	if [ "$dev" = "${p##*/}" ] ; then
+	    echo $m
+	fi
+    done
+}
+
+#
+# Unwind block device stack
+# 
+# Stops unwinding if either no more 'holders'
+# are found or if a device is mounted
+# 
+# Unmounts top-level device and deconfigures
+# all devices down the stack
+#
+# Root fs is not unmounted
+#
+iscsi_unwind_stack()
+{
+    local p=$1
+    local d=${p##*/}
+    local u
+    local m
+
+    if [ ! -d ${p} ] ; then
+	return;
+    fi
+
+    m=$(iscsi_check_if_mounted $d)
+    if [ -z "$m" ] ; then
+	for s in $p/holders/* ; do
+	    [ -e $s ] || continue
+	    p=$(cd -P $s; echo $PWD)
+	    u=$(iscsi_unwind_stack $p)
+	    if [ "$u" ] ; then
+		echo -n "$u "
+	    fi
+	done
+    else
+	if [ "$m" = "/" ] ; then
+	    echo -n "$d "
+	    return 1
+	fi
+	if ! umount $m ; then
+	    echo -n "$d "
+	    return 1
+	fi
+    fi
 
-	if [ "${dev##/sd}" = "$dev" ] ; then
-	    continue;
+    if [ "${d#dm-}" != "$d" ] ; then
+	if ! dmsetup remove -j $DM_MAJOR -m ${d#dm-} 2> /dev/null ; then
+	    echo -n "$d "
+	    return 1
 	fi
-	p="/sys/block${dev%%[0-9]*}"
+    fi
 
-	if [ ! -d ${p} ] && [ ! -d ${p}/device ] ; then
-	    continue;
+    if [ "${d#md}" != "$d" ] ; then
+	if ! mdadm --manage /dev/$d --stop 2> /dev/null ; then
+	    echo -n "$d "
+	    return 1
 	fi
+    fi
+    return 0
+}
 
-	s=$(cd -P ${p}/device && echo $PWD)
+#
+# Return all targets for a given session
+#
+iscsi_get_target()
+{
+    local session=$1
+    local d
 
-	case "$s" in
-	    */session[0-9]*/*)
-		# This is an iSCSI device
-		umount "$m"
-	    ;;
-	esac
+    for d in $session/device/target* ; do
+	[ -e "$d" ] || continue
+	echo "$d"
     done
 }
 
+#
+# Checks all devices presented by a target
+# and tries to umount them.
+# Skip unmounting for the root fs.
+# Stops on the first device which could not be unmounted
+# and returns the mount device of that device.
+#
+iscsi_check_target()
+{
+    local t=$1
+    local d b m
+
+    for d in $t/* ; do
+	[ -d $d/block ] || continue
+	for b in $d/block/sd* ; do
+	    [ -d "$b" ] || continue
+	    m=$(iscsi_unwind_stack $b)
+	    if [ -n "$m" ] ; then
+		echo $m
+		return 1
+	    fi
+	done
+    done
+}
+
+#
+# Check all sessions for mounted devices
+# and shutdown the session if the affected
+# devices could be umounted cleanly.
+# If umount fails disable shutdown on all
+# affected network interfaces
+#
+iscsi_stop_sessions()
+{
+    local t m s i
+
+    i=0
+    for session in /sys/class/iscsi_session/session* ; do
+	[ -e "$session" ] || continue;
+	[ -e $session/device ] || continue
+	t=$(iscsi_get_target $session)
+	m=$(iscsi_check_target $t)
+	s=${session##*/session}
+	if [ -z "$m" ] ; then
+	    iscsiadm -m session -r ${s} -u
+	    i=$(( $i + 1 ))
+	else
+	    iscsi_check_interface $s
+	fi
+    done
+    echo $i
+}
+
 iscsi_list_all_nodes()
 {
     # Check for active sessions
@@ -101,84 +396,45 @@ iscsi_list_all_nodes()
     done
 }
 
-iscsi_discover_all_targets()
-{
-	# Strip off any existing ID information
-	RAW_NODE_LIST=`iscsiadm -m node | sed -nre 's/^(\[[0-9a-f]*\] )?(.*)$/\2/p'`
-	# Obtain IPv4 list
-	IPV4_NODE_LIST=`echo "$RAW_NODE_LIST" | sed -nre 's/^([0-9]{1,3}(\.[0-9]{1,3}){3}):[^: ]* (.*)$/\1 \3/p'`
-	# Now obtain IPv6 list
-	IPV6_NODE_LIST=`echo "$RAW_NODE_LIST" | sed -nre 's/^([0-9a-f]{1,4}(:[0-9a-f]{0,4}){6}:[0-9a-f]{1,4}):[^: ]* (.*)$/\1 \3/p'`
-
-	DISC_TARGETS=""
-	while read NODE_ADDR NODE_NAME; do
-		[ -z "$NODE_ADDR" -a -z "$NODE_NAME" ] && continue
-		NODE_ATTRS=`iscsiadm -m node -p "$NODE_ADDR" -T "$NODE_NAME"`
-		NODE_STATUS=`echo "$NODE_ATTRS" | sed -nre 's/^.*node\.conn\[0\]\.startup = ([a-z]*).*$/\1/p'`
-
-		if [ "$NODE_STATUS" == 'automatic' ]; then
-			DISC_TARGETS=`echo "$DISC_TARGETS" | sed -re '/'"$NODE_ADDR"'/!{s/(.*)/\1 '"$NODE_ADDR"'/}'`
-		fi
-	done < <(echo "$IPV4_NODE_LIST"; echo "$IPV6_NODE_LIST")
-
-	for TARGET_ADDR in $DISC_TARGETS; do
-		echo -n "Attempting discovery on target at ${TARGET_ADDR}: "
-		iscsiadm -m discovery -t st -p "$TARGET_ADDR" > /dev/null 2>&1
-		if [ "$?" -ne 0 ]; then
-			rc_failed 1
-			rc_status -v
-			return 1
-		fi
-		rc_status -v
-	done
-}
-
 case "$1" in
     start)
-	[ ! -d /var/lib/iscsi ] && mkdir -p /var/lib/iscsi
 	if checkproc $DAEMON ; then
 	    RETVAL=0
 	else
 	    echo -n "Starting iSCSI initiator service: "
-	    modprobe iscsi_tcp
-	    modprobe -q ib_iser
+	    iscsi_load_transport_modules
+	    if grep -q bnx2i /proc/modules && [ -x $BRCM_ISCSIUIO ] ; then
+		startproc $BRCM_ISCSIUIO
+	    fi
 	    startproc $DAEMON $ARGS
 	    RETVAL=$?
 	    rc_status -v
 	fi
 	if [ "$RETVAL" == "0" ]; then
-	    iscsi_discover_all_targets
-	    RETVAL=$?
-	fi
-	if [ "$RETVAL" == "0" ]; then
 	    iscsi_login_all_nodes
 	fi
 	;;
     stop)
-	iscsi_umount_all_luns
-	if iscsi_logout_all_nodes ; then
-	    iscsiadm -k 0
-	    RETVAL=$?
-	else
-	    RETVAL=1
-	fi
+	n=$(iscsi_stop_sessions)
 	echo -n "Stopping iSCSI initiator service: "
-	if [ "$RETVAL" == "0" ]; then
-	    rm -f $PID_FILE
-	    status=0
-	    modprobe -r iscsi_tcp
-	    if [ "$?" -ne "0" -a "$?" -ne "1" ]; then
-	    	status=1
+	if [ "$n" ] && [ "$n" != "0" ] ; then
+	    m=$(iscsiadm -m session 2> /dev/null)
+	    if [ -z "$m" ] ; then
+		killproc -KILL $DAEMON
+		RETVAL=$?
+		if grep -q bnx2i /proc/modules && [ -x $BRCM_ISCSIUIO ]; then
+		    killproc -KILL $BRCM_ISCSIUIO
+		fi
+ 		RETVAL=$?
+	    else
+		RETVAL=1
 	    fi
-	    modprobe -q -r ib_iser
-            if [ "$?" -ne "0" -a "$?" -ne "1" ]; then
-	        status=1 
-            fi
-	    rc_failed $status
-	else
 	    rc_failed $RETVAL
+	    rc_status -v
+	else
+	    # umounting failed, leave initiator running
+	    rc_status -s
 	fi
-	rc_status -v
 	;;
     status)
 	echo -n "Checking for iSCSI initiator service: "
@@ -190,7 +446,7 @@ case "$1" in
 	    rc_status -v
 	fi
 	;;
-    restart)
+    restart|reload)
 	$0 stop
 	RETVAL=$?
 	if [ "$RETVAL" != "0" ]; then
@@ -201,7 +457,7 @@ case "$1" in
 	$0 start
 	;;
     *)
-	echo "Usage: $0 {start|stop|status|restart}"
+	echo "Usage: $0 {start|stop|status|restart|reload}"
 	exit 1
 	;;
 esac

-- 
Debian Open-iSCSI Packaging



More information about the Pkg-iscsi-maintainers mailing list