1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. 5 * Copyright (c) Intel Corporation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk/stdinc.h" 36 37 #include "spdk/endian.h" 38 #include "spdk/env.h" 39 #include "spdk/event.h" 40 #include "spdk/thread.h" 41 #include "spdk/queue.h" 42 #include "spdk/trace.h" 43 #include "spdk/net.h" 44 #include "spdk/sock.h" 45 #include "spdk/string.h" 46 47 #include "spdk_internal/log.h" 48 49 #include "iscsi/task.h" 50 #include "iscsi/conn.h" 51 #include "iscsi/tgt_node.h" 52 #include "iscsi/portal_grp.h" 53 #include "spdk/scsi.h" 54 55 #define SPDK_ISCSI_CONNECTION_MEMSET(conn) \ 56 memset(&(conn)->portal, 0, sizeof(*(conn)) - \ 57 offsetof(struct spdk_iscsi_conn, portal)); 58 59 static int g_connections_per_lcore; 60 static uint32_t *g_num_connections; 61 62 struct spdk_iscsi_conn *g_conns_array = MAP_FAILED; 63 static int g_conns_array_fd = -1; 64 static char g_shm_name[64]; 65 66 static pthread_mutex_t g_conns_mutex = PTHREAD_MUTEX_INITIALIZER; 67 68 static struct spdk_poller *g_shutdown_timer = NULL; 69 70 static uint32_t spdk_iscsi_conn_allocate_reactor(const struct spdk_cpuset *cpumask); 71 72 static void spdk_iscsi_conn_full_feature_migrate(void *arg1, void *arg2); 73 static void spdk_iscsi_conn_stop(struct spdk_iscsi_conn *conn); 74 static void spdk_iscsi_conn_sock_cb(void *arg, struct spdk_sock_group *group, 75 struct spdk_sock *sock); 76 77 static struct spdk_iscsi_conn * 78 allocate_conn(void) 79 { 80 struct spdk_iscsi_conn *conn; 81 int i; 82 83 pthread_mutex_lock(&g_conns_mutex); 84 for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) { 85 conn = &g_conns_array[i]; 86 if (!conn->is_valid) { 87 SPDK_ISCSI_CONNECTION_MEMSET(conn); 88 conn->is_valid = 1; 89 pthread_mutex_unlock(&g_conns_mutex); 90 return conn; 91 } 92 } 93 pthread_mutex_unlock(&g_conns_mutex); 94 95 return NULL; 96 } 97 98 static void 99 free_conn(struct spdk_iscsi_conn *conn) 100 { 101 free(conn->portal_host); 102 free(conn->portal_port); 103 conn->is_valid = 0; 104 } 105 106 static struct spdk_iscsi_conn * 107 spdk_find_iscsi_connection_by_id(int cid) 108 { 109 if (g_conns_array[cid].is_valid == 1) { 110 return &g_conns_array[cid]; 111 } else { 112 return NULL; 113 } 114 } 115 116 int spdk_initialize_iscsi_conns(void) 117 { 118 size_t conns_size = sizeof(struct spdk_iscsi_conn) * MAX_ISCSI_CONNECTIONS; 119 uint32_t i, last_core; 120 121 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_init\n"); 122 123 snprintf(g_shm_name, sizeof(g_shm_name), "/spdk_iscsi_conns.%d", spdk_app_get_shm_id()); 124 g_conns_array_fd = shm_open(g_shm_name, O_RDWR | O_CREAT, 0600); 125 if (g_conns_array_fd < 0) { 126 SPDK_ERRLOG("could not shm_open %s\n", g_shm_name); 127 goto err; 128 } 129 130 if (ftruncate(g_conns_array_fd, conns_size) != 0) { 131 SPDK_ERRLOG("could not ftruncate\n"); 132 goto err; 133 } 134 g_conns_array = mmap(0, conns_size, PROT_READ | PROT_WRITE, MAP_SHARED, 135 g_conns_array_fd, 0); 136 137 if (g_conns_array == MAP_FAILED) { 138 fprintf(stderr, "could not mmap cons array file %s (%d)\n", g_shm_name, errno); 139 goto err; 140 } 141 142 memset(g_conns_array, 0, conns_size); 143 144 for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) { 145 g_conns_array[i].id = i; 146 } 147 148 last_core = spdk_env_get_last_core(); 149 g_num_connections = calloc(last_core + 1, sizeof(uint32_t)); 150 if (!g_num_connections) { 151 SPDK_ERRLOG("Could not allocate array size=%u for g_num_connections\n", 152 last_core + 1); 153 goto err; 154 } 155 156 return 0; 157 158 err: 159 if (g_conns_array != MAP_FAILED) { 160 munmap(g_conns_array, conns_size); 161 g_conns_array = MAP_FAILED; 162 } 163 164 if (g_conns_array_fd >= 0) { 165 close(g_conns_array_fd); 166 g_conns_array_fd = -1; 167 shm_unlink(g_shm_name); 168 } 169 170 return -1; 171 } 172 173 static void 174 spdk_iscsi_poll_group_add_conn_sock(struct spdk_iscsi_conn *conn) 175 { 176 struct spdk_iscsi_poll_group *poll_group = &g_spdk_iscsi.poll_group[spdk_env_get_current_core()]; 177 int rc; 178 179 rc = spdk_sock_group_add_sock(poll_group->sock_group, conn->sock, spdk_iscsi_conn_sock_cb, conn); 180 if (rc < 0) { 181 SPDK_ERRLOG("Failed to add sock=%p of conn=%p\n", conn->sock, conn); 182 } 183 } 184 185 static void 186 spdk_iscsi_poll_group_remove_conn_sock(struct spdk_iscsi_conn *conn) 187 { 188 struct spdk_iscsi_poll_group *poll_group = &g_spdk_iscsi.poll_group[spdk_env_get_current_core()]; 189 int rc; 190 191 rc = spdk_sock_group_remove_sock(poll_group->sock_group, conn->sock); 192 if (rc < 0) { 193 SPDK_ERRLOG("Failed to remove sock=%p of conn=%p\n", conn->sock, conn); 194 } 195 } 196 197 static void 198 spdk_iscsi_poll_group_add_conn(struct spdk_iscsi_conn *conn) 199 { 200 struct spdk_iscsi_poll_group *poll_group = &g_spdk_iscsi.poll_group[spdk_env_get_current_core()]; 201 202 conn->is_stopped = false; 203 STAILQ_INSERT_TAIL(&poll_group->connections, conn, link); 204 spdk_iscsi_poll_group_add_conn_sock(conn); 205 } 206 207 static void 208 spdk_iscsi_poll_group_remove_conn(struct spdk_iscsi_conn *conn) 209 { 210 struct spdk_iscsi_poll_group *poll_group = &g_spdk_iscsi.poll_group[spdk_env_get_current_core()]; 211 212 conn->is_stopped = true; 213 STAILQ_REMOVE(&poll_group->connections, conn, spdk_iscsi_conn, link); 214 } 215 216 /** 217 * \brief Create an iSCSI connection from the given parameters and schedule it 218 * on a reactor. 219 * 220 * \code 221 * 222 * # identify reactor where the new connections work item will be scheduled 223 * reactor = spdk_iscsi_conn_allocate_reactor() 224 * allocate spdk_iscsi_conn object 225 * initialize spdk_iscsi_conn object 226 * schedule iSCSI connection work item on reactor 227 * 228 * \endcode 229 */ 230 int 231 spdk_iscsi_conn_construct(struct spdk_iscsi_portal *portal, 232 struct spdk_sock *sock) 233 { 234 struct spdk_iscsi_conn *conn; 235 int bufsize, i, rc; 236 237 conn = allocate_conn(); 238 if (conn == NULL) { 239 SPDK_ERRLOG("Could not allocate connection.\n"); 240 return -1; 241 } 242 243 pthread_mutex_lock(&g_spdk_iscsi.mutex); 244 conn->timeout = g_spdk_iscsi.timeout; 245 conn->nopininterval = g_spdk_iscsi.nopininterval; 246 conn->nopininterval *= spdk_get_ticks_hz(); /* seconds to TSC */ 247 conn->nop_outstanding = false; 248 conn->data_out_cnt = 0; 249 conn->data_in_cnt = 0; 250 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 251 conn->MaxRecvDataSegmentLength = 8192; // RFC3720(12.12) 252 253 conn->portal = portal; 254 conn->pg_tag = portal->group->tag; 255 conn->portal_host = strdup(portal->host); 256 conn->portal_port = strdup(portal->port); 257 conn->portal_cpumask = portal->cpumask; 258 conn->sock = sock; 259 260 conn->state = ISCSI_CONN_STATE_INVALID; 261 conn->login_phase = ISCSI_SECURITY_NEGOTIATION_PHASE; 262 conn->ttt = 0; 263 264 conn->partial_text_parameter = NULL; 265 266 for (i = 0; i < MAX_CONNECTION_PARAMS; i++) { 267 conn->conn_param_state_negotiated[i] = false; 268 } 269 270 for (i = 0; i < MAX_SESSION_PARAMS; i++) { 271 conn->sess_param_state_negotiated[i] = false; 272 } 273 274 for (i = 0; i < DEFAULT_MAXR2T; i++) { 275 conn->outstanding_r2t_tasks[i] = NULL; 276 } 277 278 TAILQ_INIT(&conn->write_pdu_list); 279 TAILQ_INIT(&conn->snack_pdu_list); 280 TAILQ_INIT(&conn->queued_r2t_tasks); 281 TAILQ_INIT(&conn->active_r2t_tasks); 282 TAILQ_INIT(&conn->queued_datain_tasks); 283 284 rc = spdk_sock_getaddr(sock, conn->target_addr, 285 sizeof conn->target_addr, 286 conn->initiator_addr, sizeof conn->initiator_addr); 287 if (rc < 0) { 288 SPDK_ERRLOG("spdk_sock_getaddr() failed\n"); 289 goto error_return; 290 } 291 292 bufsize = 2 * 1024 * 1024; 293 rc = spdk_sock_set_recvbuf(conn->sock, bufsize); 294 if (rc != 0) { 295 SPDK_ERRLOG("spdk_sock_set_recvbuf failed\n"); 296 } 297 298 bufsize = 32 * 1024 * 1024 / g_spdk_iscsi.MaxConnections; 299 if (bufsize > 2 * 1024 * 1024) { 300 bufsize = 2 * 1024 * 1024; 301 } 302 rc = spdk_sock_set_sendbuf(conn->sock, bufsize); 303 if (rc != 0) { 304 SPDK_ERRLOG("spdk_sock_set_sendbuf failed\n"); 305 } 306 307 /* set low water mark */ 308 rc = spdk_sock_set_recvlowat(conn->sock, 1); 309 if (rc != 0) { 310 SPDK_ERRLOG("spdk_sock_set_recvlowat() failed\n"); 311 goto error_return; 312 } 313 314 /* set default params */ 315 rc = spdk_iscsi_conn_params_init(&conn->params); 316 if (rc < 0) { 317 SPDK_ERRLOG("iscsi_conn_params_init() failed\n"); 318 error_return: 319 spdk_iscsi_param_free(conn->params); 320 free_conn(conn); 321 return -1; 322 } 323 conn->logout_timer = NULL; 324 conn->shutdown_timer = NULL; 325 SPDK_NOTICELOG("Launching connection on acceptor thread\n"); 326 conn->pending_task_cnt = 0; 327 conn->pending_activate_event = false; 328 329 conn->lcore = spdk_env_get_current_core(); 330 __sync_fetch_and_add(&g_num_connections[conn->lcore], 1); 331 332 spdk_iscsi_poll_group_add_conn(conn); 333 return 0; 334 } 335 336 void 337 spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 338 { 339 if (pdu->task) { 340 if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) { 341 if (pdu->task->scsi.offset > 0) { 342 conn->data_in_cnt--; 343 if (pdu->bhs.flags & ISCSI_DATAIN_STATUS) { 344 /* Free the primary task after the last subtask done */ 345 conn->data_in_cnt--; 346 spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task)); 347 } 348 } 349 } else if (pdu->bhs.opcode == ISCSI_OP_SCSI_RSP && 350 pdu->task->scsi.status != SPDK_SCSI_STATUS_GOOD) { 351 if (pdu->task->scsi.offset > 0) { 352 spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task)); 353 } 354 } 355 spdk_iscsi_task_put(pdu->task); 356 } 357 spdk_put_pdu(pdu); 358 } 359 360 static int spdk_iscsi_conn_free_tasks(struct spdk_iscsi_conn *conn) 361 { 362 struct spdk_iscsi_pdu *pdu, *tmp_pdu; 363 struct spdk_iscsi_task *iscsi_task, *tmp_iscsi_task; 364 365 TAILQ_FOREACH_SAFE(pdu, &conn->write_pdu_list, tailq, tmp_pdu) { 366 TAILQ_REMOVE(&conn->write_pdu_list, pdu, tailq); 367 if (pdu->task) { 368 spdk_iscsi_task_put(pdu->task); 369 } 370 spdk_put_pdu(pdu); 371 } 372 373 TAILQ_FOREACH_SAFE(pdu, &conn->snack_pdu_list, tailq, tmp_pdu) { 374 TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq); 375 if (pdu->task) { 376 spdk_iscsi_task_put(pdu->task); 377 } 378 spdk_put_pdu(pdu); 379 } 380 381 TAILQ_FOREACH_SAFE(iscsi_task, &conn->queued_datain_tasks, link, tmp_iscsi_task) { 382 TAILQ_REMOVE(&conn->queued_datain_tasks, iscsi_task, link); 383 pdu = iscsi_task->pdu; 384 spdk_iscsi_task_put(iscsi_task); 385 spdk_put_pdu(pdu); 386 } 387 388 if (conn->pending_task_cnt) { 389 return -1; 390 } 391 392 return 0; 393 } 394 395 static void spdk_iscsi_conn_free(struct spdk_iscsi_conn *conn) 396 { 397 if (conn == NULL) { 398 return; 399 } 400 401 spdk_iscsi_param_free(conn->params); 402 403 /* 404 * Each connection pre-allocates its next PDU - make sure these get 405 * freed here. 406 */ 407 spdk_put_pdu(conn->pdu_in_progress); 408 409 free(conn->auth.user); 410 free(conn->auth.secret); 411 free(conn->auth.muser); 412 free(conn->auth.msecret); 413 free_conn(conn); 414 } 415 416 static void spdk_iscsi_remove_conn(struct spdk_iscsi_conn *conn) 417 { 418 struct spdk_iscsi_sess *sess; 419 int idx; 420 uint32_t i, j; 421 422 idx = -1; 423 sess = conn->sess; 424 conn->sess = NULL; 425 if (sess == NULL) { 426 spdk_iscsi_conn_free(conn); 427 return; 428 } 429 430 for (i = 0; i < sess->connections; i++) { 431 if (sess->conns[i] == conn) { 432 idx = i; 433 break; 434 } 435 } 436 437 if (sess->connections < 1) { 438 SPDK_ERRLOG("zero connection\n"); 439 sess->connections = 0; 440 } else { 441 if (idx < 0) { 442 SPDK_ERRLOG("remove conn not found\n"); 443 } else { 444 for (j = idx; j < sess->connections - 1; j++) { 445 sess->conns[j] = sess->conns[j + 1]; 446 } 447 sess->conns[sess->connections - 1] = NULL; 448 } 449 sess->connections--; 450 } 451 452 SPDK_NOTICELOG("Terminating connections(tsih %d): %d\n", sess->tsih, sess->connections); 453 454 if (sess->connections == 0) { 455 /* cleanup last connection */ 456 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 457 "cleanup last conn free sess\n"); 458 spdk_free_sess(sess); 459 } 460 461 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "cleanup free conn\n"); 462 spdk_iscsi_conn_free(conn); 463 } 464 465 static void 466 spdk_iscsi_conn_cleanup_backend(struct spdk_iscsi_conn *conn) 467 { 468 int rc; 469 470 if (conn->sess->connections > 1) { 471 /* connection specific cleanup */ 472 } else if (!g_spdk_iscsi.AllowDuplicateIsid) { 473 /* clean up all tasks to all LUNs for session */ 474 rc = spdk_iscsi_tgt_node_cleanup_luns(conn, 475 conn->sess->target); 476 if (rc < 0) { 477 SPDK_ERRLOG("target abort failed\n"); 478 } 479 } 480 } 481 482 static void 483 _spdk_iscsi_conn_free(struct spdk_iscsi_conn *conn) 484 { 485 pthread_mutex_lock(&g_conns_mutex); 486 spdk_iscsi_remove_conn(conn); 487 pthread_mutex_unlock(&g_conns_mutex); 488 } 489 490 static int 491 _spdk_iscsi_conn_check_shutdown(void *arg) 492 { 493 struct spdk_iscsi_conn *conn = arg; 494 int rc; 495 496 rc = spdk_iscsi_conn_free_tasks(conn); 497 if (rc < 0) { 498 return -1; 499 } 500 501 spdk_poller_unregister(&conn->shutdown_timer); 502 503 spdk_iscsi_conn_stop(conn); 504 _spdk_iscsi_conn_free(conn); 505 506 return -1; 507 } 508 509 void 510 spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) 511 { 512 struct spdk_iscsi_tgt_node *target; 513 int rc; 514 515 conn->state = ISCSI_CONN_STATE_EXITED; 516 517 if (conn->sess != NULL && conn->pending_task_cnt > 0) { 518 target = conn->sess->target; 519 if (target != NULL) { 520 spdk_iscsi_conn_cleanup_backend(conn); 521 } 522 } 523 524 spdk_clear_all_transfer_task(conn, NULL); 525 spdk_iscsi_poll_group_remove_conn_sock(conn); 526 spdk_sock_close(&conn->sock); 527 spdk_poller_unregister(&conn->logout_timer); 528 spdk_poller_unregister(&conn->flush_poller); 529 530 rc = spdk_iscsi_conn_free_tasks(conn); 531 if (rc < 0) { 532 /* The connection cannot be freed yet. Check back later. */ 533 conn->shutdown_timer = spdk_poller_register(_spdk_iscsi_conn_check_shutdown, conn, 1000); 534 } else { 535 spdk_iscsi_conn_stop(conn); 536 _spdk_iscsi_conn_free(conn); 537 } 538 } 539 540 static int 541 spdk_iscsi_get_active_conns(void) 542 { 543 struct spdk_iscsi_conn *conn; 544 int num = 0; 545 int i; 546 547 pthread_mutex_lock(&g_conns_mutex); 548 for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) { 549 conn = spdk_find_iscsi_connection_by_id(i); 550 if (conn == NULL) { 551 continue; 552 } 553 num++; 554 } 555 pthread_mutex_unlock(&g_conns_mutex); 556 return num; 557 } 558 559 static void 560 spdk_iscsi_conns_cleanup(void) 561 { 562 free(g_num_connections); 563 munmap(g_conns_array, sizeof(struct spdk_iscsi_conn) * 564 MAX_ISCSI_CONNECTIONS); 565 shm_unlink(g_shm_name); 566 if (g_conns_array_fd >= 0) { 567 close(g_conns_array_fd); 568 g_conns_array_fd = -1; 569 } 570 } 571 572 static void 573 spdk_iscsi_conn_check_shutdown_cb(void *arg1, void *arg2) 574 { 575 spdk_iscsi_conns_cleanup(); 576 spdk_shutdown_iscsi_conns_done(); 577 } 578 579 static int 580 spdk_iscsi_conn_check_shutdown(void *arg) 581 { 582 struct spdk_event *event; 583 584 if (spdk_iscsi_get_active_conns() == 0) { 585 spdk_poller_unregister(&g_shutdown_timer); 586 event = spdk_event_allocate(spdk_env_get_current_core(), spdk_iscsi_conn_check_shutdown_cb, NULL, 587 NULL); 588 spdk_event_call(event); 589 } 590 591 return -1; 592 } 593 594 /** 595 * This function will stop executing the specified connection. 596 */ 597 static void 598 spdk_iscsi_conn_stop(struct spdk_iscsi_conn *conn) 599 { 600 struct spdk_iscsi_tgt_node *target; 601 602 if (conn->state == ISCSI_CONN_STATE_EXITED && conn->sess != NULL && 603 conn->sess->session_type == SESSION_TYPE_NORMAL && 604 conn->full_feature) { 605 target = conn->sess->target; 606 pthread_mutex_lock(&target->mutex); 607 target->num_active_conns--; 608 pthread_mutex_unlock(&target->mutex); 609 610 assert(conn->dev != NULL); 611 spdk_scsi_dev_free_io_channels(conn->dev); 612 } 613 614 __sync_fetch_and_sub(&g_num_connections[spdk_env_get_current_core()], 1); 615 spdk_iscsi_poll_group_remove_conn(conn); 616 } 617 618 void spdk_shutdown_iscsi_conns(void) 619 { 620 struct spdk_iscsi_conn *conn; 621 int i; 622 623 pthread_mutex_lock(&g_conns_mutex); 624 625 for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) { 626 conn = spdk_find_iscsi_connection_by_id(i); 627 if (conn == NULL) { 628 continue; 629 } 630 conn->state = ISCSI_CONN_STATE_EXITING; 631 } 632 633 pthread_mutex_unlock(&g_conns_mutex); 634 g_shutdown_timer = spdk_poller_register(spdk_iscsi_conn_check_shutdown, NULL, 635 1000); 636 } 637 638 int 639 spdk_iscsi_drop_conns(struct spdk_iscsi_conn *conn, const char *conn_match, 640 int drop_all) 641 { 642 struct spdk_iscsi_conn *xconn; 643 const char *xconn_match; 644 int i, num; 645 646 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_drop_conns\n"); 647 648 num = 0; 649 pthread_mutex_lock(&g_conns_mutex); 650 for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) { 651 xconn = spdk_find_iscsi_connection_by_id(i); 652 653 if (xconn == NULL) { 654 continue; 655 } 656 657 if (xconn == conn) { 658 continue; 659 } 660 661 if (!drop_all && xconn->initiator_port == NULL) { 662 continue; 663 } 664 665 xconn_match = 666 drop_all ? xconn->initiator_name : spdk_scsi_port_get_name(xconn->initiator_port); 667 668 if (!strcasecmp(conn_match, xconn_match) && 669 conn->target == xconn->target) { 670 671 if (num == 0) { 672 /* 673 * Only print this message before we report the 674 * first dropped connection. 675 */ 676 SPDK_ERRLOG("drop old connections %s by %s\n", 677 conn->target->name, conn_match); 678 } 679 680 SPDK_ERRLOG("exiting conn by %s (%s)\n", 681 xconn_match, xconn->initiator_addr); 682 if (xconn->sess != NULL) { 683 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "TSIH=%u\n", xconn->sess->tsih); 684 } else { 685 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "TSIH=xx\n"); 686 } 687 688 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CID=%u\n", xconn->cid); 689 xconn->state = ISCSI_CONN_STATE_EXITING; 690 num++; 691 } 692 } 693 694 pthread_mutex_unlock(&g_conns_mutex); 695 696 if (num != 0) { 697 SPDK_ERRLOG("exiting %d conns\n", num); 698 } 699 700 return 0; 701 } 702 703 /** 704 * \brief Reads data for the specified iSCSI connection from its TCP socket. 705 * 706 * The TCP socket is marked as non-blocking, so this function may not read 707 * all data requested. 708 * 709 * Returns SPDK_ISCSI_CONNECTION_FATAL if the recv() operation indicates a fatal 710 * error with the TCP connection (including if the TCP connection was closed 711 * unexpectedly. 712 * 713 * Otherwise returns the number of bytes successfully read. 714 */ 715 int 716 spdk_iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int bytes, 717 void *buf) 718 { 719 int ret; 720 721 if (bytes == 0) { 722 return 0; 723 } 724 725 ret = spdk_sock_recv(conn->sock, buf, bytes); 726 727 if (ret > 0) { 728 spdk_trace_record(TRACE_READ_FROM_SOCKET_DONE, conn->id, ret, 0, 0); 729 return ret; 730 } 731 732 if (ret < 0) { 733 if (errno == EAGAIN || errno == EWOULDBLOCK) { 734 return 0; 735 } 736 737 /* For connect reset issue, do not output error log */ 738 if (errno == ECONNRESET) { 739 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_sock_recv() failed, errno %d: %s\n", 740 errno, spdk_strerror(errno)); 741 } else { 742 SPDK_ERRLOG("spdk_sock_recv() failed, errno %d: %s\n", 743 errno, spdk_strerror(errno)); 744 } 745 } 746 747 /* connection closed */ 748 return SPDK_ISCSI_CONNECTION_FATAL; 749 } 750 751 void 752 spdk_iscsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task) 753 { 754 struct spdk_iscsi_task *task = spdk_iscsi_task_from_scsi_task(scsi_task); 755 756 spdk_iscsi_task_mgmt_response(task->conn, task); 757 spdk_iscsi_task_put(task); 758 } 759 760 static void 761 process_completed_read_subtask_list(struct spdk_iscsi_conn *conn, 762 struct spdk_iscsi_task *primary) 763 { 764 struct spdk_iscsi_task *subtask, *tmp; 765 766 TAILQ_FOREACH_SAFE(subtask, &primary->subtask_list, subtask_link, tmp) { 767 if (subtask->scsi.offset == primary->bytes_completed) { 768 TAILQ_REMOVE(&primary->subtask_list, subtask, subtask_link); 769 primary->bytes_completed += subtask->scsi.length; 770 spdk_iscsi_task_response(conn, subtask); 771 spdk_iscsi_task_put(subtask); 772 } else { 773 break; 774 } 775 } 776 } 777 778 static void 779 process_read_task_completion(struct spdk_iscsi_conn *conn, 780 struct spdk_iscsi_task *task, 781 struct spdk_iscsi_task *primary) 782 { 783 struct spdk_iscsi_task *tmp; 784 785 if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) { 786 TAILQ_FOREACH(tmp, &primary->subtask_list, subtask_link) { 787 spdk_scsi_task_copy_status(&tmp->scsi, &task->scsi); 788 } 789 } 790 791 if ((task != primary) && 792 (task->scsi.offset != primary->bytes_completed)) { 793 TAILQ_FOREACH(tmp, &primary->subtask_list, subtask_link) { 794 if (task->scsi.offset < tmp->scsi.offset) { 795 TAILQ_INSERT_BEFORE(tmp, task, subtask_link); 796 return; 797 } 798 } 799 800 TAILQ_INSERT_TAIL(&primary->subtask_list, task, subtask_link); 801 return; 802 } 803 804 primary->bytes_completed += task->scsi.length; 805 spdk_iscsi_task_response(conn, task); 806 807 if ((task != primary) || 808 (task->scsi.transfer_len == task->scsi.length)) { 809 spdk_iscsi_task_put(task); 810 } 811 process_completed_read_subtask_list(conn, primary); 812 813 spdk_iscsi_conn_handle_queued_datain_tasks(conn); 814 } 815 816 void 817 spdk_iscsi_task_cpl(struct spdk_scsi_task *scsi_task) 818 { 819 struct spdk_iscsi_task *primary; 820 struct spdk_iscsi_task *task = spdk_iscsi_task_from_scsi_task(scsi_task); 821 struct spdk_iscsi_conn *conn = task->conn; 822 823 spdk_trace_record(TRACE_ISCSI_TASK_DONE, conn->id, 0, (uintptr_t)task, 0); 824 825 primary = spdk_iscsi_task_get_primary(task); 826 827 if (spdk_iscsi_task_is_read(primary)) { 828 process_read_task_completion(conn, task, primary); 829 } else { 830 primary->bytes_completed += task->scsi.length; 831 if ((task != primary) && 832 (task->scsi.status != SPDK_SCSI_STATUS_GOOD)) { 833 spdk_scsi_task_copy_status(&primary->scsi, &task->scsi); 834 } 835 836 if (primary->bytes_completed == primary->scsi.transfer_len) { 837 spdk_del_transfer_task(conn, primary->tag); 838 spdk_iscsi_task_response(conn, primary); 839 /* 840 * Check if this is the last task completed for an iSCSI write 841 * that required child subtasks. If task != primary, we know 842 * for sure that it was part of an iSCSI write with child subtasks. 843 * The trickier case is when the last task completed was the initial 844 * task - in this case the task will have a smaller length than 845 * the overall transfer length. 846 */ 847 if (task != primary || task->scsi.length != task->scsi.transfer_len) { 848 TAILQ_REMOVE(&conn->active_r2t_tasks, primary, link); 849 spdk_iscsi_task_put(primary); 850 } 851 } 852 spdk_iscsi_task_put(task); 853 } 854 } 855 856 static int 857 spdk_iscsi_get_pdu_length(struct spdk_iscsi_pdu *pdu, int header_digest, 858 int data_digest) 859 { 860 int data_len, enable_digest, total; 861 862 enable_digest = 1; 863 if (pdu->bhs.opcode == ISCSI_OP_LOGIN_RSP) { 864 enable_digest = 0; 865 } 866 867 total = ISCSI_BHS_LEN; 868 869 total += (4 * pdu->bhs.total_ahs_len); 870 871 if (enable_digest && header_digest) { 872 total += ISCSI_DIGEST_LEN; 873 } 874 875 data_len = DGET24(pdu->bhs.data_segment_len); 876 if (data_len > 0) { 877 total += ISCSI_ALIGN(data_len); 878 if (enable_digest && data_digest) { 879 total += ISCSI_DIGEST_LEN; 880 } 881 } 882 883 return total; 884 } 885 886 void 887 spdk_iscsi_conn_handle_nop(struct spdk_iscsi_conn *conn) 888 { 889 uint64_t tsc; 890 891 /** 892 * This function will be executed by nop_poller of iSCSI polling group, so 893 * we need to check the connection state first, then do the nop interval 894 * expiration check work. 895 */ 896 if ((conn->state == ISCSI_CONN_STATE_EXITED) || 897 (conn->state == ISCSI_CONN_STATE_EXITING)) { 898 return; 899 } 900 901 /* Check for nop interval expiration */ 902 tsc = spdk_get_ticks(); 903 if (conn->nop_outstanding) { 904 if ((tsc - conn->last_nopin) > (conn->timeout * spdk_get_ticks_hz())) { 905 SPDK_ERRLOG("Timed out waiting for NOP-Out response from initiator\n"); 906 SPDK_ERRLOG(" tsc=0x%lx, last_nopin=0x%lx\n", tsc, conn->last_nopin); 907 SPDK_ERRLOG(" initiator=%s, target=%s\n", conn->initiator_name, 908 conn->target_short_name); 909 conn->state = ISCSI_CONN_STATE_EXITING; 910 } 911 } else if (tsc - conn->last_nopin > conn->nopininterval) { 912 spdk_iscsi_send_nopin(conn); 913 } 914 } 915 916 /** 917 * \brief Makes one attempt to flush response PDUs back to the initiator. 918 * 919 * Builds a list of iovecs for response PDUs that must be sent back to the 920 * initiator and passes it to writev(). 921 * 922 * Since the socket is non-blocking, writev() may not be able to flush all 923 * of the iovecs, and may even partially flush one of the iovecs. In this 924 * case, the partially flushed PDU will remain on the write_pdu_list with 925 * an offset pointing to the next byte to be flushed. 926 * 927 * Returns 0 if all PDUs were flushed. 928 * 929 * Returns 1 if some PDUs could not be flushed due to lack of send buffer 930 * space. 931 * 932 * Returns -1 if an exception error occurred indicating the TCP connection 933 * should be closed. 934 */ 935 static int 936 spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn) 937 { 938 const int array_size = 32; 939 struct iovec iovec_array[array_size]; 940 struct iovec *iov = iovec_array; 941 int iovec_cnt = 0; 942 int bytes = 0; 943 int total_length = 0; 944 uint32_t writev_offset; 945 struct spdk_iscsi_pdu *pdu; 946 int pdu_length; 947 948 pdu = TAILQ_FIRST(&conn->write_pdu_list); 949 950 if (pdu == NULL) { 951 return 0; 952 } 953 954 /* 955 * Build up a list of iovecs for the first few PDUs in the 956 * connection's write_pdu_list. 957 */ 958 while (pdu != NULL && ((array_size - iovec_cnt) >= 5)) { 959 pdu_length = spdk_iscsi_get_pdu_length(pdu, 960 conn->header_digest, 961 conn->data_digest); 962 iovec_cnt += spdk_iscsi_build_iovecs(conn, 963 &iovec_array[iovec_cnt], 964 pdu); 965 total_length += pdu_length; 966 pdu = TAILQ_NEXT(pdu, tailq); 967 } 968 969 /* 970 * Check if the first PDU was partially written out the last time 971 * this function was called, and if so adjust the iovec array 972 * accordingly. 973 */ 974 writev_offset = TAILQ_FIRST(&conn->write_pdu_list)->writev_offset; 975 total_length -= writev_offset; 976 while (writev_offset > 0) { 977 if (writev_offset >= iov->iov_len) { 978 writev_offset -= iov->iov_len; 979 iov++; 980 iovec_cnt--; 981 } else { 982 iov->iov_len -= writev_offset; 983 iov->iov_base = (char *)iov->iov_base + writev_offset; 984 writev_offset = 0; 985 } 986 } 987 988 spdk_trace_record(TRACE_FLUSH_WRITEBUF_START, conn->id, total_length, 0, iovec_cnt); 989 990 bytes = spdk_sock_writev(conn->sock, iov, iovec_cnt); 991 if (bytes == -1) { 992 if (errno == EWOULDBLOCK || errno == EAGAIN) { 993 return 1; 994 } else { 995 SPDK_ERRLOG("spdk_sock_writev() failed, errno %d: %s\n", 996 errno, spdk_strerror(errno)); 997 return -1; 998 } 999 } 1000 1001 spdk_trace_record(TRACE_FLUSH_WRITEBUF_DONE, conn->id, bytes, 0, 0); 1002 1003 pdu = TAILQ_FIRST(&conn->write_pdu_list); 1004 1005 /* 1006 * Free any PDUs that were fully written. If a PDU was only 1007 * partially written, update its writev_offset so that next 1008 * time only the unwritten portion will be sent to writev(). 1009 */ 1010 while (bytes > 0) { 1011 pdu_length = spdk_iscsi_get_pdu_length(pdu, 1012 conn->header_digest, 1013 conn->data_digest); 1014 pdu_length -= pdu->writev_offset; 1015 1016 if (bytes >= pdu_length) { 1017 bytes -= pdu_length; 1018 TAILQ_REMOVE(&conn->write_pdu_list, pdu, tailq); 1019 1020 if ((conn->full_feature) && 1021 (conn->sess->ErrorRecoveryLevel >= 1) && 1022 spdk_iscsi_is_deferred_free_pdu(pdu)) { 1023 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "stat_sn=%d\n", 1024 from_be32(&pdu->bhs.stat_sn)); 1025 TAILQ_INSERT_TAIL(&conn->snack_pdu_list, pdu, 1026 tailq); 1027 } else { 1028 spdk_iscsi_conn_free_pdu(conn, pdu); 1029 } 1030 1031 pdu = TAILQ_FIRST(&conn->write_pdu_list); 1032 } else { 1033 pdu->writev_offset += bytes; 1034 bytes = 0; 1035 } 1036 } 1037 1038 return TAILQ_EMPTY(&conn->write_pdu_list) ? 0 : 1; 1039 } 1040 1041 /** 1042 * \brief Flushes response PDUs back to the initiator. 1043 * 1044 * This function may return without all PDUs having flushed to the 1045 * underlying TCP socket buffer - for example, in the case where the 1046 * socket buffer is already full. 1047 * 1048 * During normal RUNNING connection state, if not all PDUs are flushed, 1049 * then subsequent calls to this routine will eventually flush 1050 * remaining PDUs. 1051 * 1052 * During other connection states (EXITING or LOGGED_OUT), this 1053 * function will spin until all PDUs have successfully been flushed. 1054 * 1055 * Returns 0 for success and when all PDUs were able to be flushed. 1056 * 1057 * Returns 1 for success but when some PDUs could not be flushed due 1058 * to lack of TCP buffer space. 1059 * 1060 * Returns -1 for an exceptional error indicating the TCP connection 1061 * should be closed. 1062 */ 1063 static int 1064 spdk_iscsi_conn_flush_pdus(void *_conn) 1065 { 1066 struct spdk_iscsi_conn *conn = _conn; 1067 int rc; 1068 1069 if (conn->state == ISCSI_CONN_STATE_RUNNING) { 1070 rc = spdk_iscsi_conn_flush_pdus_internal(conn); 1071 if (rc == 0 && conn->flush_poller != NULL) { 1072 spdk_poller_unregister(&conn->flush_poller); 1073 } else if (rc == 1 && conn->flush_poller == NULL) { 1074 conn->flush_poller = spdk_poller_register(spdk_iscsi_conn_flush_pdus, conn, 50); 1075 } 1076 } else { 1077 /* 1078 * If the connection state is not RUNNING, then 1079 * keep trying to flush PDUs until our list is 1080 * empty - to make sure all data is sent before 1081 * closing the connection. 1082 */ 1083 do { 1084 rc = spdk_iscsi_conn_flush_pdus_internal(conn); 1085 } while (rc == 1); 1086 } 1087 1088 if (rc < 0 && conn->state < ISCSI_CONN_STATE_EXITING) { 1089 /* 1090 * If the poller has already started destruction of the connection, 1091 * i.e. the socket read failed, then the connection state may already 1092 * be EXITED. We don't want to set it back to EXITING in that case. 1093 */ 1094 conn->state = ISCSI_CONN_STATE_EXITING; 1095 } 1096 1097 return -1; 1098 } 1099 1100 void 1101 spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) 1102 { 1103 TAILQ_INSERT_TAIL(&conn->write_pdu_list, pdu, tailq); 1104 spdk_iscsi_conn_flush_pdus(conn); 1105 } 1106 1107 #define GET_PDU_LOOP_COUNT 16 1108 1109 static int 1110 spdk_iscsi_conn_handle_incoming_pdus(struct spdk_iscsi_conn *conn) 1111 { 1112 struct spdk_iscsi_pdu *pdu; 1113 int i, rc; 1114 1115 /* Read new PDUs from network */ 1116 for (i = 0; i < GET_PDU_LOOP_COUNT; i++) { 1117 rc = spdk_iscsi_read_pdu(conn, &pdu); 1118 if (rc == 0) { 1119 break; 1120 } else if (rc == SPDK_ISCSI_CONNECTION_FATAL) { 1121 return rc; 1122 } 1123 1124 if (conn->state == ISCSI_CONN_STATE_LOGGED_OUT) { 1125 SPDK_ERRLOG("pdu received after logout\n"); 1126 spdk_put_pdu(pdu); 1127 return SPDK_ISCSI_CONNECTION_FATAL; 1128 } 1129 1130 rc = spdk_iscsi_execute(conn, pdu); 1131 spdk_put_pdu(pdu); 1132 if (rc != 0) { 1133 SPDK_ERRLOG("spdk_iscsi_execute() fatal error on %s(%s)\n", 1134 conn->target_port != NULL ? spdk_scsi_port_get_name(conn->target_port) : "NULL", 1135 conn->initiator_port != NULL ? spdk_scsi_port_get_name(conn->initiator_port) : "NULL"); 1136 return rc; 1137 } 1138 1139 if (conn->is_stopped) { 1140 break; 1141 } 1142 } 1143 1144 return i; 1145 } 1146 1147 static void 1148 spdk_iscsi_conn_sock_cb(void *arg, struct spdk_sock_group *group, struct spdk_sock *sock) 1149 { 1150 struct spdk_iscsi_conn *conn = arg; 1151 int rc; 1152 1153 assert(conn != NULL); 1154 1155 if ((conn->state == ISCSI_CONN_STATE_EXITED) || 1156 (conn->state == ISCSI_CONN_STATE_EXITING)) { 1157 return; 1158 } 1159 1160 /* Handle incoming PDUs */ 1161 rc = spdk_iscsi_conn_handle_incoming_pdus(conn); 1162 if (rc < 0) { 1163 conn->state = ISCSI_CONN_STATE_EXITING; 1164 spdk_iscsi_conn_flush_pdus(conn); 1165 } 1166 } 1167 1168 static void 1169 spdk_iscsi_conn_full_feature_migrate(void *arg1, void *arg2) 1170 { 1171 struct spdk_iscsi_conn *conn = arg1; 1172 1173 if (conn->sess->session_type == SESSION_TYPE_NORMAL) { 1174 assert(conn->dev != NULL); 1175 spdk_scsi_dev_allocate_io_channels(conn->dev); 1176 } 1177 1178 /* The poller has been unregistered, so now we can re-register it on the new core. */ 1179 conn->lcore = spdk_env_get_current_core(); 1180 spdk_iscsi_poll_group_add_conn(conn); 1181 } 1182 1183 void 1184 spdk_iscsi_conn_migration(struct spdk_iscsi_conn *conn) 1185 { 1186 int lcore; 1187 struct spdk_event *event; 1188 struct spdk_iscsi_tgt_node *target; 1189 1190 lcore = spdk_iscsi_conn_allocate_reactor(conn->portal->cpumask); 1191 if (conn->sess->session_type == SESSION_TYPE_NORMAL) { 1192 target = conn->sess->target; 1193 pthread_mutex_lock(&target->mutex); 1194 target->num_active_conns++; 1195 if (target->num_active_conns == 1) { 1196 /** 1197 * This is the only active connection for this target node. 1198 * Save the lcore in the target node so it can be used for 1199 * any other connections to this target node. 1200 */ 1201 target->lcore = lcore; 1202 } else { 1203 /** 1204 * There are other active connections for this target node. 1205 * Ignore the lcore specified by the allocator and use the 1206 * the target node's lcore to ensure this connection runs on 1207 * the same lcore as other connections for this target node. 1208 */ 1209 lcore = target->lcore; 1210 } 1211 pthread_mutex_unlock(&target->mutex); 1212 } 1213 1214 spdk_iscsi_poll_group_remove_conn_sock(conn); 1215 spdk_iscsi_conn_stop(conn); 1216 1217 __sync_fetch_and_add(&g_num_connections[lcore], 1); 1218 conn->last_nopin = spdk_get_ticks(); 1219 event = spdk_event_allocate(lcore, spdk_iscsi_conn_full_feature_migrate, 1220 conn, NULL); 1221 spdk_event_call(event); 1222 } 1223 1224 void 1225 spdk_iscsi_conn_set_min_per_core(int count) 1226 { 1227 g_connections_per_lcore = count; 1228 } 1229 1230 int 1231 spdk_iscsi_conn_get_min_per_core(void) 1232 { 1233 return g_connections_per_lcore; 1234 } 1235 1236 static uint32_t 1237 spdk_iscsi_conn_allocate_reactor(const struct spdk_cpuset *cpumask) 1238 { 1239 uint32_t i, selected_core; 1240 int32_t num_pollers, min_pollers; 1241 1242 min_pollers = INT_MAX; 1243 selected_core = spdk_env_get_first_core(); 1244 1245 SPDK_ENV_FOREACH_CORE(i) { 1246 if (!spdk_cpuset_get_cpu(cpumask, i)) { 1247 continue; 1248 } 1249 1250 /* This core is running. Check how many pollers it already has. */ 1251 num_pollers = g_num_connections[i]; 1252 1253 if ((num_pollers > 0) && (num_pollers < g_connections_per_lcore)) { 1254 /* Fewer than the maximum connections per core, 1255 * but at least 1. Use this core. 1256 */ 1257 return i; 1258 } else if (num_pollers < min_pollers) { 1259 /* Track the core that has the minimum number of pollers 1260 * to be used if no cores meet our criteria 1261 */ 1262 selected_core = i; 1263 min_pollers = num_pollers; 1264 } 1265 } 1266 1267 return selected_core; 1268 } 1269 1270 static int 1271 logout_timeout(void *arg) 1272 { 1273 struct spdk_iscsi_conn *conn = arg; 1274 1275 spdk_iscsi_conn_destruct(conn); 1276 1277 return -1; 1278 } 1279 1280 void 1281 spdk_iscsi_conn_logout(struct spdk_iscsi_conn *conn) 1282 { 1283 conn->state = ISCSI_CONN_STATE_LOGGED_OUT; 1284 conn->logout_timer = spdk_poller_register(logout_timeout, conn, ISCSI_LOGOUT_TIMEOUT * 1000000); 1285 } 1286 1287 SPDK_TRACE_REGISTER_FN(iscsi_conn_trace) 1288 { 1289 spdk_trace_register_owner(OWNER_ISCSI_CONN, 'c'); 1290 spdk_trace_register_object(OBJECT_ISCSI_PDU, 'p'); 1291 spdk_trace_register_description("READ FROM SOCKET DONE", "", TRACE_READ_FROM_SOCKET_DONE, 1292 OWNER_ISCSI_CONN, OBJECT_NONE, 0, 0, 0, ""); 1293 spdk_trace_register_description("FLUSH WRITEBUF START", "", TRACE_FLUSH_WRITEBUF_START, 1294 OWNER_ISCSI_CONN, OBJECT_NONE, 0, 0, 0, "iovec: "); 1295 spdk_trace_register_description("FLUSH WRITEBUF DONE", "", TRACE_FLUSH_WRITEBUF_DONE, 1296 OWNER_ISCSI_CONN, OBJECT_NONE, 0, 0, 0, ""); 1297 spdk_trace_register_description("READ PDU", "", TRACE_READ_PDU, 1298 OWNER_ISCSI_CONN, OBJECT_ISCSI_PDU, 1, 0, 0, "opc: "); 1299 spdk_trace_register_description("ISCSI TASK DONE", "", TRACE_ISCSI_TASK_DONE, 1300 OWNER_ISCSI_CONN, OBJECT_SCSI_TASK, 0, 0, 0, ""); 1301 spdk_trace_register_description("ISCSI TASK QUEUE", "", TRACE_ISCSI_TASK_QUEUE, 1302 OWNER_ISCSI_CONN, OBJECT_SCSI_TASK, 1, 1, 0, "pdu: "); 1303 spdk_trace_register_description("ISCSI CONN ACTIVE", "", TRACE_ISCSI_CONN_ACTIVE, 1304 OWNER_ISCSI_CONN, OBJECT_NONE, 0, 0, 0, ""); 1305 spdk_trace_register_description("ISCSI CONN IDLE", "", TRACE_ISCSI_CONN_IDLE, 1306 OWNER_ISCSI_CONN, OBJECT_NONE, 0, 0, 0, ""); 1307 } 1308