changeset 10766:84a888430fd9

6876266 assertion failed: refcnt->ir_refcnt > 0, file: ../../common/io/idm/idm.c, line: 2197
author Peter Cudhea - Sun Microsystems - Burlington, MA United States <Peter.Cudhea@Sun.COM>
date Mon, 12 Oct 2009 16:45:00 -0400
parents 7ae75584baf6
children 67bc80b80c57
files usr/src/cmd/mdb/common/modules/idm/idm.c usr/src/uts/common/io/idm/idm.c usr/src/uts/common/io/idm/idm_conn_sm.c usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_conn.c
diffstat 4 files changed, 45 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/idm/idm.c	Mon Oct 12 20:05:55 2009 -0700
+++ b/usr/src/cmd/mdb/common/modules/idm/idm.c	Mon Oct 12 16:45:00 2009 -0400
@@ -47,6 +47,7 @@
 #define	ISCSI_CMD_SM_STRINGS
 #define	ISCSI_ICS_NAMES
 #define	ISCSI_LOGIN_STATE_NAMES
+#define	IDM_CN_NOTIFY_STRINGS
 #include <sys/idm/idm.h>
 #include <iscsi.h>
 #include <iscsit.h>
@@ -160,6 +161,7 @@
 static const char *iscsi_iscsi_cmd_state(unsigned int state);
 static const char *iscsi_iscsi_sess_state(unsigned int state);
 static const char *iscsi_iscsi_conn_state(unsigned int state);
+static const char *iscsi_iscsi_conn_event(unsigned int event);
 static const char *iscsi_iscsi_login_state(unsigned int state);
 
 static void iscsi_format_timestamp(char *ts_str, int strlen,
@@ -1809,6 +1811,12 @@
 				event_name=
 				    iscsi_iscsi_sess_event(sar->sar_event);
 				break;
+			case SAS_ISCSI_CONN:
+				state_name =
+				    iscsi_iscsi_conn_state(sar->sar_state);
+				event_name=
+				    iscsi_iscsi_conn_event(sar->sar_event);
+				break;
 			default:
 				state_name = event_name = "N/A";
 				break;
@@ -1940,6 +1948,13 @@
 	return ((state < CS_MAX_STATE) ? idm_cs_name[state] : "N/A");
 }
 
+static const char *
+iscsi_iscsi_conn_event(unsigned int event)
+{
+
+	return ((event < CN_MAX) ? idm_cn_strings[event] : "N/A");
+}
+
 /*ARGSUSED*/
 static const char *
 iscsi_idm_task_state(unsigned int state)
--- a/usr/src/uts/common/io/idm/idm.c	Mon Oct 12 20:05:55 2009 -0700
+++ b/usr/src/uts/common/io/idm/idm.c	Mon Oct 12 16:45:00 2009 -0400
@@ -284,7 +284,7 @@
 idm_status_t
 idm_ini_conn_connect(idm_conn_t *ic)
 {
-	idm_status_t	rc = IDM_STATUS_SUCCESS;
+	idm_status_t	rc;
 
 	rc = idm_conn_sm_init(ic);
 	if (rc != IDM_STATUS_SUCCESS) {
@@ -303,18 +303,17 @@
 	    !(ic->ic_state_flags & CF_ERROR)) {
 		cv_wait(&ic->ic_state_cv, &ic->ic_state_mutex);
 	}
-	mutex_exit(&ic->ic_state_mutex);
 
+	/*
+	 * The CN_READY_TO_LOGIN and/or the CN_CONNECT_FAIL call to
+	 * idm_notify_client has already been generated by the idm conn
+	 * state machine.  If connection fails any time after this
+	 * check, we will detect it in iscsi_login.
+	 */
 	if (ic->ic_state_flags & CF_ERROR) {
-		/* ic->ic_conn_sm_status will contains failure status */
-		idm_conn_rele(ic);
-		return (ic->ic_conn_sm_status);
+		rc = ic->ic_conn_sm_status;
 	}
-
-	/* Ready to login */
-	ASSERT(ic->ic_state_flags & CF_LOGIN_READY);
-	(void) idm_notify_client(ic, CN_READY_FOR_LOGIN, NULL);
-
+	mutex_exit(&ic->ic_state_mutex);
 	idm_conn_rele(ic);
 
 	return (rc);
--- a/usr/src/uts/common/io/idm/idm_conn_sm.c	Mon Oct 12 20:05:55 2009 -0700
+++ b/usr/src/uts/common/io/idm/idm_conn_sm.c	Mon Oct 12 16:45:00 2009 -0400
@@ -458,6 +458,7 @@
 		/* T4 */
 		idm_update_state(ic, CS_S4_IN_LOGIN, event_ctx);
 		break;
+	case CE_TRANSPORT_FAIL:
 	case CE_CONNECT_FAIL:
 	case CE_LOGOUT_OTHER_CONN_RCV:
 	case CE_TX_PROTOCOL_ERROR:
@@ -1127,6 +1128,7 @@
 		break;
 	case CS_S4_IN_LOGIN:
 		if (ic->ic_conn_type == CONN_TYPE_INI) {
+			(void) idm_notify_client(ic, CN_READY_FOR_LOGIN, NULL);
 			mutex_enter(&ic->ic_state_mutex);
 			ic->ic_state_flags |= CF_LOGIN_READY;
 			cv_signal(&ic->ic_state_cv);
@@ -1503,6 +1505,7 @@
 	 * for now lets just call the client's notify function and return
 	 * the status.
 	 */
+	ASSERT(!mutex_owned(&ic->ic_state_mutex));
 	cn = (cn > CN_MAX) ? CN_MAX : cn;
 	IDM_SM_LOG(CE_NOTE, "idm_notify_client: ic=%p %s(%d)\n",
 	    (void *)ic, idm_cn_strings[cn], cn);
--- a/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_conn.c	Mon Oct 12 20:05:55 2009 -0700
+++ b/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_conn.c	Mon Oct 12 16:45:00 2009 -0400
@@ -386,7 +386,9 @@
 	 * Don't access icp if the notification is CN_CONNECT_DESTROY
 	 * since icp may have already been freed.
 	 *
-	 * Handle CN_FFP_ENABLED and CN_CONNECT_DESTROY immediately
+	 * In particular, we cannot audit the CN_CONNECT_DESTROY event.
+	 *
+	 * Handle a few cases immediately, the rest in a task queue.
 	 */
 	switch (icn) {
 	case CN_CONNECT_FAIL:
@@ -395,17 +397,28 @@
 		 * Wakeup any thread waiting for login stuff to happen.
 		 */
 		ASSERT(icp != NULL);
+
+		mutex_enter(&icp->conn_state_mutex);
+		idm_sm_audit_event(&icp->conn_state_audit,
+		    SAS_ISCSI_CONN, icp->conn_state, icn, data);
+		mutex_exit(&icp->conn_state_mutex);
 		iscsi_login_update_state(icp, LOGIN_ERROR);
 		return (IDM_STATUS_SUCCESS);
+
 	case CN_READY_FOR_LOGIN:
 		idm_conn_hold(ic); /* Released in CN_CONNECT_LOST */
+		ASSERT(icp != NULL);
+
 		mutex_enter(&icp->conn_state_mutex);
+		idm_sm_audit_event(&icp->conn_state_audit,
+		    SAS_ISCSI_CONN, icp->conn_state, icn, data);
 		icp->conn_state_idm_connected = B_TRUE;
 		cv_broadcast(&icp->conn_state_change);
 		mutex_exit(&icp->conn_state_mutex);
 
 		iscsi_login_update_state(icp, LOGIN_READY);
 		return (IDM_STATUS_SUCCESS);
+
 	case CN_CONNECT_DESTROY:
 		/*
 		 * We released any dependecies we had on this object in
@@ -417,6 +430,10 @@
 	}
 
 	ASSERT(icp != NULL);
+	mutex_enter(&icp->conn_state_mutex);
+	idm_sm_audit_event(&icp->conn_state_audit,
+	    SAS_ISCSI_CONN, icp->conn_state, icn, data);
+	mutex_exit(&icp->conn_state_mutex);
 	isp = icp->conn_sess;
 
 	/*