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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c
          +++ new/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c
↓ open down ↓ 38 lines elided ↑ open up ↑
  39   39  #include <sys/sysmacros.h>
  40   40  #include <sys/note.h>
  41   41  #include <sys/sdt.h>
  42   42  #include <sys/errno.h>
  43   43  
  44   44  #include <sys/stmf.h>
  45   45  #include <sys/stmf_ioctl.h>
  46   46  #include <sys/portif.h>
  47   47  #include <sys/idm/idm.h>
  48   48  #include <sys/idm/idm_text.h>
       49 +#include <sys/idm/idm_so.h>
  49   50  
  50   51  #define ISCSIT_LOGIN_SM_STRINGS
  51   52  #include "iscsit.h"
  52   53  #include "iscsit_auth.h"
  53   54  
  54   55  typedef struct {
  55   56          list_node_t             le_ctx_node;
  56   57          iscsit_login_event_t    le_ctx_event;
  57   58          idm_pdu_t               *le_pdu;
  58   59  } login_event_ctx_t;
↓ open down ↓ 666 lines elided ↑ open up ↑
 725  726              iscsit_conn_t *, ict, login_event_ctx_t *, ctx,
 726  727              iscsit_login_state_t, new_state);
 727  728  
 728  729          mutex_enter(&lsm->icl_mutex);
 729  730          idm_sm_audit_state_change(&lsm->icl_state_audit, SAS_ISCSIT_LOGIN,
 730  731              (int)lsm->icl_login_state, (int)new_state);
 731  732          lsm->icl_login_last_state = lsm->icl_login_state;
 732  733          lsm->icl_login_state = new_state;
 733  734          mutex_exit(&lsm->icl_mutex);
 734  735  
 735      -        switch (lsm->icl_login_state) {
      736 +        /*
      737 +         * Tale of caution here. The use of new_state instead of using
      738 +         * lsm->icl_login_state is deliberate (which had been used originally).
      739 +         * Since the icl_mutex is dropped under the right circumstances
      740 +         * the login state changes between setting the state and examining
      741 +         * the state to proceed. No big surprise since the lock was being
      742 +         * used in the first place to prevent just that type of change.
      743 +         *
      744 +         * There has been a case where network errors occurred while a client
      745 +         * was attempting to reinstate the connection causing multiple
      746 +         * login packets to arrive into the state machine. Those multiple
      747 +         * packets which were processed incorrectly caused the reference
      748 +         * count on the connection to be one higher than it should be and
      749 +         * from then on the connection can't close correctly causing a hang.
      750 +         *
      751 +         * Upon examination of the core it was found that the connection
      752 +         * audit data had calls looking like:
      753 +         *    login_sm_event_dispatch
      754 +         *    login_sm_processing
      755 +         *    login_sm_new_state
      756 +         * That call sequence means the new state was/is ILS_LOGIN_ERROR
      757 +         * yet the audit trail continues with a call to
      758 +         *    login_sm_send_next_response
      759 +         * which could only occur if icl_login_state had changed. Had the
      760 +         * design of COMSTAR taken this into account the code would
      761 +         * originally have held the icl_mutex across the processing of the
      762 +         * state processing. Lock order and calls which sleep prevent that
      763 +         * from being possible. The next best solution is to use the local
      764 +         * variable which holds the state.
      765 +         */
      766 +        switch (new_state) {
 736  767          case ILS_LOGIN_WAITING:
 737  768                  /* Do nothing, waiting for more login PDU's */
 738  769                  break;
 739  770          case ILS_LOGIN_PROCESSING:
 740  771                  /* All login PDU's received, process login request */
 741  772                  login_sm_process_request(ict);
 742  773                  break;
 743  774          case ILS_LOGIN_RESPONDING:
 744  775                  rpdu = login_sm_build_login_response(ict);
 745  776                  login_sm_send_next_response(ict, rpdu);
↓ open down ↓ 995 lines elided ↑ open up ↑
1741 1772  }
1742 1773  
1743 1774  
1744 1775  static idm_status_t
1745 1776  login_sm_session_register(iscsit_conn_t *ict)
1746 1777  {
1747 1778          iscsit_sess_t           *ist = ict->ict_sess;
1748 1779          stmf_scsi_session_t     *ss;
1749 1780          iscsi_transport_id_t    *iscsi_tptid;
1750 1781          uint16_t                ident_len, adn_len, tptid_sz;
     1782 +        char                    prop_buf[KSTAT_STRLEN + 1];
     1783 +        char                    peer_buf[IDM_SA_NTOP_BUFSIZ];
1751 1784  
1752 1785          /*
1753 1786           * Hold target mutex until we have finished registering with STMF
1754 1787           */
1755 1788          mutex_enter(&ist->ist_tgt->target_mutex);
1756 1789          if (ist->ist_tgt->target_state != TS_STMF_ONLINE) {
1757 1790                  mutex_exit(&ist->ist_tgt->target_mutex);
1758 1791                  SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR,
1759 1792                      ISCSI_LOGIN_STATUS_TGT_REMOVED);
1760 1793                  return (IDM_STATUS_FAIL);
↓ open down ↓ 40 lines elided ↑ open up ↑
1801 1834                  stmf_remote_port_free(ss->ss_rport);
1802 1835                  stmf_free(ss);
1803 1836                  SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR,
1804 1837                      ISCSI_LOGIN_STATUS_TARGET_ERROR);
1805 1838                  return (IDM_STATUS_FAIL);
1806 1839          }
1807 1840  
1808 1841          ss->ss_port_private = ict->ict_sess;
1809 1842          ict->ict_sess->ist_stmf_sess = ss;
1810 1843          mutex_exit(&ist->ist_tgt->target_mutex);
     1844 +        (void) snprintf(prop_buf, sizeof (prop_buf), "peername_%"PRIxPTR"",
     1845 +            (uintptr_t)ict->ict_sess);
     1846 +        (void) idm_sa_ntop(&ict->ict_ic->ic_raddr, peer_buf,
     1847 +            sizeof (peer_buf));
     1848 +        (void) stmf_add_rport_info(ss, prop_buf, peer_buf);
