changeset 11017:d8051a5359bd

6898410 explicitly invoke relogin to the boot target
author Jack Meng <Jack.Meng@Sun.COM>
date Tue, 10 Nov 2009 11:20:11 +0800
parents efcd833e2d40
children 98dcc2fc68b6
files usr/src/uts/common/io/scsi/adapters/iscsi/iscsid.c
diffstat 1 files changed, 87 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/adapters/iscsi/iscsid.c	Mon Nov 09 17:37:50 2009 -0800
+++ b/usr/src/uts/common/io/scsi/adapters/iscsi/iscsid.c	Tue Nov 10 11:20:11 2009 +0800
@@ -69,6 +69,7 @@
 static iscsi_sess_t *iscsi_add_boot_sess(iscsi_hba_t *ihp, int isid);
 static boolean_t iscsid_make_entry(ib_boot_prop_t *boot_prop_entry,
     entry_t *entry);
+static boolean_t iscsid_check_active_boot_conn(iscsi_hba_t *ihp);
 
 extern int modrootloaded;
 int iscsi_configroot_retry = 20;
@@ -76,6 +77,8 @@
 static int iscsi_net_up = 0;
 extern ib_boot_prop_t   *iscsiboot_prop;
 
+#define	ISCSI_CONFIGROOT_DELAY	1
+
 /*
  * iSCSI target discovery thread table
  */
@@ -777,22 +780,36 @@
 				 */
 				iscsi_boot_session_create(ihp,
 				    iscsiboot_prop);
-			} else {
+				retry++;
+				continue;
+			}
+			rc = iscsid_check_active_boot_conn(ihp);
+			if (rc == B_FALSE) {
 				/*
-				 * The boot session has been created, if
-				 * the target lun has not been online,
-				 * we should wait here for a while
+				 * no active connection for the boot
+				 * session, retry the login until
+				 * one is found or the retry count
+				 * is exceeded
 				 */
-				do {
-					lun_online =
-					    iscsiboot_prop->boot_tgt.lun_online;
-					if (lun_online == 0) {
-						delay(SEC_TO_TICK(1));
-						cur_sec++;
-					}
-				} while ((lun_online == 0) &&
-				    (cur_sec < iscsi_boot_max_delay));
+				delay(SEC_TO_TICK(ISCSI_CONFIGROOT_DELAY));
+				retry++;
+				continue;
 			}
+			/*
+			 * The boot session has been created with active
+			 * connection. If the target lun has not been online,
+			 * we should wait here for a while
+			 */
+			do {
+				lun_online =
+				    iscsiboot_prop->boot_tgt.lun_online;
+				if (lun_online == 0) {
+					delay(SEC_TO_TICK(
+					    ISCSI_CONFIGROOT_DELAY));
+					cur_sec++;
+				}
+			} while ((lun_online == 0) &&
+			    (cur_sec < iscsi_boot_max_delay));
 			retry++;
 		}
 		if (!rc) {
@@ -865,22 +882,36 @@
 				 */
 				iscsi_boot_session_create(ihp,
 				    iscsiboot_prop);
-			} else {
+				retry++;
+				continue;
+			}
+			rc = iscsid_check_active_boot_conn(ihp);
+			if (rc == B_FALSE) {
 				/*
-				 * The boot session has been created, if
-				 * the target lun has not been online,
-				 * we should wait here for a while
+				 * no active connection for the boot
+				 * session, retry the login until
+				 * one is found or the retry count
+				 * is exceeded
 				 */
-				do {
-					lun_online =
-					    iscsiboot_prop->boot_tgt.lun_online;
-					if (lun_online == 0) {
-						delay(SEC_TO_TICK(1));
-						cur_sec++;
-					}
-				} while ((lun_online == 0) &&
-				    (cur_sec < iscsi_boot_max_delay));
+				delay(SEC_TO_TICK(ISCSI_CONFIGROOT_DELAY));
+				retry++;
+				continue;
 			}
+			/*
+			 * The boot session has been created with active
+			 * connection. If the target lun has not been online,
+			 * we should wait here for a while
+			 */
+			do {
+				lun_online =
+				    iscsiboot_prop->boot_tgt.lun_online;
+				if (lun_online == 0) {
+					delay(SEC_TO_TICK(
+					    ISCSI_CONFIGROOT_DELAY));
+					cur_sec++;
+				}
+			} while ((lun_online == 0) &&
+			    (cur_sec < iscsi_boot_max_delay));
 			retry++;
 		}
 		if (!rc) {
@@ -2446,3 +2477,33 @@
 		return (ihp->hba_mpxio_enabled);
 	}
 }
+
+static boolean_t
+iscsid_check_active_boot_conn(iscsi_hba_t *ihp)
+{
+	iscsi_sess_t	*isp = NULL;
+	iscsi_conn_t	*icp = NULL;
+
+	rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
+	isp = ihp->hba_sess_list;
+	while (isp != NULL) {
+		if (isp->sess_boot == B_TRUE) {
+			rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
+			icp = isp->sess_conn_list;
+			while (icp != NULL) {
+				if (icp->conn_state ==
+				    ISCSI_CONN_STATE_LOGGED_IN) {
+					rw_exit(&isp->sess_conn_list_rwlock);
+					rw_exit(&ihp->hba_sess_list_rwlock);
+					return (B_TRUE);
+				}
+				icp = icp->conn_next;
+			}
+			rw_exit(&isp->sess_conn_list_rwlock);
+		}
+		isp = isp->sess_next;
+	}
+	rw_exit(&ihp->hba_sess_list_rwlock);
+
+	return (B_FALSE);
+}