1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <signal.h> 28 #include <pthread.h> 29 #include <assert.h> 30 #include <sys/select.h> 31 #include <stdlib.h> 32 #include <poll.h> 33 #include <strings.h> 34 #include <sys/filio.h> 35 #include <errno.h> 36 #include <utility.h> 37 #include <unistd.h> 38 #include <sys/stropts.h> 39 #include <syslog.h> 40 #include <sys/iscsi_protocol.h> 41 42 #include <iscsitgt_impl.h> 43 #include "iscsi_conn.h" 44 #include "iscsi_sess.h" 45 #include "iscsi_login.h" 46 #include "iscsi_ffp.h" 47 #include "iscsi_provider_impl.h" 48 #include "utility.h" 49 #include "target.h" 50 #include "port.h" 51 #include "t10.h" 52 53 /* 54 * defined here so that pad_text is initialized to zero's. It's 55 * never modified. 56 */ 57 static const char pad_text[ISCSI_PAD_WORD_LEN] = { 0 }; 58 59 static void iscsi_conn_data_rqst(t10_cmd_t *cmd); 60 static void iscsi_conn_cmdcmplt(t10_cmd_t *cmd); 61 static void iscsi_conn_data_in(t10_cmd_t *); 62 static void iscsi_conn_pkt(iscsi_conn_t *c, iscsi_rsp_hdr_t *in); 63 64 static void send_datain_pdu(iscsi_conn_t *c, t10_cmd_t *cmd, 65 uint8_t final_flag); 66 static void send_scsi_rsp(iscsi_conn_t *c, t10_cmd_t *cmd); 67 static void queue_noop_in(iscsi_conn_t *c); 68 static char *state_to_str(iscsi_state_t s); 69 static void send_async_logout(iscsi_conn_t *c); 70 static void send_async_scsi(iscsi_conn_t *c, int key, int asc, int ascq); 71 72 void * 73 conn_poller(void *v) 74 { 75 iscsi_conn_t *c = (iscsi_conn_t *)v; 76 int nbytes; 77 int pval; 78 nfds_t nfds = 1; 79 struct pollfd fds[1]; 80 iscsi_state_t state; 81 target_queue_t *mgmtq = c->c_mgmtq; 82 Boolean_t one_time_noop = False; 83 84 fds[0].fd = c->c_fd; 85 fds[0].events = POLLIN; 86 87 util_title(c->c_mgmtq, Q_CONN_LOGIN, c->c_num, "Start Poller"); 88 while ((pval = poll(fds, nfds, 30 * 1000)) >= 0) { 89 90 /* 91 * The true asynchronous events are when we're in S5_LOGGED_IN 92 * state. In the iscsi_full_feature() code the state is 93 * locked and checked before sending any messages along. The 94 * mutex is grabbed here only to prevent a collision between 95 * some thread setting the state and our reading of the value. 96 * There's no harm in us grabbing the state which might 97 * change right after we unlock the mutex. 98 */ 99 (void) pthread_mutex_lock(&c->c_state_mutex); 100 state = c->c_state; 101 (void) pthread_mutex_unlock(&c->c_state_mutex); 102 103 switch (state) { 104 case S1_FREE: 105 /* 106 * If we moved to the free state. The session 107 * was sent a message to shutdown. Once it 108 * completes it will reply with a shutdown 109 * response which will close the main 110 * connection thread. So, this thread just 111 * returns a stop processing incoming packets. 112 */ 113 goto error; 114 115 case S3_XPT_UP: 116 if (ioctl(c->c_fd, FIONREAD, &nbytes) < 0) { 117 queue_message_set(c->c_dataq, 0, msg_shutdown, 118 0); 119 goto error; 120 } 121 122 /* 123 * To be fully compliant the code should use 124 * ioctl(fd, I_PEEK, (struct strpeek v)); and 125 * look to see if the header is indeed a login 126 * packet. If not, just close the connection. 127 */ 128 if (nbytes < sizeof (iscsi_login_hdr_t)) { 129 queue_message_set(c->c_dataq, 0, 130 msg_shutdown, 0); 131 goto error; 132 } else { 133 /* 134 * Change the state to S4_IN_LOGIN. 135 * Since we haven't touched the data 136 * waiting on the stream when the 137 * sema_post() occurs below the poller 138 * will find data again and send 139 * another packet ready message at 140 * which point we deal with the 141 * login. 142 */ 143 conn_state(c, T4); 144 } 145 break; 146 147 case S4_IN_LOGIN: 148 if (iscsi_handle_login_pkt(c) == False) 149 goto error; 150 break; 151 152 case S7_LOGOUT_REQUESTED: 153 case S5_LOGGED_IN: 154 if (fds[0].revents & POLLIN) { 155 156 if (iscsi_full_feature(c) == False) 157 goto error; 158 159 } else { 160 /* 161 * Being S5_LOGGED_IN, and POLLIN not set, 162 * means the that the poll(,,timer) went off. 163 * If the session is normal, then queue a single 164 * NOOP request, but only once per connection. 165 */ 166 if (c->c_sess->s_type == SessionNormal) { 167 if (one_time_noop == False) { 168 queue_noop_in(c); 169 one_time_noop = True; 170 } 171 } 172 } 173 break; 174 175 case S6_IN_LOGOUT: 176 goto error; 177 178 case S8_CLEANUP_WAIT: 179 queue_prt(c->c_mgmtq, Q_CONN_ERRS, 180 "Haven't handled state S8\n"); 181 queue_message_set(c->c_dataq, 0, 182 msg_shutdown_rsp, 0); 183 goto error; 184 } 185 186 } 187 188 error: 189 /* 190 * Only when we're logged in would we have an active session 191 * which needs to be shut down. In the case of S4_IN_LOGIN we could 192 * transition to either S1_FREE in which case a shutdown message 193 * was sent to the session which in turn will reply with a shutdown 194 * response causing the conn_process to exit. 195 */ 196 if (c->c_state == S5_LOGGED_IN) 197 conn_state(c, T8); 198 199 /* 200 * If a msg_conn_lost was already sent it's invalid to reference 201 * the management queue from the connection structure at this point. 202 */ 203 util_title(mgmtq, Q_CONN_LOGIN, c->c_num, "End Poller"); 204 205 if (pval == -1) 206 queue_message_set(c->c_dataq, 0, msg_conn_lost, 0); 207 return (NULL); 208 } 209 210 /* 211 * conn_process -- thread which runs a connection 212 */ 213 void * 214 conn_process(void *v) 215 { 216 iscsi_conn_t *c = (iscsi_conn_t *)v; 217 iscsi_cmd_t *cmd; 218 Boolean_t process = True; 219 Boolean_t is_last = False; 220 msg_t *m; 221 void *thr_status; 222 int i; 223 mgmt_request_t *mgmt; 224 char debug[80]; 225 time_t tval = time((time_t *)0); 226 Boolean_t drop_t10_cmds = False; 227 228 c->c_dataq = queue_alloc(); 229 c->c_maxcmdsn = CMD_MAXOUTSTANDING; 230 231 if (sema_init(&c->c_datain, 0, USYNC_THREAD, NULL) != 0) { 232 port_conn_remove(c); 233 free(c); 234 return (NULL); 235 } 236 237 util_title(c->c_mgmtq, Q_CONN_LOGIN, c->c_num, "Start Receiver"); 238 util_title(c->c_mgmtq, Q_CONN_LOGIN, c->c_num, 239 ctime_r(&tval, debug, sizeof (debug))); 240 241 c->c_thr_id_process = pthread_self(); 242 243 assert(c->c_state == S1_FREE); 244 conn_state(c, T3); 245 246 (void) pthread_create(&c->c_thr_id_poller, NULL, 247 conn_poller, (void *)c); 248 249 do { 250 m = queue_message_get(c->c_dataq); 251 switch (m->msg_type) { 252 case msg_mgmt_rqst: 253 mgmt = (mgmt_request_t *)m->msg_data; 254 if (c->c_state == S5_LOGGED_IN) { 255 if (mgmt->m_request == mgmt_logout) { 256 conn_state(c, T11); 257 queue_message_set(mgmt->m_q, 0, 258 msg_mgmt_rply, 0); 259 } else { 260 queue_message_set(c->c_sessq, 0, 261 msg_mgmt_rqst, m->msg_data); 262 } 263 } else { 264 /* 265 * Corner case which can occur when the 266 * connection has just started and is in the 267 * process of logging in and we get a 268 * mangement request. There's no session 269 * information or even a queue setup. Just 270 * show an empty connection. 271 * 272 * For the mgmt_logout, it's possible that 273 * we sent the T11 state change causing the 274 * connection to enter the S7 state. If we 275 * get a logout request again the specification 276 * says to just drop the connection. 277 */ 278 if (mgmt->m_request == mgmt_logout) 279 conn_state(c, T18); 280 else { 281 (void) pthread_mutex_lock( 282 &mgmt->m_resp_mutex); 283 tgt_buf_add(mgmt->m_u.m_resp, 284 "connection", NULL); 285 (void) pthread_mutex_unlock( 286 &mgmt->m_resp_mutex); 287 } 288 queue_message_set(mgmt->m_q, 0, 289 msg_mgmt_rply, 0); 290 } 291 m->msg_data = NULL; 292 break; 293 294 case msg_conn_lost: 295 queue_prt(c->c_mgmtq, Q_CONN_LOGIN, 296 "CON%x Shutdown: connection\n", c->c_num); 297 298 if (c->c_state == S5_LOGGED_IN) 299 conn_state(c, T8); 300 break; 301 302 case msg_shutdown_rsp: 303 if (c->c_state == S6_IN_LOGOUT) 304 conn_state(c, T13); 305 (void) pthread_join(c->c_thr_id_poller, &thr_status); 306 is_last = (Boolean_t)m->msg_data; 307 m->msg_data = NULL; 308 process = False; 309 break; 310 311 case msg_shutdown: 312 if (c->c_state == S5_LOGGED_IN) { 313 conn_state(c, T8); 314 } else if (c->c_state == S4_IN_LOGIN) { 315 conn_state(c, T7); 316 } else { 317 (void) pthread_join(c->c_thr_id_poller, 318 &thr_status); 319 process = False; 320 } 321 break; 322 323 case msg_targ_inventory_change: 324 if (c->c_state == S5_LOGGED_IN) { 325 send_async_scsi(c, KEY_UNIT_ATTENTION, 0x3f, 326 0x0e); 327 } 328 break; 329 330 case msg_send_pkt: 331 iscsi_conn_pkt(c, (iscsi_rsp_hdr_t *)m->msg_data); 332 break; 333 334 case msg_cmd_data_rqst: 335 /* 336 * The STE needs more data to complete 337 * the write command. 338 */ 339 if (!drop_t10_cmds) { 340 iscsi_conn_data_rqst((t10_cmd_t *)m->msg_data); 341 } 342 break; 343 344 case msg_cmd_data_in: 345 /* 346 * Data is available to satisfy the READ command 347 */ 348 if (!drop_t10_cmds) { 349 iscsi_conn_data_in((t10_cmd_t *)m->msg_data); 350 } 351 break; 352 353 case msg_cmd_cmplt: 354 /* 355 * Status is available for a previous STEOut. 356 * The status may be good and the previous STEOut data 357 * wasn't sent so we phase collapse. 358 */ 359 if (!drop_t10_cmds) { 360 iscsi_conn_cmdcmplt((t10_cmd_t *)m->msg_data); 361 } 362 break; 363 364 case msg_wait_for_destroy: { 365 t10_conn_shutdown_t *t_c_s; 366 367 /* 368 * Handshake through private queues with 369 * message sender. Acknowledge receipt of 370 * the msg which indicates the start of t10 371 * cmd destroy, wait for a reply indicating 372 * the completion of cmd destroy handling, 373 * ack that, then drop any subsequent t10 cmd 374 * messages as they've already been canceled 375 * and freed. 376 */ 377 t_c_s = (t10_conn_shutdown_t *)m->msg_data; 378 queue_message_set(t_c_s->conn_to_t10_q, 0, 1, 379 (void *)NULL); 380 queue_message_free(queue_message_get( 381 t_c_s->t10_to_conn_q)); 382 queue_message_set(t_c_s->conn_to_t10_q, 0, 1, 383 (void *)NULL); 384 drop_t10_cmds = True; 385 break; 386 } 387 388 default: 389 queue_prt(c->c_mgmtq, Q_CONN_ERRS, 390 "CON%x Didn't handle msg_type %d\n", c->c_num, 391 m->msg_type); 392 break; 393 } 394 395 queue_message_free(m); 396 } while (process == True); 397 398 /* 399 * Free any resources used. 400 */ 401 if (c->c_text_area) 402 free(c->c_text_area); 403 if (c->c_fd != -1) 404 (void) close(c->c_fd); 405 406 /* 407 * It's possible, but very unlikely that c_sessq is NULL at this 408 * point. I saw one case where the system had problems causing the 409 * poller routine to exit real early so that the session was never 410 * setup causing the daemon to get a SEGV in queue_free when a NULL 411 * was passed in. 412 */ 413 if ((is_last == True) && (c->c_sessq != NULL)) 414 queue_free(c->c_sessq, sess_queue_data_remove); 415 416 /* 417 * See if there are any commands outstanding and free them. 418 * NOTE: Should walk through the data_ptr list and find data structure 419 * who have alligence to this connection and free them as well. 420 */ 421 (void) pthread_mutex_lock(&c->c_mutex); 422 (void) pthread_mutex_lock(&c->c_state_mutex); 423 424 for (i = 0, cmd = c->c_cmd_head; cmd; i++) 425 cmd = cmd->c_next; /* debug count of lost ttt's */ 426 427 (void) snprintf(debug, sizeof (debug), "CON%x %d Lost TTTs: ", 428 c->c_num, i); 429 430 for (i = 0, cmd = c->c_cmd_head; cmd; i++) { 431 iscsi_cmd_t *n = cmd->c_next; 432 if (cmd->c_state != CmdCanceled) { 433 (void) snprintf(debug + strlen(debug), 434 sizeof (debug) - strlen(debug), 435 "0x%x ", cmd->c_ttt); 436 } 437 438 /* 439 * Make sure to free the resources that the T10 440 * layer still has allocated. These are commands which 441 * the T10 layer couldn't release directly during it's 442 * shutdown. 443 */ 444 if (cmd->c_t10_cmd) { 445 if (cmd->c_t10_dup) { 446 iscsi_cancel_dups(cmd, T10_Cmd_T8); 447 } else { 448 t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T8); 449 } 450 } 451 452 /* 453 * Perform the final clean up which is done during 454 * cmd_remove(). 455 */ 456 if (cmd->c_scb_extended) 457 free(cmd->c_scb_extended); 458 if (cmd->c_data_alloc == True) 459 free(cmd->c_data); 460 461 umem_cache_free(iscsi_cmd_cache, cmd); 462 cmd = n; 463 } 464 (void) pthread_mutex_unlock(&c->c_state_mutex); 465 (void) pthread_mutex_unlock(&c->c_mutex); 466 467 if (i) { 468 /* 469 * If there where lost commands found send a message indicating 470 * which ones. This message is purely for information 471 * and is not indicative of an error. 472 */ 473 queue_prt(c->c_mgmtq, Q_CONN_LOGIN, debug); 474 } 475 476 if (c->c_cmds_avg_cnt != 0) 477 queue_prt(c->c_mgmtq, Q_CONN_LOGIN, 478 "CON%x Average completion %lldms\n", c->c_num, 479 (c->c_cmds_avg_sum / c->c_cmds_avg_cnt) / (1000 * 1000)); 480 481 (void) sema_destroy(&c->c_datain); 482 if (c->c_targ_alias) 483 free(c->c_targ_alias); 484 485 util_title(c->c_mgmtq, Q_CONN_LOGIN, c->c_num, "End Receiver"); 486 487 queue_message_set(c->c_mgmtq, 0, msg_pthread_join, 488 (void *)(uintptr_t)pthread_self()); 489 /* 490 * Remove this connection from linked list of current connections. 491 * This will also free the connection queue. Must not hold the 492 * q here because port_conn_remove-->queue_free->conn_queue_data 493 * will possible grab the mutex. 494 */ 495 port_conn_remove(c); 496 free(c); 497 return (NULL); 498 } 499 500 /* 501 * []---- 502 * | iscsi_conn_pkt -- send out PDU from receive thread 503 * | 504 * | (1) This PDU could be either: 505 * | (a) A NOP request was sent from the initiator which the recieve 506 * | side processed and is requesting to be sent back. 507 * | (b) Nothing has been received in N seconds and we're looking 508 * | to see if the connection is still alive. 509 * | (c) A task management request was processed by the receive side 510 * | and the response must be sent. 511 * | (2) Fields to be filled in 512 * | Need to delay filling in several of the fields until 513 * | now to avoid using sequence number which would be out of 514 * | order. 515 * []---- 516 */ 517 static void 518 iscsi_conn_pkt(iscsi_conn_t *c, iscsi_rsp_hdr_t *in) 519 { 520 if (c->c_state != S5_LOGGED_IN) { 521 free(in); 522 return; 523 } 524 525 (void) pthread_mutex_lock(&c->c_mutex); 526 /* 527 * Make any final per command adjustments. 528 */ 529 switch (in->opcode & ISCSI_OPCODE_MASK) { 530 case ISCSI_OP_NOOP_IN: 531 in->statsn = htonl(c->c_statsn); 532 /* 533 * RFC 3720 section 10.19. specifies: 534 * - ITT is different from 0xffffffff in NOP-In when responding 535 * to incomming NOP-Out; and set to 0xffffffff otherwise 536 * - StatSN is not advanced for ITT set to 0xffffffff 537 */ 538 if (((iscsi_nop_in_hdr_t *)in)->itt != ISCSI_RSVD_TASK_TAG) 539 c->c_statsn++; 540 break; 541 } 542 (void) pthread_mutex_lock(&c->c_sess->s_mutex); 543 in->expcmdsn = htonl(c->c_sess->s_seencmdsn + 1); 544 in->maxcmdsn = htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn); 545 546 if (ISCSI_NOP_SEND_ENABLED() || ISCSI_TASK_RESPONSE_ENABLED()) { 547 uiscsiproto_t info; 548 549 info.uip_target_addr = &c->c_target_sockaddr; 550 info.uip_initiator_addr = &c->c_initiator_sockaddr; 551 552 info.uip_target = c->c_sess->s_t_name; 553 info.uip_initiator = c->c_sess->s_i_name; 554 info.uip_lun = 0; 555 556 info.uip_itt = in->itt; 557 info.uip_ttt = ISCSI_RSVD_TASK_TAG; 558 559 info.uip_cmdsn = ntohl(in->expcmdsn); 560 info.uip_statsn = ntohl(in->statsn); 561 info.uip_datasn = 0; 562 563 info.uip_datalen = ntoh24(in->dlength); 564 info.uip_flags = in->flags; 565 566 switch (in->opcode & ISCSI_OPCODE_MASK) { 567 case ISCSI_OP_NOOP_IN: 568 ISCSI_NOP_SEND(&info); 569 break; 570 case ISCSI_OP_SCSI_TASK_MGT_RSP: 571 ISCSI_TASK_RESPONSE(&info); 572 break; 573 default: 574 assert(0); 575 } 576 } 577 578 (void) pthread_mutex_unlock(&c->c_sess->s_mutex); 579 (void) pthread_mutex_unlock(&c->c_mutex); 580 581 send_iscsi_pkt(c, (iscsi_hdr_t *)in, 0); 582 free(in); 583 } 584 585 /* 586 * []---- 587 * | iscsi_conn_data_rqst -- request that data be sent from the initiator 588 * []---- 589 */ 590 static void 591 iscsi_conn_data_rqst(t10_cmd_t *t) 592 { 593 iscsi_cmd_t *cmd = T10_TRANS_ID(t); 594 iscsi_conn_t *c; 595 iscsi_rtt_hdr_t rtt; 596 597 bzero(&rtt, sizeof (rtt)); 598 599 c = cmd->c_allegiance; 600 (void) pthread_mutex_lock(&c->c_mutex); 601 (void) pthread_mutex_lock(&c->c_state_mutex); 602 if ((c->c_state != S5_LOGGED_IN) || 603 (cmd->c_state == CmdCanceled)) { 604 t10_cmd_shoot_event(t, T10_Cmd_T5); 605 (void) pthread_mutex_unlock(&c->c_state_mutex); 606 (void) pthread_mutex_unlock(&c->c_mutex); 607 return; 608 } 609 (void) pthread_mutex_unlock(&c->c_state_mutex); 610 611 /* 612 * Save the data pointer from the emulation code. It's their 613 * responsibility to allocate space for the data which the 614 * initiator will return. When we receive a DATAOUT packet 615 * we'll copy data from the socket directly to this buffer. 616 */ 617 cmd->c_data = T10_DATA(t); 618 619 /* 620 * RFC3270.10.8.3 621 * The statsn field will contain the next statsn. The statsn for this 622 * connection is not advanced after this PDU is sent. 623 */ 624 rtt.statsn = htonl(c->c_statsn); 625 626 rtt.opcode = ISCSI_OP_RTT_RSP; 627 rtt.flags = ISCSI_FLAG_FINAL; 628 rtt.itt = cmd->c_itt; 629 rtt.ttt = cmd->c_ttt; 630 rtt.data_offset = htonl(T10_DATA_OFFSET(t)); 631 rtt.data_length = htonl(MIN(T10_DATA_LEN(t), c->c_max_burst_len)); 632 rtt.rttsn = htonl(cmd->c_datasn++); 633 634 (void) pthread_mutex_lock(&c->c_sess->s_mutex); 635 rtt.maxcmdsn = htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn); 636 rtt.expcmdsn = htonl(c->c_sess->s_seencmdsn + 1); 637 (void) pthread_mutex_unlock(&c->c_sess->s_mutex); 638 639 #ifdef FULL_DEBUG 640 queue_prt(c->c_mgmtq, Q_CONN_IO, 641 "CON%x R2T TTT 0x%x offset 0x%x, len 0x%x\n", 642 c->c_num, cmd->c_ttt, T10_DATA_OFFSET(t), T10_DATA_LEN(t)); 643 #endif 644 645 t10_cmd_shoot_event(t, T10_Cmd_T7); 646 (void) pthread_mutex_unlock(&c->c_mutex); 647 648 if (ISCSI_DATA_REQUEST_ENABLED()) { 649 uiscsiproto_t info; 650 651 info.uip_target_addr = &c->c_target_sockaddr; 652 info.uip_initiator_addr = &c->c_initiator_sockaddr; 653 654 info.uip_target = c->c_sess->s_t_name; 655 info.uip_initiator = c->c_sess->s_i_name; 656 info.uip_lun = cmd->c_lun; 657 658 info.uip_itt = rtt.itt; 659 info.uip_ttt = rtt.ttt; 660 661 info.uip_cmdsn = ntohl(rtt.expcmdsn); 662 info.uip_statsn = c->c_statsn; 663 info.uip_datasn = 0; 664 665 info.uip_datalen = 0; 666 info.uip_flags = rtt.flags; 667 668 ISCSI_DATA_REQUEST(&info); 669 } 670 671 send_iscsi_pkt(c, (iscsi_hdr_t *)&rtt, 0); 672 } 673 674 /* 675 * []---- 676 * | iscsi_conn_data_in -- Send data to initiator 677 * []---- 678 */ 679 void 680 iscsi_conn_data_in(t10_cmd_t *t) 681 { 682 iscsi_cmd_t *cmd = (iscsi_cmd_t *)T10_TRANS_ID(t); 683 iscsi_conn_t *c; 684 685 c = cmd->c_allegiance; 686 (void) pthread_mutex_lock(&c->c_mutex); 687 (void) pthread_mutex_lock(&c->c_state_mutex); 688 if ((c->c_state != S5_LOGGED_IN) || 689 (cmd->c_state == CmdCanceled)) { 690 691 t10_cmd_shoot_event(t, T10_Cmd_T5); 692 while (cmd->c_t10_delayed) { 693 t10_cmd_shoot_event(cmd->c_t10_delayed->id_t10_cmd, 694 T10_Cmd_T5); 695 iscsi_cmd_delayed_remove(cmd, cmd->c_t10_delayed); 696 } 697 (void) pthread_mutex_unlock(&c->c_state_mutex); 698 (void) pthread_mutex_unlock(&c->c_mutex); 699 return; 700 } 701 (void) pthread_mutex_unlock(&c->c_state_mutex); 702 703 /* 704 * Need to deal with out of order data PDUs. RFC3720 allows 705 * the initiator to indicate if it can handle out-of-order 706 * PDUs. 707 */ 708 if ((c->c_data_pdu_in_order == True) && 709 (cmd->c_offset_in != T10_DATA_OFFSET(t))) { 710 iscsi_cmd_delayed_store(cmd, t); 711 (void) pthread_mutex_unlock(&c->c_mutex); 712 return; 713 } 714 715 while (t != NULL) { 716 cmd->c_offset_in += T10_DATA_LEN(t); 717 if (T10_CMD_LAST(t) == True) { 718 if (cmd->c_offset_in == cmd->c_dlen_expected) { 719 send_datain_pdu(c, t, 720 ISCSI_FLAG_FINAL | ISCSI_FLAG_DATA_STATUS); 721 } else { 722 /* 723 * Normally the target only sends a SCSI 724 * Response PDU for DataOut operations since 725 * the it indicates successful completion 726 * in the last DataIn PDU per the spec. 727 * There are cases where the initiator asks 728 * for more data then we send, for example 729 * an INQUIRY command usually returns less 730 * data then asked for. So, in this case we 731 * send the DataIn PDU with the appropriate 732 * amount, followed by a SCSI Response 733 * indicating the difference between what the 734 * initiator expected and we're sending. 735 */ 736 737 queue_prt(c->c_mgmtq, Q_CONN_ERRS, 738 "CON%x Underflow occurred\n", c->c_num); 739 send_datain_pdu(c, t, 0); 740 send_scsi_rsp(c, t); 741 } 742 iscsi_cmd_free(c, cmd); 743 } else { 744 send_datain_pdu(c, t, 0); 745 } 746 t10_cmd_shoot_event(t, T10_Cmd_T5); 747 748 if (cmd->c_t10_delayed && 749 (cmd->c_t10_delayed->id_offset == cmd->c_offset_in)) { 750 t = cmd->c_t10_delayed->id_t10_cmd; 751 iscsi_cmd_delayed_remove(cmd, cmd->c_t10_delayed); 752 } else { 753 t = NULL; 754 } 755 } 756 (void) pthread_mutex_unlock(&c->c_mutex); 757 } 758 759 /* 760 * []---- 761 * | iscsi_conn_cmdcmplt -- Send out appropriate completion PDU 762 * []---- 763 */ 764 static void 765 iscsi_conn_cmdcmplt(t10_cmd_t *t) 766 { 767 iscsi_cmd_t *cmd = (iscsi_cmd_t *)T10_TRANS_ID(t); 768 iscsi_conn_t *c; 769 770 c = cmd->c_allegiance; 771 (void) pthread_mutex_lock(&c->c_mutex); 772 (void) pthread_mutex_lock(&c->c_state_mutex); 773 if ((c->c_state != S5_LOGGED_IN) || 774 (cmd->c_state == CmdCanceled)) { 775 776 t10_cmd_shoot_event(t, T10_Cmd_T5); 777 (void) pthread_mutex_unlock(&c->c_state_mutex); 778 (void) pthread_mutex_unlock(&c->c_mutex); 779 return; 780 } 781 (void) pthread_mutex_unlock(&c->c_state_mutex); 782 783 if (T10_SENSE_LEN(t) || (T10_DATA(t) == 0)) { 784 785 /* 786 * If d_sense_len is set there's a problem and we need to send 787 * a SCSI response packet. Or if there's no data buffer then 788 * this is an acknowledgement that a SCSI Write completed 789 * successfully. 790 */ 791 send_scsi_rsp(c, t); 792 793 } else { 794 795 /* 796 * send data out with final bit. Last packet of a SCSI 797 * READ Op and we'll send it out with the final/status 798 * bits set. 799 */ 800 send_datain_pdu(c, t, 801 ISCSI_FLAG_FINAL | ISCSI_FLAG_DATA_STATUS); 802 803 } 804 805 t10_cmd_shoot_event(t, T10_Cmd_T5); 806 807 if (cmd->c_scb_extended != NULL) 808 free(cmd->c_scb_extended); 809 iscsi_cmd_free(c, cmd); 810 (void) pthread_mutex_unlock(&c->c_mutex); 811 } 812 813 /* 814 * []---- 815 * | send_datain_pdu -- Send DataIn PDU with READ data 816 * | 817 * | If this is the last read operation and it completed successfully 818 * | the final flag will be set along with the status bit which indicates 819 * | successful completion. This is known as a phase collapse for iSCSI. 820 * | 821 * | NOTE: connection mutex must be held. 822 * []---- 823 */ 824 static void 825 send_datain_pdu(iscsi_conn_t *c, t10_cmd_t *t, uint8_t final_flag) 826 { 827 iscsi_cmd_t *cmd = (iscsi_cmd_t *)T10_TRANS_ID(t); 828 iscsi_data_rsp_hdr_t rsp; 829 830 assert(pthread_mutex_trylock(&c->c_mutex) != 0); 831 bzero(&rsp, sizeof (rsp)); 832 833 rsp.opcode = ISCSI_OP_SCSI_DATA_RSP; 834 rsp.flags = final_flag; 835 rsp.cmd_status = cmd->c_status; 836 rsp.itt = cmd->c_itt; 837 rsp.ttt = ISCSI_RSVD_TASK_TAG; 838 rsp.datasn = htonl(cmd->c_datasn++); 839 rsp.offset = htonl(T10_DATA_OFFSET(t)); 840 rsp.lun[1] = (uint8_t)cmd->c_lun; 841 842 hton24(rsp.dlength, T10_DATA_LEN(t)); 843 844 /* 845 * The statsn is only incremented when the Status bit is set 846 * for a DataIn PDU. This must be done *after* the value 847 * was stored in the PDU. 848 */ 849 if (final_flag & ISCSI_FLAG_DATA_STATUS) { 850 rsp.statsn = htonl(c->c_statsn); 851 c->c_statsn++; 852 } else 853 rsp.statsn = 0; 854 855 (void) pthread_mutex_lock(&c->c_sess->s_mutex); 856 rsp.maxcmdsn = htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn); 857 rsp.expcmdsn = htonl(c->c_sess->s_seencmdsn + 1); 858 (void) pthread_mutex_unlock(&c->c_sess->s_mutex); 859 860 if (ISCSI_DATA_SEND_ENABLED()) { 861 uiscsiproto_t info; 862 863 info.uip_target_addr = &c->c_target_sockaddr; 864 info.uip_initiator_addr = &c->c_initiator_sockaddr; 865 866 info.uip_target = c->c_sess->s_t_name; 867 info.uip_initiator = c->c_sess->s_i_name; 868 info.uip_lun = cmd->c_lun; 869 870 info.uip_itt = rsp.itt; 871 info.uip_ttt = rsp.ttt; 872 873 info.uip_cmdsn = ntohl(rsp.expcmdsn); 874 info.uip_statsn = ntohl(rsp.statsn); 875 info.uip_datasn = ntohl(rsp.datasn); 876 877 info.uip_datalen = T10_DATA_LEN(t); 878 info.uip_flags = rsp.flags; 879 880 ISCSI_DATA_SEND(&info); 881 } 882 883 send_iscsi_pkt(c, (iscsi_hdr_t *)&rsp, T10_DATA(t)); 884 } 885 886 /* 887 * []---- 888 * | send_scsi_rsp -- Send SCSI reponse PDU 889 * | 890 * | NOTE: connection mutex must be held. 891 * []---- 892 */ 893 static void 894 send_scsi_rsp(iscsi_conn_t *c, t10_cmd_t *t) 895 { 896 iscsi_cmd_t *cmd = (iscsi_cmd_t *)T10_TRANS_ID(t); 897 iscsi_scsi_rsp_hdr_t rsp; 898 void *auto_sense = NULL; 899 900 assert(pthread_mutex_trylock(&c->c_mutex) != 0); 901 bzero(&rsp, sizeof (rsp)); 902 903 rsp.opcode = ISCSI_OP_SCSI_RSP; 904 rsp.flags = ISCSI_FLAG_FINAL; 905 rsp.itt = cmd->c_itt; 906 rsp.statsn = htonl(c->c_statsn++); 907 (void) pthread_mutex_lock(&c->c_sess->s_mutex); 908 rsp.expcmdsn = htonl(c->c_sess->s_seencmdsn + 1); 909 rsp.maxcmdsn = htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn); 910 (void) pthread_mutex_unlock(&c->c_sess->s_mutex); 911 rsp.cmd_status = T10_CMD_STATUS(t); 912 913 if (cmd->c_writeop == True) { 914 if (cmd->c_offset_out != cmd->c_dlen_expected) 915 rsp.flags |= ISCSI_FLAG_CMD_OVERFLOW; 916 rsp.residual_count = htonl(cmd->c_dlen_expected - 917 cmd->c_offset_out); 918 } else { 919 if (cmd->c_offset_in != cmd->c_dlen_expected) 920 rsp.flags |= ISCSI_FLAG_CMD_UNDERFLOW; 921 rsp.residual_count = htonl(cmd->c_dlen_expected - 922 cmd->c_offset_in); 923 } 924 925 if (rsp.cmd_status) { 926 rsp.response = ISCSI_STATUS_CMD_COMPLETED; 927 rsp.residual_count = htonl(T10_CMD_RESID(t)); 928 929 if (T10_SENSE_LEN(t) != 0) { 930 /* 931 * Need to handle autosense stuff. The data should 932 * be store in the d_sense area 933 */ 934 auto_sense = (void *)T10_SENSE_DATA(t); 935 hton24(rsp.dlength, T10_SENSE_LEN(t)); 936 } 937 queue_prt(c->c_mgmtq, Q_CONN_ERRS, 938 "CON%x SCSI Error Status: %d\n", 939 c->c_num, rsp.cmd_status); 940 } else { 941 rsp.response = ISCSI_STATUS_CMD_COMPLETED; 942 rsp.expdatasn = htonl(cmd->c_datasn); 943 } 944 945 if (ISCSI_SCSI_RESPONSE_ENABLED()) { 946 uiscsiproto_t info; 947 948 info.uip_target_addr = &c->c_target_sockaddr; 949 info.uip_initiator_addr = &c->c_initiator_sockaddr; 950 951 info.uip_target = c->c_sess->s_t_name; 952 info.uip_initiator = c->c_sess->s_i_name; 953 info.uip_lun = cmd->c_lun; 954 955 info.uip_itt = rsp.itt; 956 info.uip_ttt = ISCSI_RSVD_TASK_TAG; 957 958 info.uip_cmdsn = ntohl(rsp.expcmdsn); 959 info.uip_statsn = ntohl(rsp.statsn); 960 info.uip_datasn = ntohl(rsp.expdatasn); 961 962 info.uip_datalen = T10_DATA_LEN(t); 963 info.uip_flags = rsp.flags; 964 965 ISCSI_SCSI_RESPONSE(&info); 966 } 967 968 send_iscsi_pkt(c, (iscsi_hdr_t *)&rsp, auto_sense); 969 } 970 971 static void 972 send_async_scsi(iscsi_conn_t *c, int key, int asc, int ascq) 973 { 974 iscsi_async_evt_hdr_t a; 975 struct scsi_extended_sense s; 976 char *buf; 977 int dlen = sizeof (s) + 2; 978 979 bzero(&a, sizeof (a)); 980 bzero(&s, sizeof (s)); 981 982 s.es_class = CLASS_EXTENDED_SENSE; 983 s.es_code = CODE_FMT_FIXED_CURRENT; 984 s.es_key = key; 985 s.es_valid = 1; 986 s.es_add_code = asc; 987 s.es_qual_code = ascq; 988 989 if ((buf = malloc(sizeof (s) + 2)) == NULL) 990 return; 991 992 buf[0] = (sizeof (s) >> 8) & 0xff; 993 buf[1] = sizeof (s) & 0xff; 994 bcopy(&s, &buf[2], sizeof (s)); 995 996 hton24(a.dlength, dlen); 997 a.opcode = ISCSI_OP_ASYNC_EVENT; 998 a.flags = ISCSI_FLAG_FINAL; 999 a.async_event = ISCSI_ASYNC_EVENT_SCSI_EVENT; 1000 (void) pthread_mutex_lock(&c->c_mutex); 1001 a.statsn = htonl(c->c_statsn++); 1002 (void) pthread_mutex_lock(&c->c_sess->s_mutex); 1003 a.expcmdsn = htonl(c->c_sess->s_seencmdsn + 1); 1004 a.maxcmdsn = htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn); 1005 (void) pthread_mutex_unlock(&c->c_sess->s_mutex); 1006 (void) pthread_mutex_unlock(&c->c_mutex); 1007 1008 queue_prt(c->c_mgmtq, Q_CONN_NONIO, 1009 "CON%x Sending async scsi sense\n", c->c_num); 1010 1011 if (ISCSI_ASYNC_SEND_ENABLED()) { 1012 uiscsiproto_t info; 1013 1014 info.uip_target_addr = &c->c_target_sockaddr; 1015 info.uip_initiator_addr = &c->c_initiator_sockaddr; 1016 1017 info.uip_target = c->c_sess->s_t_name; 1018 info.uip_initiator = c->c_sess->s_i_name; 1019 info.uip_lun = 0; 1020 1021 info.uip_itt = ISCSI_RSVD_TASK_TAG; 1022 info.uip_ttt = ISCSI_RSVD_TASK_TAG; 1023 1024 info.uip_cmdsn = ntohl(a.expcmdsn); 1025 info.uip_statsn = ntohl(a.statsn); 1026 info.uip_datasn = 0; 1027 1028 info.uip_datalen = dlen; 1029 info.uip_flags = a.flags; 1030 1031 ISCSI_ASYNC_SEND(&info); 1032 } 1033 1034 send_iscsi_pkt(c, (iscsi_hdr_t *)&a, buf); 1035 } 1036 1037 /* 1038 * []---- 1039 * | send_async_logout -- request logout from initiator 1040 * []---- 1041 */ 1042 static void 1043 send_async_logout(iscsi_conn_t *c) 1044 { 1045 iscsi_async_evt_hdr_t a; 1046 1047 bzero(&a, sizeof (a)); 1048 1049 a.opcode = ISCSI_OP_ASYNC_EVENT; 1050 a.flags = ISCSI_FLAG_FINAL; 1051 a.async_event = ISCSI_ASYNC_EVENT_REQUEST_LOGOUT; 1052 (void) pthread_mutex_lock(&c->c_mutex); 1053 a.statsn = htonl(c->c_statsn++); 1054 (void) pthread_mutex_lock(&c->c_sess->s_mutex); 1055 a.expcmdsn = htonl(c->c_sess->s_seencmdsn + 1); 1056 a.maxcmdsn = htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn); 1057 a.param3 = htons(ASYNC_LOGOUT_TIMEOUT); 1058 a.rsvd4[0] = 0xff; 1059 a.rsvd4[1] = 0xff; /* According to the spec these four */ 1060 a.rsvd4[2] = 0xff; /* values must be 0xff */ 1061 a.rsvd4[3] = 0xff; 1062 (void) pthread_mutex_unlock(&c->c_sess->s_mutex); 1063 (void) pthread_mutex_unlock(&c->c_mutex); 1064 1065 queue_prt(c->c_mgmtq, Q_CONN_NONIO, 1066 "CON%x Sending async logout request\n", c->c_num); 1067 1068 if (ISCSI_ASYNC_SEND_ENABLED()) { 1069 uiscsiproto_t info; 1070 1071 info.uip_target_addr = &c->c_target_sockaddr; 1072 info.uip_initiator_addr = &c->c_initiator_sockaddr; 1073 1074 info.uip_target = c->c_sess->s_t_name; 1075 info.uip_initiator = c->c_sess->s_i_name; 1076 info.uip_lun = 0; 1077 1078 info.uip_itt = ISCSI_RSVD_TASK_TAG; 1079 info.uip_ttt = ISCSI_RSVD_TASK_TAG; 1080 1081 info.uip_cmdsn = ntohl(a.expcmdsn); 1082 info.uip_statsn = ntohl(a.statsn); 1083 info.uip_datasn = 0; 1084 1085 info.uip_datalen = 0; 1086 info.uip_flags = a.flags; 1087 1088 ISCSI_ASYNC_SEND(&info); 1089 } 1090 1091 send_iscsi_pkt(c, (iscsi_hdr_t *)&a, 0); 1092 } 1093 1094 /* 1095 * []---- 1096 * | queue_noop_in -- generate a NOP request and queue it to be sent. 1097 * []---- 1098 */ 1099 static void 1100 queue_noop_in(iscsi_conn_t *c) 1101 { 1102 iscsi_nop_in_hdr_t *in; 1103 iscsi_cmd_t *cmd = iscsi_cmd_alloc(c, ISCSI_OP_NOOP_IN); 1104 1105 if (cmd == NULL) 1106 return; 1107 1108 in = (iscsi_nop_in_hdr_t *)calloc(sizeof (*in), 1); 1109 if (in == NULL) 1110 return; 1111 1112 /* 1113 * Immediate flag is reserved in nop-in command. RFC-3720 10.19. 1114 * See CR 6597310. 1115 */ 1116 in->opcode = ISCSI_OP_NOOP_IN; 1117 in->flags = ISCSI_FLAG_FINAL; 1118 in->ttt = cmd->c_ttt; 1119 in->itt = ISCSI_RSVD_TASK_TAG; 1120 1121 (void) pthread_mutex_lock(&c->c_mutex); 1122 iscsi_cmd_free(c, cmd); 1123 (void) pthread_mutex_unlock(&c->c_mutex); 1124 queue_message_set(c->c_dataq, 0, msg_send_pkt, (void *)in); 1125 } 1126 1127 void 1128 iscsi_capacity_change(char *targ_name, int lun) 1129 { 1130 iscsi_conn_t *conn; 1131 extern pthread_mutex_t port_mutex; 1132 1133 /* 1134 * SBC-2 revision 16, section 4.6 -- Initialization 1135 * Any time the parameter data returned by the READ CAPACITY(10) 1136 * (see 5.10) or the READ CAPACITY(16) command (see 5.11) changes, 1137 * the device server should establish a unit attention condition for 1138 * the initiator port associated with each I_T nexus. 1139 * Since the transport knows which initiators are currently accessing 1140 * the target the message will be sent from here. 1141 */ 1142 (void) pthread_mutex_lock(&port_mutex); 1143 for (conn = conn_head; conn; conn = conn->c_next) { 1144 (void) pthread_mutex_lock(&conn->c_state_mutex); 1145 if ((conn->c_state == S5_LOGGED_IN) && 1146 (conn->c_sess->s_type == SessionNormal) && 1147 (strcmp(conn->c_sess->s_t_name, targ_name) == 0)) { 1148 1149 queue_message_set(conn->c_sessq, 0, 1150 msg_lu_capacity_change, (void *)(uintptr_t)lun); 1151 } 1152 (void) pthread_mutex_unlock(&conn->c_state_mutex); 1153 } 1154 (void) pthread_mutex_unlock(&port_mutex); 1155 } 1156 1157 /* 1158 * []---- 1159 * | iscsi_inventory_change -- Send notice to initiator that something changed. 1160 * []---- 1161 */ 1162 void 1163 iscsi_inventory_change(char *targ_name) 1164 { 1165 iscsi_conn_t *c; 1166 extern pthread_mutex_t port_mutex; 1167 1168 /* 1169 * SPC-3 revision 21c, Section 6.21 REPORT_LUNS 1170 * If the logical unit inventory changes for any reason 1171 * (e.g. completion of initialization, removal of a logical unit, 1172 * or create of a logical unit), then the device server shall generate 1173 * a unit attention condition for all I_T nexuses, with the additional 1174 * sense code set to REPORTED LUNS DATA HAS CHANGED. 1175 */ 1176 (void) pthread_mutex_lock(&port_mutex); 1177 for (c = conn_head; c; c = c->c_next) { 1178 (void) pthread_mutex_lock(&c->c_state_mutex); 1179 if ((c->c_state == S5_LOGGED_IN) && 1180 (c->c_sess->s_type == SessionNormal) && 1181 (strcmp(c->c_sess->s_t_name, targ_name) == 0)) { 1182 1183 queue_prt(c->c_mgmtq, Q_CONN_NONIO, 1184 "CON%x Sending Inventory change out\n", c->c_num); 1185 /* 1186 * Send a message indicating that the logical unit 1187 * inventory has changed. 1) This message is sent 1188 * to the session level which will pass it onto 1189 * the SAM layer causing a UNIT_ATTENTION during 1190 * the next command. 2) This message is also sent 1191 * directly to the outgoing side of the connection 1192 * which will send an asynchronous event message 1193 * to the initiator. 1194 */ 1195 queue_message_set(c->c_sessq, 0, 1196 msg_targ_inventory_change, 0); 1197 queue_message_set(c->c_dataq, 0, 1198 msg_targ_inventory_change, 0); 1199 } 1200 (void) pthread_mutex_unlock(&c->c_state_mutex); 1201 } 1202 (void) pthread_mutex_unlock(&port_mutex); 1203 } 1204 1205 /* 1206 * []---- 1207 * | state_to_str -- return string for given state, used for debug 1208 * []---- 1209 */ 1210 static char * 1211 state_to_str(iscsi_state_t s) 1212 { 1213 switch (s) { 1214 case S1_FREE: return ("FREE"); 1215 case S3_XPT_UP: return ("XPT_UP"); 1216 case S4_IN_LOGIN: return ("IN_LOGIN"); 1217 case S5_LOGGED_IN: return ("LOGGED_IN"); 1218 case S6_IN_LOGOUT: return ("IN_LOGOUT"); 1219 case S7_LOGOUT_REQUESTED: return ("LOGOUT_REQUEST"); 1220 case S8_CLEANUP_WAIT: return ("CLEANUP_WAIT"); 1221 } 1222 return ("Unknown"); 1223 } 1224 1225 /* 1226 * []---- 1227 * | event_to_str -- return string for given event, used for debug 1228 * []---- 1229 */ 1230 static char * 1231 event_to_str(iscsi_transition_t t) 1232 { 1233 switch (t) { 1234 case T3: return ("T3"); 1235 case T4: return ("T4"); 1236 case T5: return ("T5"); 1237 case T6: return ("T6"); 1238 case T7: return ("T7"); 1239 case T8: return ("T8"); 1240 case T9: return ("T9"); 1241 case T10: return ("T10"); 1242 case T11: return ("T11"); 1243 case T12: return ("T12"); 1244 case T13: return ("T13"); 1245 case T15: return ("T15"); 1246 case T16: return ("T16"); 1247 case T17: return ("T17"); 1248 case T18: return ("T18"); 1249 } 1250 return ("Unknown"); 1251 } 1252 1253 /* 1254 * []---- 1255 * | conn_state -- Attempt to change from one state to the next 1256 * []---- 1257 */ 1258 void 1259 conn_state(iscsi_conn_t *c, iscsi_transition_t t) 1260 { 1261 iscsi_state_t old_state = c->c_state; 1262 Boolean_t lock = False; 1263 1264 (void) pthread_mutex_lock(&c->c_state_mutex); 1265 lock = True; 1266 1267 switch (c->c_state) { 1268 case S1_FREE: 1269 switch (t) { 1270 case T3: 1271 c->c_state = S3_XPT_UP; 1272 break; 1273 1274 } 1275 break; 1276 1277 case S3_XPT_UP: 1278 switch (t) { 1279 case T6: 1280 c->c_state = S1_FREE; 1281 break; 1282 1283 case T4: 1284 c->c_statsn = 0; 1285 c->c_state = S4_IN_LOGIN; 1286 break; 1287 1288 } 1289 break; 1290 1291 case S4_IN_LOGIN: 1292 switch (t) { 1293 case T7: 1294 /* 1295 * When there's a session a shutdown messages is 1296 * sent giving the opportunity to free resources 1297 * used by the session code and STE. Very early 1298 * on a session might not exist when a failure 1299 * occurs like getting a bad opcode. The connection 1300 * process routine is going to sit around waiting 1301 * for a message which will never come so fake 1302 * a completion message here if there's no session. 1303 */ 1304 if (c->c_sessq == NULL) { 1305 queue_message_set(c->c_dataq, 0, 1306 msg_shutdown_rsp, (void *)True); 1307 } else { 1308 queue_message_set(c->c_sessq, 0, msg_shutdown, 1309 (void *)c); 1310 } 1311 c->c_state = S1_FREE; 1312 break; 1313 case T5: 1314 c->c_state = S5_LOGGED_IN; 1315 if (strncmp(c->c_sess->s_i_name, 1316 "iqn.1991-05.com.microsoft", 1317 strlen("iqn.1991-05.com.microsoft")) == 0) 1318 c->c_sess->s_cmdsn++; 1319 break; 1320 } 1321 break; 1322 1323 case S5_LOGGED_IN: 1324 switch (t) { 1325 case T8: 1326 c->c_state = S1_FREE; 1327 queue_message_set(c->c_sessq, 0, msg_shutdown, 1328 (void *)c); 1329 break; 1330 case T9: 1331 queue_message_set(c->c_sessq, 0, msg_shutdown, 1332 (void *)c); 1333 c->c_state = S6_IN_LOGOUT; 1334 break; 1335 case T11: 1336 c->c_state = S7_LOGOUT_REQUESTED; 1337 /* 1338 * need to unlock here conn_state may get 1339 * call again, which can create deadlock 1340 */ 1341 (void) pthread_mutex_unlock(&c->c_state_mutex); 1342 lock = False; 1343 send_async_logout(c); 1344 break; 1345 case T15: 1346 c->c_state = S8_CLEANUP_WAIT; 1347 break; 1348 } 1349 break; 1350 1351 case S6_IN_LOGOUT: 1352 switch (t) { 1353 case T13: 1354 if (c->c_last_pkg) { 1355 iscsi_logout_rsp_hdr_t *rsp = 1356 (iscsi_logout_rsp_hdr_t *)c->c_last_pkg; 1357 assert(rsp->opcode == ISCSI_OP_LOGOUT_RSP); 1358 1359 if (ISCSI_LOGOUT_RESPONSE_ENABLED()) { 1360 uiscsiproto_t info; 1361 char nil = '\0'; 1362 1363 info.uip_target_addr = 1364 &c->c_target_sockaddr; 1365 info.uip_initiator_addr = 1366 &c->c_initiator_sockaddr; 1367 info.uip_target = &nil; 1368 1369 info.uip_initiator = 1370 c->c_sess->s_i_name; 1371 info.uip_lun = 0; 1372 1373 info.uip_itt = rsp->itt; 1374 info.uip_ttt = ISCSI_RSVD_TASK_TAG; 1375 1376 info.uip_cmdsn = ntohl(rsp->expcmdsn); 1377 info.uip_statsn = ntohl(rsp->statsn); 1378 info.uip_datasn = 0; 1379 1380 info.uip_datalen = ntoh24(rsp->dlength); 1381 info.uip_flags = rsp->flags; 1382 1383 ISCSI_LOGOUT_RESPONSE(&info); 1384 } 1385 1386 /* 1387 * need to unlock here conn_state may get 1388 * call again, which can create deadlock 1389 */ 1390 (void) pthread_mutex_unlock(&c->c_state_mutex); 1391 lock = False; 1392 send_iscsi_pkt(c, c->c_last_pkg, NULL); 1393 free(c->c_last_pkg); 1394 } 1395 c->c_state = S1_FREE; 1396 break; 1397 case T17: 1398 c->c_state = S8_CLEANUP_WAIT; 1399 break; 1400 } 1401 break; 1402 1403 case S7_LOGOUT_REQUESTED: 1404 switch (t) { 1405 case T18: 1406 c->c_state = S1_FREE; 1407 queue_message_set(c->c_sessq, 0, msg_shutdown, 1408 (void *)c); 1409 break; 1410 case T10: 1411 queue_message_set(c->c_sessq, 0, msg_shutdown, 1412 (void *)c); 1413 c->c_state = S6_IN_LOGOUT; 1414 break; 1415 case T12: 1416 c->c_state = S7_LOGOUT_REQUESTED; 1417 break; 1418 case T16: 1419 c->c_state = S8_CLEANUP_WAIT; 1420 break; 1421 } 1422 break; 1423 1424 case S8_CLEANUP_WAIT: 1425 default: 1426 break; 1427 } 1428 queue_prt(c->c_mgmtq, Q_CONN_NONIO, "CON%x ---- %s(%s) -> %s\n", 1429 c->c_num, state_to_str(old_state), event_to_str(t), 1430 state_to_str(c->c_state)); 1431 if (lock) 1432 (void) pthread_mutex_unlock(&c->c_state_mutex); 1433 } 1434 1435 /* 1436 * []---- 1437 * | send_iscsi_pkt -- output PDU header, data, and alignment bytes if needed 1438 * | 1439 * | NOTE: This routine may be called with the connection mutex held. This 1440 * | is done to prevent a state change being made to a command pointer. This 1441 * | routine is currently written so that it doesn't need to have this mutex 1442 * | held or calls a routine which needs it to be held. 1443 * []---- 1444 */ 1445 void 1446 send_iscsi_pkt(iscsi_conn_t *c, iscsi_hdr_t *h, char *opt_text) 1447 { 1448 int dlen = ntoh24(h->dlength); 1449 int pad_len; 1450 uint32_t crc; 1451 1452 #ifdef ETHEREAL_DEBUG 1453 uint32_t alen; 1454 char *abuf; 1455 1456 /* 1457 * For ethereal to correctly show the entire PDU and data everything 1458 * must be written once else the Solaris TCP stack will send this 1459 * out in multiple packets. Normally this isn't a problem, but when 1460 * attempting to debug certain interactions between an initiator 1461 * and this target is extremely benefical to have ethereal correctly 1462 * decode the SCSI payload for non I/O type packets. 1463 */ 1464 if (dlen < 512) { 1465 /* 1466 * Find out how many pad bytes we need to send out. 1467 */ 1468 pad_len = (ISCSI_PAD_WORD_LEN - 1469 (dlen & (ISCSI_PAD_WORD_LEN - 1))) & 1470 (ISCSI_PAD_WORD_LEN - 1); 1471 alen = sizeof (*h) + dlen + pad_len; 1472 if ((abuf = malloc(alen)) == NULL) { 1473 conn_state(c, T8); 1474 return; 1475 } 1476 bzero(abuf, alen); 1477 bcopy(h, abuf, sizeof (*h)); 1478 if (opt_text) 1479 bcopy(opt_text, abuf + sizeof (*h), dlen); 1480 if (write(c->c_fd, abuf, alen) != alen) { 1481 conn_state(c, T8); 1482 free(abuf); 1483 return; 1484 } 1485 free(abuf); 1486 #ifdef FULL_DEBUG 1487 queue_prt(c->c_mgmtq, Q_CONN_IO, 1488 "CON%x Response(0x%x), Data: len=0x%x addr=0x%llx\n", 1489 c->c_num, h->opcode, dlen, opt_text); 1490 #endif 1491 return; 1492 } 1493 #endif 1494 1495 /* 1496 * Sanity check. If there's a length in the header we must 1497 * have text to send or if the length is zero there better not 1498 * be any text. 1499 */ 1500 if (((dlen == 0) && (opt_text != NULL)) || 1501 ((dlen != 0) && (opt_text == NULL))) 1502 return; 1503 1504 if (write(c->c_fd, h, sizeof (*h)) < 0) { 1505 if (errno == EPIPE) { 1506 1507 /* 1508 * For some reason the initiator has closed the 1509 * socket on us. This is most likely caused because 1510 * of some network related condition 1511 * (e.g. broken cable). We'll shutdown our side and 1512 * wait for a reconnect from the initiator. 1513 */ 1514 queue_prt(c->c_mgmtq, Q_CONN_ERRS, 1515 "CON%x iscsi_pkt -- initiator closed socket\n", 1516 c->c_num); 1517 } else { 1518 1519 /* 1520 * This is not good. 1521 */ 1522 queue_prt(c->c_mgmtq, Q_CONN_ERRS, 1523 "CON%x iscsi_pkt write failed, errno %d\n", 1524 c->c_num, errno); 1525 } 1526 conn_state(c, T8); 1527 return; 1528 } 1529 1530 /* 1531 * Only start generating digest values once we've completed the 1532 * login phase. If the state is not checked here and during login 1533 * header or data digests have been enabled we would generate 1534 * a digest value during the Login RSP PDU which the initiator 1535 * is not expecting. 1536 */ 1537 if ((c->c_state == S5_LOGGED_IN) && (c->c_header_digest == True)) { 1538 crc = iscsi_crc32c((void *)h, sizeof (*h)); 1539 if (write(c->c_fd, &crc, sizeof (crc)) != sizeof (crc)) { 1540 conn_state(c, T8); 1541 return; 1542 } 1543 } 1544 1545 if (dlen) { 1546 if (write(c->c_fd, opt_text, dlen) != dlen) { 1547 conn_state(c, T8); 1548 return; 1549 } 1550 1551 /* 1552 * Find out how many pad bytes we need to send out. 1553 */ 1554 pad_len = (ISCSI_PAD_WORD_LEN - 1555 (dlen & (ISCSI_PAD_WORD_LEN - 1))) & 1556 (ISCSI_PAD_WORD_LEN - 1); 1557 if (pad_len) { 1558 if (write(c->c_fd, pad_text, pad_len) != pad_len) { 1559 conn_state(c, T8); 1560 return; 1561 } 1562 } 1563 1564 if ((c->c_state == S5_LOGGED_IN) && 1565 (c->c_data_digest == True)) { 1566 1567 crc = iscsi_crc32c((void *)opt_text, 1568 (unsigned long)dlen); 1569 1570 /* 1571 * Include the pad information in the calculation of 1572 * the CRC for the data. 1573 */ 1574 crc = iscsi_crc32c_continued((void *)pad_text, 1575 (unsigned long)pad_len, crc); 1576 1577 if (write(c->c_fd, &crc, sizeof (crc)) != 1578 sizeof (crc)) { 1579 conn_state(c, T8); 1580 return; 1581 } 1582 } 1583 } 1584 #ifdef FULL_DEBUG 1585 if (dlen != 0) { 1586 queue_prt(c->c_mgmtq, Q_CONN_IO, 1587 "CON%x Response(0x%x), Data: len=0x%x addr=0x%llx\n", 1588 c->c_num, h->opcode, dlen, opt_text); 1589 } 1590 #endif 1591 } 1592