|
|
3f3ec35 |
From c0e509e7535372cd5d655bc5a20d3d2bae45df84 Mon Sep 17 00:00:00 2001
|
|
|
3f3ec35 |
From: Mike Christie <michaelc@cs.wisc.edu>
|
|
|
3f3ec35 |
Date: Wed, 7 May 2014 14:38:13 -0500
|
|
|
3f3ec35 |
Subject: [PATCH] iscsid: retry login for ISCSI_ERR_HOST_NOT_FOUND
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
If a driver is being loaded then the scsi_host might not yet
|
|
|
3f3ec35 |
be added. This has iscsid retry login if the host is not yet
|
|
|
3f3ec35 |
in sysfs.
|
|
|
3f3ec35 |
---
|
|
|
3f3ec35 |
usr/initiator.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++------
|
|
|
3f3ec35 |
1 file changed, 100 insertions(+), 11 deletions(-)
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
diff --git a/usr/initiator.c b/usr/initiator.c
|
|
|
3f3ec35 |
index 05a5b19..b4b8957 100644
|
|
|
3f3ec35 |
--- a/usr/initiator.c
|
|
|
3f3ec35 |
+++ b/usr/initiator.c
|
|
|
3f3ec35 |
@@ -55,10 +55,19 @@
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
#define PROC_DIR "/proc"
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
+struct login_task_retry_info {
|
|
|
3f3ec35 |
+ actor_t retry_actor;
|
|
|
3f3ec35 |
+ queue_task_t *qtask;
|
|
|
3f3ec35 |
+ node_rec_t *rec;
|
|
|
3f3ec35 |
+ int retry_count;
|
|
|
3f3ec35 |
+};
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
static void iscsi_login_timedout(void *data);
|
|
|
3f3ec35 |
static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
|
|
|
3f3ec35 |
struct iscsi_conn *conn, unsigned long tmo,
|
|
|
3f3ec35 |
int event);
|
|
|
3f3ec35 |
+static int queue_session_login_task_retry(struct login_task_retry_info *info,
|
|
|
3f3ec35 |
+ node_rec_t *rec, queue_task_t *qtask);
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
static int iscsi_ev_context_alloc(iscsi_conn_t *conn)
|
|
|
3f3ec35 |
{
|
|
|
3f3ec35 |
@@ -324,14 +333,17 @@ session_release(iscsi_session_t *session)
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
static iscsi_session_t*
|
|
|
3f3ec35 |
-__session_create(node_rec_t *rec, struct iscsi_transport *t)
|
|
|
3f3ec35 |
+__session_create(node_rec_t *rec, struct iscsi_transport *t, int *rc)
|
|
|
3f3ec35 |
{
|
|
|
3f3ec35 |
iscsi_session_t *session;
|
|
|
3f3ec35 |
- int hostno, rc = 0;
|
|
|
3f3ec35 |
+ int hostno;
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+ *rc = 0;
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
session = calloc(1, sizeof (*session));
|
|
|
3f3ec35 |
if (session == NULL) {
|
|
|
3f3ec35 |
log_debug(1, "can not allocate memory for session");
|
|
|
3f3ec35 |
+ *rc = ISCSI_ERR_NOMEM;
|
|
|
3f3ec35 |
return NULL;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
log_debug(2, "Allocted session %p", session);
|
|
|
3f3ec35 |
@@ -356,8 +368,8 @@ __session_create(node_rec_t *rec, struct iscsi_transport *t)
|
|
|
3f3ec35 |
session->initiator_name = dconfig->initiator_name;
|
|
|
3f3ec35 |
else {
|
|
|
3f3ec35 |
log_error("No initiator name set. Cannot create session.");
|
|
|
3f3ec35 |
- free(session);
|
|
|
3f3ec35 |
- return NULL;
|
|
|
3f3ec35 |
+ *rc = ISCSI_ERR_INVAL;
|
|
|
3f3ec35 |
+ goto free_session;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
if (strlen(session->nrec.iface.alias))
|
|
|
3f3ec35 |
@@ -386,8 +398,8 @@ __session_create(node_rec_t *rec, struct iscsi_transport *t)
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
iscsi_session_init_params(session);
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
- hostno = iscsi_sysfs_get_host_no_from_hwinfo(&rec->iface, &rc);
|
|
|
3f3ec35 |
- if (!rc) {
|
|
|
3f3ec35 |
+ hostno = iscsi_sysfs_get_host_no_from_hwinfo(&rec->iface, rc);
|
|
|
3f3ec35 |
+ if (!*rc) {
|
|
|
3f3ec35 |
/*
|
|
|
3f3ec35 |
* if the netdev or mac was set, then we are going to want
|
|
|
3f3ec35 |
* to want to bind the all the conns/eps to a specific host
|
|
|
3f3ec35 |
@@ -395,10 +407,18 @@ __session_create(node_rec_t *rec, struct iscsi_transport *t)
|
|
|
3f3ec35 |
*/
|
|
|
3f3ec35 |
session->conn[0].bind_ep = 1;
|
|
|
3f3ec35 |
session->hostno = hostno;
|
|
|
3f3ec35 |
+ } else if (*rc == ISCSI_ERR_HOST_NOT_FOUND) {
|
|
|
3f3ec35 |
+ goto free_session;
|
|
|
3f3ec35 |
+ } else {
|
|
|
3f3ec35 |
+ *rc = 0;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
list_add_tail(&session->list, &t->sessions);
|
|
|
3f3ec35 |
return session;
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+free_session:
|
|
|
3f3ec35 |
+ free(session);
|
|
|
3f3ec35 |
+ return NULL;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
static void iscsi_flush_context_pool(struct iscsi_session *session)
|
|
|
3f3ec35 |
@@ -1862,8 +1882,7 @@ static int session_is_running(node_rec_t *rec)
|
|
|
3f3ec35 |
return 0;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
-int
|
|
|
3f3ec35 |
-session_login_task(node_rec_t *rec, queue_task_t *qtask)
|
|
|
3f3ec35 |
+static int __session_login_task(node_rec_t *rec, queue_task_t *qtask)
|
|
|
3f3ec35 |
{
|
|
|
3f3ec35 |
iscsi_session_t *session;
|
|
|
3f3ec35 |
iscsi_conn_t *conn;
|
|
|
3f3ec35 |
@@ -1930,8 +1949,10 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
|
|
|
3f3ec35 |
rec->conn[0].iscsi.OFMarker = 0;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
- session = __session_create(rec, t);
|
|
|
3f3ec35 |
- if (!session)
|
|
|
3f3ec35 |
+ session = __session_create(rec, t, &rc);
|
|
|
3f3ec35 |
+ if (rc == ISCSI_ERR_HOST_NOT_FOUND)
|
|
|
3f3ec35 |
+ return rc;
|
|
|
3f3ec35 |
+ else if (!session)
|
|
|
3f3ec35 |
return ISCSI_ERR_LOGIN;
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
/* FIXME: login all connections! marked as "automatic" */
|
|
|
3f3ec35 |
@@ -1979,6 +2000,74 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
|
|
|
3f3ec35 |
return ISCSI_SUCCESS;
|
|
|
3f3ec35 |
}
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
+int
|
|
|
3f3ec35 |
+session_login_task(node_rec_t *rec, queue_task_t *qtask)
|
|
|
3f3ec35 |
+{
|
|
|
3f3ec35 |
+ int rc;
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+ rc = __session_login_task(rec, qtask);
|
|
|
3f3ec35 |
+ if (rc == ISCSI_ERR_HOST_NOT_FOUND) {
|
|
|
3f3ec35 |
+ rc = queue_session_login_task_retry(NULL, rec, qtask);
|
|
|
3f3ec35 |
+ if (rc)
|
|
|
3f3ec35 |
+ return rc;
|
|
|
3f3ec35 |
+ /*
|
|
|
3f3ec35 |
+ * we are going to internally retry. Will return final rc
|
|
|
3f3ec35 |
+ * when completed
|
|
|
3f3ec35 |
+ */
|
|
|
3f3ec35 |
+ return ISCSI_SUCCESS;
|
|
|
3f3ec35 |
+ }
|
|
|
3f3ec35 |
+ return rc;
|
|
|
3f3ec35 |
+}
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+static void session_login_task_retry(void *data)
|
|
|
3f3ec35 |
+{
|
|
|
3f3ec35 |
+ struct login_task_retry_info *info = data;
|
|
|
3f3ec35 |
+ int rc;
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+ rc = __session_login_task(info->rec, info->qtask);
|
|
|
3f3ec35 |
+ if (rc == ISCSI_ERR_HOST_NOT_FOUND) {
|
|
|
3f3ec35 |
+ if (info->retry_count == 5) {
|
|
|
3f3ec35 |
+ /* give up */
|
|
|
3f3ec35 |
+ goto write_rsp;
|
|
|
3f3ec35 |
+ }
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+ rc = queue_session_login_task_retry(info, info->rec,
|
|
|
3f3ec35 |
+ info->qtask);
|
|
|
3f3ec35 |
+ if (rc)
|
|
|
3f3ec35 |
+ goto write_rsp;
|
|
|
3f3ec35 |
+ /* we are going to internally retry */
|
|
|
3f3ec35 |
+ return;
|
|
|
3f3ec35 |
+ } else if (rc) {
|
|
|
3f3ec35 |
+ /* hard error - no retry */
|
|
|
3f3ec35 |
+ goto write_rsp;
|
|
|
3f3ec35 |
+ } else
|
|
|
3f3ec35 |
+ /* successfully started login operation */
|
|
|
3f3ec35 |
+ goto free;
|
|
|
3f3ec35 |
+write_rsp:
|
|
|
3f3ec35 |
+ mgmt_ipc_write_rsp(info->qtask, rc);
|
|
|
3f3ec35 |
+free:
|
|
|
3f3ec35 |
+ free(info);
|
|
|
3f3ec35 |
+}
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+static int queue_session_login_task_retry(struct login_task_retry_info *info,
|
|
|
3f3ec35 |
+ node_rec_t *rec, queue_task_t *qtask)
|
|
|
3f3ec35 |
+{
|
|
|
3f3ec35 |
+ if (!info) {
|
|
|
3f3ec35 |
+ info = malloc(sizeof(*info));
|
|
|
3f3ec35 |
+ if (!info)
|
|
|
3f3ec35 |
+ return ISCSI_ERR_NOMEM;
|
|
|
3f3ec35 |
+ memset(info, 0, sizeof(*info));
|
|
|
3f3ec35 |
+ info->qtask = qtask;
|
|
|
3f3ec35 |
+ info->rec = rec;
|
|
|
3f3ec35 |
+ }
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
+ info->retry_count++;
|
|
|
3f3ec35 |
+ log_debug(4, "queue session setup attempt in %d secs, retries %d\n",
|
|
|
3f3ec35 |
+ 3, info->retry_count);
|
|
|
3f3ec35 |
+ actor_timer(&info->retry_actor, 3000, session_login_task_retry, info);
|
|
|
3f3ec35 |
+ return 0;
|
|
|
3f3ec35 |
+}
|
|
|
3f3ec35 |
+
|
|
|
3f3ec35 |
static int
|
|
|
3f3ec35 |
sync_conn(iscsi_session_t *session, uint32_t cid)
|
|
|
3f3ec35 |
{
|
|
|
3f3ec35 |
@@ -2006,7 +2095,7 @@ iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid)
|
|
|
3f3ec35 |
if (!t)
|
|
|
3f3ec35 |
return ISCSI_ERR_TRANS_NOT_FOUND;
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
- session = __session_create(rec, t);
|
|
|
3f3ec35 |
+ session = __session_create(rec, t, &err;;
|
|
|
3f3ec35 |
if (!session)
|
|
|
3f3ec35 |
return ISCSI_ERR_LOGIN;
|
|
|
3f3ec35 |
|
|
|
3f3ec35 |
--
|
|
|
3f3ec35 |
1.9.3
|
|
|
3f3ec35 |
|