* [RFC PATCH] iscsi tools: manage qla4xxx iscsi sessions with iscsiadm
@ 2011-05-06 12:30 vikas.chaudhary
0 siblings, 0 replies; only message in thread
From: vikas.chaudhary @ 2011-05-06 12:30 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, open-iscsi, vikas.chaudhary, lalit.chandivade,
ravi.anand, Manish Rangankar
From: Manish Rangankar <manish.rangankar@qlogic.com>
This patch is based on initial work done by Mike Christie here,
http://groups.google.com/group/open-iscsi/browse_thread/thread/193fe9037f3127da#
This patch modifies iscsiadm so it can control sessions that are accessed
through qla4xxx.
To do discovery using the qla4xxx iscsi class interface first check the
available qla4xxx iface
./iscsiadm -m iface -P 0
will display the different ifaces like this:
qla4xxx.00:0e:1e:04:87:fa qla4xxx,00:0e:1e:04:87:fa,192.168.1.112,\
<empty>,<empty>
qla4xxx.00:0e:1e:04:87:fe qla4xxx,00:0e:1e:04:87:fe,<empty>,<empty>,<empty>
Issue discovery command
./iscsiadm -m discovery -t sendtargets -I qla4xxx.00:0e:1e:04:87:fa \
-p 192.168.1.10:3260
192.168.1.10:3260,1 iqn.2001-05.com.target:0-7d76ca2b7d54b541-disk2
192.168.1.10:3260,1 iqn.2001-05.com.target:0-46f6ca2b7d84b541-disk3
192.168.1.10:3260,1 iqn.2001-05.com.target:0-4c76ca2b7db4b541-disk4
192.168.1.10:3260,1 iqn.2001-05.com.target:0-7346ca2b6d04b6bb-disk1
To view discovered nodes do
./iscsiadm -m node
To login
./iscsiadm -m node -T iqn.2001-05.com.target:0-7346ca2b6d04b6bb-disk1 \
-I qla4xxx.00:0e:1e:04:87:fa -p 192.168.1.10:3260 -l
An error or ok message is displayed to indicate login failure or success.
To see the sessions use
./iscsiadm -m session
And then to logout do
./iscsiadm -m node -T iqn.2001-05.com.target:0-7346ca2b6d04b6bb-disk1 \
-I qla4xxx.00:0e:1e:04:87:fa -p 192.168.1.10:3260 -u
An error or a ok message is displayed to indicate logout failure or success.
Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
include/iscsi_if.h | 1 +
usr/discovery.c | 4 +
usr/initiator.c | 325 ++++++++++++++++++++++++++++++++++++------------
usr/initiator.h | 12 ++-
usr/initiator_common.c | 4 +
usr/io.c | 7 +-
usr/iscsi_ipc.h | 3 -
usr/iscsi_sysfs.c | 4 +-
usr/iscsiadm.c | 10 --
usr/iscsid.c | 19 ---
usr/mgmt_ipc.c | 2 +-
usr/netlink.c | 28 +++--
usr/session_mgmt.c | 1 -
usr/transport.c | 4 +
14 files changed, 294 insertions(+), 130 deletions(-)
diff --git a/include/iscsi_if.h b/include/iscsi_if.h
index d31c681..f38697f 100644
--- a/include/iscsi_if.h
+++ b/include/iscsi_if.h
@@ -488,6 +488,7 @@ enum iscsi_host_param {
#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */
#define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal,
and verification */
+#define CAP_LOGIN_OFFLOAD 0x4000 /* offload normal session login */
/*
* These flags describes reason of stop_conn() call
diff --git a/usr/discovery.c b/usr/discovery.c
index 3c49aff..7b13500 100644
--- a/usr/discovery.c
+++ b/usr/discovery.c
@@ -1318,6 +1318,9 @@ redirect_reconnect:
iscsi_copy_operational_params(&session->conn[0], &config->session_conf,
&config->conn_conf);
+ if ((session->t->caps & CAP_LOGIN_OFFLOAD))
+ goto start_conn;
+
status_class = 0;
status_detail = 0;
rc = ISCSI_ERR_LOGIN;
@@ -1420,6 +1423,7 @@ redirect_reconnect:
if (!(t->caps & CAP_TEXT_NEGO))
return 0;
+start_conn:
log_debug(2, "%s discovery set params\n", __FUNCTION__);
rc = iscsi_session_set_params(conn);
if (rc) {
diff --git a/usr/initiator.c b/usr/initiator.c
index 5eb05b5..412fb54 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -451,7 +451,8 @@ session_conn_shutdown(iscsi_conn_t *conn, queue_task_t *qtask,
log_debug(2, "disconnect conn");
/* this will check for a valid interconnect connection */
- conn->session->t->template->ep_disconnect(conn);
+ if (session->t->template->ep_disconnect)
+ session->t->template->ep_disconnect(conn);
if (session->id == -1)
goto cleanup;
@@ -481,7 +482,9 @@ session_conn_shutdown(iscsi_conn_t *conn, queue_task_t *qtask,
cleanup:
if (session->id != -1) {
log_debug(2, "kdestroy session %u", session->id);
- if (ipc->destroy_session(session->t->handle, session->id)) {
+ session->r_stage = R_STAGE_SESSION_DESTOYED;
+ err = ipc->destroy_session(session->t->handle, session->id);
+ if (err) {
log_error("can not safely destroy session %d",
session->id);
return ISCSI_ERR_INTERNAL;
@@ -806,8 +809,8 @@ __conn_error_handle(iscsi_session_t *session, iscsi_conn_t *conn)
if (session->r_stage == R_STAGE_SESSION_REOPEN) {
queue_task_t *qtask;
- if (session->sync_qtask)
- qtask = session->sync_qtask;
+ if (session->notify_qtask)
+ qtask = session->notify_qtask;
else
qtask = &session->reopen_qtask;
iscsi_login_eh(conn, qtask, ISCSI_ERR_TRANS);
@@ -1039,9 +1042,11 @@ setup_full_feature_phase(iscsi_conn_t *conn)
session->nrec.conn[conn->id].port,
session->nrec.iface.name);
} else {
- session->sync_qtask = NULL;
+ session->notify_qtask = NULL;
+
+ if (!(session->t->caps & CAP_LOGIN_OFFLOAD))
+ session_online_devs(session->hostno, session->id);
- session_online_devs(session->hostno, session->id);
mgmt_ipc_write_rsp(c->qtask, ISCSI_SUCCESS);
log_warning("connection%d:%d is operational after recovery "
"(%d attempts)", session->id, conn->id,
@@ -1119,8 +1124,10 @@ static void iscsi_stop(void *data)
iscsi_ev_context_put(ev_context);
- if (!iscsi_send_logout(conn))
- return;
+ if (!(conn->session->t->caps & CAP_LOGIN_OFFLOAD)) {
+ if (!iscsi_send_logout(conn))
+ return;
+ }
rc = session_conn_shutdown(conn, conn->logout_qtask, ISCSI_SUCCESS);
if (rc)
@@ -1491,8 +1498,9 @@ static void session_conn_poll(void *data)
log_debug(3, "created new iSCSI session sid %d host "
"no %u", session->id, session->hostno);
- if (ipc->create_conn(session->t->handle,
- session->id, conn->id, &conn->id)) {
+ err = ipc->create_conn(session->t->handle,
+ session->id, conn->id, &conn->id);
+ if (err) {
log_error("Can't create connection.");
err = ISCSI_ERR_INTERNAL;
goto cleanup;
@@ -1529,6 +1537,11 @@ static void session_conn_poll(void *data)
conn->exp_statsn = iscsi_sysfs_get_exp_statsn(session->id);
+ if (session->t->caps & CAP_LOGIN_OFFLOAD) {
+ setup_full_feature_phase(conn);
+ return;
+ }
+
if (iscsi_login_begin(session, c)) {
iscsi_login_eh(conn, qtask, ISCSI_ERR_LOGIN);
return;
@@ -1550,6 +1563,65 @@ cleanup:
session_conn_shutdown(conn, qtask, err);
}
+/*
+ * LLD like qla4xxx notify the userspace that a login succeeded, the next
+ * step will be from userspace to trigger the LUN discovery.
+ */
+static void iscsi_session_created(void *data)
+{
+ struct iscsi_ev_context *ev_context = data;
+ struct iscsi_conn *conn = ev_context->conn;
+ struct iscsi_session *session = conn->session;
+ queue_task_t *qtask;
+
+ iscsi_ev_context_put(ev_context);
+
+ if (!(session->t->caps & CAP_LOGIN_OFFLOAD))
+ return;
+
+ if (conn->state != STATE_IN_LOGIN)
+ /* just a notification that the session struct was created */
+ return;
+ conn->state = STATE_LOGGED_IN;
+ /*
+ * ok we were in_login and now we got the notification that we are
+ * logged in
+ */
+ log_debug(3, "session created sid %u host no %d", session->id,
+ session->hostno);
+ qtask = session->notify_qtask;
+ session->notify_qtask = NULL;
+ session_scan_host(session, session->hostno, qtask);
+}
+
+static void iscsi_session_destroyed(void *data)
+{
+ struct iscsi_ev_context *ev_context = data;
+ struct iscsi_conn *conn = ev_context->conn;
+ struct iscsi_session *session = conn->session;
+
+ iscsi_ev_context_put(ev_context);
+
+ if (session->r_stage == R_STAGE_SESSION_DESTOYED)
+ /*
+ * session destruction was initiated by iscsid and this is
+ * just an async notice that the kernel destruction has
+ * been completed. We can ignore this.
+ */
+ return;
+
+ /*
+ * session destruction was initiated by the kernel.
+ * The kernel part is done and so we must clean up iscsid bits.
+ */
+ log_debug(3, "session destroyed sid %u host no %d", session->id,
+ session->hostno);
+
+ if (session_conn_shutdown(conn, NULL, ISCSI_SUCCESS))
+ log_error("BUG: Could not shutdown session.");
+}
+
+
static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
struct iscsi_conn *conn, unsigned long tmo,
int event)
@@ -1561,6 +1633,17 @@ static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
ev_context->conn = conn;
switch (event) {
+ case EV_SESSION_CREATED:
+ actor_new(&ev_context->actor, iscsi_session_created,
+ ev_context);
+ actor_schedule(&ev_context->actor);
+ break;
+ case EV_SESSION_DESTROYED:
+ actor_new(&ev_context->actor, iscsi_session_destroyed,
+ ev_context);
+ actor_schedule(&ev_context->actor);
+ break;
+
case EV_CONN_RECV_PDU:
actor_new(&ev_context->actor, session_conn_recv_pdu,
ev_context);
@@ -1635,8 +1718,136 @@ static int session_is_running(node_rec_t *rec)
return 0;
}
+static int iscsi_sw_session_login(struct node_rec *rec, queue_task_t *qtask,
+ struct iscsi_session *session)
+{
+ struct iscsi_conn *conn = &session->conn[0];
+
+ if (iscsi_host_set_net_params(&rec->iface, session))
+ return ISCSI_ERR_LOGIN;
+
+ conn->state = STATE_XPT_WAIT;
+ if (iscsi_conn_connect(conn, qtask))
+ return ISCSI_ERR_TRANS;
+
+ if (gettimeofday(&conn->initial_connect_time, NULL))
+ log_error("Could not get initial connect time. If "
+ "login errors iscsid may give up the initial "
+ "login early. You should manually login.");
+
+ qtask->rsp.command = MGMT_IPC_SESSION_LOGIN;
+ qtask->rsp.err = ISCSI_SUCCESS;
+ return ISCSI_SUCCESS;
+}
+
+static int iscsi_session_offload_login(struct node_rec *rec,
+ queue_task_t *qtask,
+ struct iscsi_session *session)
+{
+ struct iscsi_conn *conn = &session->conn[0];
+ int err = 0, rc = 0, sleep_count = 0;
+ uint32_t host_no, host_no_ret;
+ struct iscsi_transport *t = session->t;
+
+ host_no = iscsi_sysfs_get_host_no_from_hwinfo(&rec->iface, &err);
+ if (rc) {
+ log_error("Could not get host no for iface %s.\n",
+ rec->iface.name);
+ return ISCSI_ERR_LOGIN;
+ }
+
+ log_debug(2, "match iface %s to hostno %u\n", rec->iface.name, host_no);
+
+ rc = t->template->ep_connect(conn, 1);
+ if (rc < 0) {
+ rc = ENOTCONN;
+ return ISCSI_ERR_LOGIN;
+ }
+
+ do {
+ rc = t->template->ep_poll(conn, 1);
+ if (rc < 0) {
+ rc = ENOTCONN;
+ return ISCSI_ERR_LOGIN;
+ } else if (rc == 0) {
+ if (sleep_count == conn->login_timeout) {
+ rc = ETIMEDOUT;
+ return ISCSI_ERR_LOGIN;
+ }
+ sleep_count++;
+ sleep(1);
+ } else
+ break;
+ } while (1);
+
+ conn->state = STATE_XPT_WAIT;
+ err = ipc->create_session(session->t->handle, conn->transport_ep_handle,
+ 0, session->nrec.session.cmds_max,
+ session->nrec.session.queue_depth,
+ &session->id, &host_no_ret);
+ if (err) {
+ log_error("Could not create hw session (err %d).\n", err);
+ return ISCSI_ERR_LOGIN;
+ }
+
+ if (host_no_ret != host_no)
+ log_error("Host no mismatch got %u. Expected %u.\n",
+ host_no_ret, host_no);
+ session->hostno = host_no_ret;
+
+ err = ipc->create_conn(session->t->handle, session->id, conn->id,
+ &conn->id);
+ if (err) {
+ log_error("Can't create connection (%d)", err);
+ err = ISCSI_ERR_INTERNAL;
+ goto destroy_kern_session;
+ }
+ log_debug(3, "created new iSCSI connection "
+ "%d:%d", session->id, conn->id);
+
+ iscsi_copy_operational_params(conn,
+ &session->nrec.session.iscsi,
+ &session->nrec.conn[conn->id].iscsi);
+
+ iscsi_session_set_params(conn);
+ iscsi_host_set_params(session);
+ iscsi_host_set_net_params(&rec->iface, session);
+
+ if (ipc->bind_conn(session->t->handle, session->id, conn->id,
+ conn->transport_ep_handle, (conn->id == 0), &rc) ||
+ rc) {
+ log_error("Could not bind conn %d:%d to session %d, "
+ "(err %d)", session->id, conn->id,
+ session->id, rc);
+ goto destroy_kern_conn;
+ }
+
+ conn->state = STATE_IN_LOGIN;
+ err = ipc->start_conn(session->t->handle, session->id, conn->id, &rc);
+ if (err || rc) {
+ log_error("can't start connection %d:%d retcode %d.",
+ session->id, conn->id, rc);
+ err = ISCSI_ERR_INTERNAL;
+ goto destroy_kern_conn;
+ }
+
+ session->notify_qtask = qtask;
+ qtask->rsp.command = MGMT_IPC_SESSION_LOGIN;
+ qtask->rsp.err = ISCSI_SUCCESS;
+ return ISCSI_SUCCESS;
+
+destroy_kern_conn:
+ if (ipc->destroy_conn(session->t->handle, session->id, conn->id))
+ log_error("can not safely destroy connection %d", conn->id);
+destroy_kern_session:
+ if (ipc->destroy_session(session->t->handle, session->id))
+ log_error("can not safely destroy session %d",
+ session->id);
+ return err;
+}
+
int
-session_login_task(node_rec_t *rec, queue_task_t *qtask)
+iscsi_session_login_task(node_rec_t *rec, queue_task_t *qtask)
{
iscsi_session_t *session;
iscsi_conn_t *conn;
@@ -1661,12 +1872,12 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
}
if (!(t->caps & CAP_MULTI_R2T) &&
- rec->session.iscsi.MaxOutstandingR2T) {
+ rec->session.iscsi.MaxOutstandingR2T > 1) {
log_error("Transport '%s' does not support "
"MaxOutstandingR2T %d. Setting "
"MaxOutstandingR2T to 1.", t->name,
rec->session.iscsi.MaxOutstandingR2T);
- rec->session.iscsi.MaxOutstandingR2T = 1;
+ rec->session.iscsi.MaxOutstandingR2T = 1;
}
if (!(t->caps & CAP_HDRDGST) &&
@@ -1708,34 +1919,20 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
/* create leading connection */
rc = __session_conn_create(session, 0);
if (rc) {
- __session_destroy(session);
- return rc;
- }
- conn = &session->conn[0];
- qtask->conn = conn;
-
- if (iscsi_host_set_net_params(&rec->iface, session)) {
- __session_destroy(session);
- return ISCSI_ERR_LOGIN;
+ goto destroy_session;
}
- if (gettimeofday(&conn->initial_connect_time, NULL))
- log_error("Could not get initial connect time. If "
- "login errors iscsid may give up the initial "
- "login early. You should manually login.");
-
- conn->state = STATE_XPT_WAIT;
- qtask->rsp.command = MGMT_IPC_SESSION_LOGIN;
- qtask->rsp.err = ISCSI_SUCCESS;
-
- if (iscsi_conn_connect(conn, qtask)) {
- log_debug(4, "Initial connect failed. Waiting %u seconds "
- "before trying to reconnect.\n",
- ISCSI_CONN_ERR_REOPEN_DELAY);
- queue_delayed_reopen(qtask, ISCSI_CONN_ERR_REOPEN_DELAY);
- }
+ qtask->conn = &session->conn[0];
+ if (t->caps & CAP_LOGIN_OFFLOAD)
+ rc = iscsi_session_offload_login(rec, qtask, session);
+ else
+ rc = iscsi_sw_session_login(rec, qtask, session);
+ if (rc == ISCSI_SUCCESS)
+ return ISCSI_SUCCESS;
- return ISCSI_SUCCESS;
+destroy_session:
+ __session_destroy(session);
+ return rc;
}
static int
@@ -1782,11 +1979,13 @@ iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid)
if (err)
goto destroy_session;
- session->sync_qtask = qtask;
qtask->rsp.command = MGMT_IPC_SESSION_SYNC;
- session_conn_reopen(&session->conn[0], qtask, STOP_CONN_RECOVER);
log_debug(3, "Started sync iSCSI session %d", session->id);
+ session->notify_qtask = qtask;
+ session_conn_reopen(&session->conn[0], qtask,
+ STOP_CONN_RECOVER);
+
return 0;
destroy_session:
@@ -1806,8 +2005,7 @@ static int session_unbind(struct iscsi_session *session)
return err;
}
-int
-session_logout_task(int sid, queue_task_t *qtask)
+int session_logout_task(int sid, queue_task_t *qtask)
{
iscsi_session_t *session;
iscsi_conn_t *conn;
@@ -1823,7 +2021,7 @@ session_logout_task(int sid, queue_task_t *qtask)
* If syncing up or if this is the initial login and mgmt_ipc
* has not been notified of that result fail the logout request
*/
- if (session->sync_qtask ||
+ if (session->notify_qtask ||
((conn->state == STATE_XPT_WAIT ||
conn->state == STATE_IN_LOGIN) &&
(session->r_stage == R_STAGE_NO_CHANGE ||
@@ -1836,7 +2034,6 @@ invalid_state:
/* FIXME: logout all active connections */
conn = &session->conn[0];
- /* FIXME: implement Logout Request */
if (conn->logout_qtask)
goto invalid_state;
@@ -1849,9 +2046,13 @@ invalid_state:
if (!session_unbind(session))
return ISCSI_SUCCESS;
- /* unbind is not supported so just do old logout */
- if (!iscsi_send_logout(conn))
- return ISCSI_SUCCESS;
+ /* LLDs that offload login also offload logout */
+ if (!(session->t->caps & CAP_LOGIN_OFFLOAD)) {
+ /* unbind is not supported so just do old logout */
+ if (!iscsi_send_logout(conn))
+ return ISCSI_SUCCESS;
+ }
+
log_error("Could not send logout pdu. Dropping session\n");
/* fallthrough */
default:
@@ -1882,37 +2083,7 @@ iscsi_host_send_targets(queue_task_t *qtask, int host_no, int do_login,
return ISCSI_SUCCESS;
}
-/*
- * HW drivers like qla4xxx present a interface that hides most of the iscsi
- * details. Userspace sends down a discovery event then it gets notified
- * if the sessions that were logged in as a result asynchronously, or
- * the card will have sessions preset in the FLASH and will log into them
- * automaotically then send us notification that a session is setup.
- */
-static void iscsi_async_session_creation(uint32_t host_no, uint32_t sid)
-{
- struct iscsi_transport *transport;
-
- transport = iscsi_sysfs_get_transport_by_hba(host_no);
- if (!transport)
- return;
-
- if (!(transport->caps & CAP_FW_DB))
- return;
-
- log_debug(3, "session created sid %u host no %d", sid, host_no);
- session_online_devs(host_no, sid);
- session_scan_host(NULL, host_no, NULL);
-}
-
-static void iscsi_async_session_destruction(uint32_t host_no, uint32_t sid)
-{
- log_debug(3, "session destroyed sid %u host no %d", sid, host_no);
-}
-
static struct iscsi_ipc_ev_clbk ipc_clbk = {
- .create_session = iscsi_async_session_creation,
- .destroy_session = iscsi_async_session_destruction,
.get_ev_context = iscsi_ev_context_get,
.put_ev_context = iscsi_ev_context_put,
.sched_ev_context = iscsi_sched_ev_context,
diff --git a/usr/initiator.h b/usr/initiator.h
index 93e9b3b..39715c3 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -58,6 +58,7 @@ typedef enum iscsi_session_r_stage_e {
R_STAGE_SESSION_CLEANUP,
R_STAGE_SESSION_REOPEN,
R_STAGE_SESSION_REDIRECT,
+ R_STAGE_SESSION_DESTOYED,
} iscsi_session_r_stage_e;
typedef enum conn_login_status_e {
@@ -89,6 +90,8 @@ typedef enum iscsi_event_e {
EV_CONN_ERROR,
EV_CONN_LOGOUT_TIMER,
EV_CONN_STOP,
+ EV_SESSION_CREATED,
+ EV_SESSION_DESTROYED,
} iscsi_event_e;
struct queue_task;
@@ -262,8 +265,11 @@ typedef struct iscsi_session {
int lu_reset_timeout;
int abort_timeout;
- /* sync up fields */
- queue_task_t *sync_qtask;
+ /*
+ * used for hw and sync up to notify caller that the operation
+ * is complete
+ */
+ queue_task_t *notify_qtask;
} iscsi_session_t;
/* login.c */
@@ -334,7 +340,7 @@ extern int iscsi_io_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
int timeout);
/* initiator.c */
-extern int session_login_task(node_rec_t *rec, queue_task_t *qtask);
+extern int iscsi_session_login_task(node_rec_t *rec, queue_task_t *qtask);
extern int session_logout_task(int sid, queue_task_t *qtask);
extern iscsi_session_t *session_find_by_sid(uint32_t sid);
extern int iscsi_sync_session(node_rec_t *rec, queue_task_t
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
index 8e4e519..201819c 100644
--- a/usr/initiator_common.c
+++ b/usr/initiator_common.c
@@ -509,6 +509,10 @@ int iscsi_session_set_params(struct iscsi_conn *conn)
session->param_mask &= ~ISCSI_IFMARKER_EN;
session->param_mask &= ~ISCSI_OFMARKER_EN;
}
+ if (t->caps & CAP_LOGIN_OFFLOAD) {
+ session->param_mask &= ~ISCSI_PING_TMO;
+ session->param_mask &= ~ISCSI_RECV_TMO;
+ }
/* Entered full-feature phase! */
for (i = 0; i < MAX_SESSION_PARAMS; i++) {
diff --git a/usr/io.c b/usr/io.c
index aa81941..0b05445 100644
--- a/usr/io.c
+++ b/usr/io.c
@@ -361,7 +361,12 @@ iscsi_io_tcp_connect(iscsi_conn_t *conn, int non_blocking)
return -1;
}
- if (conn->session) {
+ /*
+ * No need to bind for discovery sessions. If using offload
+ * we actually do not want to try and bind.
+ */
+ if (conn->session &&
+ conn->session->type != ISCSI_SESSION_TYPE_DISCOVERY) {
if (bind_conn_to_iface(conn, &conn->session->nrec.iface))
return -1;
}
diff --git a/usr/iscsi_ipc.h b/usr/iscsi_ipc.h
index 695ee63..0d9e5fd 100644
--- a/usr/iscsi_ipc.h
+++ b/usr/iscsi_ipc.h
@@ -42,9 +42,6 @@ struct iscsi_ev_context;
* code to call into the initiator to shedule handling.
*/
struct iscsi_ipc_ev_clbk {
- void (*create_session) (uint32_t host_no, uint32_t sid);
- void (*destroy_session) (uint32_t host_no, uint32_t sid);
-
struct iscsi_ev_context *(*get_ev_context) (struct iscsi_conn *conn,
int ev_size);
void (*put_ev_context) (struct iscsi_ev_context *ev_context);
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
index e82fe80..dd526db 100644
--- a/usr/iscsi_sysfs.c
+++ b/usr/iscsi_sysfs.c
@@ -148,7 +148,6 @@ static int read_transports(void)
*/
if (!strcmp(t->name, "qla4xxx")) {
t->caps |= CAP_DATA_PATH_OFFLOAD;
- t->caps |= CAP_FW_DB;
}
if (list_empty(&t->list))
@@ -1111,7 +1110,8 @@ void iscsi_sysfs_set_queue_depth(void *data, int hostno, int target, int lun)
err = sysfs_set_param(id, SCSI_SUBSYS, "queue_depth", write_buf,
strlen(write_buf));
if (err && err != EINVAL)
- log_error("Could not queue depth for LUN %d err %d.", lun, err);
+ log_error("Could not queue depth for LUN %d err %d.",
+ lun, err);
}
void iscsi_sysfs_set_device_online(void *data, int hostno, int target, int lun)
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index a4b75af..f776de9 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -467,15 +467,6 @@ static int iscsi_logout_matched_portal(void *data, struct list_head *list,
if (!iscsi_match_session(pattern_rec, info))
return -1;
- /* we do not support this yet */
- if (t->caps & CAP_FW_DB) {
- log_error("Could not logout session of [sid: %d, "
- "target: %s, portal: %s,%d].", info->sid,
- info->targetname, info->persistent_address,
- info->port);
- log_error("Logout not supported for driver: %s.", t->name);
- return -1;
- }
return iscsi_logout_portal(info, list);
}
@@ -1002,7 +993,6 @@ do_sendtargets(discovery_rec_t *drec, struct list_head *ifaces,
free(iface);
continue;
}
-
host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
if (rc || host_no == -1) {
log_debug(1, "Could not match iface" iface_fmt " to "
diff --git a/usr/iscsid.c b/usr/iscsid.c
index 67a6944..fb60c7d 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -200,25 +200,6 @@ static int sync_session(void *data, struct session_info *info)
if (!t)
return 0;
- /*
- * Just rescan the device in case this is the first startup.
- * (TODO: should do this async and check for state).
- */
- if (t->caps & CAP_FW_DB) {
- uint32_t host_no;
- int err;
-
- host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &err);
- if (err) {
- log_error("Could not get host no from sid %u. Can not "
- "sync session: %s", info->sid,
- iscsi_err_to_str(err));
- return 0;
- }
- iscsi_sysfs_scan_host(host_no, 0);
- return 0;
- }
-
memset(&rec, 0, sizeof(node_rec_t));
/*
* We might get the local ip address for software. We do not
diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
index 3e4d2ef..055e5e4 100644
--- a/usr/mgmt_ipc.c
+++ b/usr/mgmt_ipc.c
@@ -83,7 +83,7 @@ mgmt_ipc_close(int fd)
static int
mgmt_ipc_session_login(queue_task_t *qtask)
{
- return session_login_task(&qtask->req.u.session.rec, qtask);
+ return iscsi_session_login_task(&qtask->req.u.session.rec, qtask);
}
static int
diff --git a/usr/netlink.c b/usr/netlink.c
index 1d2a0fd..b218da0 100644
--- a/usr/netlink.c
+++ b/usr/netlink.c
@@ -1044,7 +1044,7 @@ static int ctldev_handle(void)
char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))];
struct nlmsghdr *nlh;
struct iscsi_ev_context *ev_context;
- uint32_t sid = 0, cid = 0;
+ uint32_t sid = 0, cid = 0, host_no = -1;
log_debug(7, "in %s", __FUNCTION__);
@@ -1060,19 +1060,13 @@ static int ctldev_handle(void)
/* drivers like qla4xxx can be inserted after iscsid is started */
switch (ev->type) {
case ISCSI_KEVENT_CREATE_SESSION:
- /* old kernels sent ISCSI_UEVENT_CREATE_SESSION on creation */
- case ISCSI_UEVENT_CREATE_SESSION:
- drop_data(nlh);
- if (ipc_ev_clbk->create_session)
- ipc_ev_clbk->create_session(ev->r.c_session_ret.host_no,
- ev->r.c_session_ret.sid);
- return 0;
+ sid = ev->r.c_session_ret.sid;
+ host_no = ev->r.c_session_ret.host_no;
+ break;
case ISCSI_KEVENT_DESTROY_SESSION:
- drop_data(nlh);
- if (ipc_ev_clbk->destroy_session)
- ipc_ev_clbk->destroy_session(ev->r.d_session.host_no,
- ev->r.d_session.sid);
- return 0;
+ sid = ev->r.d_session.sid;
+ host_no = ev->r.d_session.host_no;
+ break;
case ISCSI_KEVENT_RECV_PDU:
sid = ev->r.recv_req.sid;
cid = ev->r.recv_req.cid;
@@ -1142,6 +1136,14 @@ static int ctldev_handle(void)
* into ctldev_handle
*/
switch (ev->type) {
+ case ISCSI_KEVENT_CREATE_SESSION:
+ rc = ipc_ev_clbk->sched_ev_context(ev_context, conn, 0,
+ EV_SESSION_CREATED);
+ break;
+ case ISCSI_KEVENT_DESTROY_SESSION:
+ rc = ipc_ev_clbk->sched_ev_context(ev_context, conn, 0,
+ EV_SESSION_DESTROYED);
+ break;
case ISCSI_KEVENT_RECV_PDU:
rc = ipc_ev_clbk->sched_ev_context(ev_context, conn, 0,
EV_CONN_RECV_PDU);
diff --git a/usr/session_mgmt.c b/usr/session_mgmt.c
index 0bfa205..fe90f25 100644
--- a/usr/session_mgmt.c
+++ b/usr/session_mgmt.c
@@ -151,7 +151,6 @@ int iscsi_login_portal_nowait(struct node_rec *rec)
int err;
INIT_LIST_HEAD(&list);
-
err = iscsi_login_portal(NULL, &list, rec);
if (err > 0)
return err;
diff --git a/usr/transport.c b/usr/transport.c
index 7a0cde1..5d6bea4 100644
--- a/usr/transport.c
+++ b/usr/transport.c
@@ -79,6 +79,10 @@ struct iscsi_transport_template be2iscsi = {
struct iscsi_transport_template qla4xxx = {
.name = "qla4xxx",
+ .set_host_ip = 0,
+ .ep_connect = ktransport_ep_connect,
+ .ep_poll = ktransport_ep_poll,
+ .ep_disconnect = ktransport_ep_disconnect,
};
static struct iscsi_transport_template *iscsi_transport_templates[] = {
--
1.7.3.2
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2011-05-06 12:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-06 12:30 [RFC PATCH] iscsi tools: manage qla4xxx iscsi sessions with iscsiadm vikas.chaudhary
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).