Print this page
NEX-15497 Multiple iSCSI targets stuck offlining and an old thread in idm_refcnt_wait_ref
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15497 Multiple iSCSI targets stuck offlining and an old thread in idm_refcnt_wait_ref
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-7907 uts/common/sys/scsi/scsi_names.h should define IQN as 223 bytes, not utf-8 characters
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-2756 iscsit should fold the case of scsi names that we get from initiators
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3622 COMSTAR should have per remote port kstats for I/O and latency
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SUP-776 iSCSI target portals not isolating IQNs on different subnets
        
@@ -44,10 +44,11 @@
 #include <sys/stmf.h>
 #include <sys/stmf_ioctl.h>
 #include <sys/portif.h>
 #include <sys/idm/idm.h>
 #include <sys/idm/idm_text.h>
+#include <sys/idm/idm_so.h>
 
 #define ISCSIT_LOGIN_SM_STRINGS
 #include "iscsit.h"
 #include "iscsit_auth.h"
 
@@ -730,11 +731,41 @@
             (int)lsm->icl_login_state, (int)new_state);
         lsm->icl_login_last_state = lsm->icl_login_state;
         lsm->icl_login_state = new_state;
         mutex_exit(&lsm->icl_mutex);
 
-        switch (lsm->icl_login_state) {
+        /*
+         * Tale of caution here. The use of new_state instead of using
+         * lsm->icl_login_state is deliberate (which had been used originally).
+         * Since the icl_mutex is dropped under the right circumstances
+         * the login state changes between setting the state and examining
+         * the state to proceed. No big surprise since the lock was being
+         * used in the first place to prevent just that type of change.
+         *
+         * There has been a case where network errors occurred while a client
+         * was attempting to reinstate the connection causing multiple
+         * login packets to arrive into the state machine. Those multiple
+         * packets which were processed incorrectly caused the reference
+         * count on the connection to be one higher than it should be and
+         * from then on the connection can't close correctly causing a hang.
+         *
+         * Upon examination of the core it was found that the connection
+         * audit data had calls looking like:
+         *    login_sm_event_dispatch
+         *    login_sm_processing
+         *    login_sm_new_state
+         * That call sequence means the new state was/is ILS_LOGIN_ERROR
+         * yet the audit trail continues with a call to
+         *    login_sm_send_next_response
+         * which could only occur if icl_login_state had changed. Had the
+         * design of COMSTAR taken this into account the code would
+         * originally have held the icl_mutex across the processing of the
+         * state processing. Lock order and calls which sleep prevent that
+         * from being possible. The next best solution is to use the local
+         * variable which holds the state.
+         */
+        switch (new_state) {
         case ILS_LOGIN_WAITING:
                 /* Do nothing, waiting for more login PDU's */
                 break;
         case ILS_LOGIN_PROCESSING:
                 /* All login PDU's received, process login request */
@@ -1746,10 +1777,12 @@
 {
         iscsit_sess_t           *ist = ict->ict_sess;
         stmf_scsi_session_t     *ss;
         iscsi_transport_id_t    *iscsi_tptid;
         uint16_t                ident_len, adn_len, tptid_sz;
+        char                    prop_buf[KSTAT_STRLEN + 1];
+        char                    peer_buf[IDM_SA_NTOP_BUFSIZ];
 
         /*
          * Hold target mutex until we have finished registering with STMF
          */
         mutex_enter(&ist->ist_tgt->target_mutex);
@@ -1806,10 +1839,15 @@
         }
 
         ss->ss_port_private = ict->ict_sess;
         ict->ict_sess->ist_stmf_sess = ss;
         mutex_exit(&ist->ist_tgt->target_mutex);
+        (void) snprintf(prop_buf, sizeof (prop_buf), "peername_%"PRIxPTR"",
+            (uintptr_t)ict->ict_sess);
+        (void) idm_sa_ntop(&ict->ict_ic->ic_raddr, peer_buf,
+            sizeof (peer_buf));
+        (void) stmf_add_rport_info(ss, prop_buf, peer_buf);
 
         return (IDM_STATUS_SUCCESS);
 }
 
 
@@ -2724,28 +2762,28 @@
                 return (NULL);
 
         /* Check for one of the supported name types */
         if (strncasecmp(name, SNS_EUI ".", strlen(SNS_EUI) + 1) == 0) {
                 sns = SNS_EUI;
-                *buflen = SNS_EUI_U8_LEN_MAX + 1;
+                *buflen = SNS_EUI_LEN_MAX + 1;
                 flag |= U8_TEXTPREP_TOUPPER;
         } else if (strncasecmp(name, SNS_IQN ".", strlen(SNS_IQN) + 1) == 0) {
                 sns = SNS_IQN;
-                *buflen = SNS_IQN_U8_LEN_MAX + 1;
+                *buflen = SNS_IQN_LEN_MAX + 1;
                 flag |= U8_TEXTPREP_TOLOWER;
         } else if (strncasecmp(name, SNS_NAA ".", strlen(SNS_NAA) + 1) == 0) {
                 sns = SNS_NAA;
-                *buflen = SNS_NAA_U8_LEN_MAX + 1;
+                *buflen = SNS_NAA_LEN_MAX + 1;
                 flag |= U8_TEXTPREP_TOUPPER;
         } else {
                 return (NULL);
         }
 
         ret = kmem_zalloc(*buflen, KM_SLEEP);
         coff = strlen(sns);
         inlen = strlen(name) - coff;
-        outlen = *buflen - coff;
+        outlen = *buflen - coff - 1;
 
         /* Fold the case and normalize string */
         if (u8_textprep_str(name + coff, &inlen, ret + coff, &outlen, flag,
             U8_UNICODE_320, &errnum) == (size_t)-1) {
                 kmem_free(ret, *buflen);