Blame SOURCES/0291-iscsi-integrate-with-systemd-and-improve-robustness.patch

712866
From e25c3dbb6f91ed999399c981f00ab1dd1b30d6f1 Mon Sep 17 00:00:00 2001
712866
From: Harald Hoyer <harald@redhat.com>
712866
Date: Wed, 12 Aug 2015 14:33:49 +0200
712866
Subject: [PATCH] iscsi: integrate with systemd and improve robustness
712866
712866
parse-cmdline sets up an initial initiator-name to let iscsid start.
712866
712866
iscsid is started before doing any iscsistart business.
712866
712866
iscsistart is done with systemd-run asynchrone to do things in
712866
paralllel. Also restarted for every new interface which shows up.
712866
712866
If rd.iscsi.waitnet (default) is set, iscsistart is done only
712866
after all interfaces are up.
712866
712866
If not all interfaces are up and rd.iscsi.testroute (default) is set,
712866
the route to a iscsi target IP is checked and skipped, if there is none.
712866
712866
If all things fail, we issue a "dummy" interface iscsiroot to retry
712866
everything in the initqueue/timeout.
712866
712866
(cherry picked from commit d94050ddaea8343d8adb8f151c8f4cad591d29d9)
712866
---
712866
 modules.d/95iscsi/cleanup-iscsi.sh   |   2 +-
712866
 modules.d/95iscsi/iscsiroot.sh       | 116 ++++++++++++++++++++++++-----------
712866
 modules.d/95iscsi/module-setup.sh    |  31 ++++++++++
712866
 modules.d/95iscsi/parse-iscsiroot.sh |  27 ++++++--
712866
 4 files changed, 134 insertions(+), 42 deletions(-)
712866
712866
diff --git a/modules.d/95iscsi/cleanup-iscsi.sh b/modules.d/95iscsi/cleanup-iscsi.sh
712866
index a2d5951..88a63e0 100755
712866
--- a/modules.d/95iscsi/cleanup-iscsi.sh
712866
+++ b/modules.d/95iscsi/cleanup-iscsi.sh
712866
@@ -2,5 +2,5 @@
712866
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
712866
 # ex: ts=8 sw=4 sts=4 et filetype=sh
712866
 
712866
-[ -e /sys/module/bnx2i ] && killproc iscsiuio
712866
+[ -z "${DRACUT_SYSTEMD}" ] && [ -e /sys/module/bnx2i ] && killproc iscsiuio
712866
 
