Blob Blame Raw
diff -aurp open-iscsi-2.0-872-rc1-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc1-bnx2i.work/usr/initiator.c
--- open-iscsi-2.0-872-rc1-bnx2i/usr/initiator.c	2010-05-18 17:58:00.000000000 -0500
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/initiator.c	2010-05-18 21:40:44.000000000 -0500
@@ -1096,6 +1096,18 @@ static void iscsi_login_timedout(void *d
 	}
 }
 
+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, MGMT_IPC_ERR_TRANS_TIMEOUT);
+	conn_delete_timers(conn);
+	__session_destroy(session);
+}
+
 static void iscsi_login_redirect(iscsi_conn_t *conn)
 {
 	iscsi_session_t *session = conn->session;
@@ -2049,6 +2061,52 @@ cleanup:
 	session_conn_shutdown(conn, qtask, err);
 }
 
+static void session_conn_uio_poll(void *data)
+{
+	struct iscsi_conn_context *conn_context = data;
+	iscsi_conn_t *conn = conn_context->conn;
+	struct iscsi_session *session = conn->session;
+	queue_task_t *qtask = conn_context->data;
+	int rc;
+
+	log_debug(4, "retrying uio poll");
+	rc = __set_net_config(session->t, session, &conn->session->nrec.iface);
+	if (rc != 0) {
+		if (rc == -EAGAIN) {
+			conn_context->data = qtask;
+			iscsi_sched_conn_context(conn_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, MGMT_IPC_ERR_INTERNAL);
+			iscsi_conn_context_put(conn_context);
+			return;
+		}
+	}
+	iscsi_conn_context_put(conn_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 = 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);
+        }
+}
+
+
 void iscsi_sched_conn_context(struct iscsi_conn_context *conn_context,
 			      struct iscsi_conn *conn, unsigned long tmo,
 			      int event)
@@ -2085,6 +2143,11 @@ void iscsi_sched_conn_context(struct isc
 			  conn_context);
 		actor_schedule(&conn_context->actor);
 		break;
+	case EV_UIO_POLL:
+		actor_new(&conn_context->actor, session_conn_uio_poll,
+			  conn_context);
+		actor_schedule(&conn_context->actor);
+		break;
 	case EV_CONN_LOGOUT_TIMER:
 		actor_timer(&conn_context->actor, tmo * 1000,
 			    iscsi_logout_timedout, conn_context);
