1 /* $NetBSD: iscsi_ioctl.c,v 1.24 2017/02/05 12:05:46 mlelstv 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 kmutex_t iscsi_cleanup_mtx; 44 static kcondvar_t iscsi_cleanup_cv; 45 static kcondvar_t iscsi_event_cv; 46 static struct lwp *iscsi_cleanproc = NULL; 47 48 static uint16_t current_id = 0; /* Global session ID counter */ 49 50 /* list of event handlers */ 51 static event_handler_list_t event_handlers = 52 TAILQ_HEAD_INITIALIZER(event_handlers); 53 54 static connection_list_t iscsi_timeout_conn_list = 55 TAILQ_HEAD_INITIALIZER(iscsi_timeout_conn_list); 56 57 static ccb_list_t iscsi_timeout_ccb_list = 58 TAILQ_HEAD_INITIALIZER(iscsi_timeout_ccb_list); 59 60 static session_list_t iscsi_cleanups_list = 61 TAILQ_HEAD_INITIALIZER(iscsi_cleanups_list); 62 63 static connection_list_t iscsi_cleanupc_list = 64 TAILQ_HEAD_INITIALIZER(iscsi_cleanupc_list); 65 66 static uint32_t handler_id = 0; /* Handler ID counter */ 67 68 /* -------------------------------------------------------------------------- */ 69 70 /* Event management functions */ 71 72 /* 73 * find_handler: 74 * Search the event handler list for the given ID. 75 * 76 * Parameter: 77 * id The handler ID. 78 * 79 * Returns: 80 * Pointer to handler if found, else NULL. 81 */ 82 83 84 static event_handler_t * 85 find_handler(uint32_t id) 86 { 87 event_handler_t *curr; 88 89 KASSERT(mutex_owned(&iscsi_cleanup_mtx)); 90 91 TAILQ_FOREACH(curr, &event_handlers, link) 92 if (curr->id == id) 93 break; 94 95 return curr; 96 } 97 98 99 /* 100 * register_event: 101 * Create event handler entry, return ID. 102 * 103 * Parameter: 104 * par The parameter. 105 */ 106 107 static void 108 register_event(iscsi_register_event_parameters_t *par) 109 { 110 event_handler_t *handler; 111 int was_empty; 112 113 handler = malloc(sizeof(event_handler_t), M_DEVBUF, M_WAITOK | M_ZERO); 114 if (handler == NULL) { 115 DEBOUT(("No mem for event handler\n")); 116 par->status = ISCSI_STATUS_NO_RESOURCES; 117 return; 118 } 119 120 TAILQ_INIT(&handler->events); 121 122 mutex_enter(&iscsi_cleanup_mtx); 123 /* create a unique ID */ 124 do { 125 ++handler_id; 126 } while (!handler_id || find_handler(handler_id) != NULL); 127 par->event_id = handler->id = handler_id; 128 129 was_empty = TAILQ_FIRST(&event_handlers) == NULL; 130 TAILQ_INSERT_TAIL(&event_handlers, handler, link); 131 if (was_empty) 132 iscsi_notify_cleanup(); 133 mutex_exit(&iscsi_cleanup_mtx); 134 135 par->status = ISCSI_STATUS_SUCCESS; 136 DEB(5, ("Register Event OK, ID %d\n", par->event_id)); 137 } 138 139 140 /* 141 * deregister_event: 142 * Destroy handler entry and any waiting events, wake up waiter. 143 * 144 * Parameter: 145 * par The parameter. 146 */ 147 148 static void 149 deregister_event(iscsi_register_event_parameters_t *par) 150 { 151 event_handler_t *handler; 152 event_t *evt; 153 154 mutex_enter(&iscsi_cleanup_mtx); 155 handler = find_handler(par->event_id); 156 if (handler == NULL) { 157 mutex_exit(&iscsi_cleanup_mtx); 158 DEB(1, ("Deregister Event ID %d not found\n", par->event_id)); 159 par->status = ISCSI_STATUS_INVALID_EVENT_ID; 160 return; 161 } 162 163 TAILQ_REMOVE(&event_handlers, handler, link); 164 if (handler->waiter != NULL) { 165 handler->waiter->status = ISCSI_STATUS_EVENT_DEREGISTERED; 166 cv_broadcast(&iscsi_event_cv); 167 } 168 169 while ((evt = TAILQ_FIRST(&handler->events)) != NULL) { 170 TAILQ_REMOVE(&handler->events, evt, link); 171 free(evt, M_TEMP); 172 } 173 mutex_exit(&iscsi_cleanup_mtx); 174 175 free(handler, M_DEVBUF); 176 par->status = ISCSI_STATUS_SUCCESS; 177 DEB(5, ("Deregister Event ID %d complete\n", par->event_id)); 178 } 179 180 181 /* 182 * check_event: 183 * Return first queued event. Optionally wait for arrival of event. 184 * 185 * Parameter: 186 * par The parameter. 187 * wait Wait for event if true 188 */ 189 190 static void 191 check_event(iscsi_wait_event_parameters_t *par, bool wait) 192 { 193 event_handler_t *handler; 194 event_t *evt; 195 int rc; 196 197 mutex_enter(&iscsi_cleanup_mtx); 198 handler = find_handler(par->event_id); 199 if (handler == NULL) { 200 mutex_exit(&iscsi_cleanup_mtx); 201 DEBOUT(("Wait Event ID %d not found\n", par->event_id)); 202 par->status = ISCSI_STATUS_INVALID_EVENT_ID; 203 return; 204 } 205 if (handler->waiter != NULL) { 206 mutex_exit(&iscsi_cleanup_mtx); 207 DEBOUT(("Wait Event ID %d already waiting\n", par->event_id)); 208 par->status = ISCSI_STATUS_EVENT_WAITING; 209 return; 210 } 211 par->status = ISCSI_STATUS_SUCCESS; 212 DEB(99, ("Wait Event ID %d\n", par->event_id)); 213 214 do { 215 evt = TAILQ_FIRST(&handler->events); 216 if (evt != NULL) { 217 TAILQ_REMOVE(&handler->events, evt, link); 218 } else { 219 if (!wait) { 220 par->status = ISCSI_STATUS_LIST_EMPTY; 221 return; 222 } 223 if (par->status != ISCSI_STATUS_SUCCESS) { 224 return; 225 } 226 handler->waiter = par; 227 rc = cv_wait_sig(&iscsi_event_cv, &iscsi_cleanup_mtx); 228 if (rc) { 229 mutex_exit(&iscsi_cleanup_mtx); 230 par->status = ISCSI_STATUS_LIST_EMPTY; 231 return; 232 } 233 } 234 } while (evt == NULL); 235 mutex_exit(&iscsi_cleanup_mtx); 236 237 par->connection_id = evt->connection_id; 238 par->session_id = evt->session_id; 239 par->event_kind = evt->event_kind; 240 par->reason = evt->reason; 241 242 free(evt, M_TEMP); 243 } 244 245 /* 246 * add_event 247 * Adds an event entry to each registered handler queue. 248 * Note that events are simply duplicated because we expect the number of 249 * handlers to be very small, usually 1 (the daemon). 250 * 251 * Parameters: 252 * kind The event kind 253 * sid The ID of the affected session 254 * cid The ID of the affected connection 255 * reason The reason code 256 */ 257 258 void 259 add_event(iscsi_event_t kind, uint32_t sid, uint32_t cid, uint32_t reason) 260 { 261 event_handler_t *curr; 262 event_t *evt; 263 264 DEB(9, ("Add_event kind %d, sid %d, cid %d, reason %d\n", 265 kind, sid, cid, reason)); 266 267 mutex_enter(&iscsi_cleanup_mtx); 268 TAILQ_FOREACH(curr, &event_handlers, link) { 269 evt = malloc(sizeof(*evt), M_TEMP, M_NOWAIT); 270 if (evt == NULL) { 271 DEBOUT(("Cannot allocate event\n")); 272 break; 273 } 274 evt->event_kind = kind; 275 evt->session_id = sid; 276 evt->connection_id = cid; 277 evt->reason = reason; 278 279 TAILQ_INSERT_TAIL(&curr->events, evt, link); 280 if (curr->waiter != NULL) { 281 curr->waiter = NULL; 282 cv_broadcast(&iscsi_event_cv); 283 } 284 } 285 mutex_exit(&iscsi_cleanup_mtx); 286 } 287 288 289 /* 290 * check_event_handlers 291 * Checks for dead event handlers. A dead event handler would deplete 292 * memory over time, so we have to make sure someone at the other 293 * end is actively monitoring events. 294 * This function is called every 30 seconds or so (less frequent if there 295 * is other activity for the cleanup thread to deal with) to go through 296 * the list of handlers and check whether the first element in the event 297 * list has changed at all. If not, the event is deregistered. 298 * Note that this will not detect dead handlers if no events are pending, 299 * but we don't care as long as events don't accumulate in the list. 300 * 301 */ 302 303 static void 304 check_event_handlers(void) 305 { 306 event_handler_t *curr, *next; 307 event_t *evt; 308 309 KASSERT(mutex_owned(&iscsi_cleanup_mtx)); 310 311 for (curr = TAILQ_FIRST(&event_handlers); curr != NULL; curr = next) { 312 next = TAILQ_NEXT(curr, link); 313 evt = TAILQ_FIRST(&curr->events); 314 315 if (evt != NULL && evt == curr->first_in_list) { 316 DEBOUT(("Found Dead Event Handler %d, removing\n", curr->id)); 317 318 TAILQ_REMOVE(&event_handlers, curr, link); 319 while ((evt = TAILQ_FIRST(&curr->events)) != NULL) { 320 TAILQ_REMOVE(&curr->events, evt, link); 321 free(evt, M_TEMP); 322 } 323 free(curr, M_DEVBUF); 324 } else 325 curr->first_in_list = evt; 326 } 327 } 328 329 330 /* -------------------------------------------------------------------------- */ 331 332 /* 333 * get_socket: 334 * Get the file pointer from the socket handle passed into login. 335 * 336 * Parameter: 337 * fdes IN: The socket handle 338 * fpp OUT: The pointer to the resulting file pointer 339 * 340 * Returns: 0 on success, else an error code. 341 * 342 */ 343 344 static int 345 get_socket(int fdes, struct file **fpp) 346 { 347 struct file *fp; 348 349 if ((fp = fd_getfile(fdes)) == NULL) { 350 return EBADF; 351 } 352 if (fp->f_type != DTYPE_SOCKET) { 353 return ENOTSOCK; 354 } 355 356 /* Add the reference */ 357 mutex_enter(&fp->f_lock); 358 fp->f_count++; 359 mutex_exit(&fp->f_lock); 360 361 *fpp = fp; 362 return 0; 363 } 364 365 /* 366 * release_socket: 367 * Release the file pointer from the socket handle passed into login. 368 * 369 * Parameter: 370 * fp IN: The pointer to the resulting file pointer 371 * 372 */ 373 374 static void 375 release_socket(struct file *fp) 376 { 377 /* Add the reference */ 378 mutex_enter(&fp->f_lock); 379 fp->f_count--; 380 mutex_exit(&fp->f_lock); 381 } 382 383 384 /* 385 * find_session: 386 * Find a session by ID. 387 * 388 * Parameter: the session ID 389 * 390 * Returns: The pointer to the session (or NULL if not found) 391 */ 392 393 session_t * 394 find_session(uint32_t id) 395 { 396 session_t *curr; 397 398 KASSERT(mutex_owned(&iscsi_cleanup_mtx)); 399 400 TAILQ_FOREACH(curr, &iscsi_sessions, sessions) 401 if (curr->id == id) { 402 break; 403 } 404 return curr; 405 } 406 407 408 /* 409 * find_connection: 410 * Find a connection by ID. 411 * 412 * Parameter: the session pointer and the connection ID 413 * 414 * Returns: The pointer to the connection (or NULL if not found) 415 */ 416 417 connection_t * 418 find_connection(session_t *session, uint32_t id) 419 { 420 connection_t *curr; 421 422 KASSERT(mutex_owned(&iscsi_cleanup_mtx)); 423 424 TAILQ_FOREACH(curr, &session->conn_list, connections) 425 if (curr->id == id) { 426 break; 427 } 428 return curr; 429 } 430 431 /* 432 * ref_session: 433 * Reference a session 434 * 435 * Session cannot be release until reference count reaches zero 436 * 437 * Returns: 1 if reference counter would overflow 438 */ 439 440 int 441 ref_session(session_t *session) 442 { 443 int rc = 1; 444 445 mutex_enter(&iscsi_cleanup_mtx); 446 KASSERT(session != NULL); 447 if (session->refcount <= CCBS_PER_SESSION) { 448 session->refcount++; 449 rc = 0; 450 } 451 mutex_exit(&iscsi_cleanup_mtx); 452 453 return rc; 454 } 455 456 /* 457 * unref_session: 458 * Unreference a session 459 * 460 * Release session reference, trigger cleanup 461 */ 462 463 void 464 unref_session(session_t *session) 465 { 466 467 mutex_enter(&iscsi_cleanup_mtx); 468 KASSERT(session != NULL); 469 KASSERT(session->refcount > 0); 470 if (--session->refcount == 0) 471 cv_broadcast(&session->sess_cv); 472 mutex_exit(&iscsi_cleanup_mtx); 473 } 474 475 476 /* 477 * kill_connection: 478 * Terminate the connection as gracefully as possible. 479 * 480 * Parameter: 481 * conn The connection to terminate 482 * status The status code for the connection's "terminating" field 483 * logout The logout reason code 484 * recover Attempt to recover connection 485 */ 486 487 void 488 kill_connection(connection_t *conn, uint32_t status, int logout, bool recover) 489 { 490 session_t *sess = conn->session; 491 int terminating; 492 493 DEBC(conn, 1, ("Kill_connection: terminating=%d, status=%d, logout=%d, " 494 "state=%d\n", 495 conn->terminating, status, logout, conn->state)); 496 497 mutex_enter(&iscsi_cleanup_mtx); 498 if (recover && 499 !conn->destroy && 500 conn->recover > MAX_RECOVERY_ATTEMPTS) { 501 DEBC(conn, 1, 502 ("Kill_connection: Too many recovery attempts, destroying\n")); 503 conn->destroy = TRUE; 504 } 505 506 if (!recover || conn->destroy) { 507 508 if (conn->in_session) { 509 conn->in_session = FALSE; 510 TAILQ_REMOVE(&sess->conn_list, conn, connections); 511 sess->mru_connection = TAILQ_FIRST(&sess->conn_list); 512 } 513 514 if (!conn->destroy) { 515 DEBC(conn, 1, ("Kill_connection setting destroy flag\n")); 516 conn->destroy = TRUE; 517 } 518 } 519 520 terminating = conn->terminating; 521 if (!terminating) 522 conn->terminating = status; 523 mutex_exit(&iscsi_cleanup_mtx); 524 525 /* Don't recurse */ 526 if (terminating) { 527 DEBC(conn, 1, ("Kill_connection exiting (already terminating)\n")); 528 goto done; 529 } 530 531 if (conn->state == ST_FULL_FEATURE) { 532 sess->active_connections--; 533 534 /* If this is the last connection and ERL < 2, reset TSIH */ 535 if (!sess->active_connections && sess->ErrorRecoveryLevel < 2) 536 sess->TSIH = 0; 537 538 /* Don't try to log out if the socket is broken or we're in the middle */ 539 /* of logging in */ 540 if (logout >= 0) { 541 conn->state = ST_WINDING_DOWN; 542 connection_timeout_start(conn, CONNECTION_TIMEOUT); 543 544 if (sess->ErrorRecoveryLevel < 2 && 545 logout == RECOVER_CONNECTION) { 546 logout = LOGOUT_CONNECTION; 547 } 548 if (!sess->active_connections && 549 logout == LOGOUT_CONNECTION) { 550 logout = LOGOUT_SESSION; 551 } 552 if (!send_logout(conn, conn, logout, FALSE)) { 553 conn->terminating = ISCSI_STATUS_SUCCESS; 554 return; 555 } 556 /* 557 * if the logout request was successfully sent, the logout response 558 * handler will do the rest of the termination processing. If the 559 * logout doesn't get a response, we'll get back in here once 560 * the timeout hits. 561 */ 562 } 563 } 564 565 conn->state = ST_SETTLING; 566 567 done: 568 /* let send thread take over next step of cleanup */ 569 mutex_enter(&conn->lock); 570 cv_broadcast(&conn->conn_cv); 571 mutex_exit(&conn->lock); 572 573 DEBC(conn, 5, ("kill_connection returns\n")); 574 } 575 576 577 /* 578 * kill_session: 579 * Terminate the session as gracefully as possible. 580 * 581 * Parameter: 582 * session Session to terminate 583 * status The status code for the termination 584 * logout The logout reason code 585 586 */ 587 588 void 589 kill_session(session_t *session, uint32_t status, int logout, bool recover) 590 { 591 connection_t *conn; 592 593 DEB(1, ("ISCSI: kill_session %d, status %d, logout %d, recover %d\n", 594 session->id, status, logout, recover)); 595 596 mutex_enter(&iscsi_cleanup_mtx); 597 if (session->terminating) { 598 mutex_exit(&iscsi_cleanup_mtx); 599 600 DEB(5, ("Session is being killed with status %d\n",session->terminating)); 601 return; 602 } 603 604 /* 605 * don't do anything if session isn't established yet, termination will be 606 * handled elsewhere 607 */ 608 if (session->sessions.tqe_next == NULL && session->sessions.tqe_prev == NULL) { 609 mutex_exit(&iscsi_cleanup_mtx); 610 611 DEB(5, ("Session is being killed which is not yet established\n")); 612 return; 613 } 614 615 if (recover) { 616 mutex_exit(&iscsi_cleanup_mtx); 617 618 /* 619 * Only recover when there's just one active connection left. 620 * Otherwise we get in all sorts of timing problems, and it doesn't 621 * make much sense anyway to recover when the other side has 622 * requested that we kill a multipathed session. 623 */ 624 if (session->active_connections == 1) { 625 conn = assign_connection(session, FALSE); 626 if (conn != NULL) 627 kill_connection(conn, status, logout, TRUE); 628 } 629 return; 630 } 631 632 if (session->refcount > 0) { 633 mutex_exit(&iscsi_cleanup_mtx); 634 635 DEB(5, ("Session is being killed while in use (refcnt = %d)\n", 636 session->refcount)); 637 return; 638 } 639 640 /* Remove session from global list */ 641 session->terminating = status; 642 TAILQ_REMOVE(&iscsi_sessions, session, sessions); 643 session->sessions.tqe_next = NULL; 644 session->sessions.tqe_prev = NULL; 645 646 mutex_exit(&iscsi_cleanup_mtx); 647 648 /* kill all connections */ 649 while ((conn = TAILQ_FIRST(&session->conn_list)) != NULL) { 650 kill_connection(conn, status, logout, FALSE); 651 logout = NO_LOGOUT; 652 } 653 } 654 655 656 /* 657 * create_connection: 658 * Create and init the necessary framework for a connection: 659 * Alloc the connection structure itself 660 * Copy connection parameters 661 * Create the send and receive threads 662 * And finally, log in. 663 * 664 * Parameter: 665 * par IN/OUT: The login parameters 666 * session IN: The owning session 667 * l IN: The lwp pointer of the caller 668 * 669 * Returns: 0 on success 670 * >0 on failure, connection structure deleted 671 * <0 on failure, connection is still terminating 672 */ 673 674 static int 675 create_connection(iscsi_login_parameters_t *par, session_t *session, 676 struct lwp *l) 677 { 678 connection_t *connection; 679 int rc; 680 681 DEB(1, ("Create Connection for Session %d\n", session->id)); 682 683 if (session->MaxConnections && 684 session->active_connections >= session->MaxConnections) { 685 DEBOUT(("Too many connections (max = %d, curr = %d)\n", 686 session->MaxConnections, session->active_connections)); 687 par->status = ISCSI_STATUS_MAXED_CONNECTIONS; 688 return EIO; 689 } 690 691 connection = malloc(sizeof(*connection), M_DEVBUF, M_WAITOK | M_ZERO); 692 if (connection == NULL) { 693 DEBOUT(("No mem for connection\n")); 694 par->status = ISCSI_STATUS_NO_RESOURCES; 695 return EIO; 696 } 697 698 mutex_enter(&iscsi_cleanup_mtx); 699 /* create a unique ID */ 700 do { 701 ++session->conn_id; 702 } while (!session->conn_id || 703 find_connection(session, session->conn_id) != NULL); 704 par->connection_id = connection->id = session->conn_id; 705 mutex_exit(&iscsi_cleanup_mtx); 706 DEB(99, ("Connection ID = %d\n", connection->id)); 707 708 connection->session = session; 709 710 TAILQ_INIT(&connection->ccbs_waiting); 711 TAILQ_INIT(&connection->pdus_to_send); 712 TAILQ_INIT(&connection->pdu_pool); 713 714 mutex_init(&connection->lock, MUTEX_DEFAULT, IPL_BIO); 715 cv_init(&connection->conn_cv, "conn"); 716 cv_init(&connection->pdu_cv, "pdupool"); 717 cv_init(&connection->ccb_cv, "ccbwait"); 718 cv_init(&connection->idle_cv, "idle"); 719 720 callout_init(&connection->timeout, CALLOUT_MPSAFE); 721 callout_setfunc(&connection->timeout, connection_timeout_co, connection); 722 connection->idle_timeout_val = CONNECTION_IDLE_TIMEOUT; 723 724 init_sernum(&connection->StatSN_buf); 725 create_pdus(connection); 726 727 if ((rc = get_socket(par->socket, &connection->sock)) != 0) { 728 DEBOUT(("Invalid socket %d\n", par->socket)); 729 730 callout_destroy(&connection->timeout); 731 cv_destroy(&connection->idle_cv); 732 cv_destroy(&connection->ccb_cv); 733 cv_destroy(&connection->pdu_cv); 734 cv_destroy(&connection->conn_cv); 735 mutex_destroy(&connection->lock); 736 free(connection, M_DEVBUF); 737 par->status = ISCSI_STATUS_INVALID_SOCKET; 738 return rc; 739 } 740 DEBC(connection, 1, ("get_socket: par_sock=%d, fdesc=%p\n", 741 par->socket, connection->sock)); 742 743 /* close the file descriptor */ 744 fd_close(par->socket); 745 746 connection->threadobj = l; 747 connection->login_par = par; 748 749 DEB(5, ("Creating receive thread\n")); 750 if ((rc = kthread_create(PRI_BIO, KTHREAD_MPSAFE, NULL, iscsi_rcv_thread, 751 connection, &connection->rcvproc, 752 "ConnRcv")) != 0) { 753 DEBOUT(("Can't create rcv thread (rc %d)\n", rc)); 754 755 release_socket(connection->sock); 756 callout_destroy(&connection->timeout); 757 cv_destroy(&connection->idle_cv); 758 cv_destroy(&connection->ccb_cv); 759 cv_destroy(&connection->pdu_cv); 760 cv_destroy(&connection->conn_cv); 761 mutex_destroy(&connection->lock); 762 free(connection, M_DEVBUF); 763 par->status = ISCSI_STATUS_NO_RESOURCES; 764 return rc; 765 } 766 DEB(5, ("Creating send thread\n")); 767 if ((rc = kthread_create(PRI_BIO, KTHREAD_MPSAFE, NULL, iscsi_send_thread, 768 connection, &connection->sendproc, 769 "ConnSend")) != 0) { 770 DEBOUT(("Can't create send thread (rc %d)\n", rc)); 771 772 connection->terminating = ISCSI_STATUS_NO_RESOURCES; 773 774 /* 775 * We must close the socket here to force the receive 776 * thread to wake up 777 */ 778 DEBC(connection, 1, 779 ("Closing Socket %p\n", connection->sock)); 780 mutex_enter(&connection->sock->f_lock); 781 connection->sock->f_count += 1; 782 mutex_exit(&connection->sock->f_lock); 783 closef(connection->sock); 784 785 /* give receive thread time to exit */ 786 kpause("settle", false, 2 * hz, NULL); 787 788 release_socket(connection->sock); 789 callout_destroy(&connection->timeout); 790 cv_destroy(&connection->idle_cv); 791 cv_destroy(&connection->ccb_cv); 792 cv_destroy(&connection->pdu_cv); 793 cv_destroy(&connection->conn_cv); 794 mutex_destroy(&connection->lock); 795 free(connection, M_DEVBUF); 796 par->status = ISCSI_STATUS_NO_RESOURCES; 797 return rc; 798 } 799 800 /* 801 * At this point, each thread will tie 'sock' into its own file descriptor 802 * tables w/o increasing the use count - they will inherit the use 803 * increments performed in get_socket(). 804 */ 805 806 if ((rc = send_login(connection)) != 0) { 807 DEBC(connection, 0, ("Login failed (rc %d)\n", rc)); 808 /* Don't attempt to recover, there seems to be something amiss */ 809 kill_connection(connection, rc, NO_LOGOUT, FALSE); 810 par->status = rc; 811 return -1; 812 } 813 814 mutex_enter(&session->lock); 815 if (session->terminating) { 816 DEBC(connection, 0, ("Session terminating\n")); 817 kill_connection(connection, rc, NO_LOGOUT, FALSE); 818 mutex_exit(&session->lock); 819 par->status = session->terminating; 820 return -1; 821 } 822 connection->state = ST_FULL_FEATURE; 823 TAILQ_INSERT_TAIL(&session->conn_list, connection, connections); 824 connection->in_session = TRUE; 825 session->total_connections++; 826 session->active_connections++; 827 session->mru_connection = connection; 828 mutex_exit(&session->lock); 829 830 DEBC(connection, 5, ("Connection created successfully!\n")); 831 return 0; 832 } 833 834 835 /* 836 * recreate_connection: 837 * Revive dead connection 838 * 839 * Parameter: 840 * par IN/OUT: The login parameters 841 * conn IN: The connection 842 * l IN: The lwp pointer of the caller 843 * 844 * Returns: 0 on success 845 * >0 on failure, connection structure deleted 846 * <0 on failure, connection is still terminating 847 */ 848 849 static int 850 recreate_connection(iscsi_login_parameters_t *par, session_t *session, 851 connection_t *connection, struct lwp *l) 852 { 853 int rc; 854 ccb_t *ccb; 855 ccb_list_t old_waiting; 856 pdu_t *pdu; 857 uint32_t sn; 858 859 DEB(1, ("ReCreate Connection %d for Session %d, ERL=%d\n", 860 connection->id, connection->session->id, 861 connection->session->ErrorRecoveryLevel)); 862 863 if (session->MaxConnections && 864 session->active_connections >= session->MaxConnections) { 865 DEBOUT(("Too many connections (max = %d, curr = %d)\n", 866 session->MaxConnections, session->active_connections)); 867 par->status = ISCSI_STATUS_MAXED_CONNECTIONS; 868 return EIO; 869 } 870 871 /* close old socket */ 872 if (connection->sock != NULL) { 873 closef(connection->sock); 874 connection->sock = NULL; 875 } 876 877 if ((rc = get_socket(par->socket, &connection->sock)) != 0) { 878 DEBOUT(("Invalid socket %d\n", par->socket)); 879 par->status = ISCSI_STATUS_INVALID_SOCKET; 880 return rc; 881 } 882 DEBC(connection, 1, ("get_socket: par_sock=%d, fdesc=%p\n", 883 par->socket, connection->sock)); 884 885 /* close the file descriptor */ 886 fd_close(par->socket); 887 888 connection->threadobj = l; 889 connection->login_par = par; 890 connection->terminating = ISCSI_STATUS_SUCCESS; 891 connection->recover++; 892 connection->num_timeouts = 0; 893 connection->state = ST_SEC_NEG; 894 connection->HeaderDigest = 0; 895 connection->DataDigest = 0; 896 897 session->active_connections++; 898 899 TAILQ_INIT(&old_waiting); 900 901 mutex_enter(&connection->lock); 902 while ((ccb = TAILQ_FIRST(&connection->ccbs_waiting)) != NULL) { 903 suspend_ccb(ccb, FALSE); 904 TAILQ_INSERT_TAIL(&old_waiting, ccb, chain); 905 } 906 init_sernum(&connection->StatSN_buf); 907 cv_broadcast(&connection->idle_cv); 908 mutex_exit(&connection->lock); 909 910 if ((rc = send_login(connection)) != 0) { 911 DEBOUT(("Login failed (rc %d)\n", rc)); 912 while ((ccb = TAILQ_FIRST(&old_waiting)) != NULL) { 913 TAILQ_REMOVE(&old_waiting, ccb, chain); 914 wake_ccb(ccb, rc); 915 } 916 /* Don't attempt to recover, there seems to be something amiss */ 917 kill_connection(connection, rc, NO_LOGOUT, FALSE); 918 par->status = rc; 919 return -1; 920 } 921 922 DEBC(connection, 9, ("Re-Login successful\n")); 923 par->status = ISCSI_STATUS_SUCCESS; 924 925 connection->state = ST_FULL_FEATURE; 926 session->mru_connection = connection; 927 928 while ((ccb = TAILQ_FIRST(&old_waiting)) != NULL) { 929 TAILQ_REMOVE(&old_waiting, ccb, chain); 930 mutex_enter(&connection->lock); 931 suspend_ccb(ccb, TRUE); 932 mutex_exit(&connection->lock); 933 934 rc = send_task_management(connection, ccb, NULL, TASK_REASSIGN); 935 /* if we get an error on reassign, restart the original request */ 936 if (rc && ccb->pdu_waiting != NULL) { 937 mutex_enter(&session->lock); 938 if (sn_a_lt_b(ccb->CmdSN, session->ExpCmdSN)) { 939 pdu = ccb->pdu_waiting; 940 sn = get_sernum(session, pdu); 941 942 /* update CmdSN */ 943 DEBC(connection, 0, ("Resend ccb %p (%d) - updating CmdSN old %u, new %u\n", 944 ccb, rc, ccb->CmdSN, sn)); 945 ccb->CmdSN = sn; 946 pdu->pdu.p.command.CmdSN = htonl(ccb->CmdSN); 947 } else { 948 DEBC(connection, 0, ("Resend ccb %p (%d) - CmdSN %u\n", 949 ccb, rc, ccb->CmdSN)); 950 } 951 mutex_exit(&session->lock); 952 resend_pdu(ccb); 953 } else { 954 DEBC(connection, 0, ("Resend ccb %p (%d) CmdSN %u - reassigned\n", 955 ccb, rc, ccb->CmdSN)); 956 ccb_timeout_start(ccb, COMMAND_TIMEOUT); 957 } 958 } 959 960 mutex_enter(&session->lock); 961 cv_broadcast(&session->sess_cv); 962 mutex_exit(&session->lock); 963 964 DEBC(connection, 0, ("Connection ReCreated successfully - status %d\n", 965 par->status)); 966 967 return 0; 968 } 969 970 /* -------------------------------------------------------------------------- */ 971 972 /* 973 * check_login_pars: 974 * Check the parameters passed into login/add_connection 975 * for validity and consistency. 976 * 977 * Parameter: 978 * par The login parameters 979 * 980 * Returns: 0 on success, else an error code. 981 */ 982 983 static int 984 check_login_pars(iscsi_login_parameters_t *par) 985 { 986 int i, n; 987 988 if (par->is_present.auth_info) { 989 /* check consistency of authentication parameters */ 990 991 if (par->auth_info.auth_number > ISCSI_AUTH_OPTIONS) { 992 DEBOUT(("Auth number invalid: %d\n", par->auth_info.auth_number)); 993 return ISCSI_STATUS_PARAMETER_INVALID; 994 } 995 996 if (par->auth_info.auth_number > 2) { 997 DEBOUT(("Auth number invalid: %d\n", par->auth_info.auth_number)); 998 return ISCSI_STATUS_NOTIMPL; 999 } 1000 1001 for (i = 0, n = 0; i < par->auth_info.auth_number; i++) { 1002 #if 0 1003 if (par->auth_info.auth_type[i] < ISCSI_AUTH_None) { 1004 DEBOUT(("Auth type invalid: %d\n", 1005 par->auth_info.auth_type[i])); 1006 return ISCSI_STATUS_PARAMETER_INVALID; 1007 } 1008 #endif 1009 if (par->auth_info.auth_type[i] > ISCSI_AUTH_CHAP) { 1010 DEBOUT(("Auth type invalid: %d\n", 1011 par->auth_info.auth_type[i])); 1012 return ISCSI_STATUS_NOTIMPL; 1013 } 1014 n = max(n, par->auth_info.auth_type[i]); 1015 } 1016 if (n) { 1017 if (!par->is_present.password || 1018 (par->auth_info.mutual_auth && 1019 !par->is_present.target_password)) { 1020 DEBOUT(("Password missing\n")); 1021 return ISCSI_STATUS_PARAMETER_MISSING; 1022 } 1023 /* Note: Default for user-name is initiator name */ 1024 } 1025 } 1026 if (par->login_type != ISCSI_LOGINTYPE_DISCOVERY && 1027 !par->is_present.TargetName) { 1028 DEBOUT(("Target name missing, login type %d\n", par->login_type)); 1029 return ISCSI_STATUS_PARAMETER_MISSING; 1030 } 1031 if (par->is_present.MaxRecvDataSegmentLength) { 1032 if (par->MaxRecvDataSegmentLength < 512 || 1033 par->MaxRecvDataSegmentLength > 0xffffff) { 1034 DEBOUT(("MaxRecvDataSegmentLength invalid: %d\n", 1035 par->MaxRecvDataSegmentLength)); 1036 return ISCSI_STATUS_PARAMETER_INVALID; 1037 } 1038 } 1039 return 0; 1040 } 1041 1042 1043 /* 1044 * login: 1045 * Handle the login ioctl - Create a session: 1046 * Alloc the session structure 1047 * Copy session parameters 1048 * And call create_connection to establish the connection. 1049 * 1050 * Parameter: 1051 * par IN/OUT: The login parameters 1052 * l IN: The lwp pointer of the caller 1053 */ 1054 1055 static void 1056 login(iscsi_login_parameters_t *par, struct lwp *l, device_t dev) 1057 { 1058 session_t *session; 1059 int rc; 1060 1061 DEB(99, ("ISCSI: login\n")); 1062 1063 if (!iscsi_InitiatorName[0]) { 1064 DEB(1, ("No Initiator Name\n")); 1065 par->status = ISCSI_STATUS_NO_INITIATOR_NAME; 1066 return; 1067 } 1068 1069 if ((par->status = check_login_pars(par)) != 0) 1070 return; 1071 1072 /* alloc the session */ 1073 session = malloc(sizeof(*session), M_DEVBUF, M_WAITOK | M_ZERO); 1074 if (session == NULL) { 1075 DEBOUT(("No mem for session\n")); 1076 par->status = ISCSI_STATUS_NO_RESOURCES; 1077 return; 1078 } 1079 TAILQ_INIT(&session->conn_list); 1080 TAILQ_INIT(&session->ccb_pool); 1081 1082 mutex_init(&session->lock, MUTEX_DEFAULT, IPL_BIO); 1083 cv_init(&session->sess_cv, "session"); 1084 cv_init(&session->ccb_cv, "ccb"); 1085 1086 mutex_enter(&iscsi_cleanup_mtx); 1087 /* create a unique ID */ 1088 do { 1089 ++current_id; 1090 } while (!current_id || find_session(current_id) != NULL); 1091 par->session_id = session->id = current_id; 1092 mutex_exit(&iscsi_cleanup_mtx); 1093 1094 create_ccbs(session); 1095 session->login_type = par->login_type; 1096 session->CmdSN = 1; 1097 1098 if ((rc = create_connection(par, session, l)) != 0) { 1099 if (rc > 0) { 1100 destroy_ccbs(session); 1101 cv_destroy(&session->ccb_cv); 1102 cv_destroy(&session->sess_cv); 1103 mutex_destroy(&session->lock); 1104 free(session, M_DEVBUF); 1105 } 1106 return; 1107 } 1108 1109 mutex_enter(&iscsi_cleanup_mtx); 1110 TAILQ_INSERT_HEAD(&iscsi_sessions, session, sessions); 1111 mutex_exit(&iscsi_cleanup_mtx); 1112 1113 /* Session established, map LUNs? */ 1114 if (par->login_type == ISCSI_LOGINTYPE_MAP) { 1115 copyinstr(par->TargetName, session->tgtname, 1116 sizeof(session->tgtname), NULL); 1117 DEB(1, ("Login: map session %d\n", session->id)); 1118 if (!map_session(session, dev)) { 1119 DEB(1, ("Login: map session %d failed\n", session->id)); 1120 kill_session(session, ISCSI_STATUS_MAP_FAILED, 1121 LOGOUT_SESSION, FALSE); 1122 par->status = ISCSI_STATUS_MAP_FAILED; 1123 return; 1124 } 1125 } 1126 } 1127 1128 1129 /* 1130 * logout: 1131 * Handle the logout ioctl - Kill a session. 1132 * 1133 * Parameter: 1134 * par IN/OUT: The login parameters 1135 */ 1136 1137 static void 1138 logout(iscsi_logout_parameters_t *par) 1139 { 1140 session_t *session; 1141 1142 DEB(5, ("ISCSI: logout session %d\n", par->session_id)); 1143 1144 mutex_enter(&iscsi_cleanup_mtx); 1145 if ((session = find_session(par->session_id)) == NULL) { 1146 mutex_exit(&iscsi_cleanup_mtx); 1147 DEBOUT(("Session %d not found\n", par->session_id)); 1148 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1149 return; 1150 } 1151 mutex_exit(&iscsi_cleanup_mtx); 1152 /* If the session exists, this always succeeds */ 1153 par->status = ISCSI_STATUS_SUCCESS; 1154 1155 kill_session(session, ISCSI_STATUS_LOGOUT, LOGOUT_SESSION, FALSE); 1156 } 1157 1158 1159 /* 1160 * add_connection: 1161 * Handle the add_connection ioctl. 1162 * 1163 * Parameter: 1164 * par IN/OUT: The login parameters 1165 * l IN: The lwp pointer of the caller 1166 */ 1167 1168 static void 1169 add_connection(iscsi_login_parameters_t *par, struct lwp *l) 1170 { 1171 session_t *session; 1172 1173 DEB(5, ("ISCSI: add_connection to session %d\n", par->session_id)); 1174 1175 mutex_enter(&iscsi_cleanup_mtx); 1176 if ((session = find_session(par->session_id)) == NULL) { 1177 mutex_exit(&iscsi_cleanup_mtx); 1178 DEBOUT(("Session %d not found\n", par->session_id)); 1179 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1180 return; 1181 } 1182 mutex_exit(&iscsi_cleanup_mtx); 1183 if ((par->status = check_login_pars(par)) == 0) { 1184 create_connection(par, session, l); 1185 } 1186 } 1187 1188 1189 /* 1190 * remove_connection: 1191 * Handle the remove_connection ioctl. 1192 * 1193 * Parameter: 1194 * par IN/OUT: The remove parameters 1195 */ 1196 1197 static void 1198 remove_connection(iscsi_remove_parameters_t *par) 1199 { 1200 connection_t *conn; 1201 session_t *session; 1202 1203 DEB(5, ("ISCSI: remove_connection %d from session %d\n", 1204 par->connection_id, par->session_id)); 1205 1206 mutex_enter(&iscsi_cleanup_mtx); 1207 if ((session = find_session(par->session_id)) == NULL) { 1208 mutex_exit(&iscsi_cleanup_mtx); 1209 DEBOUT(("Session %d not found\n", par->session_id)); 1210 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1211 return; 1212 } 1213 1214 if ((conn = find_connection(session, par->connection_id)) == NULL) { 1215 mutex_exit(&iscsi_cleanup_mtx); 1216 DEBOUT(("Connection %d not found in session %d\n", 1217 par->connection_id, par->session_id)); 1218 1219 par->status = ISCSI_STATUS_INVALID_CONNECTION_ID; 1220 } else { 1221 mutex_exit(&iscsi_cleanup_mtx); 1222 kill_connection(conn, ISCSI_STATUS_LOGOUT, LOGOUT_CONNECTION, 1223 FALSE); 1224 par->status = ISCSI_STATUS_SUCCESS; 1225 } 1226 } 1227 1228 1229 /* 1230 * restore_connection: 1231 * Handle the restore_connection ioctl. 1232 * 1233 * Parameter: 1234 * par IN/OUT: The login parameters 1235 * l IN: The lwp pointer of the caller 1236 */ 1237 1238 static void 1239 restore_connection(iscsi_login_parameters_t *par, struct lwp *l) 1240 { 1241 session_t *session; 1242 connection_t *connection; 1243 1244 DEB(1, ("ISCSI: restore_connection %d of session %d\n", 1245 par->connection_id, par->session_id)); 1246 1247 mutex_enter(&iscsi_cleanup_mtx); 1248 if ((session = find_session(par->session_id)) == NULL) { 1249 mutex_exit(&iscsi_cleanup_mtx); 1250 DEBOUT(("Session %d not found\n", par->session_id)); 1251 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1252 return; 1253 } 1254 1255 if ((connection = find_connection(session, par->connection_id)) == NULL) { 1256 mutex_exit(&iscsi_cleanup_mtx); 1257 DEBOUT(("Connection %d not found in session %d\n", 1258 par->connection_id, par->session_id)); 1259 par->status = ISCSI_STATUS_INVALID_CONNECTION_ID; 1260 return; 1261 } 1262 mutex_exit(&iscsi_cleanup_mtx); 1263 1264 if ((par->status = check_login_pars(par)) == 0) { 1265 recreate_connection(par, session, connection, l); 1266 } 1267 } 1268 1269 1270 #ifndef ISCSI_MINIMAL 1271 1272 /* 1273 * map_databuf: 1274 * Map user-supplied data buffer into kernel space. 1275 * 1276 * Parameter: 1277 * p IN: The proc pointer of the caller 1278 * buf IN/OUT: The virtual address of the buffer, modified 1279 * on exit to reflect kernel VA. 1280 * datalen IN: The size of the data buffer 1281 * 1282 * Returns: 1283 * An ISCSI status code on error, else 0. 1284 */ 1285 1286 uint32_t 1287 map_databuf(struct proc *p, void **buf, uint32_t datalen) 1288 { 1289 vaddr_t kva, databuf, offs; 1290 int error; 1291 1292 /* page align address */ 1293 databuf = (vaddr_t) * buf & ~PAGE_MASK; 1294 /* offset of VA into page */ 1295 offs = (vaddr_t) * buf & PAGE_MASK; 1296 /* round to full page including offset */ 1297 datalen = (datalen + offs + PAGE_MASK) & ~PAGE_MASK; 1298 1299 /* Do some magic to the vm space reference count (copied from "copyin_proc") */ 1300 if ((p->p_sflag & PS_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) { 1301 return ISCSI_STATUS_NO_RESOURCES; 1302 } 1303 p->p_vmspace->vm_refcnt++; 1304 1305 /* this is lifted from uvm_io */ 1306 error = uvm_map_extract(&p->p_vmspace->vm_map, databuf, datalen, 1307 kernel_map, &kva, 1308 UVM_EXTRACT_QREF | UVM_EXTRACT_CONTIG | 1309 UVM_EXTRACT_FIXPROT); 1310 if (error) { 1311 DEBOUT(("uvm_map_extract failed, error = %d\n", error)); 1312 return ISCSI_STATUS_NO_RESOURCES; 1313 } 1314 /* add offset back into kernel VA */ 1315 *buf = (void *) (kva + offs); 1316 1317 return 0; 1318 } 1319 1320 1321 /* 1322 * unmap_databuf: 1323 * Remove kernel space mapping of data buffer. 1324 * 1325 * Parameter: 1326 * p IN: The proc pointer of the caller 1327 * buf IN: The kernel virtual address of the buffer 1328 * datalen IN: The size of the data buffer 1329 * 1330 * Returns: 1331 * An ISCSI status code on error, else 0. 1332 */ 1333 1334 void 1335 unmap_databuf(struct proc *p, void *buf, uint32_t datalen) 1336 { 1337 struct vm_map_entry *dead_entries; 1338 vaddr_t databuf; 1339 1340 /* round to full page */ 1341 datalen = (datalen + ((uintptr_t) buf & PAGE_MASK) + PAGE_MASK) & ~PAGE_MASK; 1342 /* page align address */ 1343 databuf = (vaddr_t) buf & ~PAGE_MASK; 1344 1345 /* following code lifted almost verbatim from uvm_io.c */ 1346 vm_map_lock(kernel_map); 1347 uvm_unmap_remove(kernel_map, databuf, databuf + datalen, &dead_entries, 1348 0); 1349 vm_map_unlock(kernel_map); 1350 if (dead_entries != NULL) { 1351 uvm_unmap_detach(dead_entries, AMAP_REFALL); 1352 } 1353 /* this apparently reverses the magic to the vm ref count, from copyin_proc */ 1354 uvmspace_free(p->p_vmspace); 1355 } 1356 1357 1358 /* 1359 * io_command: 1360 * Handle the io_command ioctl. 1361 * 1362 * Parameter: 1363 * par IN/OUT: The iocommand parameters 1364 * l IN: The lwp pointer of the caller 1365 */ 1366 1367 static void 1368 io_command(iscsi_iocommand_parameters_t *par, struct lwp *l) 1369 { 1370 uint32_t datalen = par->req.datalen; 1371 void *databuf = par->req.databuf; 1372 session_t *session; 1373 1374 DEB(9, ("ISCSI: io_command, SID=%d, lun=%" PRIu64 "\n", par->session_id, par->lun)); 1375 mutex_enter(&iscsi_cleanup_mtx); 1376 if ((session = find_session(par->session_id)) == NULL) { 1377 mutex_exit(&iscsi_cleanup_mtx); 1378 DEBOUT(("Session %d not found\n", par->session_id)); 1379 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1380 return; 1381 } 1382 mutex_exit(&iscsi_cleanup_mtx); 1383 1384 par->req.senselen_used = 0; 1385 par->req.datalen_used = 0; 1386 par->req.error = 0; 1387 par->req.status = 0; 1388 par->req.retsts = SCCMD_UNKNOWN; /* init to failure code */ 1389 1390 if (par->req.cmdlen > 16 || par->req.senselen > sizeof(par->req.sense)) { 1391 par->status = ISCSI_STATUS_PARAMETER_INVALID; 1392 return; 1393 } 1394 1395 if (datalen && (par->status = map_databuf(l->l_proc, 1396 &par->req.databuf, datalen)) != 0) { 1397 return; 1398 } 1399 par->status = send_io_command(session, par->lun, &par->req, 1400 par->options.immediate, par->connection_id); 1401 1402 if (datalen) { 1403 unmap_databuf(l->l_proc, par->req.databuf, datalen); 1404 par->req.databuf = databuf; /* restore original addr */ 1405 } 1406 1407 switch (par->status) { 1408 case ISCSI_STATUS_SUCCESS: 1409 par->req.retsts = SCCMD_OK; 1410 break; 1411 1412 case ISCSI_STATUS_TARGET_BUSY: 1413 par->req.retsts = SCCMD_BUSY; 1414 break; 1415 1416 case ISCSI_STATUS_TIMEOUT: 1417 case ISCSI_STATUS_SOCKET_ERROR: 1418 par->req.retsts = SCCMD_TIMEOUT; 1419 break; 1420 1421 default: 1422 par->req.retsts = (par->req.senselen_used) ? SCCMD_SENSE 1423 : SCCMD_UNKNOWN; 1424 break; 1425 } 1426 } 1427 #endif 1428 1429 /* 1430 * send_targets: 1431 * Handle the send_targets ioctl. 1432 * Note: If the passed buffer is too small to hold the complete response, 1433 * the response is kept in the session structure so it can be 1434 * retrieved with the next call to this function without having to go to 1435 * the target again. Once the complete response has been retrieved, it 1436 * is discarded. 1437 * 1438 * Parameter: 1439 * par IN/OUT: The send_targets parameters 1440 */ 1441 1442 static void 1443 send_targets(iscsi_send_targets_parameters_t *par) 1444 { 1445 int rc; 1446 uint32_t rlen, cplen; 1447 session_t *session; 1448 1449 mutex_enter(&iscsi_cleanup_mtx); 1450 if ((session = find_session(par->session_id)) == NULL) { 1451 mutex_exit(&iscsi_cleanup_mtx); 1452 DEBOUT(("Session %d not found\n", par->session_id)); 1453 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1454 return; 1455 } 1456 mutex_exit(&iscsi_cleanup_mtx); 1457 1458 DEB(9, ("ISCSI: send_targets, rsp_size=%d; Saved list: %p\n", 1459 par->response_size, session->target_list)); 1460 1461 if (session->target_list == NULL) { 1462 rc = send_send_targets(session, par->key); 1463 if (rc) { 1464 par->status = rc; 1465 return; 1466 } 1467 } 1468 rlen = session->target_list_len; 1469 par->response_total = rlen; 1470 cplen = min(par->response_size, rlen); 1471 if (cplen) { 1472 copyout(session->target_list, par->response_buffer, cplen); 1473 } 1474 par->response_used = cplen; 1475 1476 /* If all of the response was copied, don't keep it around */ 1477 if (rlen && par->response_used == rlen) { 1478 free(session->target_list, M_TEMP); 1479 session->target_list = NULL; 1480 } 1481 1482 par->status = ISCSI_STATUS_SUCCESS; 1483 } 1484 1485 1486 /* 1487 * set_node_name: 1488 * Handle the set_node_name ioctl. 1489 * 1490 * Parameter: 1491 * par IN/OUT: The set_node_name parameters 1492 */ 1493 1494 static void 1495 set_node_name(iscsi_set_node_name_parameters_t *par) 1496 { 1497 1498 if (strlen(par->InitiatorName) >= ISCSI_STRING_LENGTH || 1499 strlen(par->InitiatorAlias) >= ISCSI_STRING_LENGTH) { 1500 DEBOUT(("*** set_node_name string too long!\n")); 1501 par->status = ISCSI_STATUS_PARAMETER_INVALID; 1502 return; 1503 } 1504 strlcpy(iscsi_InitiatorName, par->InitiatorName, sizeof(iscsi_InitiatorName)); 1505 strlcpy(iscsi_InitiatorAlias, par->InitiatorAlias, sizeof(iscsi_InitiatorAlias)); 1506 memcpy(&iscsi_InitiatorISID, par->ISID, 6); 1507 DEB(5, ("ISCSI: set_node_name, ISID A=%x, B=%x, C=%x, D=%x\n", 1508 iscsi_InitiatorISID.ISID_A, iscsi_InitiatorISID.ISID_B, 1509 iscsi_InitiatorISID.ISID_C, iscsi_InitiatorISID.ISID_D)); 1510 1511 if (!iscsi_InitiatorISID.ISID_A && !iscsi_InitiatorISID.ISID_B && 1512 !iscsi_InitiatorISID.ISID_C && !iscsi_InitiatorISID.ISID_D) { 1513 iscsi_InitiatorISID.ISID_A = T_FORMAT_EN; 1514 iscsi_InitiatorISID.ISID_B = htons(0x1); 1515 iscsi_InitiatorISID.ISID_C = 0x37; 1516 iscsi_InitiatorISID.ISID_D = 0; 1517 } 1518 1519 par->status = ISCSI_STATUS_SUCCESS; 1520 } 1521 1522 1523 /* 1524 * connection_status: 1525 * Handle the connection_status ioctl. 1526 * 1527 * Parameter: 1528 * par IN/OUT: The status parameters 1529 */ 1530 1531 static void 1532 connection_status(iscsi_conn_status_parameters_t *par) 1533 { 1534 connection_t *conn; 1535 session_t *session; 1536 1537 mutex_enter(&iscsi_cleanup_mtx); 1538 if ((session = find_session(par->session_id)) == NULL) { 1539 mutex_exit(&iscsi_cleanup_mtx); 1540 par->status = ISCSI_STATUS_INVALID_SESSION_ID; 1541 return; 1542 } 1543 1544 if (par->connection_id) { 1545 conn = find_connection(session, par->connection_id); 1546 } else { 1547 conn = TAILQ_FIRST(&session->conn_list); 1548 } 1549 par->status = (conn == NULL) ? ISCSI_STATUS_INVALID_CONNECTION_ID : 1550 ISCSI_STATUS_SUCCESS; 1551 mutex_exit(&iscsi_cleanup_mtx); 1552 DEB(9, ("ISCSI: connection_status, session %d connection %d --> %d\n", 1553 par->session_id, par->connection_id, par->status)); 1554 } 1555 1556 1557 /* 1558 * get_version: 1559 * Handle the get_version ioctl. 1560 * 1561 * Parameter: 1562 * par IN/OUT: The version parameters 1563 */ 1564 1565 static void 1566 get_version(iscsi_get_version_parameters_t *par) 1567 { 1568 par->status = ISCSI_STATUS_SUCCESS; 1569 par->interface_version = INTERFACE_VERSION; 1570 par->major = VERSION_MAJOR; 1571 par->minor = VERSION_MINOR; 1572 strlcpy(par->version_string, VERSION_STRING, 1573 sizeof(par->version_string)); 1574 } 1575 1576 1577 /* -------------------------------------------------------------------- */ 1578 1579 /* 1580 * kill_all_sessions: 1581 * Terminate all sessions (called when the driver unloads). 1582 */ 1583 1584 int 1585 kill_all_sessions(void) 1586 { 1587 session_t *sess; 1588 int rc = 0; 1589 1590 mutex_enter(&iscsi_cleanup_mtx); 1591 while ((sess = TAILQ_FIRST(&iscsi_sessions)) != NULL) { 1592 mutex_exit(&iscsi_cleanup_mtx); 1593 kill_session(sess, ISCSI_STATUS_DRIVER_UNLOAD, LOGOUT_SESSION, 1594 FALSE); 1595 mutex_enter(&iscsi_cleanup_mtx); 1596 } 1597 if (TAILQ_FIRST(&iscsi_sessions) != NULL) { 1598 DEBOUT(("Failed to kill all sessions\n")); 1599 rc = EBUSY; 1600 } 1601 mutex_exit(&iscsi_cleanup_mtx); 1602 1603 return rc; 1604 } 1605 1606 /* 1607 * handle_connection_error: 1608 * Deal with a problem during send or receive. 1609 * 1610 * Parameter: 1611 * conn The connection the problem is associated with 1612 * status The status code to insert into any unfinished CCBs 1613 * dologout Whether Logout should be attempted 1614 */ 1615 1616 void 1617 handle_connection_error(connection_t *conn, uint32_t status, int dologout) 1618 { 1619 1620 DEBC(conn, 0, ("*** Connection Error, status=%d, logout=%d, state=%d\n", 1621 status, dologout, conn->state)); 1622 1623 if (!conn->terminating && conn->state <= ST_LOGOUT_SENT) { 1624 /* if we get an error while winding down, escalate it */ 1625 if (dologout >= 0 && conn->state >= ST_WINDING_DOWN) { 1626 dologout = NO_LOGOUT; 1627 } 1628 kill_connection(conn, status, dologout, TRUE); 1629 } 1630 } 1631 1632 /* 1633 * add a connection to the cleanup list 1634 */ 1635 void 1636 add_connection_cleanup(connection_t *conn) 1637 { 1638 mutex_enter(&iscsi_cleanup_mtx); 1639 TAILQ_INSERT_TAIL(&iscsi_cleanupc_list, conn, connections); 1640 iscsi_notify_cleanup(); 1641 mutex_exit(&iscsi_cleanup_mtx); 1642 } 1643 1644 /* 1645 * callout wrappers for timeouts, the work is done by the cleanup thread 1646 */ 1647 void 1648 connection_timeout_co(void *par) 1649 { 1650 connection_t *conn = par; 1651 1652 mutex_enter(&iscsi_cleanup_mtx); 1653 conn->timedout = TOUT_QUEUED; 1654 TAILQ_INSERT_TAIL(&iscsi_timeout_conn_list, conn, tchain); 1655 iscsi_notify_cleanup(); 1656 mutex_exit(&iscsi_cleanup_mtx); 1657 } 1658 1659 void 1660 connection_timeout_start(connection_t *conn, int ticks) 1661 { 1662 mutex_enter(&iscsi_cleanup_mtx); 1663 if (conn->timedout != TOUT_QUEUED) { 1664 conn->timedout = TOUT_ARMED; 1665 callout_schedule(&conn->timeout, ticks); 1666 } 1667 mutex_exit(&iscsi_cleanup_mtx); 1668 } 1669 1670 void 1671 connection_timeout_stop(connection_t *conn) 1672 { 1673 callout_stop(&conn->timeout); 1674 mutex_enter(&iscsi_cleanup_mtx); 1675 if (conn->timedout == TOUT_QUEUED) { 1676 TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, tchain); 1677 conn->timedout = TOUT_NONE; 1678 } 1679 if (curlwp != iscsi_cleanproc) { 1680 while (conn->timedout == TOUT_BUSY) 1681 kpause("connbusy", false, 1, &iscsi_cleanup_mtx); 1682 } 1683 mutex_exit(&iscsi_cleanup_mtx); 1684 } 1685 1686 void 1687 ccb_timeout_co(void *par) 1688 { 1689 ccb_t *ccb = par; 1690 1691 mutex_enter(&iscsi_cleanup_mtx); 1692 ccb->timedout = TOUT_QUEUED; 1693 TAILQ_INSERT_TAIL(&iscsi_timeout_ccb_list, ccb, tchain); 1694 iscsi_notify_cleanup(); 1695 mutex_exit(&iscsi_cleanup_mtx); 1696 } 1697 1698 void 1699 ccb_timeout_start(ccb_t *ccb, int ticks) 1700 { 1701 mutex_enter(&iscsi_cleanup_mtx); 1702 if (ccb->timedout != TOUT_QUEUED) { 1703 ccb->timedout = TOUT_ARMED; 1704 callout_schedule(&ccb->timeout, ticks); 1705 } 1706 mutex_exit(&iscsi_cleanup_mtx); 1707 } 1708 1709 void 1710 ccb_timeout_stop(ccb_t *ccb) 1711 { 1712 callout_stop(&ccb->timeout); 1713 mutex_enter(&iscsi_cleanup_mtx); 1714 if (ccb->timedout == TOUT_QUEUED) { 1715 TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, tchain); 1716 ccb->timedout = TOUT_NONE; 1717 } 1718 if (curlwp != iscsi_cleanproc) { 1719 while (ccb->timedout == TOUT_BUSY) 1720 kpause("ccbbusy", false, 1, &iscsi_cleanup_mtx); 1721 } 1722 mutex_exit(&iscsi_cleanup_mtx); 1723 } 1724 1725 /* 1726 * iscsi_cleanup_thread 1727 * Global thread to handle connection and session cleanup after termination. 1728 */ 1729 1730 static void 1731 iscsi_cleanup_thread(void *par) 1732 { 1733 int s, rc; 1734 session_t *sess, *nxts; 1735 connection_t *conn, *nxtc; 1736 ccb_t *ccb; 1737 1738 mutex_enter(&iscsi_cleanup_mtx); 1739 while (iscsi_num_send_threads || !iscsi_detaching || 1740 !TAILQ_EMPTY(&iscsi_cleanupc_list) || !TAILQ_EMPTY(&iscsi_cleanups_list)) { 1741 TAILQ_FOREACH_SAFE(conn, &iscsi_cleanupc_list, connections, nxtc) { 1742 1743 TAILQ_REMOVE(&iscsi_cleanupc_list, conn, connections); 1744 mutex_exit(&iscsi_cleanup_mtx); 1745 1746 sess = conn->session; 1747 1748 /* 1749 * This implies that connection cleanup only runs when 1750 * the send/recv threads have been killed 1751 */ 1752 DEBC(conn, 5, ("Cleanup: Waiting for threads to exit\n")); 1753 while (conn->sendproc || conn->rcvproc) 1754 kpause("threads", false, hz, NULL); 1755 1756 for (s=1; conn->usecount > 0 && s < 3; ++s) 1757 kpause("usecount", false, hz, NULL); 1758 1759 if (conn->usecount > 0) { 1760 DEBC(conn, 5, ("Cleanup: %d CCBs busy\n", conn->usecount)); 1761 /* retry later */ 1762 mutex_enter(&iscsi_cleanup_mtx); 1763 TAILQ_INSERT_HEAD(&iscsi_cleanupc_list, conn, connections); 1764 continue; 1765 } 1766 1767 KASSERT(!conn->in_session); 1768 1769 callout_halt(&conn->timeout, &iscsi_cleanup_mtx); 1770 closef(conn->sock); 1771 callout_destroy(&conn->timeout); 1772 cv_destroy(&conn->idle_cv); 1773 cv_destroy(&conn->ccb_cv); 1774 cv_destroy(&conn->pdu_cv); 1775 cv_destroy(&conn->conn_cv); 1776 mutex_destroy(&conn->lock); 1777 free(conn, M_DEVBUF); 1778 1779 mutex_enter(&iscsi_cleanup_mtx); 1780 1781 if (--sess->total_connections == 0) { 1782 DEB(1, ("Cleanup: session %d\n", sess->id)); 1783 if (!sess->terminating) { 1784 sess->terminating = ISCSI_CONNECTION_TERMINATED; 1785 KASSERT(sess->sessions.tqe_prev != NULL); 1786 TAILQ_REMOVE(&iscsi_sessions, sess, sessions); 1787 sess->sessions.tqe_next = NULL; 1788 sess->sessions.tqe_prev = NULL; 1789 } 1790 KASSERT(sess->sessions.tqe_prev == NULL); 1791 TAILQ_INSERT_HEAD(&iscsi_cleanups_list, sess, sessions); 1792 } 1793 } 1794 1795 TAILQ_FOREACH_SAFE(sess, &iscsi_cleanups_list, sessions, nxts) { 1796 if (sess->refcount > 0) 1797 continue; 1798 TAILQ_REMOVE(&iscsi_cleanups_list, sess, sessions); 1799 sess->sessions.tqe_next = NULL; 1800 sess->sessions.tqe_prev = NULL; 1801 mutex_exit(&iscsi_cleanup_mtx); 1802 1803 DEB(1, ("Cleanup: Unmap session %d\n", sess->id)); 1804 if (unmap_session(sess) == 0) { 1805 DEB(1, ("Cleanup: Unmap session %d failed\n", sess->id)); 1806 mutex_enter(&iscsi_cleanup_mtx); 1807 TAILQ_INSERT_HEAD(&iscsi_cleanups_list, sess, sessions); 1808 continue; 1809 } 1810 1811 if (sess->target_list != NULL) 1812 free(sess->target_list, M_TEMP); 1813 1814 /* notify event handlers of session shutdown */ 1815 add_event(ISCSI_SESSION_TERMINATED, sess->id, 0, sess->terminating); 1816 DEB(1, ("Cleanup: session ended %d\n", sess->id)); 1817 1818 destroy_ccbs(sess); 1819 cv_destroy(&sess->ccb_cv); 1820 cv_destroy(&sess->sess_cv); 1821 mutex_destroy(&sess->lock); 1822 free(sess, M_DEVBUF); 1823 1824 mutex_enter(&iscsi_cleanup_mtx); 1825 } 1826 1827 /* handle ccb timeouts */ 1828 while ((ccb = TAILQ_FIRST(&iscsi_timeout_ccb_list)) != NULL) { 1829 TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, tchain); 1830 KASSERT(ccb->timedout == TOUT_QUEUED); 1831 ccb->timedout = TOUT_BUSY; 1832 mutex_exit(&iscsi_cleanup_mtx); 1833 ccb_timeout(ccb); 1834 mutex_enter(&iscsi_cleanup_mtx); 1835 if (ccb->timedout == TOUT_BUSY) 1836 ccb->timedout = TOUT_NONE; 1837 } 1838 1839 /* handle connection timeouts */ 1840 while ((conn = TAILQ_FIRST(&iscsi_timeout_conn_list)) != NULL) { 1841 TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, tchain); 1842 KASSERT(conn->timedout == TOUT_QUEUED); 1843 conn->timedout = TOUT_BUSY; 1844 mutex_exit(&iscsi_cleanup_mtx); 1845 connection_timeout(conn); 1846 mutex_enter(&iscsi_cleanup_mtx); 1847 if (conn->timedout == TOUT_BUSY) 1848 conn->timedout = TOUT_NONE; 1849 } 1850 1851 /* Go to sleep, but wake up every 30 seconds to 1852 * check for dead event handlers */ 1853 rc = cv_timedwait(&iscsi_cleanup_cv, &iscsi_cleanup_mtx, 1854 (TAILQ_FIRST(&event_handlers)) ? 120 * hz : 0); 1855 1856 /* if timed out, not woken up */ 1857 if (rc == EWOULDBLOCK) 1858 check_event_handlers(); 1859 } 1860 mutex_exit(&iscsi_cleanup_mtx); 1861 1862 add_event(ISCSI_DRIVER_TERMINATING, 0, 0, ISCSI_STATUS_DRIVER_UNLOAD); 1863 1864 /* 1865 * Wait for all event handlers to deregister, but don't wait more 1866 * than 1 minute (assume registering app has died if it takes longer). 1867 */ 1868 mutex_enter(&iscsi_cleanup_mtx); 1869 for (s = 0; TAILQ_FIRST(&event_handlers) != NULL && s < 60; s++) 1870 kpause("waiteventclr", true, hz, &iscsi_cleanup_mtx); 1871 mutex_exit(&iscsi_cleanup_mtx); 1872 1873 iscsi_cleanproc = NULL; 1874 DEB(5, ("Cleanup thread exits\n")); 1875 kthread_exit(0); 1876 } 1877 1878 void 1879 iscsi_init_cleanup(void) 1880 { 1881 1882 mutex_init(&iscsi_cleanup_mtx, MUTEX_DEFAULT, IPL_BIO); 1883 cv_init(&iscsi_cleanup_cv, "cleanup"); 1884 cv_init(&iscsi_event_cv, "iscsievtwait"); 1885 1886 if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, iscsi_cleanup_thread, 1887 NULL, &iscsi_cleanproc, "iscsi_cleanup") != 0) { 1888 panic("Can't create cleanup thread!"); 1889 } 1890 } 1891 1892 int 1893 iscsi_destroy_cleanup(void) 1894 { 1895 1896 iscsi_detaching = true; 1897 mutex_enter(&iscsi_cleanup_mtx); 1898 while (iscsi_cleanproc != NULL) { 1899 iscsi_notify_cleanup(); 1900 kpause("detach_wait", false, hz, &iscsi_cleanup_mtx); 1901 } 1902 mutex_exit(&iscsi_cleanup_mtx); 1903 1904 cv_destroy(&iscsi_event_cv); 1905 cv_destroy(&iscsi_cleanup_cv); 1906 mutex_destroy(&iscsi_cleanup_mtx); 1907 1908 return 0; 1909 } 1910 1911 void 1912 iscsi_notify_cleanup(void) 1913 { 1914 KASSERT(mutex_owned(&iscsi_cleanup_mtx)); 1915 1916 cv_signal(&iscsi_cleanup_cv); 1917 } 1918 1919 1920 /* -------------------------------------------------------------------- */ 1921 1922 /* 1923 * iscsi_ioctl: 1924 * Driver ioctl entry. 1925 * 1926 * Parameter: 1927 * file File structure 1928 * cmd The ioctl Command 1929 * addr IN/OUT: The command parameter 1930 * flag Flags (ignored) 1931 * l IN: The lwp object of the caller 1932 */ 1933 1934 int 1935 iscsiioctl(struct file *fp, u_long cmd, void *addr) 1936 { 1937 struct lwp *l = curlwp; 1938 struct iscsifd *d = fp->f_iscsi; 1939 1940 DEB(1, ("ISCSI Ioctl cmd = %x\n", (int) cmd)); 1941 1942 switch (cmd) { 1943 case ISCSI_GET_VERSION: 1944 get_version((iscsi_get_version_parameters_t *) addr); 1945 break; 1946 1947 case ISCSI_LOGIN: 1948 login((iscsi_login_parameters_t *) addr, l, d->dev); 1949 break; 1950 1951 case ISCSI_ADD_CONNECTION: 1952 add_connection((iscsi_login_parameters_t *) addr, l); 1953 break; 1954 1955 case ISCSI_RESTORE_CONNECTION: 1956 restore_connection((iscsi_login_parameters_t *) addr, l); 1957 break; 1958 1959 case ISCSI_LOGOUT: 1960 logout((iscsi_logout_parameters_t *) addr); 1961 break; 1962 1963 case ISCSI_REMOVE_CONNECTION: 1964 remove_connection((iscsi_remove_parameters_t *) addr); 1965 break; 1966 1967 #ifndef ISCSI_MINIMAL 1968 case ISCSI_IO_COMMAND: 1969 io_command((iscsi_iocommand_parameters_t *) addr, l); 1970 break; 1971 #endif 1972 1973 case ISCSI_SEND_TARGETS: 1974 send_targets((iscsi_send_targets_parameters_t *) addr); 1975 break; 1976 1977 case ISCSI_SET_NODE_NAME: 1978 set_node_name((iscsi_set_node_name_parameters_t *) addr); 1979 break; 1980 1981 case ISCSI_CONNECTION_STATUS: 1982 connection_status((iscsi_conn_status_parameters_t *) addr); 1983 break; 1984 1985 case ISCSI_REGISTER_EVENT: 1986 register_event((iscsi_register_event_parameters_t *) addr); 1987 break; 1988 1989 case ISCSI_DEREGISTER_EVENT: 1990 deregister_event((iscsi_register_event_parameters_t *) addr); 1991 break; 1992 1993 case ISCSI_WAIT_EVENT: 1994 check_event((iscsi_wait_event_parameters_t *) addr, TRUE); 1995 break; 1996 1997 case ISCSI_POLL_EVENT: 1998 check_event((iscsi_wait_event_parameters_t *) addr, FALSE); 1999 break; 2000 2001 default: 2002 DEBOUT(("Invalid IO-Control Code\n")); 2003 return ENOTTY; 2004 } 2005 2006 /* 2007 * NOTE: We return 0 even if the function fails as long as the ioctl code 2008 * is good, so the status code is copied back to the caller. 2009 */ 2010 return 0; 2011 } 2012