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