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