Mercurial > illumos > illumos-gate
changeset 12579:611412d35eb8
6951720 host side port offline whiel IO running made iscsi target system panic
6929441 iscsit sometimes doesn't teardown connections during session reinstatement
6835615 IDM refcnt rules are obscure and to be better defined
author | Priya Krishnan <Priya.Krishnan@Sun.COM> |
---|---|
date | Mon, 07 Jun 2010 17:33:23 -0400 |
parents | f9062c43c8bc |
children | 4daad5d7c55d |
files | usr/src/uts/common/io/comstar/port/iscsit/iscsit.c usr/src/uts/common/io/comstar/port/iscsit/iscsit.h usr/src/uts/common/io/comstar/port/iscsit/iscsit_sess.c usr/src/uts/common/io/comstar/port/iscsit/iscsit_tgt.c usr/src/uts/common/io/idm/idm_conn_sm.c |
diffstat | 5 files changed, 87 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit.c Mon Jun 07 14:07:27 2010 -0700 +++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit.c Mon Jun 07 17:33:23 2010 -0400 @@ -1367,10 +1367,14 @@ iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict); } + idm_refcnt_wait_ref(&ict->ict_refcnt); + /* + * The session state machine does not need to post + * events to IDM any longer, so it is safe to set + * the idm connection reference to NULL + */ ict->ict_ic = NULL; - idm_refcnt_wait_ref(&ict->ict_refcnt); - /* Reap the login state machine */ iscsit_login_sm_fini(ict); @@ -1386,6 +1390,23 @@ return (IDM_STATUS_SUCCESS); } +void +iscsit_conn_logout(iscsit_conn_t *ict) +{ + /* + * If the iscsi connection is active, then + * logout the IDM connection by sending a + * CE_LOGOUT_SESSION_SUCCESS, else, no action + * needs to be taken because the connection + * is already in the teardown process. + */ + mutex_enter(&ict->ict_mutex); + if (ict->ict_lost == B_FALSE && ict->ict_destroyed == B_FALSE) { + idm_conn_event(ict->ict_ic, CE_LOGOUT_SESSION_SUCCESS, NULL); + } + mutex_exit(&ict->ict_mutex); +} + /* * STMF-related functions *
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit.h Mon Jun 07 14:07:27 2010 -0700 +++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit.h Mon Jun 07 17:33:23 2010 -0400 @@ -688,6 +688,9 @@ void iscsit_conn_rele(iscsit_conn_t *ict); +void +iscsit_conn_logout(iscsit_conn_t *ict); + /* * Session functions */ @@ -706,6 +709,9 @@ void iscsit_sess_hold(iscsit_sess_t *ist); +idm_status_t +iscsit_sess_check_hold(iscsit_sess_t *ist); + void iscsit_sess_rele(iscsit_sess_t *ist);
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_sess.c Mon Jun 07 14:07:27 2010 -0700 +++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_sess.c Mon Jun 07 17:33:23 2010 -0400 @@ -319,6 +319,20 @@ idm_refcnt_rele(&ist->ist_refcnt); } +idm_status_t +iscsit_sess_check_hold(iscsit_sess_t *ist) +{ + mutex_enter(&ist->ist_mutex); + if (ist->ist_state != SS_Q6_DONE && + ist->ist_state != SS_Q7_ERROR) { + idm_refcnt_hold(&ist->ist_refcnt); + mutex_exit(&ist->ist_mutex); + return (IDM_STATUS_SUCCESS); + } + mutex_exit(&ist->ist_mutex); + return (IDM_STATUS_FAIL); +} + iscsit_conn_t * iscsit_sess_lookup_conn(iscsit_sess_t *ist, uint16_t cid) { @@ -562,6 +576,8 @@ static void sess_sm_q2_active(iscsit_sess_t *ist, sess_event_ctx_t *ctx) { + iscsit_conn_t *ict; + switch (ctx->se_ctx_event) { case SE_CONN_LOGGED_IN: /* N2 track FFP connections */ @@ -577,6 +593,19 @@ break; case SE_SESSION_REINSTATE: /* N11 */ + /* + * Shutdown the iSCSI connections by + * sending an implicit logout to all + * the IDM connections and transition + * the session to SS_Q6_DONE state. + */ + mutex_enter(&ist->ist_mutex); + for (ict = list_head(&ist->ist_conn_list); + ict != NULL; + ict = list_next(&ist->ist_conn_list, ict)) { + iscsit_conn_logout(ict); + } + mutex_exit(&ist->ist_mutex); sess_sm_new_state(ist, ctx, SS_Q6_DONE); break; default: @@ -588,7 +617,7 @@ static void sess_sm_q3_logged_in(iscsit_sess_t *ist, sess_event_ctx_t *ctx) { - iscsit_conn_t *ict; + iscsit_conn_t *ict; switch (ctx->se_ctx_event) { case SE_CONN_IN_LOGIN: @@ -645,8 +674,7 @@ */ continue; } - idm_conn_event(ict->ict_ic, CE_LOGOUT_SESSION_SUCCESS, - NULL); + iscsit_conn_logout(ict); } mutex_exit(&ist->ist_mutex);
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_tgt.c Mon Jun 07 14:07:27 2010 -0700 +++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_tgt.c Mon Jun 07 17:33:23 2010 -0400 @@ -1230,9 +1230,7 @@ result = avl_find(sess_avl, &tmp_sess, &where); if (result != NULL) { - iscsit_sess_hold(result); - UNLOCK_FOR_SESS_LOOKUP(tgt); - return (result); + goto found_result; } /* @@ -1244,9 +1242,7 @@ (strcmp(result->ist_initiator_name, initiator_name) == 0) && (memcmp(result->ist_isid, isid, ISCSI_ISID_LEN) == 0) && (result->ist_tpgt_tag == tag)) { - iscsit_sess_hold(result); - UNLOCK_FOR_SESS_LOOKUP(tgt); - return (result); + goto found_result; } result = avl_nearest(sess_avl, where, AVL_AFTER); @@ -1254,14 +1250,18 @@ (strcmp(result->ist_initiator_name, initiator_name) == 0) && (memcmp(result->ist_isid, isid, ISCSI_ISID_LEN) == 0) && (result->ist_tpgt_tag == tag)) { - iscsit_sess_hold(result); - UNLOCK_FOR_SESS_LOOKUP(tgt); - return (result); + goto found_result; } - UNLOCK_FOR_SESS_LOOKUP(tgt); + result = NULL; - return (NULL); +found_result: + if ((result != NULL) && + (iscsit_sess_check_hold(result) != IDM_STATUS_SUCCESS)) { + result = NULL; + } + UNLOCK_FOR_SESS_LOOKUP(tgt); + return (result); } static idm_status_t
--- a/usr/src/uts/common/io/idm/idm_conn_sm.c Mon Jun 07 14:07:27 2010 -0700 +++ b/usr/src/uts/common/io/idm/idm_conn_sm.c Mon Jun 07 17:33:23 2010 -0400 @@ -601,6 +601,22 @@ (void) idm_notify_client(ic, CN_LOGIN_FAIL, NULL); idm_update_state(ic, CS_S9_INIT_ERROR, event_ctx); break; + case CE_LOGOUT_SESSION_SUCCESS: + /* + * T8 + * A session reinstatement request can be received while a + * session is active and a login is in process. The iSCSI + * connections are shut down by a CE_LOGOUT_SESSION_SUCCESS + * event sent from the session to the IDM layer. + */ + if (IDM_CONN_ISTGT(ic)) { + ic->ic_transport_ops->it_tgt_conn_disconnect(ic); + } else { + ic->ic_transport_ops->it_ini_conn_disconnect(ic); + } + idm_update_state(ic, CS_S11_COMPLETE, event_ctx); + break; + case CE_LOGIN_SND: ASSERT(ic->ic_client_callback == NULL); /*