Mercurial > illumos > illumos-gate
changeset 10317:0a8cd85041eb
6842646 iSCSI initiator will hang when logging in iscsitgt:default target with the same IP in different tpgt
author | yi zhang - Sun Microsystems - Beijing China <Zhang.Yi@Sun.COM> |
---|---|
date | Sun, 16 Aug 2009 01:17:24 +0800 |
parents | d68e26bd3bfd |
children | 811db323512d |
files | usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_conn.c usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_login.c |
diffstat | 2 files changed, 39 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_conn.c Sat Aug 15 09:43:34 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_conn.c Sun Aug 16 01:17:24 2009 +0800 @@ -478,13 +478,14 @@ /* * This logic assumes that the IDM login-snooping code - * and the initiator login code will agree on whether - * the connection is in FFP. The reason we do this - * is that we don't want to process CN_FFP_DISABLED until - * CN_FFP_ENABLED has been full handled. + * and the initiator login code will agree to go when + * the connection is in FFP or final error received. + * The reason we do this is that we don't want to process + * CN_FFP_DISABLED until CN_FFP_ENABLED has been full handled. */ mutex_enter(&icp->conn_login_mutex); - while (icp->conn_login_state != LOGIN_FFP) { + while ((icp->conn_login_state != LOGIN_FFP) && + (icp->conn_login_state != LOGIN_ERROR)) { cv_wait(&icp->conn_login_cv, &icp->conn_login_mutex); } mutex_exit(&icp->conn_login_mutex); @@ -524,8 +525,13 @@ case FD_CONN_FAIL: default: - iscsi_conn_update_state_locked(icp, - ISCSI_CONN_STATE_FAILED); + if (icp->conn_state == ISCSI_CONN_STATE_IN_LOGIN) { + iscsi_conn_update_state_locked(icp, + ISCSI_CONN_STATE_FREE); + } else { + iscsi_conn_update_state_locked(icp, + ISCSI_CONN_STATE_FAILED); + } break; } @@ -544,7 +550,8 @@ * what CN_CONNECT_LOST means to us. */ in_login = (boolean_t)data; - if (in_login) { + if (in_login || + (icp->conn_prev_state == ISCSI_CONN_STATE_IN_LOGIN)) { mutex_enter(&icp->conn_state_mutex); icp->conn_state_idm_connected = B_FALSE;
--- a/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_login.c Sat Aug 15 09:43:34 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_login.c Sun Aug 16 01:17:24 2009 +0800 @@ -57,6 +57,14 @@ #define ISCSI_LOGIN_RETRY_DELAY 5 /* seconds */ +#define ISCSI_LOGIN_TRANSIT_FFP(flags) \ + (!(flags & ISCSI_FLAG_LOGIN_CONTINUE) && \ + (flags & ISCSI_FLAG_LOGIN_TRANSIT) && \ + (ISCSI_LOGIN_CURRENT_STAGE(flags) == \ + ISCSI_OP_PARMS_NEGOTIATION_STAGE) && \ + (ISCSI_LOGIN_NEXT_STAGE(flags) == \ + ISCSI_FULL_FEATURE_PHASE)) + /* * +--------------------------------------------------------------------+ * | External Login Interface | @@ -310,7 +318,11 @@ } } break; + case ISCSI_CONN_STATE_FREE: + mutex_exit(&icp->conn_state_mutex); + break; default: + mutex_exit(&icp->conn_state_mutex); ASSERT(0); break; } @@ -535,6 +547,18 @@ icp->conn_login_max_data_length); /* pass back whatever error we discovered */ if (!ISCSI_SUCCESS(rval)) { + if (ISCSI_LOGIN_TRANSIT_FFP(ilrhp->flags)) { + /* + * iSCSI connection transit to next + * FFP stage while iscsi params + * ngeotiate error, LOGIN_ERROR + * marked so CN_FFP_ENABLED can + * be fully handled before + * CN_FFP_DISABLED can be processed. + */ + iscsi_login_update_state(icp, + LOGIN_ERROR); + } goto iscsi_login_done; }