Home | History | Annotate | Download | only in iscsitgtd
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _TARGET_CONN_H
     28 #define	_TARGET_CONN_H
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 /*
     33  * Block comment which describes the contents of this file.
     34  */
     35 
     36 #ifdef __cplusplus
     37 extern "C" {
     38 #endif
     39 
     40 #include <sys/iscsi_protocol.h>
     41 #include <sys/socket.h>
     42 #include "queue.h"
     43 #include "iscsi_sess.h"
     44 #include "iscsi_cmd.h"
     45 
     46 #define	LBUFSIZE 80
     47 
     48 #define	TARGET_LOCATION			"targets"
     49 /*
     50  * Currently I'm having some problems with network reads/write when the
     51  * data size is larger than 8k. To work around this problem I set the
     52  * various negotiation parameters during login to limit things to 8k.
     53  */
     54 
     55 #define	NETWORK_SNDRCV		65536
     56 #define	NETWORK_SNDRCV_STR	"65536"
     57 
     58 typedef enum iscsi_state {
     59 	S1_FREE,
     60 	/* S2_XPT_WAIT, Not possible for target */
     61 	S3_XPT_UP,
     62 	S4_IN_LOGIN,
     63 	S5_LOGGED_IN,
     64 	S6_IN_LOGOUT,
     65 	S7_LOGOUT_REQUESTED,
     66 	S8_CLEANUP_WAIT
     67 } iscsi_state_t;
     68 
     69 typedef enum iscsi_transition {
     70 	T3, T4, T5, T6, T7, T8,
     71 	T9, T10, T11, T12, T13, T15,
     72 	T16, T17, T18
     73 } iscsi_transition_t;
     74 
     75 /*
     76  * When grabbing mutex's make sure to grab c_mutex before c_mutex_state
     77  * if you need to grab both.
     78  */
     79 typedef struct iscsi_conn {
     80 	int		c_fd;
     81 
     82 	/*
     83 	 * This is a linked list of all connections. Not just the connections
     84 	 * associated with a particular session.
     85 	 */
     86 	struct iscsi_conn	*c_next,
     87 				*c_prev;
     88 
     89 	target_queue_t	*c_mgmtq;
     90 
     91 	/*
     92 	 * Time as reported by time(2) when this connection was started.
     93 	 */
     94 	time_t		c_up_at;
     95 
     96 	/*
     97 	 * This queue is used to accept notification that incoming packets
     98 	 * are available and command completion status from Session.
     99 	 */
    100 	target_queue_t	*c_dataq;
    101 
    102 	/*
    103 	 * Messages are sent to Session, and from there onto STE, using
    104 	 * this queue.
    105 	 */
    106 	target_queue_t	*c_sessq;
    107 
    108 	iscsi_sess_t	*c_sess;
    109 
    110 	pthread_mutex_t	c_state_mutex;
    111 	iscsi_state_t	c_state;
    112 
    113 	/*
    114 	 * Protected by c_mutex
    115 	 */
    116 	int		c_statsn;
    117 
    118 	int		c_cid;
    119 
    120 	/*
    121 	 * Pointer to data buffer used to store text messages which have
    122 	 * the 'C' bit set. Since the text data separates name/value pairs
    123 	 * with a '\0' strlen can't be used to determine the amount of space
    124 	 * used so we keep the length in c_text_len;
    125 	 */
    126 	char		*c_text_area;
    127 	int		c_text_len;
    128 	int		c_text_sent;
    129 
    130 	sema_t		c_datain;
    131 	pthread_t	c_thr_id_poller,
    132 			c_thr_id_process;
    133 
    134 	pthread_mutex_t	c_mutex;
    135 	iscsi_cmd_t	*c_cmd_head;
    136 	iscsi_cmd_t	*c_cmd_tail;
    137 
    138 	struct sockaddr_storage	c_initiator_sockaddr;
    139 	struct sockaddr_storage c_target_sockaddr;
    140 
    141 	int		c_num;
    142 
    143 	int		c_auth_pass	: 1;
    144 
    145 	int		c_cmds_active;
    146 
    147 	/*
    148 	 * A performance issue has been found when the backing store
    149 	 * is UFS. Because of the indirect blocks used by UFS large files
    150 	 * (many GBs in size) perform poorly. This in turn can cause the
    151 	 * initiator to issue commands which don't complete in time. So,
    152 	 * we'll monitor the completion times for commands if if it's
    153 	 * increasing the command window will be reduced.
    154 	 * The avg_sum is in nanoseconds. This will wrap once every 584
    155 	 * years.
    156 	 */
    157 	uint64_t	c_cmds_avg_cnt;
    158 	hrtime_t	c_cmds_avg_sum;
    159 
    160 	/*
    161 	 * During an orderly shutdown the logout response is created when
    162 	 * we receive the logout request. We must however wait for all I/O
    163 	 * to complete before processing the data else we'll loose data
    164 	 * which the initiator believes was successfully transferred.
    165 	 * Once the STE and sessions have closed they will send a shutdown
    166 	 * complete message. At that point the transmit side of the connection
    167 	 * will set the state to T13 which pushes this message out.
    168 	 * Unfortunately we need information from the Logout Request PDU
    169 	 * to create the Logout Response PDU. Otherwise the response could
    170 	 * be generated on the fly in the T13 state handler. By creating
    171 	 * the response PDU and saving a pointer gives us some flexibility
    172 	 * in the future if the final outgoing packet needs to change.
    173 	 * Otherwise, storing that one bit of information from the request
    174 	 * PDU might become dated.
    175 	 */
    176 	iscsi_hdr_t	*c_last_pkg;
    177 
    178 	/*
    179 	 * Connection parameters
    180 	 */
    181 	Boolean_t	c_header_digest,
    182 			c_data_digest,
    183 			c_ifmarker,
    184 			c_ofmarker,
    185 			c_initialR2T,
    186 			c_immediate_data,
    187 			c_data_pdu_in_order,
    188 			c_data_sequence_in_order;
    189 	int		c_tpgt,
    190 			c_maxcmdsn,
    191 			c_max_recv_data,
    192 			c_default_time_2_wait,
    193 			c_default_time_2_retain,
    194 			c_erl,
    195 			c_max_burst_len,
    196 			c_first_burst_len,
    197 			c_max_outstanding_r2t,
    198 			c_max_connections;
    199 	char		*c_targ_alias,
    200 			*auth_text;
    201 	int		auth_text_length;
    202 
    203 } iscsi_conn_t;
    204 
    205 void *conn_process(void *v);
    206 void conn_state(iscsi_conn_t *c, iscsi_transition_t t);
    207 void send_iscsi_pkt(iscsi_conn_t *c, iscsi_hdr_t *h, char *opt_text);
    208 int read_retry(int fd, char *buf, int count);
    209 void iscsi_inventory_change(char *targ_name);
    210 void iscsi_capacity_change(char *targ_name, int lun);
    211 
    212 #ifdef __cplusplus
    213 }
    214 #endif
    215 
    216 #endif /* _TARGET_CONN_H */
    217