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

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