Print this page
NEX-9981 Deadman timer panic from idm_refcnt_wait_ref thread while offlining iSCSI targets
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-6018 Return of the walking dead idm_refcnt_wait_ref comstar threads
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-3177 enums and string arrays required to be in sync.
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/sys/idm/idm.h
+++ new/usr/src/uts/common/sys/idm/idm.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
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 2009 Sun Microsystems, Inc. All rights reserved.
24 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 25 * Use is subject to license terms.
25 26 */
26 27
27 28 #ifndef _IDM_H
28 29 #define _IDM_H
29 30
30 31 #ifdef __cplusplus
31 32 extern "C" {
32 33 #endif
33 34
35 +#include <sys/stmf_defines.h>
36 +
34 37 typedef enum {
35 38 IDM_STATUS_SUCCESS = 0,
36 39 IDM_STATUS_FAIL,
37 40 IDM_STATUS_NORESOURCES,
38 41 IDM_STATUS_REJECT,
39 42 IDM_STATUS_IO,
40 43 IDM_STATUS_ABORTED,
41 44 IDM_STATUS_SUSPENDED,
42 45 IDM_STATUS_HEADER_DIGEST,
43 46 IDM_STATUS_DATA_DIGEST,
44 47 IDM_STATUS_PROTOCOL_ERROR,
45 48 IDM_STATUS_LOGIN_FAIL
46 49 } idm_status_t;
47 50
51 +#define IDM_CLIENT_NOTIFY_LIST() \
52 + item(CN_UNDEFINED) \
53 + item(CN_CONNECT_ACCEPT) /* Target only */ \
54 + item(CN_LOGIN_FAIL) \
55 + item(CN_READY_FOR_LOGIN) /* Initiator only */ \
56 + item(CN_FFP_ENABLED) \
57 + item(CN_FFP_DISABLED) \
58 + item(CN_CONNECT_LOST) \
59 + item(CN_CONNECT_DESTROY) \
60 + item(CN_CONNECT_FAIL) \
61 + item(CN_MAX)
48 62
49 63 typedef enum {
50 - CN_CONNECT_ACCEPT = 1, /* Target only */
51 - CN_LOGIN_FAIL,
52 - CN_READY_FOR_LOGIN, /* Initiator only */
53 - CN_FFP_ENABLED,
54 - CN_FFP_DISABLED,
55 - CN_CONNECT_LOST,
56 - CN_CONNECT_DESTROY,
57 - CN_CONNECT_FAIL,
58 - CN_MAX
64 +#define item(a) a,
65 + IDM_CLIENT_NOTIFY_LIST()
66 +#undef item
59 67 } idm_client_notify_t;
60 68
61 69 #ifdef IDM_CN_NOTIFY_STRINGS
62 70 static const char *idm_cn_strings[CN_MAX + 1] = {
63 - "CN_UNDEFINED",
64 - "CN_CONNECT_ACCEPT",
65 - "CN_LOGIN_FAIL",
66 - "CN_READY_FOR_LOGIN",
67 - "CN_FFP_ENABLED",
68 - "CN_FFP_DISABLED",
69 - "CN_CONNECT_LOST",
70 - "CN_CONNECT_DESTROY",
71 - "CN_CONNECT_FAIL",
72 - "CN_MAX"
71 +#define item(a) #a,
72 + IDM_CLIENT_NOTIFY_LIST()
73 +#undef item
73 74 };
74 75 #endif
75 76
76 77 typedef enum {
77 78 FD_CONN_FAIL,
78 79 FD_CONN_LOGOUT,
79 80 FD_SESS_LOGOUT
80 81 } idm_ffp_disable_t;
81 82
82 83 typedef enum {
83 84 AT_INTERNAL_SUSPEND,
84 85 AT_INTERNAL_ABORT,
85 86 AT_TASK_MGMT_ABORT
86 87 } idm_abort_type_t;
87 88
89 +#define IDM_TASK_STATE_LIST() \
90 + item(TASK_IDLE) \
91 + item(TASK_ACTIVE) \
92 + item(TASK_SUSPENDING) \
93 + item(TASK_SUSPENDED) \
94 + item(TASK_ABORTING) \
95 + item(TASK_ABORTED) \
96 + item(TASK_COMPLETE) \
97 + item(TASK_MAX_STATE)
98 +
88 99 typedef enum {
89 - TASK_IDLE,
90 - TASK_ACTIVE,
91 - TASK_SUSPENDING,
92 - TASK_SUSPENDED,
93 - TASK_ABORTING,
94 - TASK_ABORTED,
95 - TASK_COMPLETE,
96 - TASK_MAX_STATE
100 +#define item(a) a,
101 + IDM_TASK_STATE_LIST()
102 +#undef item
97 103 } idm_task_state_t;
98 104
99 105 #ifdef IDM_TASK_SM_STRINGS
100 106 static const char *idm_ts_name[TASK_MAX_STATE+1] = {
101 - "TASK_IDLE",
102 - "TASK_ACTIVE",
103 - "TASK_SUSPENDING",
104 - "TASK_SUSPENDED",
105 - "TASK_ABORTING",
106 - "TASK_ABORTED",
107 - "TASK_COMPLETE",
108 - "TASK_MAX_STATE"
107 +#define item(a) #a,
108 + IDM_TASK_STATE_LIST()
109 +#undef item
109 110 };
110 111 #endif
111 112
112 113 typedef enum {
113 114 KV_HANDLED = 0,
114 115 KV_HANDLED_NO_TRANSIT,
115 116 KV_UNHANDLED,
116 117 KV_TARGET_ONLY,
117 118 KV_NO_RESOURCES,
118 119 KV_INTERNAL_ERROR,
119 120 KV_VALUE_ERROR,
120 121 KV_MISSING_FIELDS,
121 122 KV_AUTH_FAILED
122 123 } kv_status_t;
123 124
124 125 /*
125 126 * Request structures
126 127 */
127 128
128 129 /* Defined in idm_impl.h */
129 130 struct idm_conn_s;
130 131 struct idm_svc_s;
131 132 struct idm_buf_s;
132 133 struct idm_pdu_s;
133 134 struct idm_task_s;
134 135
135 136 typedef idm_status_t (idm_client_notify_cb_t)(
136 137 struct idm_conn_s *ic, idm_client_notify_t cn, uintptr_t data);
137 138
138 139 typedef void (idm_rx_pdu_cb_t)(struct idm_conn_s *ic, struct idm_pdu_s *pdu);
139 140
140 141 typedef void (idm_rx_pdu_error_cb_t)(struct idm_conn_s *ic,
141 142 struct idm_pdu_s *pdu, idm_status_t status);
142 143
143 144 typedef void (idm_buf_cb_t)(struct idm_buf_s *idb, idm_status_t status);
144 145
145 146 typedef void (idm_pdu_cb_t)(struct idm_pdu_s *pdu, idm_status_t status);
146 147
147 148 typedef void (idm_task_cb_t)(struct idm_task_s *task, idm_status_t status);
148 149
149 150 typedef void (idm_build_hdr_cb_t)(
150 151 struct idm_task_s *task, struct idm_pdu_s *pdu, uint8_t opcode);
151 152
152 153 typedef void (idm_update_statsn_cb_t)(
153 154 struct idm_task_s *task, struct idm_pdu_s *pdu);
154 155
155 156 typedef void (idm_keepalive_cb_t)(struct idm_conn_s *ic);
156 157
157 158 typedef union idm_sockaddr {
158 159 struct sockaddr sin;
159 160 struct sockaddr_in sin4;
160 161 struct sockaddr_in6 sin6;
161 162 } idm_sockaddr_t;
162 163
163 164 #define SIZEOF_SOCKADDR(so) \
164 165 ((so)->sa_family == AF_INET ? \
165 166 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
166 167
167 168 typedef struct {
168 169 idm_rx_pdu_cb_t *icb_rx_scsi_cmd;
169 170 idm_rx_pdu_cb_t *icb_rx_scsi_rsp;
170 171 idm_rx_pdu_cb_t *icb_rx_misc;
171 172 idm_rx_pdu_error_cb_t *icb_rx_error;
172 173 idm_task_cb_t *icb_task_aborted;
173 174 idm_client_notify_cb_t *icb_client_notify;
174 175 idm_build_hdr_cb_t *icb_build_hdr;
175 176 idm_update_statsn_cb_t *icb_update_statsn; /* advance statsn */
176 177 idm_keepalive_cb_t *icb_keepalive;
177 178 } idm_conn_ops_t;
178 179
179 180 typedef struct {
180 181 int cr_domain;
181 182 int cr_type;
182 183 int cr_protocol;
183 184 boolean_t cr_bound;
184 185 idm_sockaddr_t cr_bound_addr;
185 186 idm_sockaddr_t cr_ini_dst_addr;
186 187 ldi_ident_t cr_li;
187 188 idm_conn_ops_t icr_conn_ops;
188 189 boolean_t cr_boot_conn;
189 190 } idm_conn_req_t;
190 191
191 192 typedef struct {
192 193 uint16_t sr_port;
193 194 ldi_ident_t sr_li;
194 195 idm_conn_ops_t sr_conn_ops;
195 196 } idm_svc_req_t;
196 197
197 198
198 199 /* This is not how other networking code handles this */
199 200 typedef struct {
200 201 union {
201 202 struct in_addr in4;
202 203 struct in6_addr in6;
203 204 } i_addr;
204 205 /* i_insize determines which is valid in the union above */
205 206 int i_insize;
206 207 } idm_ipaddr_t;
207 208
208 209 typedef struct {
209 210 idm_ipaddr_t a_addr;
210 211 uint32_t a_port,
211 212 a_oid;
212 213 } idm_addr_t;
213 214
214 215 typedef struct {
215 216 uint32_t al_vers, /* In */
216 217 al_oid; /* In */
217 218 uint32_t al_in_cnt; /* In */
218 219 uint32_t al_out_cnt; /* Out */
219 220 uint32_t al_tpgt; /* Out */
220 221 idm_addr_t al_addrs[1]; /* Out */
221 222 } idm_addr_list_t;
222 223
223 224 /*
224 225 * State machine auditing
225 226 */
226 227
227 228 #define SM_AUDIT_BUF_MAX_REC 32
228 229
229 230 typedef enum {
230 231 SAR_UNDEFINED = 0,
231 232 SAR_STATE_EVENT,
232 233 SAR_STATE_CHANGE
233 234 } sm_audit_record_type_t;
234 235
235 236 typedef enum {
236 237 SAS_UNDEFINED = 0,
237 238 SAS_IDM_CONN,
238 239 SAS_IDM_TASK,
239 240 SAS_ISCSIT_TGT,
240 241 SAS_ISCSIT_SESS,
241 242 SAS_ISCSIT_LOGIN,
242 243 SAS_ISCSI_CMD,
243 244 SAS_ISCSI_SESS,
244 245 SAS_ISCSI_CONN,
245 246 SAS_ISCSI_LOGIN
246 247 } sm_audit_sm_type_t;
247 248
248 249 typedef struct {
249 250 timespec_t sar_timestamp;
250 251 sm_audit_sm_type_t sar_sm_type;
251 252 sm_audit_record_type_t sar_type;
252 253 int sar_state;
253 254 int sar_new_state; /* Only for SAR_STATE_CHANGE */
254 255 int sar_event; /* Only for SAR_STATE_EVENT */
255 256 uintptr_t sar_event_info; /* Only for SAR_STATE_EVENT */
256 257 } sm_audit_record_t;
257 258
258 259 typedef struct {
259 260 int sab_index;
260 261 int sab_max_index;
261 262 sm_audit_record_t sab_records[SM_AUDIT_BUF_MAX_REC];
262 263 } sm_audit_buf_t;
263 264
264 265 extern boolean_t idm_sm_logging;
265 266 extern boolean_t idm_conn_logging;
266 267 extern boolean_t idm_svc_logging;
267 268
268 269 #define IDM_SM_LOG if (idm_sm_logging) cmn_err
269 270 #define IDM_CONN_LOG if (idm_conn_logging) cmn_err
270 271 #define IDM_SVC_LOG if (idm_svc_logging) cmn_err
271 272
272 273 void idm_sm_audit_init(sm_audit_buf_t *audit_buf);
273 274
274 275 void idm_sm_audit_event(sm_audit_buf_t *audit_buf,
275 276 sm_audit_sm_type_t sm_type,
276 277 int state, int event, uintptr_t event_info);
277 278
278 279 void idm_sm_audit_state_change(sm_audit_buf_t *audit_buf,
279 280 sm_audit_sm_type_t sm_type, int state, int new_state);
280 281
281 282
282 283 #include <sys/iscsi_protocol.h>
283 284 #include <sys/idm/idm_conn_sm.h>
284 285 #include <sys/idm/idm_transport.h>
285 286 #include <sys/idm/idm_impl.h>
286 287 #include <sys/idm/idm_text.h>
287 288 #include <sys/idm/idm_so.h>
288 289
289 290 /*
290 291 * iSCSI Initiator Services
291 292 */
292 293
293 294 idm_status_t
294 295 idm_ini_conn_create(idm_conn_req_t *cr, idm_conn_t **new_con);
295 296
296 297 idm_status_t
297 298 idm_ini_conn_connect(idm_conn_t *ic);
298 299
299 300 void
300 301 idm_ini_conn_disconnect(idm_conn_t *ic);
301 302
302 303 void
303 304 idm_ini_conn_disconnect_sync(idm_conn_t *ic);
304 305
305 306 void
306 307 idm_ini_conn_destroy(idm_conn_t *ic);
307 308
308 309 /*
309 310 * iSCSI Target Services
310 311 */
311 312
312 313 idm_status_t
313 314 idm_tgt_svc_create(idm_svc_req_t *sr, idm_svc_t **new_svc);
314 315
315 316 idm_status_t
316 317 idm_tgt_svc_online(idm_svc_t *is);
317 318
318 319 void
319 320 idm_tgt_svc_offline(idm_svc_t *is);
320 321
321 322 void
322 323 idm_tgt_svc_destroy(idm_svc_t *is);
323 324
324 325 void
325 326 idm_tgt_svc_destroy_if_unref(idm_svc_t *is);
326 327
327 328 idm_svc_t *
328 329 idm_tgt_svc_lookup(uint16_t port);
329 330
330 331 void
331 332 idm_tgt_svc_hold(idm_svc_t *is);
332 333
333 334 void
334 335 idm_tgt_svc_rele_and_destroy(idm_svc_t *is);
335 336
336 337 idm_status_t
337 338 idm_tgt_conn_accept(idm_conn_t *ic);
338 339
339 340 void
340 341 idm_tgt_conn_reject(idm_conn_t *ic);
341 342
342 343 void
343 344 idm_conn_hold(idm_conn_t *ic);
344 345
345 346 void
346 347 idm_conn_rele(idm_conn_t *ic);
347 348
348 349 void
349 350 idm_conn_set_target_name(idm_conn_t *ic, char *target_name);
350 351
351 352 void
352 353 idm_conn_set_initiator_name(idm_conn_t *ic, char *initiator_name);
353 354
354 355 void
355 356 idm_conn_set_isid(idm_conn_t *ic, uint8_t isid[ISCSI_ISID_LEN]);
356 357
357 358 /*
358 359 * Target data transfer services
359 360 */
360 361 idm_status_t
361 362 idm_buf_tx_to_ini(idm_task_t *idt, idm_buf_t *idb,
362 363 uint32_t offset, uint32_t xfer_length,
363 364 idm_buf_cb_t idb_buf_cb, void *cb_arg);
364 365
365 366 idm_status_t
366 367 idm_buf_rx_from_ini(idm_task_t *idt, idm_buf_t *idb,
367 368 uint32_t offset, uint32_t xfer_length,
368 369 idm_buf_cb_t idb_buf_cb, void *cb_arg);
369 370
370 371 void
371 372 idm_buf_tx_to_ini_done(idm_task_t *idt, idm_buf_t *idb, idm_status_t status);
372 373
373 374 void
374 375 idm_buf_rx_from_ini_done(idm_task_t *idt, idm_buf_t *idb, idm_status_t status);
375 376
376 377 #define XFER_BUF_TX_TO_INI 0
377 378 #define XFER_BUF_RX_FROM_INI 1
378 379 /*
379 380 * Shared Initiator/Target Services
380 381 */
381 382 kv_status_t
382 383 idm_negotiate_key_values(idm_conn_t *ic, nvlist_t *request_nvl,
383 384 nvlist_t *response_nvl, nvlist_t *negotiated_nvl);
384 385
385 386 void
386 387 idm_notice_key_values(idm_conn_t *ic, nvlist_t *negotiated_nvl);
387 388
388 389 kv_status_t
389 390 idm_declare_key_values(idm_conn_t *ic, nvlist_t *config_nvl,
390 391 nvlist_t *outgoing_nvl);
391 392
392 393 /*
393 394 * Buffer services
394 395 */
395 396
396 397 idm_buf_t *
397 398 idm_buf_alloc(idm_conn_t *ic, void *bufptr, uint64_t buflen);
398 399
399 400 void
400 401 idm_buf_free(idm_buf_t *idb);
401 402
402 403 void
403 404 idm_buf_bind_in(idm_task_t *idt, idm_buf_t *buf);
404 405
405 406 void
406 407 idm_buf_bind_out(idm_task_t *idt, idm_buf_t *buf);
407 408
408 409 void
409 410 idm_buf_unbind_in(idm_task_t *idt, idm_buf_t *buf);
410 411
411 412 void
412 413 idm_buf_unbind_out(idm_task_t *idt, idm_buf_t *buf);
413 414
414 415 idm_buf_t *
415 416 idm_buf_find(void *lbuf, size_t data_offset);
416 417
417 418 void
418 419 idm_bufpat_set(idm_buf_t *idb);
419 420
420 421 boolean_t
421 422 idm_bufpat_check(idm_buf_t *idb, int check_len, idm_bufpat_check_type_t type);
422 423
423 424 extern boolean_t idm_pattern_checking;
424 425
425 426 #define IDM_BUFPAT_SET(CHK_BUF) \
426 427 if (idm_pattern_checking && (CHK_BUF)->idb_bufalloc) { \
427 428 idm_bufpat_set(CHK_BUF); \
428 429 }
429 430
430 431 #define IDM_BUFPAT_CHECK(CHK_BUF, CHK_LEN, CHK_TYPE) \
431 432 if (idm_pattern_checking) { \
432 433 (void) idm_bufpat_check(CHK_BUF, CHK_LEN, CHK_TYPE); \
433 434 }
|
↓ open down ↓ |
315 lines elided |
↑ open up ↑ |
434 435
435 436 /*
436 437 * Task services
437 438 */
438 439 idm_task_t *
439 440 idm_task_alloc(idm_conn_t *ic);
440 441
441 442 void
442 443 idm_task_start(idm_task_t *idt, uintptr_t handle);
443 444
444 -void
445 +stmf_status_t
445 446 idm_task_abort(idm_conn_t *ic, idm_task_t *idt, idm_abort_type_t abort_type);
446 447
447 448 void
448 449 idm_task_cleanup(idm_task_t *idt);
449 450
450 451 void
451 452 idm_task_done(idm_task_t *idt);
452 453
453 454 void
454 455 idm_task_free(idm_task_t *idt);
455 456
456 457 idm_task_t *
457 458 idm_task_find(idm_conn_t *ic, uint32_t itt, uint32_t ttt);
458 459
459 460 idm_task_t *
460 461 idm_task_find_and_complete(idm_conn_t *ic, uint32_t itt, uint32_t ttt);
461 462
462 463 void *
463 464 idm_task_find_by_handle(idm_conn_t *ic, uintptr_t handle);
464 465
465 466 void
466 467 idm_task_hold(idm_task_t *idt);
467 468
468 469 void
469 470 idm_task_rele(idm_task_t *idt);
470 471
471 472 /*
472 473 * PDU Services
473 474 */
474 475
475 476 idm_pdu_t *
476 477 idm_pdu_alloc(uint_t hdrlen, uint_t datalen);
477 478
478 479 idm_pdu_t *
479 480 idm_pdu_alloc_nosleep(uint_t hdrlen, uint_t datalen);
480 481
481 482 void
482 483 idm_pdu_free(idm_pdu_t *pdu);
483 484
484 485 void
485 486 idm_pdu_init(idm_pdu_t *pdu, idm_conn_t *ic, void *private, idm_pdu_cb_t *cb);
486 487
487 488 void
488 489 idm_pdu_init_hdr(idm_pdu_t *pdu, uint8_t *hdr, uint_t hdrlen);
489 490
490 491 void
491 492 idm_pdu_init_data(idm_pdu_t *pdu, uint8_t *data, uint_t datalen);
492 493
493 494 void
494 495 idm_pdu_complete(idm_pdu_t *pdu, idm_status_t status);
495 496
496 497 void
497 498 idm_pdu_tx(idm_pdu_t *pdu);
498 499
499 500 /*
500 501 * Object reference tracking
501 502 */
502 503
503 504 void
504 505 idm_refcnt_init(idm_refcnt_t *refcnt, void *referenced_obj);
505 506
506 507 void
507 508 idm_refcnt_destroy(idm_refcnt_t *refcnt);
508 509
509 510 void
510 511 idm_refcnt_reset(idm_refcnt_t *refcnt);
511 512
512 513 void
513 514 idm_refcnt_hold(idm_refcnt_t *refcnt);
514 515
515 516 void
516 517 idm_refcnt_rele(idm_refcnt_t *refcnt);
|
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
517 518
518 519 void
519 520 idm_refcnt_rele_and_destroy(idm_refcnt_t *refcnt, idm_refcnt_cb_t *cb_func);
520 521
521 522 void
522 523 idm_refcnt_wait_ref(idm_refcnt_t *refcnt);
523 524
524 525 void
525 526 idm_refcnt_async_wait_ref(idm_refcnt_t *refcnt, idm_refcnt_cb_t *cb_func);
526 527
528 +int
529 +idm_refcnt_is_held(idm_refcnt_t *refcnt);
527 530
528 531 #ifdef __cplusplus
529 532 }
530 533 #endif
531 534
532 535 #endif /* _IDM_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX