|
|
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 |
|