summaryrefslogtreecommitdiffstats
path: root/src/spdk/lib/iscsi/conn.h
blob: a85d2ddebde32034a0614a42826588a12c627216 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*-
 *   BSD LICENSE
 *
 *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SPDK_ISCSI_CONN_H
#define SPDK_ISCSI_CONN_H

#include "spdk/stdinc.h"

#include "iscsi/iscsi.h"
#include "spdk/queue.h"
#include "spdk/cpuset.h"
#include "spdk/scsi.h"

/*
 * MAX_CONNECTION_PARAMS: The numbers of the params in conn_param_table
 * MAX_SESSION_PARAMS: The numbers of the params in sess_param_table
 */
#define MAX_CONNECTION_PARAMS 14
#define MAX_SESSION_PARAMS 19

#define MAX_ADDRBUF 64
#define MAX_INITIATOR_ADDR (MAX_ADDRBUF)
#define MAX_TARGET_ADDR (MAX_ADDRBUF)

#define OWNER_ISCSI_CONN		0x1

#define OBJECT_ISCSI_PDU		0x1

#define TRACE_GROUP_ISCSI		0x1
#define TRACE_ISCSI_READ_FROM_SOCKET_DONE	SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x0)
#define TRACE_ISCSI_FLUSH_WRITEBUF_START	SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x1)
#define TRACE_ISCSI_FLUSH_WRITEBUF_DONE		SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x2)
#define TRACE_ISCSI_READ_PDU			SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x3)
#define TRACE_ISCSI_TASK_DONE			SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x4)
#define TRACE_ISCSI_TASK_QUEUE			SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x5)
#define TRACE_ISCSI_TASK_EXECUTED		SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x6)
#define TRACE_ISCSI_PDU_COMPLETED		SPDK_TPOINT_ID(TRACE_GROUP_ISCSI, 0x7)

enum iscsi_pdu_recv_state {
	/* Ready to wait for PDU */
	ISCSI_PDU_RECV_STATE_AWAIT_PDU_READY,

	/* Active connection waiting for any PDU header */
	ISCSI_PDU_RECV_STATE_AWAIT_PDU_HDR,

	/* Active connection waiting for payload */
	ISCSI_PDU_RECV_STATE_AWAIT_PDU_PAYLOAD,

	/* Active connection does not wait for payload */
	ISCSI_PDU_RECV_STATE_ERROR,
};

struct spdk_poller;
struct spdk_iscsi_conn;

struct spdk_iscsi_lun {
	struct spdk_iscsi_conn		*conn;
	struct spdk_scsi_lun		*lun;
	struct spdk_scsi_lun_desc	*desc;
	struct spdk_poller		*remove_poller;
};

struct spdk_iscsi_conn {
	int				id;
	int				is_valid;
	/*
	 * All fields below this point are reinitialized each time the
	 *  connection object is allocated.  Make sure to update the
	 *  SPDK_ISCSI_CONNECTION_MEMSET() macro if changing which fields
	 *  are initialized when allocated.
	 */
	struct spdk_iscsi_portal	*portal;
	int				pg_tag;
	char				portal_host[MAX_PORTAL_ADDR + 1];
	char				portal_port[MAX_PORTAL_ADDR + 1];
	struct spdk_iscsi_poll_group	*pg;
	struct spdk_sock		*sock;
	struct spdk_iscsi_sess		*sess;

	enum iscsi_connection_state	state;
	int				login_phase;
	bool				is_logged_out;
	struct spdk_iscsi_pdu		*login_rsp_pdu;

	uint64_t	last_flush;
	uint64_t	last_fill;
	uint64_t	last_nopin;

	/* Timer used to destroy connection after requesting logout if
	 *  initiator does not send logout request.
	 */
	struct spdk_poller *logout_request_timer;

	/* Timer used to destroy connection after logout if initiator does
	 *  not close the connection.
	 */
	struct spdk_poller *logout_timer;

	/* Timer used to wait for connection to close
	 */
	struct spdk_poller *shutdown_timer;

	struct spdk_iscsi_pdu *pdu_in_progress;
	enum iscsi_pdu_recv_state pdu_recv_state;