1811 1849  
1812 1850          return (IDM_STATUS_SUCCESS);
1813 1851  }
1814 1852  
1815 1853  
1816 1854  static idm_status_t
1817 1855  login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu)
1818 1856  {
1819 1857          uint8_t                 csg_req;
1820 1858          iscsit_conn_login_t     *lsm = &ict->ict_login_sm;
↓ open down ↓ 898 lines elided ↑ open up ↑
2719 2757          int             errnum;
2720 2758          int             flag = U8_TEXTPREP_NFKC;
2721 2759          size_t          inlen, outlen, coff;
2722 2760  
2723 2761          if (name == NULL)
2724 2762                  return (NULL);
2725 2763  
2726 2764          /* Check for one of the supported name types */
2727 2765          if (strncasecmp(name, SNS_EUI ".", strlen(SNS_EUI) + 1) == 0) {
2728 2766                  sns = SNS_EUI;
2729      -                *buflen = SNS_EUI_U8_LEN_MAX + 1;
     2767 +                *buflen = SNS_EUI_LEN_MAX + 1;
2730 2768                  flag |= U8_TEXTPREP_TOUPPER;
2731 2769          } else if (strncasecmp(name, SNS_IQN ".", strlen(SNS_IQN) + 1) == 0) {
2732 2770                  sns = SNS_IQN;
2733      -                *buflen = SNS_IQN_U8_LEN_MAX + 1;
     2771 +                *buflen = SNS_IQN_LEN_MAX + 1;
2734 2772                  flag |= U8_TEXTPREP_TOLOWER;
2735 2773          } else if (strncasecmp(name, SNS_NAA ".", strlen(SNS_NAA) + 1) == 0) {
2736 2774                  sns = SNS_NAA;
2737      -                *buflen = SNS_NAA_U8_LEN_MAX + 1;
     2775 +                *buflen = SNS_NAA_LEN_MAX + 1;
2738 2776                  flag |= U8_TEXTPREP_TOUPPER;
2739 2777          } else {
2740 2778                  return (NULL);
2741 2779          }
2742 2780  
2743 2781          ret = kmem_zalloc(*buflen, KM_SLEEP);
2744 2782          coff = strlen(sns);
2745 2783          inlen = strlen(name) - coff;
2746      -        outlen = *buflen - coff;
     2784 +        outlen = *buflen - coff - 1;
2747 2785  
2748 2786          /* Fold the case and normalize string */
2749 2787          if (u8_textprep_str(name + coff, &inlen, ret + coff, &outlen, flag,
2750 2788              U8_UNICODE_320, &errnum) == (size_t)-1) {
2751 2789                  kmem_free(ret, *buflen);
2752 2790                  return (NULL);
2753 2791          }
2754 2792  
2755 2793          /* Copy the name type prefix */
2756 2794          bcopy(sns, ret, coff);
2757 2795  
2758 2796          return (ret);
2759 2797  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX