Print this page
    
6740 ISCSI_OP_SCSI_RSP needs support
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/comstar/port/iscsit/iscsit.h
          +++ new/usr/src/uts/common/io/comstar/port/iscsit/iscsit.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  #ifndef _ISCSIT_H_
  28   28  #define _ISCSIT_H_
  29   29  
  30   30  #include <sys/iscsit/iscsi_if.h>
  31   31  #include <sys/iscsit/iscsit_common.h>
  32   32  
  33   33  #include "iscsit_authclient.h"
  34   34  
  35   35  /*
  36   36   * For some reason iscsi_protocol.h lists the max version as "0x02" and the
  37   37   * min version as "0x00".  RFC3720 clearly states that the current version
  38   38   * number is 0x00 so that is what we will use.
  39   39   */
  40   40  #define ISCSIT_MIN_VERSION                      0x00
  41   41  #define ISCSIT_MAX_VERSION                      0x00
  42   42  #define ISCSIT_MAX_CONNECTIONS                  32 /* MC/S support  */
  43   43  #define ISCSIT_MAX_RECV_DATA_SEGMENT_LENGTH     (32*1024)
  44   44  #define ISCSIT_MAX_BURST_LENGTH                 (1024*1024)
  45   45  #define ISCSIT_MAX_FIRST_BURST_LENGTH           ISCSI_DEFAULT_FIRST_BURST_LENGTH
  46   46  #define ISCSIT_MAX_TIME2WAIT                    ISCSI_MAX_TIME2WAIT
  47   47  #define ISCSIT_MAX_TIME2RETAIN                  ISCSI_DEFAULT_TIME_TO_RETAIN
  48   48  #define ISCSIT_MAX_OUTSTANDING_R2T              ISCSI_DEFAULT_MAX_OUT_R2T
  49   49  #define ISCSIT_MAX_ERROR_RECOVERY_LEVEL         0
  50   50  #define ISCSIT_MAX_OUTSTANDING_UNEXPECTED_PDUS  0
  51   51  
  52   52  #define ISCSIT_DEFAULT_TPG      "iscsit-default-tpg"
  53   53  #define ISCSIT_DEFAULT_TPGT     1
  54   54  
  55   55  #define ISCSI_MAX_TSIH          0xffff
  56   56  #define ISCSI_UNSPEC_TSIH       0
  57   57  
  58   58  /* Max targets per system */
  59   59  #define ISCSIT_MAX_TARGETS      1024
  60   60  
  61   61  #define ISCSIT_MAX_WINDOW       1024
  62   62  #define ISCSIT_RXPDU_QUEUE_LEN  2048
  63   63  
  64   64  #define ISCSIT_CMDSN_LT_EXPCMDSN        -1
  65   65  #define ISCSIT_CMDSN_EQ_EXPCMDSN        1
  66   66  #define ISCSIT_CMDSN_GT_EXPCMDSN        0
  67   67  /*
  68   68   * MC/S: A timeout is maintained to recover from lost CmdSN (holes in the
  69   69   * CmdSN ordering). When the timeout is reached, the ExpCmdSN is advanced
  70   70   * past the hole to continue processing the queued commands. This value is
  71   71   * system-tunable (volatile rxpdu_queue_threshold) and should be in the
  72   72   * range from 5 to 30 seconds.
  73   73   */
  74   74  #define ISCSIT_RXPDU_QUEUE_THRESHOLD            5       /* 5 seconds */
  75   75  #define ISCSIT_RXPDU_QUEUE_MONITOR_INTERVAL     5       /* 5 seconds */
  76   76  
  77   77  /* Time in seconds to wait between calls to stmf_deregister_local_port */
  78   78  #define TGT_DEREG_RETRY_SECONDS 1
  79   79  
  80   80  #define ISCSIT_GLOBAL_LOCK(rw) rw_enter(&iscsit_global.global_rwlock, (rw))
  81   81  #define ISCSIT_GLOBAL_UNLOCK() rw_exit(&iscsit_global.global_rwlock)
  82   82  
  83   83  /* Circular buffer to hold the out-of-order PDUs in MC/S */
  84   84  typedef struct {
  85   85          idm_pdu_t       *cb_buffer[ISCSIT_RXPDU_QUEUE_LEN];
  86   86          int             cb_num_elems;
  87   87  } iscsit_cbuf_t;
  88   88  
  89   89  /*
  90   90   * Used for serial number arithmetic (RFC 1982)
  91   91   */
  92   92  #define ISCSIT_SNA32_CHECK      0x80000000
  93   93  
  94   94  typedef struct {
  95   95          char            tpg_name[MAX_TPG_NAMELEN];
  96   96          kmutex_t        tpg_mutex;
  97   97          idm_refcnt_t    tpg_refcnt;
  98   98          int             tpg_online;
  99   99          avl_tree_t      tpg_portal_list;
 100  100          avl_node_t      tpg_global_ln;
 101  101          list_node_t     tpg_delete_ln;
 102  102  } iscsit_tpg_t;
 103  103  
 104  104  #define IS_DEFAULT_TPGT(TPGT) \
 105  105          (((TPGT) != NULL) && \
 106  106              ((TPGT)->tpgt_tpg == iscsit_global.global_default_tpg))
 107  107  
 108  108  typedef struct {
 109  109          iscsit_tpg_t    *tpgt_tpg;
 110  110          idm_refcnt_t    tpgt_refcnt;
 111  111          avl_node_t      tpgt_tgt_ln;
 112  112          list_node_t     tpgt_delete_ln;
 113  113          uint16_t        tpgt_tag;
 114  114          boolean_t       tpgt_needs_tpg_offline;
 115  115  } iscsit_tpgt_t;
 116  116  
 117  117  typedef struct {
 118  118          struct sockaddr_storage portal_addr;
 119  119          int                     portal_online;
 120  120          idm_refcnt_t            portal_refcnt;
 121  121          avl_node_t              portal_tpg_ln;
 122  122          iscsit_tpg_t            *portal_tpg;
 123  123          idm_svc_t               *portal_svc;
 124  124          boolean_t               portal_default;
 125  125          void                    *portal_isns;
 126  126  } iscsit_portal_t;
 127  127  
 128  128  
 129  129  /* Target states and events, update iscsit_ts_name table whenever modified */
 130  130  typedef enum {
 131  131          TS_UNDEFINED = 0,
 132  132          TS_CREATED,
 133  133          TS_ONLINING,
 134  134          TS_ONLINE,
 135  135          TS_STMF_ONLINE,
 136  136          TS_DELETING_NEED_OFFLINE,
 137  137          TS_OFFLINING,
 138  138          TS_OFFLINE,
 139  139          TS_STMF_OFFLINE,
 140  140          TS_DELETING_STMF_DEREG,
 141  141          TS_DELETING_STMF_DEREG_FAIL,
 142  142          TS_DELETING,
 143  143          TS_MAX_STATE
 144  144  } iscsit_tgt_state_t;
 145  145  
 146  146  #ifdef ISCSIT_TGT_SM_STRINGS
 147  147  static const char *iscsit_ts_name[TS_MAX_STATE+1] = {
 148  148          "TS_UNDEFINED",
 149  149          "TS_CREATED",
 150  150          "TS_ONLINING",
 151  151          "TS_ONLINE",
 152  152          "TS_STMF_ONLINE",
 153  153          "TS_DELETING_NEED_OFFLINE",
 154  154          "TS_OFFLINING",
 155  155          "TS_OFFLINE",
 156  156          "TS_STMF_OFFLINE",
 157  157          "TS_DELETING_STMF_DEREG",
 158  158          "TS_DELETING_STMF_DEREG_FAIL",
 159  159          "TS_DELETING",
 160  160          "TS_MAX_STATE"
 161  161  };
 162  162  #endif
 163  163  
 164  164  typedef enum {
 165  165          TE_UNDEFINED = 0,
 166  166          TE_STMF_ONLINE_REQ,
 167  167          TE_ONLINE_SUCCESS,
 168  168          TE_ONLINE_FAIL,
 169  169          TE_STMF_ONLINE_COMPLETE_ACK,
 170  170          TE_STMF_OFFLINE_REQ,
 171  171          TE_OFFLINE_COMPLETE,
 172  172          TE_STMF_OFFLINE_COMPLETE_ACK,
 173  173          TE_DELETE,
 174  174          TE_STMF_DEREG_SUCCESS,
 175  175          TE_STMF_DEREG_FAIL,
 176  176          TE_STMF_DEREG_RETRY,
 177  177          TE_WAIT_REF_COMPLETE,
 178  178          TE_MAX_EVENT
 179  179  } iscsit_tgt_event_t;
 180  180  
 181  181  #ifdef ISCSIT_TGT_SM_STRINGS
 182  182  static const char *iscsit_te_name[TE_MAX_EVENT+1] = {
 183  183          "TE_UNDEFINED",
 184  184          "TE_STMF_ONLINE_REQ",
 185  185          "TE_ONLINE_SUCCESS",
 186  186          "TE_ONLINE_FAIL",
 187  187          "TE_STMF_ONLINE_COMPLETE_ACK",
 188  188          "TE_STMF_OFFLINE_REQ",
 189  189          "TE_OFFLINE_COMPLETE",
 190  190          "TE_STMF_OFFLINE_COMPLETE_ACK",
 191  191          "TE_DELETE",
 192  192          "TE_STMF_DEREG_SUCCESS",
 193  193          "TE_STMF_DEREG_FAIL",
 194  194          "TE_STMF_DEREG_RETRY",
 195  195          "TE_WAIT_REF_COMPLETE",
 196  196          "TE_MAX_EVENT"
 197  197  };
 198  198  #endif
 199  199  
 200  200  typedef struct {
 201  201          char                    *target_name;
 202  202          nvlist_t                *target_props;
 203  203          kmutex_t                target_mutex;
 204  204          idm_refcnt_t            target_refcnt;
 205  205          idm_refcnt_t            target_sess_refcnt;
 206  206          avl_tree_t              target_tpgt_list;
 207  207          avl_tree_t              target_sess_list;
 208  208          avl_node_t              target_global_ln;
 209  209          avl_node_t              target_global_deleted_ln;
 210  210          /* STMF lport == iSCSI target */
 211  211          scsi_devid_desc_t       *target_devid;
 212  212          stmf_local_port_t       *target_stmf_lport;
 213  213          uint8_t                 target_stmf_lport_registered;
 214  214  
 215  215          /* Target state */
 216  216          boolean_t               target_sm_busy;
 217  217          boolean_t               target_deleting;
 218  218          iscsit_tgt_state_t      target_state;
 219  219          iscsit_tgt_state_t      target_last_state;
 220  220          sm_audit_buf_t          target_state_audit;
 221  221          list_t                  target_events;
 222  222          uint64_t                target_generation;
 223  223  } iscsit_tgt_t;
 224  224  
 225  225  typedef struct {
 226  226          char                    ini_name[MAX_ISCSI_NODENAMELEN];
 227  227          nvlist_t                *ini_props;
 228  228          avl_node_t              ini_global_ln;
 229  229  } iscsit_ini_t;
 230  230  
 231  231  /*
 232  232   * iSCSI Auth Information
 233  233   */
 234  234  typedef struct conn_auth {
 235  235          char                    ca_tgt_chapuser[iscsitAuthStringMaxLength];
 236  236          uint8_t                 ca_tgt_chapsecret[iscsitAuthStringMaxLength];
 237  237          int                     ca_tgt_chapsecretlen;
 238  238  
 239  239          char                    ca_ini_chapuser[iscsitAuthStringMaxLength];
 240  240          uint8_t                 ca_ini_chapsecret[iscsitAuthStringMaxLength];
 241  241          int                     ca_ini_chapsecretlen;
 242  242  
 243  243          /* RADIUS authentication information    */
 244  244          boolean_t               ca_use_radius;
 245  245          struct sockaddr_storage ca_radius_server;
 246  246          uint8_t                 ca_radius_secret[iscsitAuthStringMaxLength];
 247  247          int                     ca_radius_secretlen;
 248  248  
 249  249          /* authentication method list */
 250  250          iscsit_auth_method_t    ca_method_valid_list[iscsitAuthMethodMaxCount];
 251  251  
 252  252          /* Target alias */
 253  253          char                    ca_tgt_alias[MAX_ISCSI_NODENAMELEN];
 254  254  } conn_auth_t;
 255  255  
 256  256  /*
 257  257   * We have three state machines (so far) between the IDM connection state
 258  258   * machine, the session state machine, and the login state machine.  All
 259  259   * of these states have some concept of "full feature mode".  It's going
 260  260   * to be obnoxious if we use a mixture of these "ffp" representations
 261  261   * since it will be difficult to ensure the three state machines
 262  262   * transition at exactly the same time.  We should drive decisions that
 263  263   * depend on FFP from the IDM state machine which is actually snooping
 264  264   * the iSCSI PDU's and will always transition at the correct time.
 265  265   *
 266  266   * A consequence of this approach is that there is a window just after
 267  267   * login completes where we may get a SCSI request but the session
 268  268   * or login state machine has not quite transitioned to "FFP".  Whether
 269  269   * this is a problem depends on how we use those state machines.  This
 270  270   * is what we should use them for:
 271  271   *
 272  272   * IDM Connection state machine - Decisions related to command processing
 273  273   * including whether a connection is in FFP
 274  274   *
 275  275   * Session state machine - Summarize the state of all available connections
 276  276   * for the purposes of ERL1, ERL2 and MC/S.  A session in LOGGED_IN state
 277  277   * should always have at least one FFP connection but there may be a brief
 278  278   * window where a session in ACTIVE might have one or more FFP connections
 279  279   * even though ACTIVE is not strictly an FFP state according to the RFC.
 280  280   *
 281  281   * Login state machine -- drive the login process, collect negotiated
 282  282   * parameters.  Another side effect of this approach is that we may get
 283  283   * the "notify ffp" callback from the IDM connection state machine before
 284  284   * the login state machine has actually transitioned to FFP state.
 285  285   */
 286  286  
 287  287  struct iscsit_conn_s;
 288  288  
 289  289  /* Update iscsit_ss_name table whenever session states are modified */
 290  290  typedef enum {
 291  291          SS_UNDEFINED = 0,
 292  292          SS_Q1_FREE,
 293  293          SS_Q2_ACTIVE,
 294  294          SS_Q3_LOGGED_IN,
 295  295          SS_Q4_FAILED,
 296  296          SS_Q5_CONTINUE,
 297  297          SS_Q6_DONE,
 298  298          SS_Q7_ERROR,
 299  299          /* Add new session states above SS_MAX_STATE */
 300  300          SS_MAX_STATE
 301  301  } iscsit_session_state_t;
 302  302  
 303  303  #ifdef ISCSIT_SESS_SM_STRINGS
 304  304  /* An array of state text values, for use in logging state transitions */
 305  305  static const char *iscsit_ss_name[SS_MAX_STATE+1] = {
 306  306          "SS_UNDEFINED",
 307  307          "SS_Q1_FREE",
 308  308          "SS_Q2_ACTIVE",
 309  309          "SS_Q3_LOGGED_IN",
 310  310          "SS_Q4_FAILED",
 311  311          "SS_Q5_CONTINUE",
 312  312          "SS_Q6_DONE",
 313  313          "SS_Q7_ERROR",
 314  314          "SS_MAX_STATE"
 315  315  };
 316  316  #endif
 317  317  
 318  318  /* Update iscsit_se_name table whenever session events are modified */
 319  319  typedef enum {
 320  320          SE_UNDEFINED = 0,
 321  321          SE_CONN_IN_LOGIN,       /* From login state machine */
 322  322          SE_CONN_LOGGED_IN,      /* FFP enabled client notification */
 323  323          SE_CONN_FFP_FAIL,       /* FFP disabled client notification */
 324  324          SE_CONN_FFP_DISABLE,    /* FFP disabled client notification */
 325  325          SE_CONN_FAIL,           /* Conn destroy client notification */
 326  326          SE_SESSION_CLOSE,       /* FFP disabled client notification */
 327  327          SE_SESSION_REINSTATE,   /* From login state machine */
 328  328          SE_SESSION_TIMEOUT,     /* Internal */
 329  329          SE_SESSION_CONTINUE,    /* From login state machine */
 330  330          SE_SESSION_CONTINUE_FAIL, /* From login state machine? */
 331  331          /* Add new events above SE_MAX_EVENT */
 332  332          SE_MAX_EVENT
 333  333  } iscsit_session_event_t;
 334  334  
 335  335  #ifdef ISCSIT_SESS_SM_STRINGS
 336  336  /* An array of event text values, for use in logging events */
 337  337  static const char *iscsit_se_name[SE_MAX_EVENT+1] = {
 338  338          "SE_UNDEFINED",
 339  339          "SE_CONN_IN_LOGIN",
 340  340          "SE_CONN_LOGGED_IN",
 341  341          "SE_CONN_FFP_FAIL",
 342  342          "SE_CONN_FFP_DISABLE",
 343  343          "SE_CONN_FAIL",
 344  344          "SE_SESSION_CLOSE",
 345  345          "SE_SESSION_REINSTATE",
 346  346          "SE_SESSION_TIMEOUT",
 347  347          "SE_SESSION_CONTINUE",
 348  348          "SE_SESSION_CONTINUE_FAIL",
 349  349          "SE_MAX_EVENT"
 350  350  };
 351  351  #endif
 352  352  
 353  353  /*
 354  354   * Set in ist_tgt after iscsit_tgt_unbind_sess to differentiate an unbound
 355  355   * session from a discovery session.
 356  356   */
 357  357  #define SESS_UNBOUND_FROM_TGT   -1
 358  358  
 359  359  typedef struct {
 360  360          stmf_scsi_session_t     *ist_stmf_sess;
 361  361          stmf_local_port_t       *ist_lport;
 362  362          iscsit_tgt_t            *ist_tgt;
 363  363          idm_refcnt_t            ist_refcnt;
 364  364          kmem_cache_t            *ist_task_cache;
 365  365          kmutex_t                ist_sn_mutex;
 366  366          kmutex_t                ist_mutex;
 367  367          kcondvar_t              ist_cv;
 368  368          iscsit_session_state_t  ist_state;
 369  369          iscsit_session_state_t  ist_last_state;
 370  370          sm_audit_buf_t          ist_state_audit;
 371  371          boolean_t               ist_sm_busy;
 372  372          boolean_t               ist_sm_complete;
 373  373          boolean_t               ist_admin_close;
 374  374          list_t                  ist_events;
 375  375          int                     ist_conn_count;
 376  376          int                     ist_ffp_conn_count;
 377  377          struct iscsit_conn_s    *ist_failed_conn;
 378  378          timeout_id_t            ist_state_timeout;
 379  379          list_t                  ist_conn_list;
 380  380          avl_node_t              ist_tgt_ln;
 381  381          char                    *ist_initiator_name;
 382  382          char                    *ist_initiator_alias;
 383  383          char                    *ist_target_name;
 384  384          char                    *ist_target_alias;
 385  385          uint8_t                 ist_isid[ISCSI_ISID_LEN];
 386  386          uint16_t                ist_tsih;
 387  387          uint16_t                ist_tpgt_tag;
 388  388          uint32_t                ist_expcmdsn;
 389  389          uint32_t                ist_maxcmdsn;
 390  390          avl_tree_t              ist_task_list;
 391  391          iscsit_cbuf_t           *ist_rxpdu_queue;
 392  392  } iscsit_sess_t;
 393  393  
 394  394  /* Update iscsit_ils_name table whenever login states are modified */
 395  395  typedef enum {
 396  396          ILS_UNDEFINED = 0,
 397  397          ILS_LOGIN_INIT,
 398  398          ILS_LOGIN_WAITING,      /* Waiting for more login PDU's */
 399  399          ILS_LOGIN_PROCESSING,   /* Processing login request */
 400  400          ILS_LOGIN_RESPONDING,   /* Sending login response */
 401  401          ILS_LOGIN_RESPONDED,    /* Sent login response (no trans. to FFP) */
 402  402          ILS_LOGIN_FFP,          /* Sending last login PDU for final response */
 403  403          ILS_LOGIN_DONE,         /* Last login PDU sent (so we can free it) */
 404  404          ILS_LOGIN_ERROR,        /* Login error, login failed */
 405  405          /* Add new login states above ILS_MAX_STATE */
 406  406          ILS_MAX_STATE
 407  407  } iscsit_login_state_t;
 408  408  
 409  409  #ifdef ISCSIT_LOGIN_SM_STRINGS
 410  410  /* An array of login state text values, for use in logging login progress */
 411  411  static const char *iscsit_ils_name[ILS_MAX_STATE+1] = {
 412  412          "ILS_UNDEFINED",
 413  413          "ILS_LOGIN_INIT",
 414  414          "ILS_LOGIN_WAITING",
 415  415          "ILS_LOGIN_PROCESSING",
 416  416          "ILS_LOGIN_RESPONDING",
 417  417          "ILS_LOGIN_RESPONDED",
 418  418          "ILS_LOGIN_FFP",
 419  419          "ILS_LOGIN_DONE",
 420  420          "ILS_LOGIN_ERROR",
 421  421          "ILS_MAX_STATE"
 422  422  };
 423  423  #endif
 424  424  
 425  425  /* Update iscsit_ile_name table whenever login events are modified */
 426  426  typedef enum {
 427  427          ILE_UNDEFINED = 0,
 428  428          ILE_LOGIN_RCV,
 429  429          ILE_LOGIN_RESP_READY,
 430  430          ILE_LOGIN_FFP,
 431  431          ILE_LOGIN_RESP_COMPLETE,
 432  432          ILE_LOGIN_ERROR,
 433  433          ILE_LOGIN_CONN_ERROR,
 434  434          /* Add new login events above ILE_MAX_EVENT */
 435  435          ILE_MAX_EVENT
 436  436  } iscsit_login_event_t;
 437  437  
 438  438  #ifdef ISCSIT_LOGIN_SM_STRINGS
 439  439  /* An array of login event text values, for use in logging login events */
 440  440  static const char *iscsit_ile_name[ILE_MAX_EVENT+1] = {
 441  441          "ILE_UNDEFINED",
 442  442          "ILE_LOGIN_RCV",
 443  443          "ILE_LOGIN_RESP_READY",
 444  444          "ILE_LOGIN_FFP",
 445  445          "ILE_LOGIN_RESP_COMPLETE",
 446  446          "ILE_LOGIN_ERROR",
 447  447          "ILE_LOGIN_CONN_ERROR",
 448  448          "ILE_MAX_EVENT"
 449  449  };
 450  450  #endif
 451  451  
 452  452  typedef struct {
 453  453          uint32_t                op_initial_params_set:1,
 454  454                                  op_discovery_session:1,
 455  455                                  op_initial_r2t:1,
 456  456                                  op_immed_data:1,
 457  457                                  op_data_pdu_in_order:1,
 458  458                                  op_data_sequence_in_order:1,
 459  459                                  op_declarative_params_set:1;
 460  460          uint64_t                op_max_connections;
 461  461          uint64_t                op_max_recv_data_segment_length;
 462  462          uint64_t                op_max_burst_length;
 463  463          uint64_t                op_first_burst_length;
 464  464          uint64_t                op_default_time_2_wait;
 465  465          uint64_t                op_default_time_2_retain;
 466  466          uint64_t                op_max_outstanding_r2t;
 467  467          uint64_t                op_error_recovery_level;
 468  468  } iscsit_op_params_t;
 469  469  
 470  470  typedef struct {
 471  471          iscsit_login_state_t    icl_login_state;
 472  472          iscsit_login_state_t    icl_login_last_state;
 473  473          sm_audit_buf_t          icl_state_audit;
 474  474          boolean_t               icl_busy;
 475  475          boolean_t               icl_login_complete;
 476  476          kmutex_t                icl_mutex;
 477  477          uint32_t                icl_login_itt;
 478  478          uint8_t                 icl_login_csg;
 479  479          uint8_t                 icl_login_nsg;
 480  480          boolean_t               icl_login_transit;
 481  481          conn_auth_t             icl_auth;
 482  482          iscsit_auth_client_t    icl_auth_client;
 483  483          int                     icl_auth_pass;
 484  484          list_t                  icl_login_events;
 485  485          list_t                  icl_pdu_list;
 486  486          uint16_t                icl_tsih;
 487  487          uint8_t                 icl_isid[ISCSI_ISID_LEN];
 488  488          uint32_t                icl_cmdsn;
 489  489          uint16_t                icl_tpgt_tag;
 490  490          char                    *icl_target_name;
 491  491          char                    *icl_target_alias;
 492  492          char                    *icl_initiator_name;
 493  493          char                    *icl_login_resp_buf;
 494  494          void                    *icl_login_resp_itb; /* mult-pdu idm buf */
 495  495          int                     icl_login_resp_len; /* For kmem_free */
 496  496          int                     icl_login_resp_valid_len;
 497  497          uint8_t                 icl_login_resp_err_class;
 498  498          uint8_t                 icl_login_resp_err_detail;
 499  499          iscsi_login_rsp_hdr_t   *icl_login_resp_tmpl;
 500  500          nvlist_t                *icl_request_nvlist;
 501  501          nvlist_t                *icl_response_nvlist;
 502  502          nvlist_t                *icl_negotiated_values;
 503  503  } iscsit_conn_login_t;
 504  504  
 505  505  #define SET_LOGIN_ERROR(SLE_ICT, SLE_CLASS, SLE_DETAIL) \
 506  506          (SLE_ICT)->ict_login_sm.icl_login_resp_err_class = (SLE_CLASS); \
 507  507          (SLE_ICT)->ict_login_sm.icl_login_resp_err_detail = (SLE_DETAIL);
 508  508  
 509  509  typedef struct iscsit_conn_s {
 510  510          idm_conn_t              *ict_ic;
 511  511          iscsit_sess_t           *ict_sess;
 512  512          kmutex_t                ict_mutex;
 513  513          idm_refcnt_t            ict_refcnt;
 514  514          idm_refcnt_t            ict_dispatch_refcnt;
 515  515          list_node_t             ict_sess_ln;
 516  516          iscsit_conn_login_t     ict_login_sm;
 517  517          iscsit_op_params_t      ict_op;
 518  518          uint16_t                ict_cid;
 519  519          uint32_t                ict_statsn;
 520  520          kmutex_t                ict_statsn_mutex;
 521  521          uint32_t                ict_keepalive_ttt;
 522  522          struct iscsit_conn_s    *ict_reinstate_conn;
 523  523          uint32_t                ict_reinstating:1,
 524  524                                  ict_lost:1,
 525  525                                  ict_destroyed:1;
 526  526          /*
 527  527           * Parameters for processing text commands
 528  528           */
 529  529          char                    *ict_text_rsp_buf;
 530  530          uint32_t                ict_text_rsp_len;
 531  531          uint32_t                ict_text_rsp_valid_len;
 532  532          uint32_t                ict_text_rsp_off;
 533  533          uint32_t                ict_text_req_itt;       /* from initiator */
 534  534          uint32_t                ict_text_rsp_ttt;
 535  535  } iscsit_conn_t;
 536  536  
 537  537  #define ICT_FLAGS_DISCOVERY     0x00000001
 538  538  
 539  539  typedef struct {
 540  540          idm_buf_t               *ibuf_idm_buf;
 541  541          stmf_data_buf_t         *ibuf_stmf_buf;
 542  542          idm_pdu_t               *ibuf_immed_data_pdu;
 543  543          boolean_t               ibuf_is_immed;
 544  544  } iscsit_buf_t;
 545  545  
 546  546  typedef struct {
 547  547          scsi_task_t             *it_stmf_task;
 548  548          idm_task_t              *it_idm_task;
 549  549          iscsit_buf_t            *it_immed_data;
 550  550          iscsit_conn_t           *it_ict;
 551  551          kmutex_t                it_mutex;
 552  552          idm_pdu_t               *it_tm_pdu;
 553  553          uint32_t                it_stmf_abort:1,
 554  554                                  it_aborted:1,
 555  555                                  it_active:1,
 556  556                                  it_tm_task:1,
 557  557                                  it_tm_responded:1;
 558  558          uint32_t                it_cmdsn;
 559  559          uint32_t                it_itt;
 560  560          uint32_t                it_ttt;
 561  561          avl_node_t              it_sess_ln;
 562  562  } iscsit_task_t;
 563  563  
 564  564  typedef struct iscsit_isns_cfg {
 565  565          kmutex_t                isns_mutex;
 566  566          boolean_t               isns_state;
 567  567          list_t                  isns_svrs;
 568  568  } iscsit_isns_cfg_t;
 569  569  
 570  570  /*
 571  571   * State values for the iscsit service
 572  572   */
 573  573  typedef enum {
 574  574          ISE_UNDEFINED = 0,
 575  575          ISE_DETACHED,
 576  576          ISE_DISABLED,
 577  577          ISE_ENABLING,
 578  578          ISE_ENABLED,
 579  579          ISE_BUSY,
 580  580          ISE_DISABLING
 581  581  } iscsit_service_enabled_t;
 582  582  
 583  583  
 584  584  typedef struct {
 585  585          iscsit_service_enabled_t        global_svc_state;
 586  586          dev_info_t                      *global_dip;
 587  587          ldi_ident_t                     global_li;
 588  588          nvlist_t                        *global_props;
 589  589          stmf_port_provider_t            *global_pp;
 590  590          stmf_dbuf_store_t               *global_dbuf_store;
 591  591          taskq_t                         *global_dispatch_taskq;
 592  592          idm_refcnt_t                    global_refcnt;
 593  593          avl_tree_t                      global_discovery_sessions;
 594  594          avl_tree_t                      global_target_list;
 595  595          list_t                          global_deleted_target_list;
 596  596          avl_tree_t                      global_tpg_list;
 597  597          avl_tree_t                      global_ini_list;
 598  598          iscsit_tpg_t                    *global_default_tpg;
 599  599          vmem_t                          *global_tsih_pool;
 600  600          iscsit_isns_cfg_t               global_isns_cfg;
 601  601          iscsi_radius_props_t            global_radius_server;
 602  602          krwlock_t                       global_rwlock;
 603  603          kmutex_t                        global_state_mutex;
 604  604  } iscsit_global_t;
 605  605  
 606  606  extern iscsit_global_t iscsit_global;
 607  607  
 608  608  void
 609  609  iscsit_global_hold();
 610  610  
 611  611  void
 612  612  iscsit_global_rele();
 613  613  
 614  614  void
 615  615  iscsit_global_wait_ref();
 616  616  
 617  617  idm_status_t
 618  618  iscsit_login_sm_init(iscsit_conn_t *ict);
 619  619  
 620  620  void
 621  621  iscsit_login_sm_fini(iscsit_conn_t *ict);
 622  622  
 623  623  void
 624  624  iscsit_login_sm_event(iscsit_conn_t *ic, iscsit_login_event_t event,
 625  625      idm_pdu_t *pdu);
 626  626  
 627  627  void
 628  628  iscsit_login_sm_event_locked(iscsit_conn_t *ic, iscsit_login_event_t event,
 629  629      idm_pdu_t *pdu);
 630  630  
 631  631  int
 632  632  iscsit_is_v4_mapped(struct sockaddr_storage *sa, struct sockaddr_storage *v4sa);
 633  633  
 634  634  void
 635  635  iscsit_send_async_event(iscsit_conn_t *ict, uint8_t async_event);
 636  636  
 637  637  void
 638  638  iscsit_pdu_tx(idm_pdu_t *pdu);
 639  639  
 640  640  void
 641  641  iscsit_send_reject(iscsit_conn_t *ict, idm_pdu_t *rejected_pdu, uint8_t reason);
 642  642  
  
    | 
      ↓ open down ↓ | 
    642 lines elided | 
    
      ↑ open up ↑ | 
  
 643  643  void
 644  644  iscsit_text_cmd_fini(iscsit_conn_t *ict);
 645  645  
 646  646  /*
 647  647   * IDM conn ops
 648  648   */
 649  649  
 650  650  idm_rx_pdu_cb_t         iscsit_op_scsi_cmd;
 651  651  idm_rx_pdu_cb_t         iscsit_rx_pdu;
 652  652  idm_rx_pdu_error_cb_t   iscsit_rx_pdu_error;
      653 +idm_rx_pdu_cb_t         iscsit_rx_scsi_rsp;
 653  654  idm_task_cb_t           iscsit_task_aborted;
 654  655  idm_client_notify_cb_t  iscsit_client_notify;
 655  656  idm_build_hdr_cb_t      iscsit_build_hdr;
 656  657  idm_update_statsn_cb_t  iscsit_update_statsn;
 657  658  idm_keepalive_cb_t      iscsit_keepalive;
 658  659  
 659  660  /*
 660  661   * lport entry points
 661  662   */
 662  663  stmf_status_t
 663  664  iscsit_xfer_scsi_data(scsi_task_t *task, stmf_data_buf_t *dbuf,
 664  665      uint32_t ioflags);
 665  666  
 666  667  stmf_status_t
 667  668  iscsit_send_scsi_status(scsi_task_t *task, uint32_t ioflags);
 668  669  
 669  670  void
 670  671  iscsit_lport_task_free(scsi_task_t *task);
 671  672  
 672  673  stmf_status_t
 673  674  iscsit_abort(stmf_local_port_t *lport, int abort_cmd, void *arg,
 674  675      uint32_t flags);
 675  676  
 676  677  void
 677  678  iscsit_ctl(stmf_local_port_t *lport, int cmd, void *arg);
 678  679  
 679  680  /*
 680  681   * Connection functions
 681  682   */
 682  683  idm_status_t
 683  684  iscsit_conn_reinstate(iscsit_conn_t *existing_ict, iscsit_conn_t *ict);
 684  685  
 685  686  void
 686  687  iscsit_conn_destroy_done(iscsit_conn_t *ict);
 687  688  
 688  689  void
 689  690  iscsit_conn_set_auth(iscsit_conn_t *ict);
 690  691  
 691  692  void
 692  693  iscsit_conn_hold(iscsit_conn_t *ict);
 693  694  
 694  695  void
 695  696  iscsit_conn_rele(iscsit_conn_t *ict);
 696  697  
 697  698  void
 698  699  iscsit_conn_logout(iscsit_conn_t *ict);
 699  700  
 700  701  /*
 701  702   * Session functions
 702  703   */
 703  704  int
 704  705  iscsit_sess_avl_compare(const void *void_sess1, const void *void_sess2);
 705  706  
 706  707  iscsit_sess_t *
 707  708  iscsit_sess_create(iscsit_tgt_t *tgt, iscsit_conn_t *ict,
 708  709      uint32_t cmdsn, uint8_t *isid, uint16_t tag,
 709  710      char *initiator_name, char *target_name,
 710  711      uint8_t *error_class, uint8_t *error_detail);
 711  712  
 712  713  void
 713  714  iscsit_sess_destroy(iscsit_sess_t *ist);
 714  715  
 715  716  void
 716  717  iscsit_sess_hold(iscsit_sess_t *ist);
 717  718  
 718  719  idm_status_t
 719  720  iscsit_sess_check_hold(iscsit_sess_t *ist);
 720  721  
 721  722  void
 722  723  iscsit_sess_rele(iscsit_sess_t *ist);
 723  724  
 724  725  iscsit_conn_t *
 725  726  iscsit_sess_lookup_conn(iscsit_sess_t *ist, uint16_t cid);
 726  727  
 727  728  void
 728  729  iscsit_sess_bind_conn(iscsit_sess_t *ist, iscsit_conn_t *ict);
 729  730  
 730  731  void
 731  732  iscsit_sess_unbind_conn(iscsit_sess_t *ist, iscsit_conn_t *ict);
 732  733  
 733  734  void
 734  735  iscsit_sess_close(iscsit_sess_t *ist);
 735  736  
 736  737  iscsit_sess_t *
 737  738  iscsit_sess_reinstate(iscsit_tgt_t *tgt, iscsit_sess_t *ist, iscsit_conn_t *ict,
 738  739      uint8_t *error_class, uint8_t *error_detail);
 739  740  
 740  741  void
 741  742  iscsit_sess_sm_event(iscsit_sess_t *ist, iscsit_session_event_t event,
 742  743      iscsit_conn_t *ict);
 743  744  
 744  745  /*
 745  746   * Target, TPGT, TPGT and portal functions
 746  747   */
 747  748  
 748  749  void
 749  750  iscsit_tgt_sm_event(iscsit_tgt_t *tgt, iscsit_tgt_event_t event);
 750  751  
 751  752  void
 752  753  tgt_sm_event_locked(iscsit_tgt_t *tgt, iscsit_tgt_event_t event);
 753  754  
 754  755  it_cfg_status_t
 755  756  iscsit_config_merge_tgt(it_config_t *cfg);
 756  757  
 757  758  void
 758  759  iscsit_config_destroy_tgts(list_t *tgt_del_list);
 759  760  
 760  761  void
 761  762  iscsit_config_destroy_tpgts(list_t *tpgt_del_list);
 762  763  
 763  764  iscsit_tgt_t *
 764  765  iscsit_tgt_lookup(char *target_name);
 765  766  
 766  767  iscsit_tgt_t *
 767  768  iscsit_tgt_lookup_locked(char *target_name);
 768  769  
 769  770  int
 770  771  iscsit_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2);
 771  772  
 772  773  int
 773  774  iscsit_tpgt_avl_compare(const void *void_tpgt1, const void *void_tpgt2);
 774  775  
 775  776  void
 776  777  iscsit_tgt_hold(iscsit_tgt_t *tgt);
 777  778  
 778  779  void
 779  780  iscsit_tgt_rele(iscsit_tgt_t *tgt);
 780  781  
 781  782  iscsit_tpgt_t *
 782  783  iscsit_tgt_lookup_tpgt(iscsit_tgt_t *tgt, uint16_t tag);
 783  784  
 784  785  void
 785  786  iscsit_tpgt_hold(iscsit_tpgt_t *tpgt);
 786  787  
 787  788  void
 788  789  iscsit_tpgt_rele(iscsit_tpgt_t *tpgt);
 789  790  
 790  791  iscsit_portal_t *
 791  792  iscsit_tgt_lookup_portal(iscsit_tgt_t *tgt, struct sockaddr_storage *sa,
 792  793      iscsit_tpgt_t **output_tpgt);
 793  794  
 794  795  iscsit_sess_t *
 795  796  iscsit_tgt_lookup_sess(iscsit_tgt_t *tgt, char *initiator_name,
 796  797      uint8_t *isid, uint16_t tsih, uint16_t tag);
 797  798  
 798  799  void
 799  800  iscsit_tgt_bind_sess(iscsit_tgt_t *tgt, iscsit_sess_t *sess);
 800  801  
 801  802  void
 802  803  iscsit_tgt_unbind_sess(iscsit_tgt_t *tgt, iscsit_sess_t *sess);
 803  804  
 804  805  it_cfg_status_t
 805  806  iscsit_config_merge_tpg(it_config_t *cfg, list_t *tpg_del_list);
 806  807  
 807  808  void
 808  809  iscsit_config_destroy_tpgs(list_t *tpg_del_list);
 809  810  
 810  811  iscsit_tpg_t *
 811  812  iscsit_tpg_lookup(char *tpg_name);
 812  813  
 813  814  int
 814  815  iscsit_tpg_avl_compare(const void *void_tpg1, const void *void_tpg2);
 815  816  
 816  817  void
 817  818  iscsit_tpg_hold(iscsit_tpg_t *tpg);
 818  819  
 819  820  void
 820  821  iscsit_tpg_rele(iscsit_tpg_t *tpg);
 821  822  
 822  823  iscsit_tpg_t *
 823  824  iscsit_tpg_createdefault();
 824  825  
 825  826  void
 826  827  iscsit_tpg_destroydefault(iscsit_tpg_t *tpg);
 827  828  
 828  829  idm_status_t
 829  830  iscsit_tpg_online(iscsit_tpg_t *tpg);
 830  831  
 831  832  void
 832  833  iscsit_tpg_offline(iscsit_tpg_t *tpg);
 833  834  
 834  835  iscsit_portal_t *
 835  836  iscsit_tpg_portal_lookup(iscsit_tpg_t *tpg, struct sockaddr_storage *sa);
 836  837  
 837  838  void
 838  839  iscsit_portal_hold(iscsit_portal_t *portal);
 839  840  
 840  841  void
 841  842  iscsit_portal_rele(iscsit_portal_t *portal);
 842  843  
 843  844  it_cfg_status_t
 844  845  iscsit_config_merge_ini(it_config_t *cfg);
 845  846  
 846  847  int
 847  848  iscsit_ini_avl_compare(const void *void_ini1, const void *void_ini2);
 848  849  
 849  850  iscsit_ini_t *
 850  851  iscsit_ini_lookup_locked(char *ini_name);
 851  852  
 852  853  int
 853  854  iscsit_portal_avl_compare(const void *void_portal1, const void *void_portal2);
 854  855  
 855  856  int
 856  857  iscsit_verify_chap_resp(iscsit_conn_login_t *lsm,
 857  858      unsigned int chap_i, uchar_t *chap_c, unsigned int challenge_len,
 858  859      uchar_t *chap_r, unsigned int resp_len);
 859  860  
 860  861  void
 861  862  iscsit_rxpdu_queue_monitor_start(void);
 862  863  
 863  864  void
 864  865  iscsit_rxpdu_queue_monitor_stop(void);
 865  866  
 866  867  #endif /* _ISCSIT_H_ */
  
    | 
      ↓ open down ↓ | 
    204 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX