Blame 0020-iscsiadm-bind-ifaces-to-portals-found-using-isns.patch

c2d5d2
From 2991867601094b39ca1cf7e14d8eefecda14ffb7 Mon Sep 17 00:00:00 2001
c2d5d2
From: Mike Christie <michaelc@cs.wisc.edu>
c2d5d2
Date: Tue, 22 Jan 2013 10:44:27 -0700
c2d5d2
Subject: iscsiadm: bind ifaces to portals found using isns
c2d5d2
c2d5d2
Bug and patch from Jayamohan Kallickal at Emulex.
c2d5d2
c2d5d2
This adds support to be able to use isns discovery and
c2d5d2
bind the portals found to offload ifaces. Note that
c2d5d2
this does not do iSNS through the offload card. It
c2d5d2
uses a normal net connection but portals that are found
c2d5d2
will be setup to login using the offload card.
c2d5d2
c2d5d2
The problem with the previous code was that isns
c2d5d2
discovery code was not reading in the iface info before
c2d5d2
binding, so the resulting setup was not binding the offload
c2d5d2
card to the record.
c2d5d2
c2d5d2
[Minor cleanup of patch by Mike Christie]
c2d5d2
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
c2d5d2
---
c2d5d2
 usr/iscsiadm.c | 127 ++++++++++++++++++++++++++++++---------------------------
c2d5d2
 1 file changed, 66 insertions(+), 61 deletions(-)
c2d5d2
c2d5d2
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
c2d5d2
index df76df9..efe6383 100644
c2d5d2
--- a/usr/iscsiadm.c
c2d5d2
+++ b/usr/iscsiadm.c
c2d5d2
@@ -1133,17 +1133,55 @@ do_software_sendtargets(discovery_rec_t *drec, struct list_head *ifaces,
c2d5d2
 	return rc;
c2d5d2
 }
c2d5d2
 
c2d5d2
+static int do_isns(discovery_rec_t *drec, struct list_head *ifaces,
c2d5d2
+		   int info_level, int do_login, int op)
c2d5d2
+{
c2d5d2
+	struct list_head rec_list;
c2d5d2
+	struct node_rec *rec, *tmp;
c2d5d2
+	int rc;
c2d5d2
+
c2d5d2
+	INIT_LIST_HEAD(&rec_list);
c2d5d2
+	/*
c2d5d2
+	 * compat: if the user did not pass any op then we do all
c2d5d2
+	 * ops for them
c2d5d2
+	 */
c2d5d2
+	if (!op)
c2d5d2
+		op = OP_NEW | OP_DELETE | OP_UPDATE;
c2d5d2
+
c2d5d2
+
c2d5d2
+	rc = idbm_bind_ifaces_to_nodes(discovery_isns, drec, ifaces,
c2d5d2
+				       &rec_list);
c2d5d2
+	if (rc) {
c2d5d2
+		log_error("Could not perform iSNS discovery: %s",
c2d5d2
+			  iscsi_err_to_str(rc));
c2d5d2
+		return rc;
c2d5d2
+	} else if (list_empty(&rec_list)) {
c2d5d2
+		log_error("No portals found");
c2d5d2
+		return ISCSI_ERR_NO_OBJS_FOUND;
c2d5d2
+	}
c2d5d2
+
c2d5d2
+	rc = exec_disc_op_on_recs(drec, &rec_list, info_level, do_login, op);
c2d5d2
+
c2d5d2
+	list_for_each_entry_safe(rec, tmp, &rec_list, list) {
c2d5d2
+		list_del(&rec->list);
c2d5d2
+		free(rec);
c2d5d2
+	}
c2d5d2
+
c2d5d2
+	return rc;
c2d5d2
+}
c2d5d2
+
c2d5d2
 static int