712866
diff --git a/modules.d/95iscsi/iscsiroot.sh b/modules.d/95iscsi/iscsiroot.sh
712866
index 1de6fb7..68da9dd 100755
712866
--- a/modules.d/95iscsi/iscsiroot.sh
712866
+++ b/modules.d/95iscsi/iscsiroot.sh
712866
@@ -38,7 +38,7 @@ iroot=${iroot#:}
712866
 # figured out a way how to check whether this is built-in or not
712866
 modprobe crc32c 2>/dev/null
712866
 
712866
-if [ -e /sys/module/bnx2i ] && ! [ -e /tmp/iscsiuio-started ]; then
712866
+if [ -z "${DRACUT_SYSTEMD}" ] && [ -e /sys/module/bnx2i ] && ! [ -e /tmp/iscsiuio-started ]; then
712866
         iscsiuio
712866
         > /tmp/iscsiuio-started
712866
 fi
712866
@@ -107,28 +107,47 @@ handle_netroot()
712866
 
712866
     parse_iscsi_root "$1" || return 1
712866
 
712866
+    # Bail out early, if there is no route to the destination
712866
+    if is_ip "$iscsi_target_ip" && [ "$netif" != "dummy" ] && ! all_ifaces_up && getargbool 1 rd.iscsi.testroute; then
712866
+        ip route get "$iscsi_target_ip" >/dev/null 2>&1 || return 0
712866
+    fi
712866
+
712866
 # XXX is this needed?
712866
     getarg ro && iscsirw=ro
712866
     getarg rw && iscsirw=rw
712866
     fsopts=${fsopts:+$fsopts,}${iscsirw}
712866
 
712866
+    if [ -z $iscsi_initiator ] && [ -f /sys/firmware/ibft/initiator/initiator-name ] && ! [ -f /tmp/iscsi_set_initiator ]; then
712866
+           iscsi_initiator=$(while read line || [ -n "$line" ]; do echo $line;done < /sys/firmware/ibft/initiator/initiator-name)
712866
+           echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
712866
+           rm -f /etc/iscsi/initiatorname.iscsi
712866
+           mkdir -p /etc/iscsi
712866
+           ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
712866
+           systemctl restart iscsid
712866
+           sleep 1
712866
+           > /tmp/iscsi_set_initiator
712866
+    fi
712866
+
712866
     if [ -z $iscsi_initiator ]; then
712866
-    # XXX Where are these from?
712866
+        [ -f /run/initiatorname.iscsi ] && . /run/initiatorname.iscsi
712866
         [ -f /etc/initiatorname.iscsi ] && . /etc/initiatorname.iscsi
712866
         [ -f /etc/iscsi/initiatorname.iscsi ] && . /etc/iscsi/initiatorname.iscsi
712866
         iscsi_initiator=$InitiatorName
712866
-
712866
-    # XXX rfc3720 says 'SCSI Initiator Name: The iSCSI Initiator Name specifies
712866
-    # the worldwide unique name of the initiator.' Could we use hostname/ip
712866
-    # if missing?
712866
     fi
712866
 
712866
     if [ -z $iscsi_initiator ]; then
712866
-       if [ -f /sys/firmware/ibft/initiator/initiator-name ]; then
712866
-           iscsi_initiator=$(while read line; do echo $line;done < /sys/firmware/ibft/initiator/initiator-name)
712866
-       fi
712866
+        iscsi_initiator=$(iscsi-iname)
712866
+        echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
712866
+        rm -f /etc/iscsi/initiatorname.iscsi
712866
+        mkdir -p /etc/iscsi
712866
+        ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
712866
+        systemctl restart iscsid
712866
+        > /tmp/iscsi_set_initiator
712866
+        # FIXME: iscsid is not yet ready, when the service is :-/
712866
+        sleep 1
712866
     fi
712866
 
712866
+
712866
     if [ -z $iscsi_target_port ]; then
712866
         iscsi_target_port=3260
712866
     fi
712866
@@ -137,23 +156,21 @@ handle_netroot()
712866
         iscsi_target_group=1
712866
     fi
712866
 
712866
-    if [ -z $iscsi_initiator ]; then
712866
-    # XXX is this correct?
712866
-        iscsi_initiator=$(iscsi-iname)
712866
-    fi
712866
-
712866
     if [ -z $iscsi_lun ]; then
712866
         iscsi_lun=0
712866
     fi
712866
 
712866
-    echo "InitiatorName='$iscsi_initiator'" > /run/initiatorname.iscsi
712866
+    echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
712866
     ln -fs /run/initiatorname.iscsi /dev/.initiatorname.iscsi
712866
-
712866
+    if ! [ -e /etc/iscsi/initiatorname.iscsi ]; then
712866
+        mkdir -p /etc/iscsi
712866
+        ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
712866
+    fi
712866
 # FIXME $iscsi_protocol??
712866
 
712866
-    if [ "$root" = "dhcp" ]; then
712866
+    if [ "$root" = "dhcp" ] || [ "$netroot" = "dhcp" ]; then
712866
         # if root is not specified try to mount the whole iSCSI LUN
712866
-        printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' $iscsi_lun >> /etc/udev/rules.d/99-iscsi-root.rules
712866
+        printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' "$iscsi_lun" >> /etc/udev/rules.d/99-iscsi-root.rules
712866
         udevadm control --reload
712866
         write_fs_tab /dev/root
712866
         wait_for_dev -n /dev/root
712866
@@ -163,29 +180,58 @@ handle_netroot()
712866
             echo "iscsi_lun=$iscsi_lun . /bin/mount-lun.sh " > $hookdir/mount/01-$$-iscsi.sh
712866
     fi
712866
 
712866
-    # force udevsettle to break
712866
-    > $hookdir/initqueue/work
712866
-
712866
-    iscsistart -i $iscsi_initiator -t $iscsi_target_name        \
712866
-        -g $iscsi_target_group -a $iscsi_target_ip      \
712866
-        -p $iscsi_target_port \
712866
-        ${iscsi_username:+-u $iscsi_username} \
712866
-        ${iscsi_password:+-w $iscsi_password} \
712866
-        ${iscsi_in_username:+-U $iscsi_in_username} \
712866
-        ${iscsi_in_password:+-W $iscsi_in_password} \
712866
-	${iscsi_iface_name:+--param iface.iscsi_ifacename=$iscsi_iface_name} \
712866
-	${iscsi_netdev_name:+--param iface.net_ifacename=$iscsi_netdev_name} \
712866
-        ${iscsi_param} \
712866
-	|| :
712866
-
712866
+    if [ -n "$DRACUT_SYSTEMD" ] && command -v systemd-run >/dev/null 2>&1; then
712866
+        netroot_enc=$(systemd-escape "iscsistart_${1}")
712866
+        status=$(systemctl is-active "$netroot_enc" 2>/dev/null)
712866
+        is_active=$?
712866
+        if [ $is_active -ne 0 ]; then
712866
+            if [ "$status" != "activating" ] && ! systemctl is-failed "$netroot_enc" >/dev/null 2>&1; then
712866
+                systemd-run --no-block --service-type=oneshot --remain-after-exit --quiet \
712866
+                            --description="Login iSCSI Target $iscsi_target_name" \
712866
+                            --unit="$netroot_enc" -- \
712866
+                            $(command -v iscsistart) \
712866
+                            -i $iscsi_initiator -t $iscsi_target_name        \
712866
+                            -g $iscsi_target_group -a $iscsi_target_ip      \
712866
+                            -p $iscsi_target_port \
712866
+                            ${iscsi_username:+-u $iscsi_username} \
712866
+                            ${iscsi_password:+-w $iscsi_password} \
712866
+                            ${iscsi_in_username:+-U $iscsi_in_username} \
712866
+                            ${iscsi_in_password:+-W $iscsi_in_password} \
712866
+	                    ${iscsi_iface_name:+--param iface.iscsi_ifacename=$iscsi_iface_name} \
712866
+	                    ${iscsi_netdev_name:+--param iface.net_ifacename=$iscsi_netdev_name} \
712866
+                            ${iscsi_param} >/dev/null 2>&1
712866
+            else
712866
+                systemctl --no-block restart "$netroot_enc" >/dev/null 2>&1
712866
+            fi
712866
+        fi
712866
+    else
712866
+        > $hookdir/initqueue/work
712866
+        iscsistart -i $iscsi_initiator -t $iscsi_target_name        \
712866
+                   -g $iscsi_target_group -a $iscsi_target_ip      \
712866
+                   -p $iscsi_target_port \
712866
+                   ${iscsi_username:+-u $iscsi_username} \
712866
+                   ${iscsi_password:+-w $iscsi_password} \
712866
+                   ${iscsi_in_username:+-U $iscsi_in_username} \
712866
+                   ${iscsi_in_password:+-W $iscsi_in_password} \
712866
+	           ${iscsi_iface_name:+--param iface.iscsi_ifacename=$iscsi_iface_name} \
712866
+	           ${iscsi_netdev_name:+--param iface.net_ifacename=$iscsi_netdev_name} \
712866
+                   ${iscsi_param} \
712866
+	    || :
712866
+    fi
712866
     netroot_enc=$(str_replace "$1" '/' '\2f')
712866
     echo 'started' > "/tmp/iscsistarted-iscsi:${netroot_enc}"
712866
+    return 0
712866
 }
712866
 
712866
 ret=0
712866
 
712866
+if [ "$netif" != "dummy" ] && getargbool 1 rd.iscsi.waitnet; then
712866
+    all_ifaces_up || exit 0
712866
+fi
712866
+
712866
 # loop over all netroot parameter
712866
-if getarg netroot; then
712866
+netroot=$(getarg netroot)
712866
+if [ $? -eq 0 ] && [ "$netroot" != "dhcp" ]; then
712866
     for nroot in $(getargs netroot); do
712866
         [ "${nroot%%:*}" = "iscsi" ] || continue
712866
         nroot="${nroot##iscsi:}"
712866
@@ -212,6 +258,6 @@ fi
712866
 
712866
 need_shutdown
712866
 
712866
-# now we have a root filesystem somewhere in /dev/sda*
712866
+# now we have a root filesystem somewhere in /dev/sd*
712866
 # let the normal block handler handle root=
712866
 exit $ret
712866
diff --git a/modules.d/95iscsi/module-setup.sh b/modules.d/95iscsi/module-setup.sh
712866
index 49f9a0e..d12eb7d 100755
712866
--- a/modules.d/95iscsi/module-setup.sh
712866
+++ b/modules.d/95iscsi/module-setup.sh
712866
@@ -83,6 +83,37 @@ install() {
712866
     inst "$moddir/iscsiroot.sh" "/sbin/iscsiroot"
712866
     if ! dracut_module_included "systemd"; then
712866
         inst "$moddir/mount-lun.sh" "/bin/mount-lun.sh"
712866
+    else
712866
+        inst_multiple -o \
712866
+                      $systemdsystemunitdir/iscsi.service \
712866
+                      $systemdsystemunitdir/iscsid.service \
712866
+                      $systemdsystemunitdir/iscsid.socket \
712866
+                      $systemdsystemunitdir/iscsiuio.service \
712866
+                      $systemdsystemunitdir/iscsiuio.socket \
712866
+                      iscsiadm iscsid
712866
+
712866
+        mkdir -p "${initdir}/$systemdsystemunitdir/sockets.target.wants"
712866
+        for i in \
712866
+                iscsiuio.socket \
712866
+            ; do
712866
+            ln_r "$systemdsystemunitdir/${i}" "$systemdsystemunitdir/sockets.target.wants/${i}"
712866
+        done
712866
+
712866
+        mkdir -p "${initdir}/$systemdsystemunitdir/basic.target.wants"
712866
+        for i in \
712866
+                iscsid.service \
712866
+            ; do
712866
+            ln_r "$systemdsystemunitdir/${i}" "$systemdsystemunitdir/basic.target.wants/${i}"
712866
+        done
712866
+
712866
+        # Make sure iscsid is started after dracut-cmdline and ready for the initqueue
712866
+        mkdir -p "${initdir}/$systemdsystemunitdir/iscsid.service.d"
712866
+        (
712866
+            echo "[Unit]"
712866
+            echo "After=dracut-cmdline.service"
712866
+            echo "Before=dracut-initqueue.service"
712866
+        ) > "${initdir}/$systemdsystemunitdir/iscsid.service.d/dracut.conf"
712866
     fi
712866
+
712866
     dracut_need_initqueue
712866
 }
