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

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