@@ -2150,8 +2213,10 @@ static int session_is_running(node_rec_t
 }
 
 static int iface_set_param(struct iscsi_transport *t, struct iface_rec *iface,
-			   struct iscsi_session *session)
+			   queue_task_t *qtask)
 {
+	struct iscsi_conn *conn = qtask->conn;
+	struct iscsi_session *session = conn->session;
 	int rc = 0;
 
 	log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, "
@@ -2170,6 +2235,29 @@ static int iface_set_param(struct iscsi_
 	}
 
 	rc = __set_net_config(t, session, iface);
+	if (rc == -EAGAIN && t->template->set_net_config) {
+		struct iscsi_conn_context *conn_context;
+
+		conn_context = iscsi_conn_context_get(conn, 0);
+		if (!conn_context) {
+			/* while reopening the recv pool should be full */
+			log_error("BUG: __session_conn_reopen could "
+				  "not get conn context for recv.");
+			return ENOMEM;
+		}
+		conn_context->data = qtask;
+		conn->state = STATE_XPT_WAIT;
+
+		iscsi_sched_conn_context(conn_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;
+	}
 	if (rc != 0)
 		return rc;
 
@@ -2203,6 +2291,7 @@ session_login_task(node_rec_t *rec, queu
 	iscsi_session_t *session;
 	iscsi_conn_t *conn;
 	struct iscsi_transport *t;
+	int rc;
 
 	if (session_is_running(rec))
 		return MGMT_IPC_ERR_EXISTS;
@@ -2276,7 +2365,16 @@ session_login_task(node_rec_t *rec, queu
 	conn = &session->conn[0];
 	qtask->conn = conn;
 
-	if (iface_set_param(t, &rec->iface, session)) {
+	rc =  iface_set_param(t, &rec->iface, qtask);
+	if (rc == EAGAIN)  {
+		/*
+		 * Cannot block iscsid, so caller is going to internally
+		 * retry the operation.
+		 */
+		qtask->rsp.command = MGMT_IPC_SESSION_LOGIN;
+		qtask->rsp.err = MGMT_IPC_OK;
+		return MGMT_IPC_OK;
+	} else if (rc) {
 		__session_destroy(session);
 		return MGMT_IPC_ERR_LOGIN_FAILURE;
 	}
Only in open-iscsi-2.0-872-rc1-bnx2i.work/usr/: initiator.c.orig
diff -aurp open-iscsi-2.0-872-rc1-bnx2i/usr/initiator.h open-iscsi-2.0-872-rc1-bnx2i.work/usr/initiator.h
--- open-iscsi-2.0-872-rc1-bnx2i/usr/initiator.h	2010-05-18 17:58:00.000000000 -0500
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/initiator.h	2010-05-18 18:13:12.000000000 -0500
@@ -88,6 +88,7 @@ typedef enum iscsi_event_e {
 	EV_CONN_ERROR,
 	EV_CONN_LOGOUT_TIMER,
 	EV_CONN_STOP,
+	EV_UIO_POLL,
 } iscsi_event_e;
 
 struct queue_task;
diff -aurp open-iscsi-2.0-872-rc1-bnx2i/usr/iscsid_req.c open-iscsi-2.0-872-rc1-bnx2i.work/usr/iscsid_req.c
--- open-iscsi-2.0-872-rc1-bnx2i/usr/iscsid_req.c	2010-05-18 17:58:00.000000000 -0500
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/iscsid_req.c	2010-05-18 21:16:21.000000000 -0500
@@ -217,6 +217,8 @@ int uip_broadcast(void *buf, size_t buf_
 		return err;
 	}
 
+	log_debug(3, "connected to uIP daemon");
+
 	/*  Send the data to uIP */
 	if ((err = write(fd, buf, buf_len)) != buf_len) {
 		log_error("got write error (%d/%d), daemon died?",
@@ -225,6 +227,8 @@ int uip_broadcast(void *buf, size_t buf_
 		return -EIO;
 	}
 
+	log_debug(3, "send iface config to uIP daemon");
+
 	/*  Set the socket to a non-blocking read, this way if there are
 	 *  problems waiting for uIP, iscsid can bailout early */
 	flags = fcntl(fd, F_GETFL, 0);
@@ -243,8 +247,10 @@ int uip_broadcast(void *buf, size_t buf_
 		/*  Wait for the response */
 		err = read(fd, &rsp, sizeof(rsp));
 		if (err == sizeof(rsp)) {
-			log_debug(3, "Broadcasted to uIP with length: %ld\n",
-				  buf_len);
+			log_debug(3, "Broadcasted to uIP with length: %ld "
+				     "cmd: 0x%x rsp: 0x%x\n", buf_len,
+				     rsp.command, rsp.err);
+			err = 0;
 			break;
 		} else if((err == -1) && (errno == EAGAIN)) {
 			usleep(250000);
@@ -256,12 +262,17 @@ int uip_broadcast(void *buf, size_t buf_
 		}
 	}
 
-	if(count == MAX_UIP_BROADCAST_READ_TRIES)
-		log_error("Could not broadcast to uIP");
+	if (count == MAX_UIP_BROADCAST_READ_TRIES) {
+		log_error("Could not broadcast to uIP after %d tries",
+			  count);
+		err = -EAGAIN;
+	} else if (rsp.err != ISCISD_UIP_MGMT_IPC_DEVICE_UP) {
+		log_debug(3, "Device is not ready\n");
+		err = -EAGAIN;
+	}
 
 	close(fd);
-
-	return 0;
+	return err;
 }
 
 void iscsid_handle_error(mgmt_ipc_err_e err)
Only in open-iscsi-2.0-872-rc1-bnx2i.work/usr/: iscsid_req.c.orig
diff -aurp open-iscsi-2.0-872-rc1-bnx2i/usr/uip_mgmt_ipc.h open-iscsi-2.0-872-rc1-bnx2i.work/usr/uip_mgmt_ipc.h
--- open-iscsi-2.0-872-rc1-bnx2i/usr/uip_mgmt_ipc.h	2010-05-18 17:58:00.000000000 -0500
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/uip_mgmt_ipc.h	2010-05-18 18:13:12.000000000 -0500
@@ -55,6 +55,8 @@ typedef enum iscsid_uip_mgmt_ipc_err {
         ISCISD_UIP_MGMT_IPC_ERR                    = 1,
         ISCISD_UIP_MGMT_IPC_ERR_NOT_FOUND          = 2,
         ISCISD_UIP_MGMT_IPC_ERR_NOMEM              = 3,
+	ISCISD_UIP_MGMT_IPC_DEVICE_UP              = 4,
+	ISCISD_UIP_MGMT_IPC_DEVICE_INITIALIZING    = 5,
 } iscsid_uip_mgmt_ipc_err_e;
 
 /* IPC Response */