Hey Roi, Vikas and Eddie,
The attached patch fixes the issue Roi reported where the login_timer
was not deleted and so we end up with a infinite loop. Roi, could you
test your failure case?
Vikas and Eddie, I ccd you guys because it modifies the bnx2i iscsiuio
code. There was a issue where iscsiuio was not ready (or the host was
not yet ready) and so iscsid would poll iscsiuio for a second or two and
it would use the login_timer as a watchdog. A couple weeks ago we hit a
issue with be2iscsi where the host was not ready to go so iscsid got
code to poll the iscsi/scsi_host. So this patch removes the iscsiuio
login_timer use and then also has it use this new common setup polling.
I have tested software iscsi.
--
You received this message because you are subscribed to the Google Groups
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.
diff --git a/usr/actor.c b/usr/actor.c
index b8f8e61..381328c 100644
--- a/usr/actor.c
+++ b/usr/actor.c
@@ -187,16 +187,12 @@ actor_timer(actor_t *thread, uint32_t timeout, void (*callback)(void *),
actor_schedule_private(thread, timeout, 0);
}
-int
+void
actor_timer_mod(actor_t *thread, uint32_t timeout, void *data)
{
- if (thread->state == ACTOR_WAITING) {
- list_del_init(&thread->list);
- thread->data = data;
- actor_schedule_private(thread, timeout, 0);
- return 1;
- }
- return 0;
+ actor_delete(thread);
+ thread->data = data;
+ actor_schedule_private(thread, timeout, 0);
}
void
diff --git a/usr/actor.h b/usr/actor.h
index 704224d..ad49b49 100644
--- a/usr/actor.h
+++ b/usr/actor.h
@@ -48,7 +48,7 @@ extern void actor_schedule_head(actor_t *thread);
extern void actor_schedule(actor_t *thread);
extern void actor_timer(actor_t *thread, uint32_t timeout,
void (*callback)(void *), void *data);
-extern int actor_timer_mod(actor_t *thread, uint32_t new_timeout, void *data);
+extern void actor_timer_mod(actor_t *thread, uint32_t new_timeout, void *data);
extern void actor_poll(void);
extern void actor_init(void);
diff --git a/usr/initiator.c b/usr/initiator.c
index b4b8957..4a94254 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -262,6 +262,7 @@ __session_conn_create(iscsi_session_t *session, int cid)
conn->state = ISCSI_CONN_STATE_FREE;
conn->session = session;
+ actor_new(&conn->login_timer, iscsi_login_timedout, NULL);
/*
* TODO: we must export the socket_fd/transport_eph from sysfs
* so if iscsid is resyncing up we can pick that up and cleanup up
@@ -526,9 +527,7 @@ queue_delayed_reopen(queue_task_t *qtask, int delay)
* iscsi_login_eh can handle the login resched as
* if it were login time out
*/
- actor_delete(&conn->login_timer);
- actor_timer(&conn->login_timer, delay * 1000,
- iscsi_login_timedout, qtask);
+ actor_timer_mod(&conn->login_timer, delay * 1000, qtask);
}
static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask)
@@ -563,53 +562,10 @@ static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask)
iscsi_sched_ev_context(ev_context, conn, 0, EV_CONN_POLL);
log_debug(3, "Setting login timer %p timeout %d", &conn->login_timer,
conn->login_timeout);
- actor_timer(&conn->login_timer, conn->login_timeout * 1000,
- iscsi_login_timedout, qtask);
+ actor_timer_mod(&conn->login_timer, conn->login_timeout * 1000, qtask);
return 0;
}
-static void iscsi_uio_poll_login_timedout(void *data)
-{
- struct queue_task *qtask = data;
- struct iscsi_conn *conn = qtask->conn;
- iscsi_session_t *session = conn->session;
-
- log_debug(3, "timeout waiting for UIO ...\n");
- mgmt_ipc_write_rsp(qtask, ISCSI_ERR_TRANS_TIMEOUT);
- conn_delete_timers(conn);
- __session_destroy(session);
-}
-
-static int iscsi_sched_uio_poll(queue_task_t *qtask)
-{
- struct iscsi_conn *conn = qtask->conn;
- struct iscsi_session *session = conn->session;
- struct iscsi_transport *t = session->t;
- struct iscsi_ev_context *ev_context;
-
- if (!t->template->set_net_config)
- return 0;
-
- ev_context = iscsi_ev_context_get(conn, 0);
- if (!ev_context) {
- /* while reopening the recv pool should be full */
- log_error("BUG: __session_conn_reopen could "
- "not get conn context for recv.");
- return -ENOMEM;
- }
-
- ev_context->data = qtask;
- conn->state = ISCSI_CONN_STATE_XPT_WAIT;
-
- iscsi_sched_ev_context(ev_context, conn, 0, EV_UIO_POLL);
-
- log_debug(3, "Setting login UIO poll timer %p timeout %d",
- &conn->login_timer, conn->login_timeout);
- actor_timer(&conn->login_timer, conn->login_timeout * 1000,
- iscsi_uio_poll_login_timedout, qtask);
- return -EAGAIN;
-}
-
static void
__session_conn_reopen(iscsi_conn_t *conn, queue_task_t *qtask, int do_stop,
int redirected)
@@ -1738,53 +1694,6 @@ failed_login:
}
-static void session_conn_uio_poll(void *data)
-{
- struct iscsi_ev_context *ev_context = data;
- iscsi_conn_t *conn = ev_context->conn;
- struct iscsi_session *session = conn->session;
- queue_task_t *qtask = ev_context->data;
- int rc;
-
- log_debug(4, "retrying uio poll");
- rc = iscsi_set_net_config(session->t, session,
- &conn->session->nrec.iface);
- if (rc != 0) {
- if (rc == ISCSI_ERR_AGAIN) {
- ev_context->data = qtask;
- iscsi_sched_ev_context(ev_context, conn, 2,
- EV_UIO_POLL);
- return;
- } else {
- log_error("session_conn_uio_poll() "
- "connection failure [0x%x]", rc);
- actor_delete(&conn->login_timer);
- iscsi_login_eh(conn, qtask, ISCSI_ERR_INTERNAL);
- iscsi_ev_context_put(ev_context);
- return;
- }
- }
-
- iscsi_ev_context_put(ev_context);
- actor_delete(&conn->login_timer);
- log_debug(4, "UIO ready trying connect");
-
- /* uIP is ready try to connect */
- 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 = ISCSI_CONN_STATE_XPT_WAIT;
- if (iscsi_conn_connect(conn, qtask)) {
- int delay = ISCSI_CONN_ERR_REOPEN_DELAY;
-
- log_debug(4, "Waiting %u seconds before trying to reconnect.\n",
- delay);
- queue_delayed_reopen(qtask, delay);
- }
-}
-
static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
struct iscsi_conn *conn, unsigned long tmo,
int event)
@@ -1826,11 +1735,6 @@ static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
ev_context);
actor_schedule(&ev_context->actor);
break;
- case EV_UIO_POLL:
- actor_new(&ev_context->actor, session_conn_uio_poll,
- ev_context);
- actor_schedule(&ev_context->actor);
- break;
case EV_CONN_LOGOUT_TIMER:
actor_timer(&ev_context->actor, tmo * 1000,
iscsi_logout_timedout, ev_context);
@@ -1968,14 +1872,12 @@ static int __session_login_task(node_rec_t *rec, queue_task_t *qtask)
rc = iscsi_host_set_net_params(&rec->iface, session);
if (rc == ISCSI_ERR_AGAIN) {
- iscsi_sched_uio_poll(qtask);
/*
- * Cannot block iscsid, so caller is going to internally
- * retry the operation.
+ * host/iscsiuio not ready. Cannot block iscsid, so caller is
+ * going to internally retry the operation.
*/
- qtask->rsp.command = MGMT_IPC_SESSION_LOGIN;
- qtask->rsp.err = ISCSI_SUCCESS;
- return ISCSI_SUCCESS;
+ __session_destroy(session);
+ return ISCSI_ERR_HOST_NOT_FOUND;
} else if (rc) {
__session_destroy(session);
return ISCSI_ERR_LOGIN;
diff --git a/usr/initiator.h b/usr/initiator.h
index c34625b..c11d77f 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -83,7 +83,6 @@ typedef enum iscsi_event_e {
EV_CONN_LOGOUT_TIMER,
EV_CONN_STOP,
EV_CONN_LOGIN,
- EV_UIO_POLL,
} iscsi_event_e;
struct queue_task;
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
index 50f8d41..4a1647e 100644
--- a/usr/initiator_common.c
+++ b/usr/initiator_common.c
@@ -687,7 +687,7 @@ int iscsi_host_set_net_params(struct iface_rec *iface,
if (!iface_is_bound_by_ipaddr(iface)) {
log_warning("Please set the iface.ipaddress for iface %s, "
"then retry the login command.\n", iface->name);
- return EINVAL;
+ return ISCSI_ERR_INVAL;
}
/* these type of drivers need the netdev upd */