1 /* $NetBSD: iscsi_ioctl.c,v 1.13 2015/09/19 18:32:42 dholland Exp $ */ 2 3 /*- 4 * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "iscsi_globals.h" 33 34 #include <sys/file.h> 35 #include <sys/filedesc.h> 36 #include <sys/proc.h> 37 38 #ifndef ISCSI_MINIMAL 39 #include <uvm/uvm.h> 40 #include <uvm/uvm_pmap.h> 41 #endif 42 43 static uint16_t current_id = 0; /* Global session ID counter */ 44 45 /* list of event handlers */ 46 static event_handler_list_t event_handlers = 47 TAILQ_HEAD_INITIALIZER(event_handlers); 48 49 static uint32_t handler_id = 0; /* Handler ID counter */ 50 51 /* -------------------------------------------------------------------------- */ 52 53 /* Event management functions */ 54 55 /* 56 * find_handler: 57 * Search the event handler list for the given ID. 58 * 59 * Parameter: 60 * id The handler ID. 61 * 62 * Returns: 63 * Pointer to handler if found, else NULL. 64 */ 65 66 67 STATIC event_handler_t * 68 find_handler(uint32_t id) 69 { 70 event_handler_t *curr; 71 72 TAILQ_FOREACH(curr, &event_handlers, link) 73 if (curr->id == id) 74 break; 75 76 return curr; 77 } 78 79 80 /* 81 * register_event: 82 * Create event handler entry, return ID. 83 * 84 * Parameter: 85 * par The parameter. 86 */ 87 88 STATIC void 89 register_event(iscsi_register_event_parameters_t *par) 90 { 91 event_handler_t *handler; 92 int was_empty; 93 int s; 94 95 handler = malloc(sizeof(event_handler_t), M_DEVBUF, M_WAITOK | M_ZERO); 96 if (handler == NULL) { 97 DEBOUT(("No mem for event handler\n")); 98 par->status = ISCSI_STATUS_NO_RESOURCES; 99 return; 100 } 101 102 TAILQ_INIT(&handler->events); 103 104 /* create a unique ID */ 105 s = splbio(); 106 do { 107 ++handler_id; 108 } while (!handler_id || find_handler(handler_id) != NULL); 109 par->event_id = handler->id = handler_id; 110 111 was_empty = TAILQ_FIRST(&event_handlers) == NULL; 112 113 TAILQ_INSERT_TAIL(&event_handlers, handler, link); 114 115 if (was_empty) { 116 wakeup(&iscsi_cleanupc_list); 117 } 118 splx(s); 119 120 par->status = ISCSI_STATUS_SUCCESS; 121 DEB(5, ("Register Event OK, ID %d\n", par->event_id)); 122 } 123 124 125 /* 126 * deregister_event: 127 * Destroy handler entry and any waiting events, wake up waiter. 128 * 129 * Parameter: 130 * par The parameter. 131 */ 132 133 STATIC void 134 deregister_event(iscsi_register_event_parameters_t *par) 135 { 136 event_handler_t *handler; 137 event_t *evt; 138 int s; 139 140 handler = find_handler(par->event_id); 141 if (handler == NULL) { 142 DEB(1, ("Deregister Event ID %d not found\n", par->event_id)); 143 par->status = ISCSI_STATUS_INVALID_EVENT_ID; 144 return; 145 } 146 147 s = splbio(); 148 TAILQ_REMOVE(&event_handlers, handler, link); 149 splx(s); 150 151 if (handler->waiter != NULL) { 152 handler->waiter->status = ISCSI_STATUS_EVENT_DEREGISTERED; 153 wakeup(handler->waiter); 154 } 155 156 while ((evt = TAILQ_FIRST(&handler->events)) != NULL) { 157 TAILQ_REMOVE(&handler->events, evt, link); 158 free(evt, M_TEMP); 159 } 160 161 free(handler, M_DEVBUF); 162 par->status = ISCSI_STATUS_SUCCESS; 163 DEB(5, ("Deregister Event ID %d complete\n", par->event_id)); 164 } 165 166 167 /* 168 * check_event: 169 * Return first queued event. Optionally wait for arrival of event. 170 * 171 * Parameter: 172 * par The parameter. 173 * wait Wait for event if true 174 */ 175 176 STATIC void 177 check_event(iscsi_wait_event_parameters_t *par, bool wait) 178 { 179 event_handler_t *handler; 180 event_t *evt; 181 182 handler = find_handler(par->event_id); 183 if (handler == NULL) { 184 DEBOUT(("Wait Event ID %d not found\n", par->event_id)); 185 par->status = ISCSI_STATUS_INVALID_EVENT_ID; 186 return; 187 } 188 if (handler->waiter != NULL) { 189 DEBOUT(("Wait Event ID %d already waiting\n", par->event_id)); 190 par->status = ISCSI_STATUS_EVENT_WAITING; 191 return; 192 } 193 par->status = ISCSI_STATUS_SUCCESS; 194 DEB(99, ("Wait Event ID %d\n", par->event_id)); 195 196 do { 197 int s = splbio(); 198 evt = TAILQ_FIRST(&handler->events); 199 if (evt != NULL) { 200 TAILQ_REMOVE(&handler->events, evt, link); 201 splx(s); 202 } else { 203 if (!wait) { 204 splx(s); 205 par->status = ISCSI_STATUS_LIST_EMPTY; 206 return; 207 } 208 if (par->status != ISCSI_STATUS_SUCCESS) { 209 splx(s); 210 return; 211 } 212 handler->waiter = par; 213 splx(s); 214 if (tsleep(par, PRIBIO | PCATCH, "iscsievtwait", 0)) 215 return; 216 } 217 } while (evt == NULL); 218 219 par->connection_id = evt->connection_id; 220 par->session_id = evt->session_id; 221 par->event_kind = evt->event_kind; 222 par->reason = evt->reason; 223 224 free(evt, M_TEMP); 225 } 226 227 /* 228 * add_event 229 * Adds an event entry to each registered handler queue. 230 * Note that events are simply duplicated because we expect the number of 231 * handlers to be very small, usually 1 (the daemon). 232 * 233 * Parameters: 234 * kind The event kind 235 * sid The ID of the affected session 236 * cid The ID of the affected connection 237 * reason The reason code 238 */ 239 240 void 241 add_event(iscsi_event_t kind, uint32_t sid, uint32_t cid, uint32_t reason) 242 { 243 event_handler_t *curr; 244 event_t *evt; 245 int s; 246 247 DEB(9, ("Add_event kind %d, sid %d, cid %d, reason %d\n", 248 kind, sid, cid, reason)); 249 250 s = splbio(); 251 TAILQ_FOREACH(curr, &event_handlers, link) { 252 evt = malloc(sizeof(*evt), M_TEMP, M_WAITOK); 253 if (evt == NULL) { 254 panic("iSCSI: add_event failed to alloc memory"); 255 } 256 evt->event_kind = kind; 257 evt->session_id = sid; 258 evt->connection_id = cid; 259 evt->reason = reason; 260 261 TAILQ_INSERT_TAIL(&curr->events, evt, link); 262 if (curr->waiter != NULL) { 263 wakeup(curr->waiter); 264 curr->waiter = NULL; 265 } 266 } 267 splx(s); 268 } 269 270 271 /* 272 * check_event_handlers 273 * Checks for dead event handlers. A dead event handler would deplete 274 * memory over time, so we have to make sure someone at the other 275 * end is actively monitoring events. 276 * This function is called every 30 seconds or so (less frequent if there 277 * is other activity for the cleanup thread to deal with) to go through 278 * the list of handlers and check whether the first element in the event 279 * list has changed at all. If not, the event is deregistered. 280 * Note that this will not detect dead handlers if no events are pending, 281 * but we don't care as long as events don't accumulate in the list. 282 * 283 * this function must be called at splbio 284 */ 285 286 STATIC void 287 check_event_handlers(void) 288 { 289 event_handler_t *curr, *next; 290 event_t *evt; 291 292 for (curr = TAILQ_FIRST(&event_handlers); curr != NULL; curr = next) { 293 next = TAILQ_NEXT(curr, link); 294 evt = TAILQ_FIRST(&curr->events); 295 296 if (evt != NULL && evt == curr->first_in_list) { 297 DEBOUT(("Found Dead Event Handler %d, removing\n", curr->id)); 298 299 TAILQ_REMOVE(&event_handlers, curr, link); 300 while ((evt = TAILQ_FIRST(&curr->events)) != NULL) { 301 TAILQ_REMOVE(&curr->events, evt, link); 302 free(evt, M_TEMP); 303 } 304 free(curr, M_DEVBUF); 305 } else 306 curr->first_in_list = evt; 307 } 308 } 309 310 311 /* -------------------------------------------------------------------------- */ 312 313 /* 314 * get_socket: 315 * Get the file pointer from the socket handle passed into login. 316 * 317 * Parameter: 318 * fdes IN: The socket handle 319 * fpp OUT: The pointer to the resulting file pointer 320 * 321 * Returns: 0 on success, else an error code. 322 * 323 */ 324 325 STATIC int 326 get_socket(int fdes, struct file **fpp) 327 { 328 struct file *fp; 329 330 if ((fp = fd_getfile(fdes)) == NULL) { 331 return EBADF; 332 } 333 if (fp->f_type != DTYPE_SOCKET) { 334 return ENOTSOCK; 335 } 336 337 /* Add the reference */ 338 mutex_enter(&fp->f_lock); 339 fp->f_count++; 340 mutex_exit(&fp->f_lock); 341 342 *fpp = fp; 343 return 0; 344 } 345 346 /* 347 * release_socket: 348 * Release the file pointer from the socket handle passed into login. 349 * 350 * Parameter: 351 * fp IN: The pointer to the resulting file pointer 352 * 353 */ 354 355 STATIC void 356 release_socket(struct file *fp) 357 { 358 /* Add the reference */ 359 mutex_enter(&fp->f_lock); 360 fp->f_count--; 361 mutex_exit(&fp->f_lock); 362 } 363 364 365 /* 366 * find_session: 367 * Find a session by ID. 368 * 369 * Parameter: the session ID 370 * 371 * Returns: The pointer to the session (or NULL if not found) 372 */ 373 374 session_t * 375 find_session(uint32_t id) 376 { 377 session_t *curr; 378 int s; 379 380 s = splbio(); 381 TAILQ_FOREACH(curr, &iscsi_sessions, sessions) 382 if (curr->id == id) { 383 break; 384 } 385 splx(s); 386 return curr; 387 } 388 389 390 /* 391 * find_connection: 392 * Find a connection by ID. 393 * 394 * Parameter: the session pointer and the connection ID 395 * 396 * Returns: The pointer to the connection (or NULL if not found) 397 */ 398 399 connection_t * 400 find_connection(session_t *session, uint32_t id) 401 { 402 connection_t *curr; 403 int s; 404 405 s = splbio(); 406 TAILQ_FOREACH(curr, &session->conn_list, connections) 407 if (curr->id == id) { 408 break; 409 } 410 splx(s); 411 return curr; 412 } 413 414 415 /* 416 * kill_connection: 417 * Terminate the connection as gracefully as possible. 418 * 419 * Parameter: 420 * conn The connection to terminate 421 * status The status code for the connection's "terminating" field 422 * logout The logout reason code 423 * recover Attempt to recover connection 424 */ 425 426 void 427 kill_connection(connection_t *conn, uint32_t status, int logout, bool recover) 428 { 429 session_t *sess = conn->session; 430 int s; 431 432 DEBC(conn, 1, ("Kill_connection: terminating=%d, status=%d, logout=%d, " 433 "state=%d\n", 434 conn->terminating, status, logout, conn->state)); 435 436 if (recover && 437 !conn->destroy && 438 conn->recover > MAX_RECOVERY_ATTEMPTS) { 439 DEBC(conn, 1, 440 ("Kill_connection: Too many recovery attempts, destroying\n")); 441 conn->destroy = TRUE; 442 } 443 444 if (!recover || conn->destroy) { 445 446 s = splbio(); 447 if (conn->in_session) { 448 conn->in_session = FALSE; 449 TAILQ_REMOVE(&sess->conn_list, conn, connections); 450 sess->mru_connection = TAILQ_FIRST(&sess->conn_list); 451 } 452 splx(s); 453 454 if (!conn->destroy) { 455 DEBC(conn, 1, ("Kill_connection setting destroy flag\n")); 456 conn->destroy = TRUE; 457 } 458 /* in case it was already terminated earlier and rcv/send-threads */ 459 /* are waiting */ 460 wakeup(conn); 461 } 462 463 /* Don't recurse */ 464 if (conn->terminating) { 465 DEBC(conn, 1, ("Kill_connection exiting (already terminating)\n")); 466 return; 467 } 468 469 if (conn->state == ST_FULL_FEATURE) { 470 sess->active_connections--; 471 472 /* If this is the last connection and ERL < 2, reset TSIH */ 473 if (!sess->active_connections && sess->ErrorRecoveryLevel < 2) 474 sess->TSIH = 0; 475 476 /* Don't try to log out if the socket is broken or we're in the middle */ 477 /* of logging in */ 478 if (logout >= 0) { 479 conn->state = ST_WINDING_DOWN; 480 callout_schedule(&conn->timeout, CONNECTION_TIMEOUT); 481 482 if (sess->ErrorRecoveryLevel < 2 && 483 logout == RECOVER_CONNECTION) { 484 logout = LOGOUT_CONNECTION; 485 } 486 if (!sess->active_connections && 487 logout == LOGOUT_CONNECTION) { 488 logout = LOGOUT_SESSION; 489 } 490 if (!send_logout(conn, conn, logout, FALSE)) { 491 return; 492 } 493 /* 494 * if the logout request was successfully sent, the logout response 495 * handler will do the rest of the termination processing. If the 496 * logout doesn't get a response, we'll get back in here once 497 * the timeout hits. 498 */ 499 } 500 } 501 502 conn->terminating = status; 503 conn->state = ST_SETTLING; 504 505 /* let send thread take over next step of cleanup */ 506 wakeup(&conn->pdus_to_send); 507 508 DEBC(conn, 5, ("kill_connection returns\n")); 509 } 510 511 512 /* 513 * kill_session: 514 * Terminate the session as gracefully as possible. 515 * 516 * Parameter: 517 * session Session to terminate 518 * status The status code for the termination 519 * logout The logout reason code 520 521 */ 522 523 void 524 kill_session(session_t *session, uint32_t status, int logout, bool recover) 525 { 526 connection_t *curr; 527 ccb_t *ccb; 528 int s; 529 530 DEB(1, ("ISCSI: kill_session %d, status %d, logout %d, recover %d\n", 531 session->id, status, logout, recover)); 532 533 /* 534 * don't do anything if session isn't established yet, termination will be 535 * handled elsewhere 536 */ 537 if (session->sessions.tqe_next == NULL && 538 session->sessions.tqe_prev == NULL) { 539 return; 540 } 541 542 if (recover) { 543 /* 544 * Only recover when there's just one active connection left. 545 * Otherwise we get in all sorts of timing problems, and it doesn't 546 * make much sense anyway to recover when the other side has 547 * requested that we kill a multipathed session. 548 */ 549 if (session->active_connections == 1) { 550 curr = assign_connection(session, FALSE); 551 if (curr != NULL) 552 kill_connection(curr, status, logout, TRUE); 553 } 554 /* don't allow the session to disappear when the target */ 555 /* requested the logout */ 556 return; 557 } 558 559 /* remove from session list */ 560 s = splbio(); 561 TAILQ_REMOVE(&iscsi_sessions, session, sessions); 562 splx(s); 563 session->sessions.tqe_next = NULL; 564 session->sessions.tqe_prev = NULL; 565 566 /* complete any throttled CCBs */ 567 s = splbio(); 568 while ((ccb = TAILQ_FIRST(&session->ccbs_throttled)) != NULL) { 569 throttle_ccb(ccb, FALSE); 570 splx(s); 571 wake_ccb(ccb, ISCSI_STATUS_LOGOUT); 572 s = splbio(); 573 } 574 splx(s); 575 576 /* 577 * unmap first to give the system an opportunity to flush its buffers, 578 * but don't try to unmap if it's a forced termination (connection is dead) 579 * to avoid waiting for pending commands that can't complete anyway. 580 */ 581 if (logout >= 0) { 582 unmap_session(session); 583 DEB(5, ("Unmap Returns\n")); 584 } 585 586 /* kill all connections */ 587 while ((curr = TAILQ_FIRST(&session->conn_list)) != NULL) { 588 kill_connection(curr, status, logout, FALSE); 589 logout = NO_LOGOUT; 590 } 591 } 592 593 594 /* 595 * create_connection: 596 * Create and init the necessary framework for a connection: 597 * Alloc the connection structure itself 598 * Copy connection parameters 599 * Create the send and receive threads 600 * And finally, log in. 601 * 602 * Parameter: 603 * par IN/OUT: The login parameters 604 * session IN: The owning session 605 * l IN: The lwp pointer of the caller 606 * 607 * Returns: 0 on success 608 * >0 on failure, connection structure deleted 609 * <0 on failure, connection is still terminating 610 */ 611 612 STATIC int 613 create_connection(iscsi_login_parameters_t *par, session_t *session, 614 struct lwp *l) 615 { 616 connection_t *connection; 617 int rc, s; 618 619 DEB(1, ("Create Connection for Session %d\n", session->id)); 620 621 if (session->MaxConnections && 622 session->active_connections >= session->MaxConnections) { 623 DEBOUT(("Too many connections (max = %d, curr = %d)\n", 624 session->MaxConnections, session->active_connections)); 625 par->status = ISCSI_STATUS_MAXED_CONNECTIONS; 626 return EIO; 627 } 628 629 connection = malloc(sizeof(*connection), M_DEVBUF, M_WAITOK | M_ZERO); 630 if (connection == NULL) { 631 DEBOUT(("No mem for connection\n")); 632 par->status = ISCSI_STATUS_NO_RESOURCES; 633 return EIO; 634 } 635 636 /* create a unique ID */ 637 do { 638 ++session->conn_id; 639 } while (!session->conn_id || 640 find_connection(session, session->conn_id) != NULL); 641 642 par->connection_id = connection->id = session->conn_id; 643 DEB(99, ("Connection ID = %d\n", connection->id)); 644 645 connection->session = session; 646 647 TAILQ_INIT(&connection->ccbs_waiting); 648 TAILQ_INIT(&connection->pdus_to_send); 649 TAILQ_INIT(&connection->pdu_pool); 650 651 callout_init(&connection->timeout, 0); 652 callout_setfunc(&connection->timeout, connection_timeout, connection); 653 connection->idle_timeout_val = CONNECTION_IDLE_TIMEOUT; 654 655 init_sernum(&connection->StatSN_buf); 656 create_pdus(connection); 657 658 if ((rc = get_socket(par->socket, &connection->sock)) != 0) { 659 DEBOUT(("Invalid socket %d\n", par->socket)); 660 661 free(connection, M_DEVBUF); 662 par->status = ISCSI_STATUS_INVALID_SOCKET; 663 return rc; 664 } 665 DEBC(connection, 1, ("get_socket: par_sock=%d, fdesc=%p\n", 666 par->socket, connection->sock)); 667 668 /* close the file descriptor */ 669 fd_close(par->socket); 670 671 connection->threadobj = l; 672 connection->login_par = par; 673 674 /*DEBOUT (("Creating receive thread\n")); */ 675 if ((rc = kthread_create(PRI_NONE, 0, NULL, iscsi_rcv_thread, 676 connection, &connection->rcvproc, 677 "ConnRcv")) != 0) { 678 DEBOUT(("Can't create rcv thread (rc %d)\n", rc)); 679 680 release_socket(connection->sock); 681 free(connection, M_DEVBUF); 682 par->status = ISCSI_STATUS_NO_RESOURCES; 683 return rc; 684 } 685 /*DEBOUT (("Creating send thread\n")); */ 686 if ((rc = kthread_create(PRI_NONE, 0, NULL, iscsi_send_thread, 687 connection, &connection->sendproc, 688 "ConnSend")) != 0) { 689 DEBOUT(("Can't create send thread (rc %d)\n", rc)); 690 691 connection->terminating = ISCSI_STATUS_NO_RESOURCES; 692 693 /* 694 * We must close the socket here to force the receive 695 * thread to wake up 696 */ 697 DEBC(connection, 1, 698 ("Closing Socket %p\n", connection->sock)); 699 mutex_enter(&connection->sock->f_lock); 700 connection->sock->f_count += 1; 701 mutex_exit(&connection->sock->f_lock); 702 closef(connection->sock); 703 704 /* give receive thread time to exit */ 705 tsleep(connection, PWAIT, "settle", 2 * hz); 706 707 release_socket(connection->sock); 708 free(connection, M_DEVBUF); 709 par->status = ISCSI_STATUS_NO_RESOURCES; 710 return rc; 711 } 712 713 /* 714 * At this point, each thread will tie 'sock' into its own file descriptor 715 * tables w/o increasing the use count - they will inherit the use 716 * increments performed in get_socket(). 717 */ 718 719 if ((rc = send_login(connection)) != 0) { 720 DEBC(connection, 0, ("Login failed (rc %d)\n", rc)); 721 /* Don't attempt to recover, there seems to be something amiss */ 722 kill_connection(connection, rc, NO_LOGOUT, FALSE); 723 par->status = rc; 724 return -1; 725 } 726 727 s = splbio(); 728 connection->state = ST_FULL_FEATURE; 729 TAILQ_INSERT_TAIL(&session->conn_list, connection, connections); 730 connection->in_session = TRUE; 731 session->total_connections++; 732 session->active_connections++; 733 session->mru_connection = connection; 734 splx(s); 735 736 DEBC(connection, 5, ("Connection created successfully!\n")); 737 return 0; 738 } 739 740 741 /* 742 * recreate_connection: 743 * Revive dead connection 744 * 745 * Parameter: 746 * par IN/OUT: The login parameters 747 * conn IN: The connection 748 * l IN: The lwp pointer of the caller 749 * 750 * Returns: 0 on success 751 * >0 on failure, connection structure deleted 752 * <0 on failure, connection is still terminating 753 */ 754 755 STATIC int 756 recreate_connection(iscsi_login_parameters_t *par, session_t *session, 757 connection_t *connection, struct lwp *l) 758 { 759 int rc, s; 760 ccb_t *ccb; 761 ccb_list_t old_waiting; 762 763 DEB(1, ("ReCreate Connection %d for Session %d, ERL=%d\n", 764 connection->id, connection->session->id, 765 connection->session->ErrorRecoveryLevel)); 766 767 if (session->MaxConnections && 768 session->active_connections >= session->MaxConnections) { 769 DEBOUT(("Too many connections (max = %d, curr = %d)\n", 770 session->MaxConnections, session->active_connections)); 771 par->status = ISCSI_STATUS_MAXED_CONNECTIONS; 772 return EIO; 773 } 774 775 /* close old socket */ 776 if (connection->sock != NULL) { 777 closef(connection->sock); 778 connection->sock = NULL; 779 } 780 781 if ((rc = get_socket(par->socket, &connection->sock)) != 0) { 782 DEBOUT(("Invalid socket %d\n", par->socket)); 783 par->status = ISCSI_STATUS_INVALID_SOCKET; 784 return rc; 785 } 786 DEBC(connection, 1, ("get_socket: par_sock=%d, fdesc=%p\n", 787 par->socket, connection->sock)); 788 789 /* close the file descriptor */ 790 fd_close(par->socket); 791 792 connection->threadobj = l; 793 connection->login_par = par; 794 connection->terminating = ISCSI_STATUS_SUCCESS; 795 connection->recover++; 796 connection->num_timeouts = 0; 797 connection->state = ST_SEC_NEG; 798 connection->HeaderDigest = 0; 799 connection->DataDigest = 0; 800 801 session->active_connections++; 802 803 TAILQ_INIT(&old_waiting); 804 s = splbio(); 805 TAILQ_CONCAT(&old_waiting, &connection->ccbs_waiting, chain); 806 splx(s); 807 808 init_sernum(&connection->StatSN_buf); 809 wakeup(connection); 810 811 if ((rc = send_login(connection)) != 0) { 812 DEBOUT(("Login failed (rc %d)\n", rc)); 813 while ((ccb = TAILQ_FIRST(&old_waiting)) != NULL) { 814 TAILQ_REMOVE(&old_waiting, ccb, chain); 815 wake_ccb(ccb, rc); 816 } 817 /* Don't attempt to recover, there seems to be something amiss */ 818 kill_connection(connection, rc, NO_LOGOUT, FALSE); 819 par->status = rc; 820 return -1; 821 } 822 823 DEBC(connection, 9, ("Re-Login successful\n")); 824 par->status = ISCSI_STATUS_SUCCESS; 825 826 s = splbio(); 827 connection->state = ST_FULL_FEATURE; 828 session->mru_connection = connection; 829 splx(s); 830 831 while ((ccb = TAILQ_FIRST(&old_waiting)) != NULL) { 832 TAILQ_REMOVE(&old_waiting, ccb, chain); 833 s = splbio(); 834 suspend_ccb(ccb, TRUE); 835 splx(s); 836 837 rc = send_task_management(connection, ccb, NULL, TASK_REASSIGN); 838 /* if we get an error on reassign, restart the original request */ 839 if (rc && ccb->pdu_waiting != NULL) { 840 if (ccb->CmdSN < session->ExpCmdSN) { 841 pdu_t *pdu = ccb->pdu_waiting; 842 843 /* update CmdSN */ 844 DEBC(connection, 1, ("Resend Updating CmdSN - old %d, new %d\n", 845 ccb->CmdSN, session->CmdSN)); 846 ccb->CmdSN = session->CmdSN; 847 if (!(pdu->pdu.Opcode & OP_IMMEDIATE)) 848 session->CmdSN++; 849 pdu->pdu.p.command.CmdSN = htonl(ccb->CmdSN); 850 } 851 resend_pdu(ccb); 852 } else { 853 callout_schedule(&ccb->timeout, COMMAND_TIMEOUT); 854 } 855 } 856 857 wakeup(session); 858 859 DEBC(connection, 5, ("Connection ReCreated successfully - status %d\n", 860 par->status)); 861 862 return 0; 863 } 864 865 /* -------------------------------------------------------------------------- */ 866 867 /* 868 * check_login_pars: 869 * Check the parameters passed into login/add_connection 870 * for validity and consistency. 871 * 872 * Parameter: 873 * par The login parameters 874 * 875 * Returns: 0 on success, else an error code. 876 */ 877 878 STATIC int 879 check_login_pars(iscsi_login_parameters_t *par) 880 { 881 int i, n; 882 883 if (par->is_present.auth_info) { 884 /* check consistency of authentication parameters */ 885 886 if (par->auth_info.auth_number > ISCSI_AUTH_OPTIONS) { 887 DEBOUT(("Auth number invalid: %d\n", par->auth_info.auth_number)); 888 return ISCSI_STATUS_PARAMETER_INVALID; 889 } 890 891 if (par->auth_info.auth_number > 2) { 892 DEBOUT(("Auth number invalid: %d\n", par->auth_info.auth_number)); 893 return ISCSI_STATUS_NOTIMPL; 894 } 895 896 for (i = 0, n = 0; i < par->auth_info.auth_number; i++) { 897 #if 0 898 if (par->auth_info.auth_type[i] < ISCSI_AUTH_None) { 899 DEBOUT(("Auth type invalid: %d\n", 900 par->auth_info.auth_type[i])); 901 return ISCSI_STATUS_PARAMETER_INVALID; 902 } 903 #endif 904 if (par->auth_info.auth_type[i] > ISCSI_AUTH_CHAP) { 905 DEBOUT(("Auth type invalid: %d\n", 906 par->auth_info.auth_type[i])); 907 return ISCSI_STATUS_NOTIMPL; 908 } 909 n = max(n, par->auth_info.auth_type[i]); 910 } 911 if (n) { 912 if (!par->is_present.password || 913 (par->auth_info.mutual_auth && 914 !par->is_present.target_password)) { 915 DEBOUT(("Password missing\n")); 916 return ISCSI_STATUS_PARAMETER_MISSING; 917 } 918 /* Note: Default for user-name is initiator name */ 919 } 920 } 921 if (par->login_type != ISCSI_LOGINTYPE_DISCOVERY && 922 !par->is_present.TargetName) { 923 DEBOUT(("Target name missing, login type %d\n", par->login_type)); 924 return ISCSI_STATUS_PARAMETER_MISSING; 925 } 926 if (par->is_present.MaxRecvDataSegmentLength) { 927 if (par->MaxRecvDataSegmentLength < 512 || 928 par->MaxRecvDataSegmentLength > 0xffffff) { 929 DEBOUT(("MaxRecvDataSegmentLength invalid: %d\n", 930 par->MaxRecvDataSegmentLength)); 931 return ISCSI_STATUS_PARAMETER_INVALID; 932 } 933 } 934 return 0; 935 } 936 937 938 /* 939 * login: 940 * Handle the login ioctl - Create a session: 941 * Alloc the session structure 942 * Copy session parameters 943 * And call create_connection to establish the connection. 944 * 945 * Parameter: 946 * par IN/OUT: The login parameters 947 * l IN: The lwp pointer of the caller 948 */ 949 950 STATIC void 951 login(iscsi_login_parameters_t *par, struct lwp *l) 952 { 953 session_t *session; 954 int rc, s; 955 956 DEB(99, ("ISCSI: login\n")); 957 958 if (!iscsi_InitiatorName[0]) { 959 DEB(1, ("No Initiator Name\n")); 960 par->status = ISCSI_STATUS_NO_INITIATOR_NAME; 961 return; 962 } 963 964 if ((par->status = check_login_pars(par)) != 0) 965 return; 966 967 /* alloc the session */ 968 session = malloc(sizeof(*session), M_DEVBUF, M_WAITOK | M_ZERO); 969 if (session == NULL) { 970 DEBOUT(("No mem for session\n")); 971 par->status = ISCSI_STATUS_NO_RESOURCES; 972 return; 973 } 974 TAILQ_INIT(&session->conn_list); 975 TAILQ_INIT(&session->ccb_pool); 976 TAILQ_INIT(&session->ccbs_throttled); 977 978 /* create a unique ID */ 979 do { 980 ++current_id; 981 } while (!current_id || find_session(current_id) != NULL); 982 par->session_id = session->id = current_id; 983 984 create_ccbs(session); 985 session->login_type = par->login_type; 986 session->CmdSN = 1; 987 988 if ((rc = create_connection(par, session, l)) != 0) { 989 if (rc > 0) { 990 free(session, M_DEVBUF); 991 } 992 return; 993 } 994 995 s = splbio(); 996 TAILQ_INSERT_HEAD(&iscsi_sessions, session, sessions); 997 splx(s); 998 999 /* Session established, map LUNs? */ 1000 if (par->login_type == ISCSI_LOGINTYPE_MAP) { 1001 copyinstr(par->TargetName, session->tgtname, 1002 sizeof(session->tgtname), NULL); 1003 if (!map_session(session)) { 1004 kill_session(session, ISCSI_STATUS_MAP_FAILED, 1005 LOGOUT_SESSION, FALSE); 1006 par->status = ISCSI_STATUS_MAP_FAILED; 1007 return; 1008 } 1009 } 1010 } 1011 1012 1013 /* 1014 * logout: 1015 * Handle the logout ioctl - Kill a session. 1016 * 1017 * Parameter: 1018 * par IN/OUT: The login parameters 1019 */ 1020 1021 STATIC void 1022 logout(iscsi_logout_parameters_t *par) 1023 { 1024 session_t *session; 1025 1026 DEB(5, ("ISCSI: logout session %d\n", par->session_id)); 1027 1028 if ((session = find_session(par->session_id)) == NULL) { 1029 DEBOUT(("Session %d not found\n", par->session_id)); 1030 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1031 return; 1032 } 1033 /* If the session exists, this always succeeds */ 1034 par->status = ISCSI_STATUS_SUCCESS; 1035 1036 kill_session(session, ISCSI_STATUS_LOGOUT, LOGOUT_SESSION, FALSE); 1037 } 1038 1039 1040 /* 1041 * add_connection: 1042 * Handle the add_connection ioctl. 1043 * 1044 * Parameter: 1045 * par IN/OUT: The login parameters 1046 * l IN: The lwp pointer of the caller 1047 */ 1048 1049 STATIC void 1050 add_connection(iscsi_login_parameters_t *par, struct lwp *l) 1051 { 1052 session_t *session; 1053 1054 DEB(5, ("ISCSI: add_connection to session %d\n", par->session_id)); 1055 1056 if ((session = find_session(par->session_id)) == NULL) { 1057 DEBOUT(("Session %d not found\n", par->session_id)); 1058 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1059 return; 1060 } 1061 if ((par->status = check_login_pars(par)) == 0) { 1062 create_connection(par, session, l); 1063 } 1064 } 1065 1066 1067 /* 1068 * remove_connection: 1069 * Handle the remove_connection ioctl. 1070 * 1071 * Parameter: 1072 * par IN/OUT: The remove parameters 1073 */ 1074 1075 STATIC void 1076 remove_connection(iscsi_remove_parameters_t *par) 1077 { 1078 connection_t *conn; 1079 session_t *session; 1080 1081 DEB(5, ("ISCSI: remove_connection %d from session %d\n", 1082 par->connection_id, par->session_id)); 1083 1084 if ((session = find_session(par->session_id)) == NULL) { 1085 DEBOUT(("Session %d not found\n", par->session_id)); 1086 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1087 return; 1088 } 1089 1090 if ((conn = find_connection(session, par->connection_id)) == NULL) { 1091 DEBOUT(("Connection %d not found in session %d\n", 1092 par->connection_id, par->session_id)); 1093 1094 par->status = ISCSI_STATUS_INVALID_CONNECTION_ID; 1095 } else { 1096 kill_connection(conn, ISCSI_STATUS_LOGOUT, LOGOUT_CONNECTION, 1097 FALSE); 1098 par->status = ISCSI_STATUS_SUCCESS; 1099 } 1100 } 1101 1102 1103 /* 1104 * restore_connection: 1105 * Handle the restore_connection ioctl. 1106 * 1107 * Parameter: 1108 * par IN/OUT: The login parameters 1109 * l IN: The lwp pointer of the caller 1110 */ 1111 1112 STATIC void 1113 restore_connection(iscsi_login_parameters_t *par, struct lwp *l) 1114 { 1115 session_t *session; 1116 connection_t *connection; 1117 1118 DEB(1, ("ISCSI: restore_connection %d of session %d\n", 1119 par->connection_id, par->session_id)); 1120 1121 if ((session = find_session(par->session_id)) == NULL) { 1122 DEBOUT(("Session %d not found\n", par->session_id)); 1123 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1124 return; 1125 } 1126 1127 if ((connection = find_connection(session, par->connection_id)) == NULL) { 1128 DEBOUT(("Connection %d not found in session %d\n", 1129 par->connection_id, par->session_id)); 1130 par->status = ISCSI_STATUS_INVALID_CONNECTION_ID; 1131 return; 1132 } 1133 1134 if ((par->status = check_login_pars(par)) == 0) { 1135 recreate_connection(par, session, connection, l); 1136 } 1137 } 1138 1139 1140 #ifndef ISCSI_MINIMAL 1141 1142 /* 1143 * map_databuf: 1144 * Map user-supplied data buffer into kernel space. 1145 * 1146 * Parameter: 1147 * p IN: The proc pointer of the caller 1148 * buf IN/OUT: The virtual address of the buffer, modified 1149 * on exit to reflect kernel VA. 1150 * datalen IN: The size of the data buffer 1151 * 1152 * Returns: 1153 * An ISCSI status code on error, else 0. 1154 */ 1155 1156 uint32_t 1157 map_databuf(struct proc *p, void **buf, uint32_t datalen) 1158 { 1159 vaddr_t kva, databuf, offs; 1160 int error; 1161 1162 /* page align address */ 1163 databuf = (vaddr_t) * buf & ~PAGE_MASK; 1164 /* offset of VA into page */ 1165 offs = (vaddr_t) * buf & PAGE_MASK; 1166 /* round to full page including offset */ 1167 datalen = (datalen + offs + PAGE_MASK) & ~PAGE_MASK; 1168 1169 /* Do some magic to the vm space reference count (copied from "copyin_proc") */ 1170 if ((p->p_sflag & PS_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) { 1171 return ISCSI_STATUS_NO_RESOURCES; 1172 } 1173 p->p_vmspace->vm_refcnt++; 1174 1175 /* this is lifted from uvm_io */ 1176 error = uvm_map_extract(&p->p_vmspace->vm_map, databuf, datalen, 1177 kernel_map, &kva, 1178 UVM_EXTRACT_QREF | UVM_EXTRACT_CONTIG | 1179 UVM_EXTRACT_FIXPROT); 1180 if (error) { 1181 DEBOUT(("uvm_map_extract failed, error = %d\n", error)); 1182 return ISCSI_STATUS_NO_RESOURCES; 1183 } 1184 /* add offset back into kernel VA */ 1185 *buf = (void *) (kva + offs); 1186 1187 return 0; 1188 } 1189 1190 1191 /* 1192 * unmap_databuf: 1193 * Remove kernel space mapping of data buffer. 1194 * 1195 * Parameter: 1196 * p IN: The proc pointer of the caller 1197 * buf IN: The kernel virtual address of the buffer 1198 * datalen IN: The size of the data buffer 1199 * 1200 * Returns: 1201 * An ISCSI status code on error, else 0. 1202 */ 1203 1204 void 1205 unmap_databuf(struct proc *p, void *buf, uint32_t datalen) 1206 { 1207 struct vm_map_entry *dead_entries; 1208 vaddr_t databuf; 1209 1210 /* round to full page */ 1211 datalen = (datalen + ((uintptr_t) buf & PAGE_MASK) + PAGE_MASK) & ~PAGE_MASK; 1212 /* page align address */ 1213 databuf = (vaddr_t) buf & ~PAGE_MASK; 1214 1215 /* following code lifted almost verbatim from uvm_io.c */ 1216 vm_map_lock(kernel_map); 1217 uvm_unmap_remove(kernel_map, databuf, databuf + datalen, &dead_entries, 1218 0); 1219 vm_map_unlock(kernel_map); 1220 if (dead_entries != NULL) { 1221 uvm_unmap_detach(dead_entries, AMAP_REFALL); 1222 } 1223 /* this apparently reverses the magic to the vm ref count, from copyin_proc */ 1224 uvmspace_free(p->p_vmspace); 1225 } 1226 1227 1228 /* 1229 * io_command: 1230 * Handle the io_command ioctl. 1231 * 1232 * Parameter: 1233 * par IN/OUT: The iocommand parameters 1234 * l IN: The lwp pointer of the caller 1235 */ 1236 1237 STATIC void 1238 io_command(iscsi_iocommand_parameters_t *par, struct lwp *l) 1239 { 1240 uint32_t datalen = par->req.datalen; 1241 void *databuf = par->req.databuf; 1242 session_t *session; 1243 1244 DEB(9, ("ISCSI: io_command, SID=%d, lun=%" PRIu64 "\n", par->session_id, par->lun)); 1245 if ((session = find_session(par->session_id)) == NULL) { 1246 DEBOUT(("Session %d not found\n", par->session_id)); 1247 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1248 return; 1249 } 1250 1251 par->req.senselen_used = 0; 1252 par->req.datalen_used = 0; 1253 par->req.error = 0; 1254 par->req.status = 0; 1255 par->req.retsts = SCCMD_UNKNOWN; /* init to failure code */ 1256 1257 if (par->req.cmdlen > 16 || par->req.senselen > sizeof(par->req.sense)) { 1258 par->status = ISCSI_STATUS_PARAMETER_INVALID; 1259 return; 1260 } 1261 1262 if (datalen && (par->status = map_databuf(l->l_proc, 1263 &par->req.databuf, datalen)) != 0) { 1264 return; 1265 } 1266 par->status = send_io_command(session, par->lun, &par->req, 1267 par->options.immediate, par->connection_id); 1268 1269 if (datalen) { 1270 unmap_databuf(l->l_proc, par->req.databuf, datalen); 1271 par->req.databuf = databuf; /* restore original addr */ 1272 } 1273 1274 switch (par->status) { 1275 case ISCSI_STATUS_SUCCESS: 1276 par->req.retsts = SCCMD_OK; 1277 break; 1278 1279 case ISCSI_STATUS_TARGET_BUSY: 1280 par->req.retsts = SCCMD_BUSY; 1281 break; 1282 1283 case ISCSI_STATUS_TIMEOUT: 1284 case ISCSI_STATUS_SOCKET_ERROR: 1285 par->req.retsts = SCCMD_TIMEOUT; 1286 break; 1287 1288 default: 1289 par->req.retsts = (par->req.senselen_used) ? SCCMD_SENSE 1290 : SCCMD_UNKNOWN; 1291 break; 1292 } 1293 } 1294 #endif 1295 1296 /* 1297 * send_targets: 1298 * Handle the send_targets ioctl. 1299 * Note: If the passed buffer is too small to hold the complete response, 1300 * the response is kept in the session structure so it can be 1301 * retrieved with the next call to this function without having to go to 1302 * the target again. Once the complete response has been retrieved, it 1303 * is discarded. 1304 * 1305 * Parameter: 1306 * par IN/OUT: The send_targets parameters 1307 */ 1308 1309 STATIC void 1310 send_targets(iscsi_send_targets_parameters_t *par) 1311 { 1312 int rc; 1313 uint32_t rlen, cplen; 1314 session_t *session; 1315 1316 if ((session = find_session(par->session_id)) == NULL) { 1317 DEBOUT(("Session %d not found\n", par->session_id)); 1318 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1319 return; 1320 } 1321 1322 DEB(9, ("ISCSI: send_targets, rsp_size=%d; Saved list: %p\n", 1323 par->response_size, session->target_list)); 1324 1325 if (session->target_list == NULL) { 1326 rc = send_send_targets(session, par->key); 1327 if (rc) { 1328 par->status = rc; 1329 return; 1330 } 1331 } 1332 rlen = session->target_list_len; 1333 par->response_total = rlen; 1334 cplen = min(par->response_size, rlen); 1335 if (cplen) { 1336 copyout(session->target_list, par->response_buffer, cplen); 1337 } 1338 par->response_used = cplen; 1339 1340 /* If all of the response was copied, don't keep it around */ 1341 if (rlen && par->response_used == rlen) { 1342 free(session->target_list, M_TEMP); 1343 session->target_list = NULL; 1344 } 1345 1346 par->status = ISCSI_STATUS_SUCCESS; 1347 } 1348 1349 1350 /* 1351 * set_node_name: 1352 * Handle the set_node_name ioctl. 1353 * 1354 * Parameter: 1355 * par IN/OUT: The set_node_name parameters 1356 */ 1357 1358 STATIC void 1359 set_node_name(iscsi_set_node_name_parameters_t *par) 1360 { 1361 1362 if (strlen(par->InitiatorName) >= ISCSI_STRING_LENGTH || 1363 strlen(par->InitiatorAlias) >= ISCSI_STRING_LENGTH) { 1364 DEBOUT(("*** set_node_name string too long!\n")); 1365 par->status = ISCSI_STATUS_PARAMETER_INVALID; 1366 return; 1367 } 1368 strlcpy(iscsi_InitiatorName, par->InitiatorName, sizeof(iscsi_InitiatorName)); 1369 strlcpy(iscsi_InitiatorAlias, par->InitiatorAlias, sizeof(iscsi_InitiatorAlias)); 1370 memcpy(&iscsi_InitiatorISID, par->ISID, 6); 1371 DEB(5, ("ISCSI: set_node_name, ISID A=%x, B=%x, C=%x, D=%x\n", 1372 iscsi_InitiatorISID.ISID_A, iscsi_InitiatorISID.ISID_B, 1373 iscsi_InitiatorISID.ISID_C, iscsi_InitiatorISID.ISID_D)); 1374 1375 if (!iscsi_InitiatorISID.ISID_A && !iscsi_InitiatorISID.ISID_B && 1376 !iscsi_InitiatorISID.ISID_C && !iscsi_InitiatorISID.ISID_D) { 1377 iscsi_InitiatorISID.ISID_A = T_FORMAT_EN; 1378 iscsi_InitiatorISID.ISID_B = htons(0x1); 1379 iscsi_InitiatorISID.ISID_C = 0x37; 1380 iscsi_InitiatorISID.ISID_D = 0; 1381 } 1382 1383 par->status = ISCSI_STATUS_SUCCESS; 1384 } 1385 1386 1387 /* 1388 * connection_status: 1389 * Handle the connection_status ioctl. 1390 * 1391 * Parameter: 1392 * par IN/OUT: The status parameters 1393 */ 1394 1395 STATIC void 1396 connection_status(iscsi_conn_status_parameters_t *par) 1397 { 1398 connection_t *conn; 1399 session_t *session; 1400 1401 if ((session = find_session(par->session_id)) == NULL) { 1402 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1403 return; 1404 } 1405 1406 if (par->connection_id) { 1407 conn = find_connection(session, par->connection_id); 1408 } else { 1409 conn = TAILQ_FIRST(&session->conn_list); 1410 } 1411 par->status = (conn == NULL) ? ISCSI_STATUS_INVALID_CONNECTION_ID : 1412 ISCSI_STATUS_SUCCESS; 1413 DEB(9, ("ISCSI: connection_status, session %d connection %d --> %d\n", 1414 par->session_id, par->connection_id, par->status)); 1415 } 1416 1417 1418 /* 1419 * get_version: 1420 * Handle the get_version ioctl. 1421 * 1422 * Parameter: 1423 * par IN/OUT: The version parameters 1424 */ 1425 1426 STATIC void 1427 get_version(iscsi_get_version_parameters_t *par) 1428 { 1429 par->status = ISCSI_STATUS_SUCCESS; 1430 par->interface_version = INTERFACE_VERSION; 1431 par->major = VERSION_MAJOR; 1432 par->minor = VERSION_MINOR; 1433 strlcpy(par->version_string, VERSION_STRING, 1434 sizeof(par->version_string)); 1435 } 1436 1437 1438 /* -------------------------------------------------------------------- */ 1439 1440 /* 1441 * kill_all_sessions: 1442 * Terminate all sessions (called when the driver unloads). 1443 */ 1444 1445 void 1446 kill_all_sessions(void) 1447 { 1448 session_t *sess; 1449 1450 while ((sess = TAILQ_FIRST(&iscsi_sessions)) != NULL) { 1451 kill_session(sess, ISCSI_STATUS_DRIVER_UNLOAD, LOGOUT_SESSION, 1452 FALSE); 1453 } 1454 } 1455 1456 /* 1457 * handle_connection_error: 1458 * Deal with a problem during send or receive. 1459 * 1460 * Parameter: 1461 * conn The connection the problem is associated with 1462 * status The status code to insert into any unfinished CCBs 1463 * dologout Whether Logout should be attempted 1464 */ 1465 1466 void 1467 handle_connection_error(connection_t *conn, uint32_t status, int dologout) 1468 { 1469 1470 DEBC(conn, 0, ("*** Connection Error, status=%d, logout=%d, state=%d\n", 1471 status, dologout, conn->state)); 1472 1473 if (!conn->terminating && conn->state <= ST_LOGOUT_SENT) { 1474 /* if we get an error while winding down, escalate it */ 1475 if (dologout >= 0 && conn->state >= ST_WINDING_DOWN) { 1476 dologout = NO_LOGOUT; 1477 } 1478 kill_connection(conn, status, dologout, TRUE); 1479 } 1480 } 1481 1482 1483 /* 1484 * iscsi_cleanup_thread 1485 * Global thread to handle connection and session cleanup after termination. 1486 */ 1487 1488 void 1489 iscsi_cleanup_thread(void *par) 1490 { 1491 int s, rc; 1492 connection_t *conn; 1493 session_t *sess, *nxt; 1494 uint32_t status; 1495 1496 s = splbio(); 1497 while ((conn = TAILQ_FIRST(&iscsi_cleanupc_list)) != NULL || 1498 iscsi_num_send_threads || 1499 !iscsi_detaching) { 1500 if (conn != NULL) { 1501 TAILQ_REMOVE(&iscsi_cleanupc_list, conn, connections); 1502 splx(s); 1503 1504 sess = conn->session; 1505 status = conn->terminating; 1506 1507 DEBC(conn, 5, ("Cleanup: Waiting for threads to exit\n")); 1508 while (conn->sendproc || conn->rcvproc) 1509 tsleep(conn, PWAIT, "termwait", hz); 1510 1511 while (conn->usecount > 0) 1512 tsleep(conn, PWAIT, "finalwait", hz); 1513 1514 callout_halt(&conn->timeout, NULL); 1515 closef(conn->sock); 1516 free(conn, M_DEVBUF); 1517 1518 --sess->total_connections; 1519 1520 s = splbio(); 1521 TAILQ_FOREACH_SAFE(sess, &iscsi_cleanups_list, sessions, nxt) { 1522 if (sess->total_connections != 0) 1523 continue; 1524 1525 TAILQ_REMOVE(&iscsi_cleanups_list, sess, sessions); 1526 splx(s); 1527 1528 DEB(1, ("Cleanup: Unmap session %d\n", sess->id)); 1529 1530 rc = unmap_session(sess); 1531 if (rc == 0) { 1532 DEB(1, ("Cleanup: Unmap session %d failed\n", sess->id)); 1533 s = splbio(); 1534 TAILQ_INSERT_HEAD(&iscsi_cleanups_list, sess, sessions); 1535 splx(s); 1536 } 1537 1538 if (sess->target_list != NULL) 1539 free(sess->target_list, M_TEMP); 1540 /* notify event handlers of session shutdown */ 1541 add_event(ISCSI_SESSION_TERMINATED, sess->id, 0, status); 1542 DEB(1, ("Cleanup: session ended %d\n", sess->id)); 1543 free(sess, M_DEVBUF); 1544 1545 s = splbio(); 1546 } 1547 splx(s); 1548 1549 DEB(5, ("Cleanup: Done\n")); 1550 1551 s = splbio(); 1552 } else { 1553 /* Go to sleep, but wake up every 30 seconds to 1554 * check for dead event handlers */ 1555 splx(s); 1556 rc = tsleep(&iscsi_cleanupc_list, PWAIT, "cleanup", 1557 (TAILQ_FIRST(&event_handlers)) ? 30 * hz : 0); 1558 s = splbio(); 1559 /* if timed out, not woken up */ 1560 if (rc == EWOULDBLOCK) 1561 check_event_handlers(); 1562 } 1563 } 1564 splx(s); 1565 1566 add_event(ISCSI_DRIVER_TERMINATING, 0, 0, ISCSI_STATUS_DRIVER_UNLOAD); 1567 1568 /* 1569 * Wait for all event handlers to deregister, but don't wait more 1570 * than 1 minute (assume registering app has died if it takes longer). 1571 */ 1572 for (s = 0; TAILQ_FIRST(&event_handlers) != NULL && s < 60; s++) 1573 tsleep(&s, PWAIT, "waiteventclr", hz); 1574 1575 iscsi_cleanproc = NULL; 1576 DEB(5, ("Cleanup thread exits\n")); 1577 kthread_exit(0); 1578 } 1579 1580 1581 /* -------------------------------------------------------------------- */ 1582 1583 /* 1584 * iscsi_ioctl: 1585 * Driver ioctl entry. 1586 * 1587 * Parameter: 1588 * dev The device (ignored) 1589 * cmd The ioctl Command 1590 * addr IN/OUT: The command parameter 1591 * flag Flags (ignored) 1592 * l IN: The lwp object of the caller 1593 */ 1594 1595 int 1596 iscsiioctl(struct file *fp, u_long cmd, void *addr) 1597 { 1598 struct lwp *l = curlwp; 1599 1600 DEB(1, ("ISCSI Ioctl cmd = %x\n", (int) cmd)); 1601 1602 switch (cmd) { 1603 case ISCSI_GET_VERSION: 1604 get_version((iscsi_get_version_parameters_t *) addr); 1605 break; 1606 1607 case ISCSI_LOGIN: 1608 login((iscsi_login_parameters_t *) addr, l); 1609 break; 1610 1611 case ISCSI_ADD_CONNECTION: 1612 add_connection((iscsi_login_parameters_t *) addr, l); 1613 break; 1614 1615 case ISCSI_RESTORE_CONNECTION: 1616 restore_connection((iscsi_login_parameters_t *) addr, l); 1617 break; 1618 1619 case ISCSI_LOGOUT: 1620 logout((iscsi_logout_parameters_t *) addr); 1621 break; 1622 1623 case ISCSI_REMOVE_CONNECTION: 1624 remove_connection((iscsi_remove_parameters_t *) addr); 1625 break; 1626 1627 #ifndef ISCSI_MINIMAL 1628 case ISCSI_IO_COMMAND: 1629 io_command((iscsi_iocommand_parameters_t *) addr, l); 1630 break; 1631 #endif 1632 1633 case ISCSI_SEND_TARGETS: 1634 send_targets((iscsi_send_targets_parameters_t *) addr); 1635 break; 1636 1637 case ISCSI_SET_NODE_NAME: 1638 set_node_name((iscsi_set_node_name_parameters_t *) addr); 1639 break; 1640 1641 case ISCSI_CONNECTION_STATUS: 1642 connection_status((iscsi_conn_status_parameters_t *) addr); 1643 break; 1644 1645 case ISCSI_REGISTER_EVENT: 1646 register_event((iscsi_register_event_parameters_t *) addr); 1647 break; 1648 1649 case ISCSI_DEREGISTER_EVENT: 1650 deregister_event((iscsi_register_event_parameters_t *) addr); 1651 break; 1652 1653 case ISCSI_WAIT_EVENT: 1654 check_event((iscsi_wait_event_parameters_t *) addr, TRUE); 1655 break; 1656 1657 case ISCSI_POLL_EVENT: 1658 check_event((iscsi_wait_event_parameters_t *) addr, FALSE); 1659 break; 1660 1661 default: 1662 DEBOUT(("Invalid IO-Control Code\n")); 1663 return ENOTTY; 1664 } 1665 1666 /* 1667 * NOTE: We return 0 even if the function fails as long as the ioctl code 1668 * is good, so the status code is copied back to the caller. 1669 */ 1670 return 0; 1671 } 1672