c2d5d2
-do_sendtargets(discovery_rec_t *drec, struct list_head *ifaces,
c2d5d2
-	       int info_level, int do_login, int op, int sync_drec)
c2d5d2
+do_target_discovery(discovery_rec_t *drec, struct list_head *ifaces,
c2d5d2
+		    int info_level, int do_login, int op, int sync_drec)
c2d5d2
 {
c2d5d2
+
c2d5d2
 	struct iface_rec *tmp, *iface;
c2d5d2
 	int rc, host_no;
c2d5d2
 	struct iscsi_transport *t;
c2d5d2
 
c2d5d2
 	if (list_empty(ifaces)) {
c2d5d2
 		ifaces = NULL;
c2d5d2
-		goto sw_st;
c2d5d2
+		goto sw_discovery;
c2d5d2
 	}
c2d5d2
 
c2d5d2
 	/* we allow users to mix hw and sw iscsi so we have to sort it out */
c2d5d2
@@ -1177,59 +1215,30 @@ do_sendtargets(discovery_rec_t *drec, struct list_head *ifaces,
c2d5d2
 			continue;
c2d5d2
 		}
c2d5d2
 
c2d5d2
-		if (t->caps & CAP_SENDTARGETS_OFFLOAD) {
c2d5d2
-			do_offload_sendtargets(drec, host_no, do_login);
c2d5d2
-			list_del(&iface->list);
c2d5d2
-			free(iface);
c2d5d2
-		}
c2d5d2
+		if (drec->type ==  DISCOVERY_TYPE_SENDTARGETS)
c2d5d2
+			if (t->caps & CAP_SENDTARGETS_OFFLOAD) {
c2d5d2
+				do_offload_sendtargets(drec, host_no, do_login);
c2d5d2
+				list_del(&iface->list);
c2d5d2
+				free(iface);
c2d5d2
+			}
c2d5d2
 	}
c2d5d2
 
c2d5d2
 	if (list_empty(ifaces))
c2d5d2
 		return ISCSI_ERR_NO_OBJS_FOUND;
c2d5d2
 
c2d5d2
-sw_st:
c2d5d2
-	return do_software_sendtargets(drec, ifaces, info_level, do_login,
c2d5d2
-				       op, sync_drec);
c2d5d2
-}
c2d5d2
-
c2d5d2
-static int do_isns(discovery_rec_t *drec, struct list_head *ifaces,
c2d5d2
-		   int info_level, int do_login, int op)
c2d5d2
-{
c2d5d2
-	struct list_head rec_list;
c2d5d2
-	struct node_rec *rec, *tmp;
c2d5d2
-	int rc;
c2d5d2
-
c2d5d2
-	INIT_LIST_HEAD(&rec_list);
c2d5d2
-	/*
c2d5d2
-	 * compat: if the user did not pass any op then we do all
c2d5d2
-	 * ops for them
c2d5d2
-	 */
c2d5d2
-	if (!op)
c2d5d2
-		op = OP_NEW | OP_DELETE | OP_UPDATE;
c2d5d2
-
c2d5d2
-	drec->type = DISCOVERY_TYPE_ISNS;
c2d5d2
-
c2d5d2
-	rc = idbm_bind_ifaces_to_nodes(discovery_isns, drec, ifaces,
c2d5d2
-				       &rec_list);
c2d5d2
-	if (rc) {
c2d5d2
-		log_error("Could not perform iSNS discovery: %s",
c2d5d2
-			  iscsi_err_to_str(rc));
c2d5d2
-		return rc;
c2d5d2
-	} else if (list_empty(&rec_list)) {
c2d5d2
-		log_error("No portals found");
c2d5d2
-		return ISCSI_ERR_NO_OBJS_FOUND;
c2d5d2
-	}
c2d5d2
-
c2d5d2
-	rc = exec_disc_op_on_recs(drec, &rec_list, info_level, do_login, op);
c2d5d2
-
c2d5d2
-	list_for_each_entry_safe(rec, tmp, &rec_list, list) {
c2d5d2
-		list_del(&rec->list);
c2d5d2
-		free(rec);
c2d5d2
+sw_discovery:
c2d5d2
+	switch (drec->type) {
c2d5d2
+	case DISCOVERY_TYPE_SENDTARGETS:
c2d5d2
+		return do_software_sendtargets(drec, ifaces, info_level,
c2d5d2
+						do_login, op, sync_drec);
c2d5d2
+	case DISCOVERY_TYPE_ISNS:
c2d5d2
+		return do_isns(drec, ifaces, info_level, do_login, op);
c2d5d2
+	default:
c2d5d2
+		log_debug(1, "Unknown Discovery Type : %d\n", drec->type);
c2d5d2
 	}
c2d5d2
-
c2d5d2
-	return rc;
c2d5d2
 }
c2d5d2
 
c2d5d2
+
c2d5d2
 static int
c2d5d2
 verify_mode_params(int argc, char **argv, char *allowed, int skip_m)
c2d5d2
 {
c2d5d2
@@ -2394,15 +2403,9 @@ static int exec_discover(int disc_type, char *ip, int port,
c2d5d2
 	rc = 0;
c2d5d2
 	switch (disc_type) {
c2d5d2
 	case DISCOVERY_TYPE_SENDTARGETS:
c2d5d2
-		/*
c2d5d2
-		 * idbm_add_discovery call above handles drec syncing so
c2d5d2
-		 * we always pass in 0 here.
c2d5d2
-		 */
c2d5d2
-		rc = do_sendtargets(drec, ifaces, info_level, do_login, op,
c2d5d2
-				    0);
c2d5d2
-		break;
c2d5d2
 	case DISCOVERY_TYPE_ISNS:
c2d5d2
-		rc = do_isns(drec, ifaces, info_level, do_login, op);
c2d5d2
+		rc = do_target_discovery(drec, ifaces, info_level, do_login, op,
c2d5d2
+				    0);
c2d5d2
 		break;
c2d5d2
 	default:
c2d5d2
 		log_error("Unsupported discovery type.");
c2d5d2
@@ -2535,8 +2538,7 @@ static int exec_disc_op(int disc_type, char *ip, int port,
c2d5d2
 		idbm_sendtargets_defaults(&drec.u.sendtargets);
c2d5d2
 		strlcpy(drec.address, ip, sizeof(drec.address));
c2d5d2
 		drec.port = port;
c2d5d2
-
c2d5d2
-		rc = do_sendtargets(&drec, ifaces, info_level,
c2d5d2
+		rc = do_target_discovery(&drec, ifaces, info_level,
c2d5d2
 				    do_login, op, 1);
c2d5d2
 		if (rc)
c2d5d2
 			goto done;
c2d5d2
@@ -2559,7 +2561,9 @@ static int exec_disc_op(int disc_type, char *ip, int port,
c2d5d2
 		else
c2d5d2
 			drec.port = port;
c2d5d2
 
c2d5d2
-		rc = do_isns(&drec, ifaces, info_level, do_login, op);
c2d5d2
+		drec.type = DISCOVERY_TYPE_ISNS;
c2d5d2
+		rc = do_target_discovery(&drec, ifaces, info_level,
c2d5d2
+					do_login, op, 0);
c2d5d2
 		if (rc)
c2d5d2
 			goto done;
c2d5d2
 		break;
c2d5d2
@@ -2590,8 +2594,9 @@ static int exec_disc_op(int disc_type, char *ip, int port,
c2d5d2
 			}
c2d5d2
 			if ((do_discover || do_login) &&
c2d5d2
 			    drec.type == DISCOVERY_TYPE_SENDTARGETS) {
c2d5d2
-				rc = do_sendtargets(&drec, ifaces, info_level,
c2d5d2
-						    do_login, op, 0);
c2d5d2
+				rc = do_target_discovery(&drec, ifaces,
c2d5d2
+						info_level, do_login,
c2d5d2
+						op, 0);
c2d5d2
 			} else if (op == OP_NOOP || op == OP_SHOW) {
c2d5d2
 				if (!idbm_print_discovery_info(&drec,
c2d5d2
 							       do_show)) {
c2d5d2
-- 
c2d5d2
1.8.1.4
c2d5d2