	TAILQ_HEAD(, spdk_iscsi_pdu) write_pdu_list;
	TAILQ_HEAD(, spdk_iscsi_pdu) snack_pdu_list;

	int pending_r2t;

	uint16_t cid;

	/* IP address */
	char initiator_addr[MAX_INITIATOR_ADDR];
	char target_addr[MAX_TARGET_ADDR];

	/* Initiator/Target port binds */
	char				initiator_name[MAX_INITIATOR_NAME];
	struct spdk_scsi_port		*initiator_port;
	char				target_short_name[MAX_TARGET_NAME];
	struct spdk_scsi_port		*target_port;
	struct spdk_iscsi_tgt_node	*target;
	struct spdk_scsi_dev		*dev;

	/* for fast access */
	int header_digest;
	int data_digest;
	int full_feature;

	struct iscsi_param *params;
	bool sess_param_state_negotiated[MAX_SESSION_PARAMS];
	bool conn_param_state_negotiated[MAX_CONNECTION_PARAMS];
	struct iscsi_chap_auth auth;
	bool authenticated;
	bool disable_chap;
	bool require_chap;
	bool mutual_chap;
	int32_t chap_group;
	uint32_t pending_task_cnt;
	uint32_t data_out_cnt;
	uint32_t data_in_cnt;

	uint64_t timeout;
	uint64_t nopininterval;
	bool nop_outstanding;

	/*
	 * This is the maximum data segment length that iscsi target can send
	 *  to the initiator on this connection.  Not to be confused with the
	 *  maximum data segment length that initiators can send to iscsi target, which
	 *  is statically defined as SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH.
	 */
	int MaxRecvDataSegmentLength;

	uint32_t StatSN;
	uint32_t exp_statsn;
	uint32_t ttt; /* target transfer tag */
	char *partial_text_parameter;

	STAILQ_ENTRY(spdk_iscsi_conn) pg_link;
	bool			is_stopped;  /* Set true when connection is stopped for migration */
	TAILQ_HEAD(queued_r2t_tasks, spdk_iscsi_task)	queued_r2t_tasks;
	TAILQ_HEAD(active_r2t_tasks, spdk_iscsi_task)	active_r2t_tasks;
	TAILQ_HEAD(queued_datain_tasks, spdk_iscsi_task)	queued_datain_tasks;

	struct spdk_iscsi_lun	*luns[SPDK_SCSI_DEV_MAX_LUN];

	TAILQ_ENTRY(spdk_iscsi_conn)	conn_link;
};

extern struct spdk_iscsi_conn *g_conns_array;

void iscsi_task_cpl(struct spdk_scsi_task *scsi_task);
void iscsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task);

int initialize_iscsi_conns(void);
void shutdown_iscsi_conns(void);
void iscsi_conns_request_logout(struct spdk_iscsi_tgt_node *target);
int iscsi_get_active_conns(struct spdk_iscsi_tgt_node *target);

int iscsi_conn_construct(struct spdk_iscsi_portal *portal, struct spdk_sock *sock);
void iscsi_conn_destruct(struct spdk_iscsi_conn *conn);
void iscsi_conn_handle_nop(struct spdk_iscsi_conn *conn);
void iscsi_conn_schedule(struct spdk_iscsi_conn *conn);
void iscsi_conn_logout(struct spdk_iscsi_conn *conn);
int iscsi_drop_conns(struct spdk_iscsi_conn *conn,
		     const char *conn_match, int drop_all);
int iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn);
int iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
					uint32_t ref_task_tag);
int iscsi_conn_abort_queued_datain_tasks(struct spdk_iscsi_conn *conn,
		struct spdk_scsi_lun *lun,
		struct spdk_iscsi_pdu *pdu);

int iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int len, void *buf);
int iscsi_conn_readv_data(struct spdk_iscsi_conn *conn,
			  struct iovec *iov, int iovcnt);
void iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
			  iscsi_conn_xfer_complete_cb cb_fn,
			  void *cb_arg);

void iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu);

void iscsi_conn_info_json(struct spdk_json_write_ctx *w, struct spdk_iscsi_conn *conn);
void iscsi_conn_pdu_generic_complete(void *cb_arg);
#endif /* SPDK_ISCSI_CONN_H */