[RFC PATCH] iscsi tools: manage qla4xxx iscsi sessions with iscsiadm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Manish Rangankar <manish.rangankar@xxxxxxxxxx>

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@xxxxxxxxxx>
Signed-off-by: Lalit Chandivade <lalit.chandivade@xxxxxxxxxx>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@xxxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux