Print this page
NEX-3414 CLONE - Port 3339 iscsi/fs:5 causes panic on initiator
NEX-3419 CLONE - Run multi initiator sessions to a single target test can panic the initiator
Reviewed by: Steve Peng <steve.peng@nexenta.com>
4487 snoop can only work with 2GB files
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Approved by: Garrett D'Amore <garrett@damore.org>
3105 Kernel inet_pton() implementation returns result in host byte order
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Robert Mustacchi <rm@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.h
+++ new/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.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.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
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 2000 by Cisco Systems, Inc. All rights reserved.
24 24 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 + * Copyright 2014-2015 Nexenta Systems, Inc. All rights reserved.
26 26 */
27 27
28 28 #ifndef _ISCSI_H
29 29 #define _ISCSI_H
30 30
31 31 /*
32 32 * Block comment which describes the contents of this file.
33 33 */
34 34
35 35 #ifdef __cplusplus
36 36 extern "C" {
37 37 #endif
38 38
39 39 #include <sys/scsi/scsi.h>
40 40 #include <sys/ddi.h>
41 41 #include <sys/sunddi.h>
42 42 #include <sys/socket.h>
43 43 #include <sys/kstat.h>
44 44 #include <sys/sunddi.h>
45 45 #include <sys/sunmdi.h>
46 46 #include <sys/mdi_impldefs.h>
47 47 #include <sys/time.h>
48 48 #include <sys/nvpair.h>
49 49 #include <sys/sdt.h>
50 50
51 51 #include <sys/iscsi_protocol.h>
52 52 #include <sys/scsi/adapters/iscsi_if.h>
53 53 #include <iscsiAuthClient.h>
54 54 #include <iscsi_stats.h>
55 55 #include <iscsi_thread.h>
56 56 #include <sys/idm/idm.h>
57 57 #include <sys/idm/idm_conn_sm.h>
58 58 #include <nvfile.h>
59 59 #include <inet/ip.h>
60 60
61 61 #ifndef MIN
62 62 #define MIN(a, b) ((a) < (b) ? (a) : (b))
63 63 #endif
64 64
65 65 #ifndef TRUE
66 66 #define TRUE 1
67 67 #endif
68 68
69 69 #ifndef FALSE
70 70 #define FALSE 0
71 71 #endif
72 72
73 73 #define LOGIN_PDU_BUFFER_SIZE (16 * 1024) /* move somewhere else */
74 74
75 75 extern boolean_t iscsi_conn_logging;
76 76 extern boolean_t iscsi_io_logging;
77 77 extern boolean_t iscsi_login_logging;
78 78 extern boolean_t iscsi_logging;
79 79 extern boolean_t iscsi_sess_logging;
80 80 #define ISCSI_CONN_LOG if (iscsi_conn_logging) cmn_err
81 81 #define ISCSI_IO_LOG if (iscsi_io_logging) cmn_err
82 82 #define ISCSI_LOGIN_LOG if (iscsi_login_logging) cmn_err
83 83 #define ISCSI_LOG if (iscsi_logging) cmn_err
84 84 #define ISCSI_SESS_LOG if (iscsi_sess_logging) cmn_err
85 85
86 86 /*
87 87 * Name Format of the different Task Queues
88 88 */
89 89 #define ISCSI_SESS_IOTH_NAME_FORMAT "io_thrd_%d.%d"
90 90 #define ISCSI_SESS_WD_NAME_FORMAT "wd_thrd_%d.%d"
91 91 #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT "login_taskq_%d.%d"
92 92 #define ISCSI_SESS_ENUM_TASKQ_NAME_FORMAT "enum_taskq_%d.%d"
93 93 #define ISCSI_CONN_CN_TASKQ_NAME_FORMAT "conn_cn_taskq_%d.%d.%d"
94 94 #define ISCSI_CONN_RXTH_NAME_FORMAT "rx_thrd_%d.%d.%d"
95 95 #define ISCSI_CONN_TXTH_NAME_FORMAT "tx_thrd_%d.%d.%d"
96 96
97 97 /*
98 98 * The iSCSI driver will not build scatter/gather lists (iovec) longer
99 99 * than the value defined here. Asserts have been include in the code
100 100 * to check.
101 101 */
102 102 #define ISCSI_MAX_IOVEC 5
103 103
104 104 #define ISCSI_DEFAULT_MAX_STORM_DELAY 32
105 105
106 106 /*
107 107 * The SNDBUF and RCVBUF size parameters for the sockets are just a
108 108 * guess for the time being (I think it is the values used by CISCO
109 109 * or UNH). Testing will have to be done to figure * out the impact
110 110 * of these values on performance.
111 111 */
112 112 #define ISCSI_SOCKET_SNDBUF_SIZE (256 * 1024)
113 113 #define ISCSI_SOCKET_RCVBUF_SIZE (256 * 1024)
114 114 #define ISCSI_TCP_NODELAY_DEFAULT 0
115 115 #define ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT 2000
116 116 #define ISCSI_TCP_CABORT_THRESHOLD_DEFAULT 10000
117 117 #define ISCSI_TCP_ABORT_THRESHOLD_DEFAULT (30 * 1000) /* milliseconds */
118 118 #define ISNS_TCP_ABORT_THRESHOLD_DEFAULT (3 * 1000) /* milliseconds */
119 119
120 120 /* Default values for tunable parameters */
121 121 #define ISCSI_DEFAULT_RX_TIMEOUT_VALUE 60
122 122 #define ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX 180
123 123 #define ISCSI_DEFAULT_LOGIN_POLLING_DELAY 60
124 124
125 125 /*
126 126 * Convenient short hand defines
127 127 */
128 128 #define TARGET_PROP "target"
129 129 #define LUN_PROP "lun"
130 130 #define MDI_GUID "wwn"
131 131 #define NDI_GUID "client-guid"
132 132
133 133 #define ISCSI_SIG_CMD 0x11111111
134 134 #define ISCSI_SIG_LUN 0x22222222
135 135 #define ISCSI_SIG_CONN 0x33333333
136 136 #define ISCSI_SIG_SESS 0x44444444
137 137 #define ISCSI_SIG_HBA 0x55555555
138 138
139 139 #define SENDTARGETS_DISCOVERY "SENDTARGETS_DISCOVERY"
140 140
141 141 #define ISCSI_LUN_MASK_MSB 0x00003f00
142 142 #define ISCSI_LUN_MASK_LSB 0x000000ff
143 143 #define ISCSI_LUN_MASK (ISCSI_LUN_MASK_MSB | ISCSI_LUN_MASK_LSB)
144 144 #define ISCSI_LUN_BYTE_COPY(lun, report_lun_data) \
145 145 lun[0] = (report_lun_data & ISCSI_LUN_MASK_MSB) >> 8; \
146 146 lun[1] = (report_lun_data & ISCSI_LUN_MASK_LSB);
147 147 /*
148 148 * Not defined by iSCSI, but used in the login code to
149 149 * determine when to send the initial Login PDU
150 150 */
151 151 #define ISCSI_INITIAL_LOGIN_STAGE -1
152 152
153 153 typedef enum iscsi_status {
154 154 /* Success */
155 155 ISCSI_STATUS_SUCCESS = 0,
156 156 /* Driver / Kernel / Code error */
157 157 ISCSI_STATUS_INTERNAL_ERROR,
158 158 /* ITT table is already full, unable to reserve slot */
159 159 ISCSI_STATUS_ITT_TABLE_FULL,
160 160 /* Login on connection failed */
161 161 ISCSI_STATUS_LOGIN_FAILED,
162 162 /* No connections are in the LOGGED_IN state */
163 163 ISCSI_STATUS_NO_CONN_LOGGED_IN,
164 164 /* TCP Transfer Error */
165 165 ISCSI_STATUS_TCP_TX_ERROR,
166 166 /* TCP Receive Error */
167 167 ISCSI_STATUS_TCP_RX_ERROR,
168 168 /* iSCSI packet RCV timeout */
169 169 ISCSI_STATUS_RX_TIMEOUT,
170 170 /* iSCSI Header Digest CRC error */
171 171 ISCSI_STATUS_HEADER_DIGEST_ERROR,
172 172 /* iSCSI Data Digest CRC error */
173 173 ISCSI_STATUS_DATA_DIGEST_ERROR,
174 174 /* kmem_alloc failure */
175 175 ISCSI_STATUS_ALLOC_FAILURE,
176 176 /* cmd (tran_abort/reset) failed */
177 177 ISCSI_STATUS_CMD_FAILED,
178 178 /* iSCSI protocol error */
179 179 ISCSI_STATUS_PROTOCOL_ERROR,
180 180 /* iSCSI protocol version mismatch */
181 181 ISCSI_STATUS_VERSION_MISMATCH,
182 182 /* iSCSI login negotiation failed */
183 183 ISCSI_STATUS_NEGO_FAIL,
184 184 /* iSCSI login authentication failed */
185 185 ISCSI_STATUS_AUTHENTICATION_FAILED,
186 186 /* iSCSI login redirection failed */
187 187 ISCSI_STATUS_REDIRECTION_FAILED,
188 188 /* iSCSI uscsi status failure */
189 189 ISCSI_STATUS_USCSI_FAILED,
190 190 /* data received would have overflowed given buffer */
191 191 ISCSI_STATUS_DATA_OVERFLOW,
192 192 /* session/connection needs to shutdown */
193 193 ISCSI_STATUS_SHUTDOWN,
194 194 /* logical unit in use */
195 195 ISCSI_STATUS_BUSY,
196 196 /* Login on connection failed, retries exceeded */
197 197 ISCSI_STATUS_LOGIN_TIMED_OUT,
198 198 /* iSCSI login tpgt negotiation failed */
199 199 ISCSI_STATUS_LOGIN_TPGT_NEGO_FAIL
200 200 } iscsi_status_t;
201 201 #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS)
202 202
203 203 /* SNA32 check value used on increment of CmdSn values */
204 204 #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */
205 205
206 206 /*
207 207 * This is the maximum number of commands that can be outstanding
208 208 * on a iSCSI session at anyone point in time.
209 209 */
210 210 #define ISCSI_CMD_TABLE_SIZE 1024
211 211
212 212 /* Used on connections thread create of receiver thread */
213 213 extern pri_t minclsyspri;
214 214
215 215 /*
216 216 * Callers of iscsid_config_one/all must hold this
217 217 * semaphore across the calls. Otherwise a ndi_devi_enter()
218 218 * deadlock in the DDI layer may occur.
219 219 */
220 220 extern ksema_t iscsid_config_semaphore;
221 221
222 222 extern kmutex_t iscsi_oid_mutex;
223 223 extern uint32_t iscsi_oid;
224 224 extern void *iscsi_state;
225 225
226 226 /*
227 227 * NOP delay is used to send a iSCSI NOP (ie. ping) across the
228 228 * wire to see if the target is still alive. NOPs are only
229 229 * sent when the RX thread hasn't received anything for the
230 230 * below amount of time.
231 231 */
232 232 #define ISCSI_DEFAULT_NOP_DELAY 5 /* seconds */
233 233 extern int iscsi_nop_delay;
234 234 /*
235 235 * If we haven't received anything in a specified period of time
236 236 * we will stop accepting IO via tran start. This will enable
237 237 * upper level drivers to see we might be having a problem and
238 238 * in the case of scsi_vhci will start to route IO down a better
239 239 * path.
240 240 */
241 241 #define ISCSI_DEFAULT_RX_WINDOW 20 /* seconds */
242 242 extern int iscsi_rx_window;
243 243 /*
244 244 * If we haven't received anything in a specified period of time
245 245 * we will stop accepting IO via tran start. This the max limit
246 246 * when encountered we will start returning a fatal error.
247 247 */
248 248 #define ISCSI_DEFAULT_RX_MAX_WINDOW 180 /* seconds */
249 249 extern int iscsi_rx_max_window;
250 250
251 251 /*
252 252 * During iscsi boot, if the boot session has been created, the
253 253 * initiator hasn't changed the boot lun to be online, we will wait
254 254 * 180s here for lun online by default.
255 255 */
256 256 #define ISCSI_BOOT_DEFAULT_MAX_DELAY 180 /* seconds */
257 257 /*
258 258 * +--------------------------------------------------------------------+
259 259 * | iSCSI Driver Structures |
260 260 * +--------------------------------------------------------------------+
261 261 */
262 262
263 263 /*
264 264 * iSCSI Auth Information
265 265 */
266 266 typedef struct iscsi_auth {
267 267 IscsiAuthStringBlock auth_recv_string_block;
268 268 IscsiAuthStringBlock auth_send_string_block;
269 269 IscsiAuthLargeBinary auth_recv_binary_block;
270 270 IscsiAuthLargeBinary auth_send_binary_block;
271 271 IscsiAuthClient auth_client_block;
272 272 int num_auth_buffers;
273 273 IscsiAuthBufferDesc auth_buffers[5];
274 274
275 275 /*
276 276 * To indicate if bi-directional authentication is enabled.
277 277 * 0 means uni-directional authentication.
278 278 * 1 means bi-directional authentication.
279 279 */
280 280 int bidirectional_auth;
281 281
282 282 /* Initiator's authentication information. */
283 283 char username[iscsiAuthStringMaxLength];
284 284 uint8_t password[iscsiAuthStringMaxLength];
285 285 int password_length;
286 286
287 287 /* Target's authentication information. */
288 288 char username_in[iscsiAuthStringMaxLength];
289 289 uint8_t password_in[iscsiAuthStringMaxLength];
290 290 int password_length_in;
291 291 } iscsi_auth_t;
292 292
293 293 /*
294 294 * iSCSI Task
295 295 */
296 296 typedef struct iscsi_task {
297 297 void *t_arg;
298 298 boolean_t t_blocking;
299 299 uint32_t t_event_count;
300 300 } iscsi_task_t;
301 301
302 302 /*
303 303 * These are all the iscsi_cmd types that we use to track our
304 304 * commands between queues and actions.
305 305 */
306 306 typedef enum iscsi_cmd_type {
307 307 ISCSI_CMD_TYPE_SCSI = 1, /* scsi cmd */
308 308 ISCSI_CMD_TYPE_NOP, /* nop / ping */
309 309 ISCSI_CMD_TYPE_ABORT, /* abort */
310 310 ISCSI_CMD_TYPE_RESET, /* reset */
311 311 ISCSI_CMD_TYPE_LOGOUT, /* logout */
312 312 ISCSI_CMD_TYPE_LOGIN, /* login */
313 313 ISCSI_CMD_TYPE_TEXT /* text */
314 314 } iscsi_cmd_type_t;
315 315
316 316 /*
317 317 * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram)
318 318 */
319 319 typedef enum iscsi_cmd_state {
320 320 ISCSI_CMD_STATE_FREE = 0,
321 321 ISCSI_CMD_STATE_PENDING,
322 322 ISCSI_CMD_STATE_ACTIVE,
323 323 ISCSI_CMD_STATE_ABORTING,
324 324 ISCSI_CMD_STATE_IDM_ABORTING,
325 325 ISCSI_CMD_STATE_COMPLETED,
326 326 ISCSI_CMD_STATE_MAX
327 327 } iscsi_cmd_state_t;
328 328
329 329 #ifdef ISCSI_CMD_SM_STRINGS
330 330 static const char *iscsi_cmd_state_names[ISCSI_CMD_STATE_MAX+1] = {
331 331 "ISCSI_CMD_STATE_FREE",
332 332 "ISCSI_CMD_STATE_PENDING",
333 333 "ISCSI_CMD_STATE_ACTIVE",
334 334 "ISCSI_CMD_STATE_ABORTING",
335 335 "ISCSI_CMD_STATE_IDM_ABORTING",
336 336 "ISCSI_CMD_STATE_COMPLETED",
337 337 "ISCSI_CMD_STATE_MAX"
338 338 };
339 339 #endif
340 340
341 341 /*
342 342 * iscsi command events
343 343 */
344 344 typedef enum iscsi_cmd_event {
345 345 ISCSI_CMD_EVENT_E1 = 0,
346 346 ISCSI_CMD_EVENT_E2,
347 347 ISCSI_CMD_EVENT_E3,
348 348 ISCSI_CMD_EVENT_E4,
349 349 ISCSI_CMD_EVENT_E6,
350 350 ISCSI_CMD_EVENT_E7,
351 351 ISCSI_CMD_EVENT_E8,
352 352 ISCSI_CMD_EVENT_E9,
353 353 ISCSI_CMD_EVENT_E10,
354 354 ISCSI_CMD_EVENT_MAX
355 355 } iscsi_cmd_event_t;
356 356
357 357 #ifdef ISCSI_CMD_SM_STRINGS
358 358 static const char *iscsi_cmd_event_names[ISCSI_CMD_EVENT_MAX+1] = {
359 359 "ISCSI_CMD_EVENT_E1",
360 360 "ISCSI_CMD_EVENT_E2",
361 361 "ISCSI_CMD_EVENT_E3",
362 362 "ISCSI_CMD_EVENT_E4",
363 363 "ISCSI_CMD_EVENT_E6",
364 364 "ISCSI_CMD_EVENT_E7",
365 365 "ISCSI_CMD_EVENT_E8",
366 366 "ISCSI_CMD_EVENT_E9",
367 367 "ISCSI_CMD_EVENT_E10",
368 368 "ISCSI_CMD_EVENT_MAX"
369 369 };
370 370 #endif
371 371
372 372 /*
373 373 * iscsi text command stages - these stages are used by iSCSI text
374 374 * processing to manage long resonses.
375 375 */
376 376 typedef enum iscsi_cmd_text_stage {
377 377 ISCSI_CMD_TEXT_INITIAL_REQ = 0,
378 378 ISCSI_CMD_TEXT_CONTINUATION,
379 379 ISCSI_CMD_TEXT_FINAL_RSP
380 380 } iscsi_cmd_text_stage_t;
381 381
382 382 /*
383 383 * iscsi cmd misc flags - bitwise applicable
384 384 */
385 385 #define ISCSI_CMD_MISCFLAG_INTERNAL 0x1
386 386 #define ISCSI_CMD_MISCFLAG_FREE 0x2
387 387 #define ISCSI_CMD_MISCFLAG_STUCK 0x4
388 388 #define ISCSI_CMD_MISCFLAG_XARQ 0x8
389 389 #define ISCSI_CMD_MISCFLAG_SENT 0x10
390 390 #define ISCSI_CMD_MISCFLAG_FLUSH 0x20
391 391
392 392 /*
393 393 * 1/2 of a 32 bit number, used for checking CmdSN
394 394 * wrapped.
395 395 */
396 396 #define ISCSI_CMD_SN_WRAP 0x80000000
397 397
398 398 #define ISCSI_CMD_PKT_STAT_INIT 0
399 399
400 400 /*
401 401 * iSCSI cmd/pkt Structure
402 402 */
403 403 typedef struct iscsi_cmd {
404 404 uint32_t cmd_sig;
405 405 struct iscsi_cmd *cmd_prev;
406 406 struct iscsi_cmd *cmd_next;
407 407 struct iscsi_conn *cmd_conn;
408 408
409 409 iscsi_cmd_type_t cmd_type;
410 410 iscsi_cmd_state_t cmd_state;
411 411 iscsi_cmd_state_t cmd_prev_state;
412 412 clock_t cmd_lbolt_pending;
413 413 clock_t cmd_lbolt_active;
414 414 clock_t cmd_lbolt_aborting;
415 415 clock_t cmd_lbolt_idm_aborting;
416 416 clock_t cmd_lbolt_timeout;
417 417 uint8_t cmd_misc_flags;
418 418 idm_task_t *cmd_itp;
419 419
420 420 union {
421 421 /* ISCSI_CMD_TYPE_SCSI */
422 422 struct {
423 423 idm_buf_t *ibp_ibuf;
424 424 idm_buf_t *ibp_obuf;
425 425 struct scsi_pkt *pkt;
426 426 struct buf *bp;
427 427 int cmdlen;
428 428 int statuslen;
429 429 size_t data_transferred;
430 430
431 431 uint32_t lun;
432 432
433 433 /*
434 434 * If SCSI_CMD_TYPE is in ABORTING_STATE
435 435 * then the abort_icmdp field will be a pointer
436 436 * to the abort command chasing this one.
437 437 */
438 438 struct iscsi_cmd *abort_icmdp;
439 439 /*
440 440 * pointer to the r2t associated with this
441 441 * command (if any)
442 442 */
443 443 struct iscsi_cmd *r2t_icmdp;
444 444 /*
445 445 * It will be true if this command has
446 446 * another R2T to handle.
447 447 */
448 448 boolean_t r2t_more;
449 449 /*
450 450 * It is used to record pkt_statistics temporarily.
451 451 */
452 452 uint_t pkt_stat;
453 453 } scsi;
454 454 /* ISCSI_CMD_TYPE_ABORT */
455 455 struct {
456 456 /* pointer to original iscsi_cmd, for abort */
457 457 struct iscsi_cmd *icmdp;
458 458 } abort;
459 459 /* ISCSI_CMD_TYPE_RESET */
460 460 struct {
461 461 int level;
462 462 uint8_t response;
463 463 } reset;
464 464 /* ISCSI_CMD_TYPE_NOP */
465 465 struct {
466 466 int rsvd;
467 467 } nop;
468 468 /* ISCSI_CMD_TYPE_R2T */
469 469 struct {
470 470 struct iscsi_cmd *icmdp;
471 471 uint32_t offset;
472 472 uint32_t length;
473 473 } r2t;
474 474 /* ISCSI_CMD_TYPE_LOGIN */
475 475 struct {
476 476 int rvsd;
477 477 } login;
478 478 /* ISCSI_CMD_TYPE_LOGOUT */
479 479 struct {
480 480 int rsvd;
481 481 } logout;
482 482 /* ISCSI_CMD_TYPE_TEXT */
483 483 struct {
484 484 char *buf;
485 485 int buf_len;
486 486 uint32_t offset;
487 487 uint32_t data_len;
488 488 uint32_t total_rx_len;
489 489 uint32_t ttt;
490 490 uint8_t lun[8];
491 491 iscsi_cmd_text_stage_t stage;
492 492 } text;
493 493 } cmd_un;
494 494
495 495 struct iscsi_lun *cmd_lun; /* associated lun */
496 496
497 497 uint32_t cmd_itt;
498 498 uint32_t cmd_ttt;
499 499
500 500 /*
501 501 * If a data digest error is seem on a data pdu. This flag
502 502 * will get set. We don't abort the cmd immediately because
503 503 * we want to read in all the data to get it out of the
504 504 * stream. Once the completion for the cmd is received we
505 505 * we will abort the cmd and state no sense data was available.
506 506 */
507 507 boolean_t cmd_crc_error_seen;
508 508
509 509 /*
510 510 * Used to block and wake up caller until action is completed.
511 511 * This is for ABORT, RESET, and PASSTHRU cmds.
512 512 */
513 513 int cmd_result;
514 514 int cmd_completed;
515 515 kmutex_t cmd_mutex;
516 516 kcondvar_t cmd_completion;
517 517
518 518 idm_pdu_t cmd_pdu;
519 519
520 520 sm_audit_buf_t cmd_state_audit;
521 521
522 522 uint32_t cmd_sn;
523 523 } iscsi_cmd_t;
524 524
525 525
526 526 /*
527 527 * iSCSI LUN Structure
528 528 */
529 529 typedef struct iscsi_lun {
530 530 uint32_t lun_sig;
531 531 int lun_state;
532 532
533 533 struct iscsi_lun *lun_next; /* next lun on this sess. */
534 534 struct iscsi_sess *lun_sess; /* parent sess. for lun */
535 535 dev_info_t *lun_dip;
536 536 mdi_pathinfo_t *lun_pip;
537 537
538 538 uint16_t lun_num; /* LUN */
539 539 uint8_t lun_addr_type; /* LUN addressing type */
540 540 uint32_t lun_oid; /* OID */
541 541 char *lun_guid; /* GUID */
|
↓ open down ↓ |
506 lines elided |
↑ open up ↑ |
542 542 int lun_guid_size; /* GUID allocation size */
543 543 char *lun_addr; /* sess,lun */
544 544 time_t lun_time_online;
545 545
546 546 uchar_t lun_cap; /* bitmap of scsi caps */
547 547
548 548 uchar_t lun_vid[ISCSI_INQ_VID_BUF_LEN]; /* Vendor ID */
549 549 uchar_t lun_pid[ISCSI_INQ_PID_BUF_LEN]; /* Product ID */
550 550
551 551 uchar_t lun_type;
552 + kmutex_t lun_mutex;
553 + int lun_refcnt;
552 554 } iscsi_lun_t;
553 555
554 556 #define ISCSI_LUN_STATE_CLEAR 0 /* used to clear all states */
555 557 #define ISCSI_LUN_STATE_OFFLINE 1
556 558 #define ISCSI_LUN_STATE_ONLINE 2
557 559 #define ISCSI_LUN_STATE_INVALID 4 /* offline failed */
558 560 #define ISCSI_LUN_STATE_BUSY 8 /* logic unit is in reset */
559 561
560 562 #define ISCSI_LUN_CAP_RESET 0x01
561 563
562 564 #define ISCSI_SCSI_RESET_SENSE_CODE 0x29
563 565 #define ISCSI_SCSI_LUNCHANGED_CODE 0x3f
564 566
565 567 #define ISCSI_SCSI_LUNCHANGED_ASCQ 0x0e
566 568
567 569 /*
568 570 *
569 571 *
570 572 */
571 573 typedef struct iscsi_queue {
572 574 iscsi_cmd_t *head;
573 575 iscsi_cmd_t *tail;
574 576 int count;
575 577 kmutex_t mutex;
576 578 } iscsi_queue_t;
577 579
578 580 #define ISCSI_CONN_DEFAULT_LOGIN_MIN 0
579 581 #define ISCSI_CONN_DEFAULT_LOGIN_REDIRECT 10
580 582
581 583 /* iSCSI tunable Parameters */
582 584 typedef struct iscsi_tunable_params {
583 585 int recv_login_rsp_timeout; /* range: 0 - 60*60 */
584 586 int conn_login_max; /* range: 0 - 60*60 */
585 587 int polling_login_delay; /* range: 0 - 60*60 */
586 588 } iscsi_tunable_params_t;
587 589
588 590 typedef union iscsi_sockaddr {
589 591 struct sockaddr sin;
590 592 struct sockaddr_in sin4;
591 593 struct sockaddr_in6 sin6;
592 594 } iscsi_sockaddr_t;
593 595
594 596 #define SIZEOF_SOCKADDR(so) ((so)->sa_family == AF_INET ? \
595 597 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
596 598
597 599 typedef enum {
598 600 LOGIN_START,
599 601 LOGIN_READY,
600 602 LOGIN_TX,
601 603 LOGIN_RX,
602 604 LOGIN_ERROR,
603 605 LOGIN_DONE,
604 606 LOGIN_FFP,
605 607 LOGIN_MAX
606 608 } iscsi_login_state_t;
607 609
608 610 #ifdef ISCSI_LOGIN_STATE_NAMES
609 611 static const char *iscsi_login_state_names[LOGIN_MAX+1] = {
610 612 "LOGIN_START",
611 613 "LOGIN_READY",
612 614 "LOGIN_TX",
613 615 "LOGIN_RX",
614 616 "LOGIN_ERROR",
615 617 "LOGIN_DONE",
616 618 "LOGIN_FFP",
617 619 "LOGIN_MAX"
618 620 };
619 621 #endif
620 622
621 623 /*
622 624 * iscsi_conn_state
623 625 */
624 626 typedef enum iscsi_conn_state {
625 627 ISCSI_CONN_STATE_UNDEFINED = 0,
626 628 ISCSI_CONN_STATE_FREE,
627 629 ISCSI_CONN_STATE_IN_LOGIN,
628 630 ISCSI_CONN_STATE_LOGGED_IN,
629 631 ISCSI_CONN_STATE_IN_LOGOUT,
630 632 ISCSI_CONN_STATE_FAILED,
631 633 ISCSI_CONN_STATE_POLLING,
632 634 ISCSI_CONN_STATE_MAX
633 635 } iscsi_conn_state_t;
634 636
635 637 #ifdef ISCSI_ICS_NAMES
636 638 static const char *iscsi_ics_name[ISCSI_CONN_STATE_MAX+1] = {
637 639 "ISCSI_CONN_STATE_UNDEFINED",
638 640 "ISCSI_CONN_STATE_FREE",
639 641 "ISCSI_CONN_STATE_IN_LOGIN",
640 642 "ISCSI_CONN_STATE_LOGGED_IN",
641 643 "ISCSI_CONN_STATE_IN_LOGOUT",
642 644 "ISCSI_CONN_STATE_FAILED",
643 645 "ISCSI_CONN_STATE_POLLING",
644 646 "ISCSI_CONN_STATE_MAX"
645 647 };
646 648 #endif
647 649
648 650 #define ISCSI_CONN_STATE_FULL_FEATURE(state) \
649 651 ((state == ISCSI_CONN_STATE_LOGGED_IN) || \
650 652 (state == ISCSI_CONN_STATE_IN_LOGOUT))
651 653
652 654 /*
653 655 * iSCSI Connection Structure
654 656 */
655 657 typedef struct iscsi_conn {
656 658 uint32_t conn_sig;
657 659 struct iscsi_conn *conn_next; /* next conn on this sess. */
658 660 struct iscsi_sess *conn_sess; /* parent sess. for conn. */
659 661
660 662 iscsi_conn_state_t conn_state; /* cur. conn. driver state */
661 663 iscsi_conn_state_t conn_prev_state; /* prev. conn. driver state */
662 664 /* protects the session state and synchronizes the state machine */
663 665 kmutex_t conn_state_mutex;
664 666 kcondvar_t conn_state_change;
665 667 boolean_t conn_state_destroy;
666 668 boolean_t conn_state_ffp;
667 669 boolean_t conn_state_idm_connected;
668 670 boolean_t conn_async_logout;
669 671 ddi_taskq_t *conn_cn_taskq;
670 672
671 673 idm_conn_t *conn_ic;
672 674
673 675 /* base connection information, may have been redirected */
674 676 iscsi_sockaddr_t conn_base_addr;
675 677
676 678 /* current connection information, may have been redirected */
677 679 iscsi_sockaddr_t conn_curr_addr;
678 680
679 681 boolean_t conn_bound;
680 682 iscsi_sockaddr_t conn_bound_addr;
681 683
682 684 uint32_t conn_cid; /* CID */
683 685 uint32_t conn_oid; /* OID */
684 686
685 687 int conn_current_stage; /* iSCSI login stage */
686 688 int conn_next_stage; /* iSCSI login stage */
687 689 int conn_partial_response;
688 690
689 691 /*
690 692 * The active queue contains iscsi_cmds that have already
691 693 * been sent on this connection. Any future responses to
692 694 * these cmds require alligence to this connection. If there
693 695 * are issues with these cmds the command may need aborted
694 696 * depending on the command type, and must be put back into
695 697 * the session's pending queue or aborted.
696 698 */
697 699 iscsi_queue_t conn_queue_active;
698 700 iscsi_queue_t conn_queue_idm_aborting;
699 701
700 702 /* lbolt from the last receive, used for nop processing */
701 703 clock_t conn_rx_lbolt;
702 704 clock_t conn_nop_lbolt;
703 705
704 706 iscsi_thread_t *conn_tx_thread;
705 707
706 708 /*
707 709 * The expstatsn is the command status sn that is expected
708 710 * next from the target. Command status is carried on a number
709 711 * of iSCSI PDUs (ex. SCSI Cmd Response, SCSI Data IN with
710 712 * S-Bit set, ...), not all PDUs. If our expstatsn is different
711 713 * than the received statsn. Something got out of sync we need to
712 714 * recover.
713 715 */
714 716 uint32_t conn_expstatsn;
715 717 uint32_t conn_laststatsn;
716 718
717 719 /* active login parameters */
718 720 iscsi_login_params_t conn_params;
719 721
720 722 /* Statistics */
721 723 struct {
722 724 kstat_t *ks;
723 725 iscsi_conn_stats_t ks_data;
724 726 } stats;
725 727
726 728 /*
727 729 * These fields are used to coordinate the asynchronous IDM
728 730 * PDU operations with the synchronous login code.
729 731 */
730 732 kmutex_t conn_login_mutex;
731 733 kcondvar_t conn_login_cv;
732 734 iscsi_login_state_t conn_login_state;
733 735 iscsi_status_t conn_login_status;
734 736 iscsi_hdr_t conn_login_resp_hdr;
735 737 char *conn_login_data;
736 738 int conn_login_datalen;
737 739 int conn_login_max_data_length;
738 740
739 741 /*
740 742 * login min and max identify the amount of time
741 743 * in lbolt that iscsi_start_login() should attempt
742 744 * to log into a target portal. The login will
743 745 * delay until the min lbolt has been reached and
744 746 * will end once max time has been reached. These
745 747 * values are normally set to the default but can
746 748 * are also altered by async commands received from
747 749 * the targetlogin.
748 750 */
749 751 clock_t conn_login_min;
750 752 clock_t conn_login_max;
751 753 sm_audit_buf_t conn_state_audit;
752 754
753 755 /* active tunable parameters */
754 756 iscsi_tunable_params_t conn_tunable_params;
755 757 boolean_t conn_timeout;
756 758 } iscsi_conn_t;
757 759
758 760
759 761 /*
760 762 * iscsi_sess_state - (reference iscsi_sess.c for state diagram)
761 763 */
762 764 typedef enum iscsi_sess_state {
763 765 ISCSI_SESS_STATE_FREE = 0,
764 766 ISCSI_SESS_STATE_LOGGED_IN,
765 767 ISCSI_SESS_STATE_FAILED,
766 768 ISCSI_SESS_STATE_IN_FLUSH,
767 769 ISCSI_SESS_STATE_FLUSHED,
768 770 ISCSI_SESS_STATE_MAX
769 771 } iscsi_sess_state_t;
770 772
771 773 #ifdef ISCSI_SESS_SM_STRINGS
772 774 static const char *iscsi_sess_state_names[ISCSI_SESS_STATE_MAX+1] = {
773 775 "ISCSI_SESS_STATE_FREE",
774 776 "ISCSI_SESS_STATE_LOGGED_IN",
775 777 "ISCSI_SESS_STATE_FAILED",
776 778 "ISCSI_SESS_STATE_IN_FLUSH",
777 779 "ISCSI_SESS_STATE_FLUSHED",
778 780 "ISCSI_SESS_STATE_MAX"
779 781 };
780 782 #endif
781 783
782 784 #define ISCSI_SESS_STATE_FULL_FEATURE(state) \
783 785 ((state == ISCSI_SESS_STATE_LOGGED_IN) || \
784 786 (state == ISCSI_SESS_STATE_IN_FLUSH))
785 787
786 788
787 789 typedef enum iscsi_sess_event {
788 790 ISCSI_SESS_EVENT_N1 = 0,
789 791 ISCSI_SESS_EVENT_N3,
790 792 ISCSI_SESS_EVENT_N5,
791 793 ISCSI_SESS_EVENT_N6,
792 794 ISCSI_SESS_EVENT_N7,
793 795 ISCSI_SESS_EVENT_MAX
794 796 } iscsi_sess_event_t;
795 797
796 798 #ifdef ISCSI_SESS_SM_STRINGS
797 799 static const char *iscsi_sess_event_names[ISCSI_SESS_EVENT_MAX+1] = {
798 800 "ISCSI_SESS_EVENT_N1",
799 801 "ISCSI_SESS_EVENT_N3",
800 802 "ISCSI_SESS_EVENT_N5",
801 803 "ISCSI_SESS_EVENT_N6",
802 804 "ISCSI_SESS_EVENT_N7",
803 805 "ISCSI_SESS_EVENT_MAX"
804 806 };
805 807 #endif
806 808
807 809 typedef enum iscsi_sess_type {
808 810 ISCSI_SESS_TYPE_NORMAL = 0,
809 811 ISCSI_SESS_TYPE_DISCOVERY
810 812 } iscsi_sess_type_t;
811 813
812 814 #define SESS_ABORT_TASK_MAX_THREADS 1
813 815
814 816 /* Sun's initiator session ID */
815 817 #define ISCSI_SUN_ISID_0 0x40 /* ISID - EN format */
816 818 #define ISCSI_SUN_ISID_1 0x00 /* Sec B */
817 819 #define ISCSI_SUN_ISID_2 0x00 /* Sec B */
818 820 #define ISCSI_SUN_ISID_3 0x2A /* Sec C - 42 = Sun's EN */
819 821 /*
820 822 * defines 4-5 are the reserved values. These reserved values
821 823 * are used as the ISID for an initiator-port in MP-API and used
822 824 * for the send targets discovery sessions. Byte 5 is overridden
823 825 * for full feature sessions. The default values of byte 5 for a
824 826 * full feature session is 0. When MS/T is enabled with more than
825 827 * one session this byte 5 will increment > 0 up to
826 828 * ISCSI_MAX_CONFIG_SESSIONS.
827 829 */
828 830 #define ISCSI_SUN_ISID_4 0x00
829 831 #define ISCSI_SUN_ISID_5 0xFF
830 832
831 833 #define ISCSI_DEFAULT_SESS_BOUND B_FALSE
832 834 #define ISCSI_DEFAULT_SESS_NUM 1
833 835
834 836 typedef enum iscsi_enum_status {
835 837 ISCSI_SESS_ENUM_FREE = 0,
836 838 ISCSI_SESS_ENUM_INPROG,
837 839 ISCSI_SESS_ENUM_DONE
838 840 } iscsi_enum_status_t;
839 841
840 842 typedef enum iscsi_enum_result {
841 843 ISCSI_SESS_ENUM_COMPLETE = 0,
842 844 ISCSI_SESS_ENUM_PARTIAL,
843 845 ISCSI_SESS_ENUM_IOFAIL,
844 846 ISCSI_SESS_ENUM_SUBMITTED,
845 847 ISCSI_SESS_ENUM_SUBFAIL,
846 848 ISCSI_SESS_ENUM_GONE,
847 849 ISCSI_SESS_ENUM_TUR_FAIL
848 850 } iscsi_enum_result_t;
849 851
850 852 /*
851 853 * iSCSI Session(Target) Structure
852 854 */
853 855 typedef struct iscsi_sess {
854 856 uint32_t sess_sig;
855 857
856 858 iscsi_sess_state_t sess_state;
857 859 iscsi_sess_state_t sess_prev_state;
858 860 clock_t sess_state_lbolt;
859 861 /* protects the session state and synchronizes the state machine */
860 862 krwlock_t sess_state_rwlock;
861 863
862 864 /*
863 865 * Associated target OID.
864 866 */
865 867 uint32_t sess_target_oid;
866 868
867 869 /*
868 870 * Session OID. Used by IMA, interfaces and exported as
869 871 * TARGET_PROP which is checked by the NDI. In addition
870 872 * this is used in our tran_lun_init function.
871 873 */
872 874 uint32_t sess_oid;
873 875
874 876 struct iscsi_sess *sess_next;
875 877 struct iscsi_hba *sess_hba;
876 878
877 879 /* list of all luns relating to session */
878 880 struct iscsi_lun *sess_lun_list;
879 881 krwlock_t sess_lun_list_rwlock;
880 882
881 883 /* list of all connections relating to session */
882 884 struct iscsi_conn *sess_conn_list;
883 885 struct iscsi_conn *sess_conn_list_last_ptr;
884 886 /* pointer to active connection in session */
885 887 struct iscsi_conn *sess_conn_act;
886 888 krwlock_t sess_conn_list_rwlock;
887 889
888 890 /* Connection ID for next connection to be added to session */
889 891 uint32_t sess_conn_next_cid;
890 892
891 893 /*
892 894 * last time any connection on this session received
893 895 * data from the target.
894 896 */
895 897 clock_t sess_rx_lbolt;
896 898
897 899 clock_t sess_failure_lbolt;
898 900
899 901 int sess_storm_delay;
900 902
901 903 /*
902 904 * sess_cmdsn_mutex protects the cmdsn and itt table/values
903 905 * Cmdsn isn't that big of a problem yet since we only have
904 906 * one connection but in the future we will need to ensure
905 907 * this locking is working so keep the sequence numbers in
906 908 * sync on the wire.
907 909 *
908 910 * We also use this lock to protect the ITT table and it's
909 911 * values. We need to make sure someone doesn't assign
910 912 * a duplicate ITT value or cell to a command. Also we
911 913 * need to make sure when someone is looking up an ITT
912 914 * that the command is still in that correct queue location.
913 915 */
914 916 kmutex_t sess_cmdsn_mutex;
915 917
916 918 /*
917 919 * iSCSI command sequencing / windowing. The next
918 920 * command to be sent via the pending queue will
919 921 * get the sess_cmdsn. If the maxcmdsn is less
920 922 * than the next cmdsn then the iSCSI window is
921 923 * closed and this command cannot be sent yet.
922 924 * Most iscsi cmd responses from the target carry
923 925 * a new maxcmdsn. If this new maxcmdsn is greater
924 926 * than the sess_maxcmdsn we will update it's value
925 927 * and set a timer to fire in one tick and reprocess
926 928 * the pending queue.
927 929 *
928 930 * The expcmdsn. Is the value the target expects
929 931 * to be sent for my next cmdsn. If the expcmdsn
930 932 * and the cmdsn get out of sync this could denote
931 933 * a communication problem.
932 934 */
933 935 uint32_t sess_cmdsn;
934 936 uint32_t sess_expcmdsn;
935 937 uint32_t sess_maxcmdsn;
936 938
937 939 /* Next Initiator Task Tag (ITT) to use */
938 940 uint32_t sess_itt;
939 941 /*
940 942 * The session iscsi_cmd table is used to a fast performance
941 943 * lookup of an ITT to a iscsi_cmd when we receive an iSCSI
942 944 * PDU from the wire. To reserve a location in the sess_cmd_table
943 945 * we try the sess_itt % ISCSI_CMD_TABLE_SIZE if this cmd table
944 946 * cell is already full. Then increament the sess_itt and
945 947 * try to get the cell position again, repeat until an empty
946 948 * cell is found. Once an empty cell is found place your
947 949 * scsi_cmd point into the cell to reserve the location. This
948 950 * selection process should be done while holding the session's
949 951 * mutex.
950 952 */
951 953 struct iscsi_cmd *sess_cmd_table[ISCSI_CMD_TABLE_SIZE];
952 954 int sess_cmd_table_count;
953 955
954 956 /*
955 957 * The pending queue contains all iscsi_cmds that require an
956 958 * open MaxCmdSn window to be put on the wire and haven't
957 959 * been placed on the wire. Once placed on the wire they
958 960 * will be moved to a connections specific active queue.
959 961 */
960 962 iscsi_queue_t sess_queue_pending;
961 963
962 964 iscsi_error_t sess_last_err;
963 965
964 966 iscsi_queue_t sess_queue_completion;
965 967 /* configured login parameters */
966 968 iscsi_login_params_t sess_params;
967 969
968 970 /* general iSCSI protocol/session info */
969 971 uchar_t sess_name[ISCSI_MAX_NAME_LEN];
970 972 int sess_name_length;
971 973 char sess_alias[ISCSI_MAX_NAME_LEN];
972 974 int sess_alias_length;
973 975 iSCSIDiscoveryMethod_t sess_discovered_by;
974 976 iscsi_sockaddr_t sess_discovered_addr;
975 977 uchar_t sess_isid[ISCSI_ISID_LEN]; /* Session ID */
976 978 uint16_t sess_tsid; /* Target ID */
977 979 /*
978 980 * If the target portal group tag(TPGT) is equal to ISCSI_DEFAULT_TPGT
979 981 * then the initiator will accept a successful login with any TPGT
980 982 * specified by the target. If a none default TPGT is configured
981 983 * then we will only successfully accept a login with that matching
982 984 * TPGT value.
983 985 */
984 986 int sess_tpgt_conf;
985 987 /* This field records the negotiated TPGT value, preserved for dtrace */
986 988 int sess_tpgt_nego;
987 989
988 990 /*
989 991 * Authentication information.
990 992 *
991 993 * DCW: Again IMA seems to take a session view at this
992 994 * information.
993 995 */
994 996 iscsi_auth_t sess_auth;
995 997
996 998 /* Statistics */
997 999 struct {
998 1000 kstat_t *ks;
999 1001 iscsi_sess_stats_t ks_data;
1000 1002 kstat_t *ks_io;
1001 1003 kstat_io_t ks_io_data;
1002 1004 kmutex_t ks_io_lock;
1003 1005 } stats;
1004 1006
1005 1007 iscsi_thread_t *sess_ic_thread;
1006 1008 boolean_t sess_window_open;
1007 1009 boolean_t sess_boot;
1008 1010 iscsi_sess_type_t sess_type;
1009 1011
1010 1012 ddi_taskq_t *sess_login_taskq;
1011 1013
1012 1014 iscsi_thread_t *sess_wd_thread;
1013 1015
1014 1016 sm_audit_buf_t sess_state_audit;
1015 1017
1016 1018 kmutex_t sess_reset_mutex;
1017 1019
1018 1020 boolean_t sess_reset_in_progress;
1019 1021
1020 1022 boolean_t sess_boot_nic_reset;
1021 1023 kmutex_t sess_enum_lock;
1022 1024 kcondvar_t sess_enum_cv;
1023 1025 iscsi_enum_status_t sess_enum_status;
1024 1026 iscsi_enum_result_t sess_enum_result;
1025 1027 uint32_t sess_enum_result_count;
1026 1028 ddi_taskq_t *sess_enum_taskq;
1027 1029
1028 1030 kmutex_t sess_state_wmutex;
1029 1031 kcondvar_t sess_state_wcv;
1030 1032 boolean_t sess_state_hasw;
1031 1033
1032 1034 /* to accelerate the state change in case of new event */
1033 1035 volatile uint32_t sess_state_event_count;
1034 1036 } iscsi_sess_t;
1035 1037
1036 1038 /*
1037 1039 * This structure will be used to store sessions to be online
1038 1040 * during normal login operation.
1039 1041 */
1040 1042 typedef struct iscsi_sess_list {
1041 1043 iscsi_sess_t *session;
1042 1044 struct iscsi_sess_list *next;
1043 1045 } iscsi_sess_list_t;
1044 1046
1045 1047 /*
1046 1048 * iSCSI client notify task context for deferred IDM notifications processing
1047 1049 */
1048 1050 typedef struct iscsi_cn_task {
1049 1051 idm_conn_t *ct_ic;
1050 1052 idm_client_notify_t ct_icn;
1051 1053 uintptr_t ct_data;
1052 1054 } iscsi_cn_task_t;
1053 1055
1054 1056 /*
1055 1057 * iscsi_network
1056 1058 */
1057 1059 typedef struct iscsi_network {
1058 1060 void* (*socket)(int domain, int, int);
1059 1061 int (*bind)(void *, struct sockaddr *, int, int, int);
1060 1062 int (*connect)(void *, struct sockaddr *, int, int, int);
1061 1063 int (*listen)(void *, int);
1062 1064 void* (*accept)(void *, struct sockaddr *, int *);
1063 1065 int (*getsockname)(void *, struct sockaddr *, socklen_t *);
1064 1066 int (*getsockopt)(void *, int, int, void *, int *, int);
1065 1067 int (*setsockopt)(void *, int, int, void *, int);
1066 1068 int (*shutdown)(void *, int);
1067 1069 void (*close)(void *);
1068 1070
1069 1071 size_t (*poll)(void *, clock_t);
1070 1072 size_t (*sendmsg)(void *, struct msghdr *);
1071 1073 size_t (*recvmsg)(void *, struct msghdr *, int);
1072 1074
1073 1075 iscsi_status_t (*sendpdu)(void *, iscsi_hdr_t *, char *, int);
1074 1076 iscsi_status_t (*recvdata)(void *, iscsi_hdr_t *, char *,
1075 1077 int, int, int);
1076 1078 iscsi_status_t (*recvhdr)(void *, iscsi_hdr_t *, int, int, int);
1077 1079
1078 1080 struct {
1079 1081 int sndbuf;
1080 1082 int rcvbuf;
1081 1083 int nodelay;
1082 1084 int conn_notify_threshold;
1083 1085 int conn_abort_threshold;
1084 1086 int abort_threshold;
1085 1087 } tweaks;
1086 1088 } iscsi_network_t;
1087 1089
1088 1090 #define ISCSI_NET_HEADER_DIGEST 0x00000001
1089 1091 #define ISCSI_NET_DATA_DIGEST 0x00000002
1090 1092
1091 1093 extern iscsi_network_t *iscsi_net;
1092 1094
1093 1095 /*
1094 1096 * If we get bus_config requests in less than 5 seconds
1095 1097 * apart skip the name services re-discovery and just
1096 1098 * complete the requested logins. This protects against
1097 1099 * bus_config storms from stale /dev links.
1098 1100 */
1099 1101 #define ISCSI_CONFIG_STORM_DELAY_DEFAULT 5
1100 1102
1101 1103 /*
1102 1104 * iSCSI HBA Structure
1103 1105 */
1104 1106 typedef struct iscsi_hba {
1105 1107 uint32_t hba_sig;
1106 1108 dev_info_t *hba_dip; /* dev info ptr */
1107 1109 scsi_hba_tran_t *hba_tran; /* scsi tran ptr */
1108 1110 ldi_ident_t hba_li;
1109 1111
1110 1112 struct iscsi_sess *hba_sess_list; /* sess. list for hba */
1111 1113 krwlock_t hba_sess_list_rwlock; /* protect sess. list */
1112 1114
1113 1115 /* lbolt of the last time we received a config request */
1114 1116 clock_t hba_config_lbolt;
1115 1117 /* current number of seconds to protect against bus config storms */
1116 1118 int hba_config_storm_delay;
1117 1119
1118 1120 /* general iSCSI protocol hba/initiator info */
1119 1121 uchar_t hba_name[ISCSI_MAX_NAME_LEN];
1120 1122 int hba_name_length;
1121 1123 uchar_t hba_alias[ISCSI_MAX_NAME_LEN];
1122 1124 int hba_alias_length;
1123 1125
1124 1126 /* Default SessionID for HBA */
1125 1127 uchar_t hba_isid[ISCSI_ISID_LEN];
1126 1128
1127 1129 /* Default HBA wide settings */
1128 1130 iscsi_login_params_t hba_params;
1129 1131
1130 1132 /*
1131 1133 * There's only one HBA and it's set to ISCSI_INITIATOR_OID
1132 1134 * (value of 1) at the beginning of time.
1133 1135 */
1134 1136 uint32_t hba_oid;
1135 1137
1136 1138 /*
1137 1139 * Keep track of which events have been sent. User daemons request
1138 1140 * this information so they don't wait for events which they won't
1139 1141 * see.
1140 1142 */
1141 1143 kmutex_t hba_discovery_events_mutex;
1142 1144 iSCSIDiscoveryMethod_t hba_discovery_events;
1143 1145 boolean_t hba_discovery_in_progress;
1144 1146
1145 1147 boolean_t hba_mpxio_enabled; /* mpxio-enabled */
1146 1148 /* if the persistent store is loaded */
1147 1149 boolean_t hba_persistent_loaded;
1148 1150
1149 1151 /*
1150 1152 * Ensures only one SendTargets operation occurs at a time
1151 1153 */
1152 1154 ksema_t hba_sendtgts_semaphore;
1153 1155
1154 1156 /*
1155 1157 * Statistics
1156 1158 */
1157 1159 struct {
1158 1160 kstat_t *ks;
1159 1161 iscsi_hba_stats_t ks_data;
1160 1162 } stats;
1161 1163
1162 1164 /*
1163 1165 * track/control the service status and client
1164 1166 *
1165 1167 * service- service online ensures the operational of cli
1166 1168 * - and the availability of iSCSI discovery/devices
1167 1169 * - so obviously offline means the unusable of cli
1168 1170 * - , disabling of all discovery methods and to offline
1169 1171 * - all discovered devices
1170 1172 *
1171 1173 * client - here the client actually means 'exclusive client'
1172 1174 * - for operations these clients take may conflict
1173 1175 * - with the changing of service status and therefore
1174 1176 * - need to be exclusive
1175 1177 *
1176 1178 * The service has three status:
1177 1179 * ISCSI_SERVICE_ENABLED - client is permitted to
1178 1180 * - request service
1179 1181 *
1180 1182 * ISCSI_SERVICE_DISABLED - client is not permitted to
1181 1183 * - request service
1182 1184 *
1183 1185 * ISCSI_SERVICE_TRANSITION - client must wait for
1184 1186 * - one of above two statuses
1185 1187 *
1186 1188 * The hba_service_client_count tracks the number of
1187 1189 * current clients, it increases with new clients and decreases
1188 1190 * with leaving clients. It stops to increase once the
1189 1191 * ISCSI_SERVICE_TRANSITION is set, and causes later clients be
1190 1192 * blocked there.
1191 1193 *
1192 1194 * The status of the service can only be changed when the number
1193 1195 * of current clients reaches zero.
1194 1196 *
1195 1197 * Clients include:
1196 1198 * iscsi_ioctl
1197 1199 * iscsi_tran_bus_config
1198 1200 * iscsi_tran_bus_unconfig
1199 1201 * isns_scn_callback
1200 1202 */
1201 1203 kmutex_t hba_service_lock;
1202 1204 kcondvar_t hba_service_cv;
1203 1205 uint32_t hba_service_status;
1204 1206 uint32_t hba_service_client_count;
1205 1207
1206 1208 /* Default HBA tunable settings */
1207 1209 iscsi_tunable_params_t hba_tunable_params;
1208 1210 boolean_t hba_service_status_overwrite;
1209 1211 } iscsi_hba_t;
1210 1212
1211 1213 /*
1212 1214 * +--------------------------------------------------------------------+
1213 1215 * | iSCSI prototypes |
1214 1216 * +--------------------------------------------------------------------+
1215 1217 */
1216 1218
1217 1219 /* IDM client callback entry points */
1218 1220 idm_rx_pdu_cb_t iscsi_rx_scsi_rsp;
1219 1221 idm_rx_pdu_cb_t iscsi_rx_misc_pdu;
1220 1222 idm_rx_pdu_error_cb_t iscsi_rx_error_pdu;
1221 1223 idm_build_hdr_cb_t iscsi_build_hdr;
1222 1224 idm_task_cb_t iscsi_task_aborted;
1223 1225 idm_client_notify_cb_t iscsi_client_notify;
1224 1226
1225 1227 /* iscsi_io.c */
1226 1228 int iscsi_sna_lte(uint32_t n1, uint32_t n2);
1227 1229 char *iscsi_get_next_text(char *data, int data_length, char *curr_text);
1228 1230
1229 1231 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg);
1230 1232 void iscsi_tx_thread(iscsi_thread_t *thread, void *arg);
1231 1233 void iscsi_wd_thread(iscsi_thread_t *thread, void *arg);
1232 1234
1233 1235 iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1234 1236
1235 1237 void iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp);
1236 1238
1237 1239 void iscsi_handle_abort(void *arg);
1238 1240 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level,
1239 1241 iscsi_lun_t *ilp);
1240 1242 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp);
1241 1243 iscsi_status_t iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun,
1242 1244 struct uscsi_cmd *ucmdp);
1243 1245 iscsi_status_t iscsi_handle_text(iscsi_conn_t *icp,
1244 1246 char *buf, uint32_t buf_len, uint32_t data_len, uint32_t *rx_data_len);
1245 1247
1246 1248 void iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1247 1249
1248 1250 /* iscsi_crc.c */
1249 1251 uint32_t iscsi_crc32c(void *address, unsigned long length);
1250 1252 uint32_t iscsi_crc32c_continued(void *address, unsigned long length,
1251 1253 uint32_t crc);
1252 1254
1253 1255 /* iscsi_queue.c */
1254 1256 void iscsi_init_queue(iscsi_queue_t *queue);
1255 1257 void iscsi_destroy_queue(iscsi_queue_t *queue);
1256 1258 void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1257 1259 void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1258 1260 void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1259 1261 void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1260 1262 void iscsi_enqueue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1261 1263 void iscsi_dequeue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1262 1264 void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1263 1265 iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *);
1264 1266 void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue);
1265 1267 void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **,
1266 1268 iscsi_cmd_t *);
1267 1269
1268 1270 /* iscsi_login.c */
1269 1271 iscsi_status_t iscsi_login_start(void *arg);
1270 1272 void iscsi_login_update_state(iscsi_conn_t *icp,
1271 1273 iscsi_login_state_t next_state);
1272 1274 void iscsi_login_update_state_locked(iscsi_conn_t *icp,
1273 1275 iscsi_login_state_t next_state);
1274 1276
1275 1277
1276 1278 /* iscsi_stats.c */
1277 1279 boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp);
1278 1280 boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp);
1279 1281 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp);
1280 1282 boolean_t iscsi_sess_kstat_term(struct iscsi_sess *isp);
1281 1283 boolean_t iscsi_conn_kstat_init(struct iscsi_conn *icp);
1282 1284 void iscsi_conn_kstat_term(struct iscsi_conn *icp);
1283 1285
1284 1286 /* iscsi_net.c */
1285 1287 void iscsi_net_init();
1286 1288 void iscsi_net_fini();
1287 1289 iscsi_status_t iscsi_net_interface(boolean_t reset);
1288 1290
1289 1291 /* iscsi_sess.c */
1290 1292 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp,
1291 1293 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc,
1292 1294 char *target_name, int tpgt, uchar_t isid_lsb,
1293 1295 iscsi_sess_type_t type, uint32_t *oid);
1294 1296 void iscsi_sess_online(void *arg);
1295 1297 int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp);
1296 1298 iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp);
1297 1299 void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event,
1298 1300 uint32_t event_count);
1299 1301 char *iscsi_sess_state_str(iscsi_sess_state_t state);
1300 1302 boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp);
1301 1303 iscsi_status_t iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp);
1302 1304 void iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp);
1303 1305 iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1304 1306 void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1305 1307 void iscsi_sess_redrive_io(iscsi_sess_t *isp);
1306 1308 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp,
1307 1309 iscsi_sess_t **ispp);
1308 1310 iscsi_enum_result_t iscsi_sess_enum_request(iscsi_sess_t *isp,
1309 1311 boolean_t wait, uint32_t event_count);
1310 1312 iscsi_enum_result_t iscsi_sess_enum_query(iscsi_sess_t *isp);
1311 1313 void iscsi_sess_enter_state_zone(iscsi_sess_t *isp);
1312 1314 void iscsi_sess_exit_state_zone(iscsi_sess_t *isp);
1313 1315
1314 1316 /* iscsi_conn.c */
1315 1317 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp,
1316 1318 iscsi_conn_t **icpp);
1317 1319 iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp);
1318 1320 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp);
1319 1321 iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp);
|
↓ open down ↓ |
758 lines elided |
↑ open up ↑ |
1320 1322 void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max);
1321 1323 iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp);
1322 1324 void iscsi_conn_retry(iscsi_sess_t *isp, iscsi_conn_t *icp);
1323 1325 void iscsi_conn_update_state(iscsi_conn_t *icp, iscsi_conn_state_t next_state);
1324 1326 void iscsi_conn_update_state_locked(iscsi_conn_t *icp,
1325 1327 iscsi_conn_state_t next_state);
1326 1328
1327 1329 /* iscsi_lun.c */
1328 1330 iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num,
1329 1331 uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid);
1330 -iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp,
1331 - iscsi_lun_t *ilp);
1332 +void iscsi_lun_hold(iscsi_lun_t *ilp);
1333 +void iscsi_lun_rele(iscsi_lun_t *ilp);
1334 +iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, iscsi_lun_t *ilp);
1332 1335 void iscsi_lun_online(iscsi_hba_t *ihp,
1333 1336 iscsi_lun_t *ilp);
1334 1337 iscsi_status_t iscsi_lun_offline(iscsi_hba_t *ihp,
1335 1338 iscsi_lun_t *ilp, boolean_t lun_free);
1336 1339
1337 1340 /* iscsi_cmd.c */
1338 1341 void iscsi_cmd_state_machine(iscsi_cmd_t *icmdp,
1339 1342 iscsi_cmd_event_t event, void *arg);
1340 1343 iscsi_cmd_t *iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags);
1341 1344 void iscsi_cmd_free(iscsi_cmd_t *icmdp);
1342 1345
1343 1346 /* iscsi_ioctl.c */
1344 1347 void * iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size);
1345 1348 int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode);
1346 1349 iscsi_conn_list_t *iscsi_ioctl_conn_oid_list_get_copyin(caddr_t, int);
1347 1350 int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *, caddr_t, int);
1348 1351 boolean_t iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp,
1349 1352 iscsi_conn_list_t *cl);
1350 1353 boolean_t iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp);
1351 1354 int iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl);
1352 1355 int iscsi_target_prop_mod(iscsi_hba_t *, iscsi_property_t *, int cmd);
1353 1356 int iscsi_set_params(iscsi_param_set_t *, iscsi_hba_t *, boolean_t);
1354 1357 int iscsi_get_persisted_param(uchar_t *, iscsi_param_get_t *,
1355 1358 iscsi_login_params_t *);
1356 1359 void iscsi_set_default_login_params(iscsi_login_params_t *params);
1357 1360 int iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp,
1358 1361 iscsi_config_sess_t *ics);
1359 1362 int iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp,
1360 1363 iscsi_config_sess_t *ics);
1361 1364 int iscsi_ioctl_set_tunable_param(iscsi_hba_t *ihp,
1362 1365 iscsi_tunable_object_t *tpss);
1363 1366 /* ioctls prototypes */
1364 1367 int iscsi_get_param(iscsi_login_params_t *params,
1365 1368 boolean_t valid_flag,
1366 1369 iscsi_param_get_t *ipgp);
1367 1370
1368 1371 /* iscsid.c */
1369 1372 boolean_t iscsid_init(iscsi_hba_t *ihp);
1370 1373 boolean_t iscsid_start(iscsi_hba_t *ihp);
1371 1374 boolean_t iscsid_stop(iscsi_hba_t *ihp);
1372 1375 void iscsid_fini();
1373 1376 void iscsid_props(iSCSIDiscoveryProperties_t *props);
1374 1377 boolean_t iscsid_enable_discovery(iscsi_hba_t *ihp,
1375 1378 iSCSIDiscoveryMethod_t idm, boolean_t poke);
1376 1379 boolean_t iscsid_disable_discovery(iscsi_hba_t *ihp,
1377 1380 iSCSIDiscoveryMethod_t idm);
1378 1381 void iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method);
1379 1382 void iscsid_do_sendtgts(entry_t *discovery_addr);
1380 1383 void iscsid_do_isns_query_one_server(
1381 1384 iscsi_hba_t *ihp, entry_t *isns_addr);
1382 1385 void iscsid_do_isns_query(iscsi_hba_t *ihp);
1383 1386 void iscsid_config_one(iscsi_hba_t *ihp,
1384 1387 char *name, boolean_t protect);
1385 1388 void iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect);
1386 1389 void iscsid_unconfig_one(iscsi_hba_t *ihp, char *name);
1387 1390 void iscsid_unconfig_all(iscsi_hba_t *ihp);
1388 1391 void isns_scn_callback(void *arg);
1389 1392 boolean_t iscsid_del(iscsi_hba_t *ihp, char *target_name,
1390 1393 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc);
1391 1394 boolean_t iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name,
1392 1395 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc);
1393 1396 void iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port,
1394 1397 struct sockaddr *dst_addr);
1395 1398 void iscsid_set_default_initiator_node_settings(iscsi_hba_t *ihp,
1396 1399 boolean_t minimal);
1397 1400
1398 1401 void iscsi_send_sysevent(iscsi_hba_t *ihp, char *eventcalss,
1399 1402 char *subclass, nvlist_t *np);
1400 1403 boolean_t iscsi_reconfig_boot_sess(iscsi_hba_t *ihp);
1401 1404 boolean_t iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp);
1402 1405 boolean_t iscsi_cmp_boot_ini_name(char *name);
1403 1406 boolean_t iscsi_cmp_boot_tgt_name(char *name);
1404 1407 boolean_t iscsi_client_request_service(iscsi_hba_t *ihp);
1405 1408 void iscsi_client_release_service(iscsi_hba_t *ihp);
1406 1409
1407 1410 extern void bcopy(const void *s1, void *s2, size_t n);
1408 1411 extern void bzero(void *s, size_t n);
1409 1412
1410 1413 #ifdef __cplusplus
1411 1414 }
1412 1415 #endif
1413 1416
1414 1417 #endif /* _ISCSI_H */
|
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX