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 open-iscsi+unsubscr...@googlegroups.com.
To post to this group, send email to open-iscsi@googlegroups.com.
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 */

Reply via email to