From 02d816b78f2fcc25775964ca6ee2eb6fad18eafc Mon Sep 17 00:00:00 2001
From: Quentin Smith <quentin@mit.edu>
Date: Sat, 11 Dec 2010 21:08:55 -0500
Subject: [PATCH] Refactor postinstall script so it has a separate script for
 connecting to the RAID

---
 debian/changelog                 |    8 ++++++
 debian/xvm-iscsi-config.install  |    1 +
 debian/xvm-iscsi-config.postinst |   14 ++++-------
 xvm-iscsi-connect                |   51 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 9 deletions(-)
 create mode 100755 xvm-iscsi-connect

diff --git a/debian/changelog b/debian/changelog
index c420750..ca62d6c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+xvm-iscsi-config (0.0.12) unstable; urgency=low
+
+  * Refactor postinstall script so it has a separate script for connecting
+    to the targets.
+  * Make connection process more resilient to failed discovery.
+
+ -- Quentin Smith <quentin@mit.edu>  Sat, 11 Dec 2010 21:15:11 -0500
+
 xvm-iscsi-config (0.0.11) unstable; urgency=low
 
   * Support multiple iSCSI targets and read their addresses
diff --git a/debian/xvm-iscsi-config.install b/debian/xvm-iscsi-config.install
index abbc5e6..ab479e2 100644
--- a/debian/xvm-iscsi-config.install
+++ b/debian/xvm-iscsi-config.install
@@ -1,3 +1,4 @@
 debian/iscsid.conf.xvm.mako etc/iscsi
 ifaces etc/iscsi
 multipath.conf.xvm etc
+xvm-iscsi-connect usr/lib
diff --git a/debian/xvm-iscsi-config.postinst b/debian/xvm-iscsi-config.postinst
index 6182942..a58dc00 100755
--- a/debian/xvm-iscsi-config.postinst
+++ b/debian/xvm-iscsi-config.postinst
@@ -34,7 +34,9 @@ $(cat /sys/class/iscsi_host/$(readlink /sys/class/iscsi_session/$i/device | perl
 
 get_new_sessions() {
     for i in $(invirt-getconf --ls iscsi.targets); do
-        echo $(invirt-getconf iscsi.targets.$i.ip) $(invirt-getconf iscsi.targets.$i.iface)
+	for j in $(invirt-getconf --ls iscsi.targets.$i.ifaces); do
+            echo $(invirt-getconf iscsi.targets.$i.ip) $(invirt-getconf iscsi.targets.$i.ifaces.$j)
+	done
     done | sort
 }
 
@@ -75,15 +77,9 @@ EOF
         fi
         if ! diff <(get_current_sessions) <(get_new_sessions) >/dev/null; then
             if [ -z "$safe" ]; then
-                for i in $(invirt-getconf --ls iscsi.targets); do
-                    iscsiadm -m discovery -t st -p $(invirt-getconf iscsi.targets.$i.ip):3260 -I $(invirt-getconf iscsi.targets.$i.iface)
-                    iscsiadm -m node -p $(invirt-getconf iscsi.targets.$i.ip):3260 -I $(invirt-getconf iscsi.targets.$i.iface) -l
-                done
+		/usr/lib/xvm-iscsi-connect
             else
-              for i in $(invirt-getconf --ls iscsi.targets); do
-                  echo "  "iscsiadm -m discovery -t st -p $(invirt-getconf iscsi.targets.$i.ip):3260 -I $(invirt-getconf iscsi.targets.$i.iface)
-                  echo "  "iscsiadm -m node -p $(invirt-getconf iscsi.targets.$i.ip):3260 -I $(invirt-getconf iscsi.targets.$i.iface) -l
-              done
+		echo "  /usr/lib/xvm-iscsi-connect"
             fi
             cat <<EOF
 You may want to recreate the LVM nodes:
diff --git a/xvm-iscsi-connect b/xvm-iscsi-connect
new file mode 100755
index 0000000..b0701d0
--- /dev/null
+++ b/xvm-iscsi-connect
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+set -e
+
+good_nodes=""
+
+for i in $(invirt-getconf --ls iscsi.targets); do
+    # Extract the portal to talk to
+    portal_ip=$(invirt-getconf iscsi.targets.$i.ip)
+
+    # Extract the interfaces we should talk to this portal
+    # on. Unfortunately, we have to ask about all the interfaces
+    # simultaneously, because iscsiadm deletes all existing mentions
+    # of a portal when you run discovery again.
+    ifaces=$(for j in $(invirt-getconf --ls iscsi.targets.$i.ifaces); do invirt-getconf iscsi.targets.$i.ifaces.$j; done)
+
+    echo "Connecting to $portal_ip via $ifaces"
+
+    # Use SendTargets to discover the available targets on the given portal.
+    iscsiadm -m discovery -t st -p $portal_ip:3260 $(for iface in $ifaces; do echo -I $iface; done)
+
+    # Because of protocol limitations (see
+    # http://www.pdl.cmu.edu/mailinglists/ips/mail/msg05174.html), the
+    # discovery attempt may have returned additional targets that are
+    # unreachable via this interface/portal. Make a list of discovered
+    # target, portal, interface combinations so we can later remove
+    # extraneous ones.
+    for iface in $ifaces; do
+	good_nodes="$good_nodes "$(echo /etc/iscsi/nodes/*/$portal_ip,3260,1/$iface)
+    done
+
+    # If the discovery attempt did not log into the target, explicitly do so now.
+    for iface in $ifaces; do
+	iscsiadm -m node -p $portal_ip:3260 -I $iface -l
+    done
+done
+
+# Find all the nodes we now know about that we weren't supposed to
+bad_nodes=$(find /etc/iscsi/nodes -type f | grep -Fxvf <(echo "$good_nodes" | sed 's/ /\n/g'))
+# and delete them.
+echo "Removing "$(echo $bad_nodes | wc -w)" extraneous discovered targets"
+for node in $bad_nodes; do
+    echo "Removing $node"
+
+    # Remove the node entry
+    rm $node;
+
+    # Remove the cached results of the discovery so iscsiadm doesn't
+    # get confused
+    find /etc/iscsi/send_targets -lname "${node%/*}" -delete
+done
-- 
1.7.9.5