712866
diff --git a/modules.d/95iscsi/parse-iscsiroot.sh b/modules.d/95iscsi/parse-iscsiroot.sh
712866
index b48be38..6a21b50 100755
712866
--- a/modules.d/95iscsi/parse-iscsiroot.sh
712866
+++ b/modules.d/95iscsi/parse-iscsiroot.sh
712866
@@ -61,12 +61,13 @@ fi
712866
 
712866
 # iscsi_firmware does not need argument checking
712866
 if [ -n "$iscsi_firmware" ] ; then
712866
-    netroot=${netroot:-iscsi:}
712866
-    modprobe -q iscsi_boot_sysfs 2>/dev/null
712866
-    modprobe -q iscsi_ibft
712866
-    initqueue --onetime --timeout /sbin/iscsiroot dummy "'$netroot'" "'$NEWROOT'"
712866
+    [ -z "$netroot" ] && netroot=iscsi:
712866
+    modprobe -b -q iscsi_boot_sysfs 2>/dev/null
712866
+    modprobe -b -q iscsi_ibft
712866
 fi
712866
 
712866
+initqueue --onetime --timeout /sbin/iscsiroot dummy "$netroot" "$NEWROOT"
712866
+
712866
 # If it's not iscsi we don't continue
712866
 [ "${netroot%%:*}" = "iscsi" ] || return
712866
 
712866
@@ -92,8 +93,22 @@ if [ -n "$netroot" ] && [ "$root" != "/dev/root" ] && [ "$root" != "dhcp" ]; the
712866
     fi
712866
 fi
712866
 
712866
-netroot_enc=$(str_replace "$netroot" '/' '\2f')
712866
-echo "[ -f '/tmp/iscsistarted-$netroot_enc' ]" > $hookdir/initqueue/finished/iscsi_started.sh
712866
+if arg=$(getarg rd.iscsi.initiator -d iscsi_initiator=) && [ -n "$arg" ]; then
712866
+    iscsi_initiator=$arg
712866
+    echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
712866
+    ln -fs /run/initiatorname.iscsi /dev/.initiatorname.iscsi
712866
+    if ! [ -e /etc/iscsi/initiatorname.iscsi ]; then
712866
+        mkdir -p /etc/iscsi
712866
+        ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
712866
+    fi
712866
+fi
712866
+
712866
+if [ -n "$iscsi_firmware" ] ; then
712866
+    echo "[ -f '/tmp/iscsistarted-firmware' ]" > $hookdir/initqueue/finished/iscsi_started.sh
712866
+else
712866
+    netroot_enc=$(str_replace "$netroot" '/' '\2f')
712866
+    echo "[ -f '/tmp/iscsistarted-$netroot_enc' ]" > $hookdir/initqueue/finished/iscsi_started.sh
712866
+fi
712866
 
712866
 # Done, all good!
712866
 rootok=1