1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk/stdinc.h" 36 37 #include "CUnit/Basic.h" 38 #include "spdk_cunit.h" 39 40 #include "spdk/util.h" 41 42 #include "scsi/dev.c" 43 #include "scsi/port.c" 44 45 #include "spdk_internal/mock.h" 46 47 DEFINE_STUB(spdk_scsi_lun_is_removing, bool, 48 (const struct spdk_scsi_lun *lun), false); 49 50 static char *g_bdev_names[] = { 51 "malloc0", 52 "malloc1", 53 "malloc2", 54 "malloc4", 55 }; 56 57 static struct spdk_scsi_port *g_initiator_port_with_pending_tasks = NULL; 58 static struct spdk_scsi_port *g_initiator_port_with_pending_mgmt_tasks = NULL; 59 60 static struct spdk_scsi_task * 61 spdk_get_task(uint32_t *owner_task_ctr) 62 { 63 struct spdk_scsi_task *task; 64 65 task = calloc(1, sizeof(*task)); 66 if (!task) { 67 return NULL; 68 } 69 70 return task; 71 } 72 73 void 74 spdk_scsi_task_put(struct spdk_scsi_task *task) 75 { 76 free(task); 77 } 78 79 struct spdk_scsi_lun *scsi_lun_construct(const char *bdev_name, 80 void (*resize_cb)(const struct spdk_scsi_lun *, void *), 81 void *resize_ctx, 82 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 83 void *hotremove_ctx) 84 { 85 struct spdk_scsi_lun *lun; 86 size_t i; 87 88 for (i = 0; i < SPDK_COUNTOF(g_bdev_names); i++) { 89 if (strcmp(bdev_name, g_bdev_names[i]) == 0) { 90 lun = calloc(1, sizeof(struct spdk_scsi_lun)); 91 SPDK_CU_ASSERT_FATAL(lun != NULL); 92 93 return lun; 94 } 95 } 96 97 return NULL; 98 } 99 100 void 101 scsi_lun_destruct(struct spdk_scsi_lun *lun) 102 { 103 free(lun); 104 } 105 106 DEFINE_STUB_V(scsi_lun_execute_mgmt_task, 107 (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)); 108 109 DEFINE_STUB_V(scsi_lun_execute_task, 110 (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)); 111 112 DEFINE_STUB(scsi_lun_allocate_io_channel, int, 113 (struct spdk_scsi_lun *lun), 0); 114 115 DEFINE_STUB_V(scsi_lun_free_io_channel, (struct spdk_scsi_lun *lun)); 116 117 bool 118 scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun, 119 const struct spdk_scsi_port *initiator_port) 120 { 121 return (g_initiator_port_with_pending_mgmt_tasks == initiator_port); 122 } 123 124 bool 125 scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun, 126 const struct spdk_scsi_port *initiator_port) 127 { 128 return (g_initiator_port_with_pending_tasks == initiator_port); 129 } 130 131 static void 132 dev_destruct_null_dev(void) 133 { 134 /* pass null for the dev */ 135 spdk_scsi_dev_destruct(NULL, NULL, NULL); 136 } 137 138 static void 139 dev_destruct_zero_luns(void) 140 { 141 struct spdk_scsi_dev dev = { .is_allocated = 1 }; 142 143 /* No luns attached to the dev */ 144 145 /* free the dev */ 146 spdk_scsi_dev_destruct(&dev, NULL, NULL); 147 } 148 149 static void 150 dev_destruct_null_lun(void) 151 { 152 struct spdk_scsi_dev dev = { .is_allocated = 1 }; 153 154 /* pass null for the lun */ 155 TAILQ_INIT(&dev.luns); 156 157 /* free the dev */ 158 spdk_scsi_dev_destruct(&dev, NULL, NULL); 159 } 160 161 static void 162 dev_destruct_success(void) 163 { 164 struct spdk_scsi_dev dev = { 165 .is_allocated = 1, 166 .luns = TAILQ_HEAD_INITIALIZER(dev.luns), 167 }; 168 int rc; 169 170 /* dev with a single lun */ 171 rc = spdk_scsi_dev_add_lun(&dev, "malloc0", 0, NULL, NULL); 172 173 CU_ASSERT(rc == 0); 174 175 /* free the dev */ 176 spdk_scsi_dev_destruct(&dev, NULL, NULL); 177 178 } 179 180 static void 181 dev_construct_num_luns_zero(void) 182 { 183 struct spdk_scsi_dev *dev; 184 const char *bdev_name_list[1] = {}; 185 int lun_id_list[1] = { 0 }; 186 187 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 0, 188 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 189 190 /* dev should be null since we passed num_luns = 0 */ 191 CU_ASSERT_TRUE(dev == NULL); 192 } 193 194 static void 195 dev_construct_no_lun_zero(void) 196 { 197 struct spdk_scsi_dev *dev; 198 const char *bdev_name_list[1] = {}; 199 int lun_id_list[1] = { 0 }; 200 201 lun_id_list[0] = 1; 202 203 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 1, 204 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 205 206 /* dev should be null since no LUN0 was specified (lun_id_list[0] = 1) */ 207 CU_ASSERT_TRUE(dev == NULL); 208 } 209 210 static void 211 dev_construct_null_lun(void) 212 { 213 struct spdk_scsi_dev *dev; 214 const char *bdev_name_list[1] = {}; 215 int lun_id_list[1] = { 0 }; 216 217 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 1, 218 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 219 220 /* dev should be null since no LUN0 was specified (lun_list[0] = NULL) */ 221 CU_ASSERT_TRUE(dev == NULL); 222 } 223 224 static void 225 dev_construct_name_too_long(void) 226 { 227 struct spdk_scsi_dev *dev; 228 const char *bdev_name_list[1] = {"malloc0"}; 229 int lun_id_list[1] = { 0 }; 230 char name[SPDK_SCSI_DEV_MAX_NAME + 1 + 1]; 231 232 /* Try to construct a dev with a name that is one byte longer than allowed. */ 233 memset(name, 'x', sizeof(name) - 1); 234 name[sizeof(name) - 1] = '\0'; 235 236 dev = spdk_scsi_dev_construct(name, bdev_name_list, lun_id_list, 1, 237 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 238 239 CU_ASSERT(dev == NULL); 240 } 241 242 static void 243 dev_construct_success(void) 244 { 245 struct spdk_scsi_dev *dev; 246 const char *bdev_name_list[1] = {"malloc0"}; 247 int lun_id_list[1] = { 0 }; 248 249 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 1, 250 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 251 252 /* Successfully constructs and returns a dev */ 253 CU_ASSERT_TRUE(dev != NULL); 254 255 /* free the dev */ 256 spdk_scsi_dev_destruct(dev, NULL, NULL); 257 } 258 259 static void 260 dev_construct_success_lun_zero_not_first(void) 261 { 262 struct spdk_scsi_dev *dev; 263 const char *bdev_name_list[2] = {"malloc1", "malloc0"}; 264 int lun_id_list[2] = { 1, 0 }; 265 266 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 2, 267 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 268 269 /* Successfully constructs and returns a dev */ 270 CU_ASSERT_TRUE(dev != NULL); 271 272 /* free the dev */ 273 spdk_scsi_dev_destruct(dev, NULL, NULL); 274 } 275 276 static void 277 dev_queue_mgmt_task_success(void) 278 { 279 struct spdk_scsi_dev *dev; 280 const char *bdev_name_list[1] = {"malloc0"}; 281 int lun_id_list[1] = { 0 }; 282 struct spdk_scsi_task *task; 283 284 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 1, 285 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 286 287 /* Successfully constructs and returns a dev */ 288 CU_ASSERT_TRUE(dev != NULL); 289 290 task = spdk_get_task(NULL); 291 292 task->function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 293 spdk_scsi_dev_queue_mgmt_task(dev, task); 294 295 spdk_scsi_task_put(task); 296 297 spdk_scsi_dev_destruct(dev, NULL, NULL); 298 } 299 300 static void 301 dev_queue_task_success(void) 302 { 303 struct spdk_scsi_dev *dev; 304 const char *bdev_name_list[1] = {"malloc0"}; 305 int lun_id_list[1] = { 0 }; 306 struct spdk_scsi_task *task; 307 308 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 1, 309 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 310 311 /* Successfully constructs and returns a dev */ 312 CU_ASSERT_TRUE(dev != NULL); 313 314 task = spdk_get_task(NULL); 315 316 spdk_scsi_dev_queue_task(dev, task); 317 318 spdk_scsi_task_put(task); 319 320 spdk_scsi_dev_destruct(dev, NULL, NULL); 321 } 322 323 static void 324 dev_stop_success(void) 325 { 326 struct spdk_scsi_dev dev = { 0 }; 327 struct spdk_scsi_task *task; 328 struct spdk_scsi_task *task_mgmt; 329 330 task = spdk_get_task(NULL); 331 332 spdk_scsi_dev_queue_task(&dev, task); 333 334 task_mgmt = spdk_get_task(NULL); 335 336 /* Enqueue the tasks into dev->task_mgmt_submit_queue */ 337 task->function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 338 spdk_scsi_dev_queue_mgmt_task(&dev, task_mgmt); 339 340 spdk_scsi_task_put(task); 341 spdk_scsi_task_put(task_mgmt); 342 } 343 344 static void 345 dev_add_port_max_ports(void) 346 { 347 struct spdk_scsi_dev dev = { 0 }; 348 const char *name; 349 int id, rc; 350 351 /* dev is set to SPDK_SCSI_DEV_MAX_PORTS */ 352 dev.num_ports = SPDK_SCSI_DEV_MAX_PORTS; 353 name = "Name of Port"; 354 id = 1; 355 356 rc = spdk_scsi_dev_add_port(&dev, id, name); 357 358 /* returns -1; since the dev already has maximum 359 * number of ports (SPDK_SCSI_DEV_MAX_PORTS) */ 360 CU_ASSERT_TRUE(rc < 0); 361 } 362 363 static void 364 dev_add_port_construct_failure1(void) 365 { 366 struct spdk_scsi_dev dev = { 0 }; 367 const int port_name_length = SPDK_SCSI_PORT_MAX_NAME_LENGTH + 2; 368 char name[port_name_length]; 369 uint64_t id; 370 int rc; 371 372 dev.num_ports = 1; 373 /* Set the name such that the length exceeds SPDK_SCSI_PORT_MAX_NAME_LENGTH 374 * SPDK_SCSI_PORT_MAX_NAME_LENGTH = 256 */ 375 memset(name, 'a', port_name_length - 1); 376 name[port_name_length - 1] = '\0'; 377 id = 1; 378 379 rc = spdk_scsi_dev_add_port(&dev, id, name); 380 381 /* returns -1; since the length of the name exceeds 382 * SPDK_SCSI_PORT_MAX_NAME_LENGTH */ 383 CU_ASSERT_TRUE(rc < 0); 384 } 385 386 static void 387 dev_add_port_construct_failure2(void) 388 { 389 struct spdk_scsi_dev dev = { 0 }; 390 const char *name; 391 uint64_t id; 392 int rc; 393 394 dev.num_ports = 1; 395 name = "Name of Port"; 396 id = 1; 397 398 /* Initialize port[0] to be valid and its index is set to 1 */ 399 dev.port[0].id = id; 400 dev.port[0].is_used = 1; 401 402 rc = spdk_scsi_dev_add_port(&dev, id, name); 403 404 /* returns -1; since the dev already has a port whose index to be 1 */ 405 CU_ASSERT_TRUE(rc < 0); 406 } 407 408 static void 409 dev_add_port_success1(void) 410 { 411 struct spdk_scsi_dev dev = { 0 }; 412 const char *name; 413 int id, rc; 414 415 dev.num_ports = 1; 416 name = "Name of Port"; 417 id = 1; 418 419 rc = spdk_scsi_dev_add_port(&dev, id, name); 420 421 /* successfully adds a port */ 422 CU_ASSERT_EQUAL(rc, 0); 423 /* Assert num_ports has been incremented to 2 */ 424 CU_ASSERT_EQUAL(dev.num_ports, 2); 425 } 426 427 static void 428 dev_add_port_success2(void) 429 { 430 struct spdk_scsi_dev dev = { 0 }; 431 const char *name; 432 uint64_t id; 433 int rc; 434 435 dev.num_ports = 1; 436 name = "Name of Port"; 437 id = 1; 438 /* set id of invalid port[0] to 1. This must be ignored */ 439 dev.port[0].id = id; 440 dev.port[0].is_used = 0; 441 442 rc = spdk_scsi_dev_add_port(&dev, id, name); 443 444 /* successfully adds a port */ 445 CU_ASSERT_EQUAL(rc, 0); 446 /* Assert num_ports has been incremented to 1 */ 447 CU_ASSERT_EQUAL(dev.num_ports, 2); 448 } 449 450 static void 451 dev_add_port_success3(void) 452 { 453 struct spdk_scsi_dev dev = { 0 }; 454 const char *name; 455 uint64_t add_id; 456 int rc; 457 458 dev.num_ports = 1; 459 name = "Name of Port"; 460 dev.port[0].id = 1; 461 dev.port[0].is_used = 1; 462 add_id = 2; 463 464 /* Add a port with id = 2 */ 465 rc = spdk_scsi_dev_add_port(&dev, add_id, name); 466 467 /* successfully adds a port */ 468 CU_ASSERT_EQUAL(rc, 0); 469 /* Assert num_ports has been incremented to 2 */ 470 CU_ASSERT_EQUAL(dev.num_ports, 2); 471 } 472 473 static void 474 dev_find_port_by_id_num_ports_zero(void) 475 { 476 struct spdk_scsi_dev dev = { 0 }; 477 struct spdk_scsi_port *rp_port; 478 uint64_t id; 479 480 dev.num_ports = 0; 481 id = 1; 482 483 rp_port = spdk_scsi_dev_find_port_by_id(&dev, id); 484 485 /* returns null; since dev's num_ports is 0 */ 486 CU_ASSERT_TRUE(rp_port == NULL); 487 } 488 489 static void 490 dev_find_port_by_id_id_not_found_failure(void) 491 { 492 struct spdk_scsi_dev dev = { 0 }; 493 struct spdk_scsi_port *rp_port; 494 const char *name; 495 int rc; 496 uint64_t id, find_id; 497 498 id = 1; 499 dev.num_ports = 1; 500 name = "Name of Port"; 501 find_id = 2; 502 503 /* Add a port with id = 1 */ 504 rc = spdk_scsi_dev_add_port(&dev, id, name); 505 506 CU_ASSERT_EQUAL(rc, 0); 507 508 /* Find port with id = 2 */ 509 rp_port = spdk_scsi_dev_find_port_by_id(&dev, find_id); 510 511 /* returns null; failed to find port specified by id = 2 */ 512 CU_ASSERT_TRUE(rp_port == NULL); 513 } 514 515 static void 516 dev_find_port_by_id_success(void) 517 { 518 struct spdk_scsi_dev dev = { 0 }; 519 struct spdk_scsi_port *rp_port; 520 const char *name; 521 int rc; 522 uint64_t id; 523 524 id = 1; 525 dev.num_ports = 1; 526 name = "Name of Port"; 527 528 /* Add a port */ 529 rc = spdk_scsi_dev_add_port(&dev, id, name); 530 531 CU_ASSERT_EQUAL(rc, 0); 532 533 /* Find port by the same id as the one added above */ 534 rp_port = spdk_scsi_dev_find_port_by_id(&dev, id); 535 536 /* Successfully found port specified by id */ 537 CU_ASSERT_TRUE(rp_port != NULL); 538 if (rp_port != NULL) { 539 /* Assert the found port's id and name are same as 540 * the port added. */ 541 CU_ASSERT_EQUAL(rp_port->id, 1); 542 CU_ASSERT_STRING_EQUAL(rp_port->name, "Name of Port"); 543 } 544 } 545 546 static void 547 dev_add_lun_bdev_not_found(void) 548 { 549 int rc; 550 struct spdk_scsi_dev dev = { .luns = TAILQ_HEAD_INITIALIZER(dev.luns), }; 551 552 rc = spdk_scsi_dev_add_lun(&dev, "malloc3", 0, NULL, NULL); 553 554 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&dev.luns)); 555 CU_ASSERT_NOT_EQUAL(rc, 0); 556 } 557 558 static void 559 dev_add_lun_no_free_lun_id(void) 560 { 561 int rc; 562 int i; 563 struct spdk_scsi_dev dev = { .luns = TAILQ_HEAD_INITIALIZER(dev.luns), }; 564 struct spdk_scsi_lun *lun; 565 566 lun = calloc(SPDK_SCSI_DEV_MAX_LUN, sizeof(*lun)); 567 SPDK_CU_ASSERT_FATAL(lun != NULL); 568 569 for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { 570 lun[i].id = i; 571 TAILQ_INSERT_TAIL(&dev.luns, &lun[i], tailq); 572 } 573 574 rc = spdk_scsi_dev_add_lun(&dev, "malloc0", -1, NULL, NULL); 575 576 CU_ASSERT_NOT_EQUAL(rc, 0); 577 578 free(lun); 579 } 580 581 static void 582 dev_add_lun_success1(void) 583 { 584 int rc; 585 struct spdk_scsi_dev dev = { .luns = TAILQ_HEAD_INITIALIZER(dev.luns), }; 586 587 rc = spdk_scsi_dev_add_lun(&dev, "malloc0", -1, NULL, NULL); 588 589 CU_ASSERT_EQUAL(rc, 0); 590 591 spdk_scsi_dev_destruct(&dev, NULL, NULL); 592 } 593 594 static void 595 dev_add_lun_success2(void) 596 { 597 int rc; 598 struct spdk_scsi_dev dev = { .luns = TAILQ_HEAD_INITIALIZER(dev.luns), }; 599 600 rc = spdk_scsi_dev_add_lun(&dev, "malloc0", 0, NULL, NULL); 601 602 CU_ASSERT_EQUAL(rc, 0); 603 604 spdk_scsi_dev_destruct(&dev, NULL, NULL); 605 } 606 607 static void 608 dev_check_pending_tasks(void) 609 { 610 struct spdk_scsi_dev dev = { .luns = TAILQ_HEAD_INITIALIZER(dev.luns), }; 611 struct spdk_scsi_lun lun = { .id = SPDK_SCSI_DEV_MAX_LUN - 1, }; 612 struct spdk_scsi_port initiator_port = {}; 613 614 g_initiator_port_with_pending_tasks = NULL; 615 g_initiator_port_with_pending_mgmt_tasks = NULL; 616 617 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, NULL) == false); 618 619 TAILQ_INSERT_TAIL(&dev.luns, &lun, tailq); 620 621 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, NULL) == true); 622 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, &initiator_port) == false); 623 624 g_initiator_port_with_pending_tasks = &initiator_port; 625 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, NULL) == true); 626 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, &initiator_port) == true); 627 628 g_initiator_port_with_pending_tasks = NULL; 629 g_initiator_port_with_pending_mgmt_tasks = &initiator_port; 630 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, NULL) == true); 631 CU_ASSERT(spdk_scsi_dev_has_pending_tasks(&dev, &initiator_port) == true); 632 } 633 634 static void 635 dev_iterate_luns(void) 636 { 637 struct spdk_scsi_dev *dev; 638 struct spdk_scsi_lun *lun; 639 const char *bdev_name_list[3] = {"malloc0", "malloc2", "malloc4"}; 640 int lun_id_list[3] = {0, 2, 4}; 641 642 dev = spdk_scsi_dev_construct("Name", bdev_name_list, lun_id_list, 3, 643 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 644 645 /* Successfully constructs and returns a dev */ 646 CU_ASSERT_TRUE(dev != NULL); 647 648 lun = spdk_scsi_dev_get_first_lun(dev); 649 CU_ASSERT(lun != NULL); 650 CU_ASSERT(lun->id == 0); 651 lun = spdk_scsi_dev_get_next_lun(lun); 652 CU_ASSERT(lun != NULL); 653 CU_ASSERT(lun->id == 2); 654 lun = spdk_scsi_dev_get_next_lun(lun); 655 CU_ASSERT(lun != NULL); 656 CU_ASSERT(lun->id == 4); 657 lun = spdk_scsi_dev_get_next_lun(lun); 658 CU_ASSERT(lun == NULL); 659 660 /* free the dev */ 661 spdk_scsi_dev_destruct(dev, NULL, NULL); 662 } 663 664 static void 665 dev_find_free_lun(void) 666 { 667 struct spdk_scsi_dev dev = { .luns = TAILQ_HEAD_INITIALIZER(dev.luns), }; 668 struct spdk_scsi_lun *lun, *prev_lun = NULL; 669 int i, rc; 670 671 lun = calloc(SPDK_SCSI_DEV_MAX_LUN, sizeof(*lun)); 672 SPDK_CU_ASSERT_FATAL(lun != NULL); 673 674 for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { 675 lun[i].id = i; 676 } 677 678 /* LUN ID 0, 1, 15, 16, 17, SPDK_SCSI_DEV_MAX_LUN - 2, and SPDK_SCSI_DEV_MAX_LUN - 1 679 * are free first. LUNs are required to be sorted by LUN ID. 680 */ 681 for (i = 2; i < 15; i++) { 682 TAILQ_INSERT_TAIL(&dev.luns, &lun[i], tailq); 683 } 684 685 for (i = 18; i < SPDK_SCSI_DEV_MAX_LUN - 2; i++) { 686 TAILQ_INSERT_TAIL(&dev.luns, &lun[i], tailq); 687 } 688 689 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 690 CU_ASSERT(rc == 0); 691 CU_ASSERT(prev_lun == NULL); 692 693 rc = scsi_dev_find_free_lun(&dev, 0, &prev_lun); 694 CU_ASSERT(rc == 0); 695 CU_ASSERT(prev_lun == NULL); 696 697 rc = scsi_dev_find_free_lun(&dev, 1, &prev_lun); 698 CU_ASSERT(rc == 0); 699 CU_ASSERT(prev_lun == NULL); 700 701 rc = scsi_dev_find_free_lun(&dev, 2, &prev_lun); 702 CU_ASSERT(rc == -EEXIST); 703 704 TAILQ_INSERT_HEAD(&dev.luns, &lun[0], tailq); 705 706 rc = scsi_dev_find_free_lun(&dev, 0, &prev_lun); 707 CU_ASSERT(rc == -EEXIST); 708 709 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 710 CU_ASSERT(rc == 0); 711 CU_ASSERT(prev_lun == &lun[0]); 712 prev_lun = NULL; 713 714 rc = scsi_dev_find_free_lun(&dev, 1, &prev_lun); 715 CU_ASSERT(rc == 0); 716 CU_ASSERT(prev_lun == &lun[0]); 717 prev_lun = NULL; 718 719 TAILQ_INSERT_AFTER(&dev.luns, &lun[0], &lun[1], tailq); 720 721 rc = scsi_dev_find_free_lun(&dev, 1, &prev_lun); 722 CU_ASSERT(rc == -EEXIST); 723 724 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 725 CU_ASSERT(rc == 0); 726 CU_ASSERT(prev_lun == &lun[14]); 727 prev_lun = NULL; 728 729 rc = scsi_dev_find_free_lun(&dev, 15, &prev_lun); 730 CU_ASSERT(rc == 0); 731 CU_ASSERT(prev_lun == &lun[14]); 732 prev_lun = NULL; 733 734 rc = scsi_dev_find_free_lun(&dev, 16, &prev_lun); 735 CU_ASSERT(rc == 0); 736 CU_ASSERT(prev_lun == &lun[14]); 737 prev_lun = NULL; 738 739 rc = scsi_dev_find_free_lun(&dev, 17, &prev_lun); 740 CU_ASSERT(rc == 0); 741 CU_ASSERT(prev_lun == &lun[14]); 742 prev_lun = NULL; 743 744 TAILQ_INSERT_AFTER(&dev.luns, &lun[14], &lun[15], tailq); 745 TAILQ_INSERT_AFTER(&dev.luns, &lun[15], &lun[16], tailq); 746 TAILQ_INSERT_AFTER(&dev.luns, &lun[16], &lun[17], tailq); 747 748 rc = scsi_dev_find_free_lun(&dev, 15, &prev_lun); 749 CU_ASSERT(rc == -EEXIST); 750 751 rc = scsi_dev_find_free_lun(&dev, 16, &prev_lun); 752 CU_ASSERT(rc == -EEXIST); 753 754 rc = scsi_dev_find_free_lun(&dev, 17, &prev_lun); 755 CU_ASSERT(rc == -EEXIST); 756 757 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 758 CU_ASSERT(rc == 0); 759 CU_ASSERT(prev_lun == &lun[SPDK_SCSI_DEV_MAX_LUN - 3]); 760 prev_lun = NULL; 761 762 rc = scsi_dev_find_free_lun(&dev, SPDK_SCSI_DEV_MAX_LUN - 2, &prev_lun); 763 CU_ASSERT(rc == 0); 764 CU_ASSERT(prev_lun == &lun[SPDK_SCSI_DEV_MAX_LUN - 3]); 765 prev_lun = NULL; 766 767 rc = scsi_dev_find_free_lun(&dev, SPDK_SCSI_DEV_MAX_LUN - 1, &prev_lun); 768 CU_ASSERT(rc == 0); 769 CU_ASSERT(prev_lun == &lun[SPDK_SCSI_DEV_MAX_LUN - 3]); 770 prev_lun = NULL; 771 772 TAILQ_INSERT_AFTER(&dev.luns, &lun[SPDK_SCSI_DEV_MAX_LUN - 3], 773 &lun[SPDK_SCSI_DEV_MAX_LUN - 1], tailq); 774 775 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 776 CU_ASSERT(rc == 0); 777 CU_ASSERT(prev_lun == &lun[SPDK_SCSI_DEV_MAX_LUN - 3]); 778 prev_lun = NULL; 779 780 rc = scsi_dev_find_free_lun(&dev, SPDK_SCSI_DEV_MAX_LUN - 2, &prev_lun); 781 CU_ASSERT(rc == 0); 782 CU_ASSERT(prev_lun == &lun[SPDK_SCSI_DEV_MAX_LUN - 3]); 783 prev_lun = NULL; 784 785 TAILQ_INSERT_AFTER(&dev.luns, &lun[SPDK_SCSI_DEV_MAX_LUN - 3], 786 &lun[SPDK_SCSI_DEV_MAX_LUN - 2], tailq); 787 788 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 789 CU_ASSERT(rc == -ENOSPC); 790 791 /* LUN ID 20 and 21 were freed. */ 792 TAILQ_REMOVE(&dev.luns, &lun[20], tailq); 793 TAILQ_REMOVE(&dev.luns, &lun[21], tailq); 794 795 rc = scsi_dev_find_free_lun(&dev, -1, &prev_lun); 796 CU_ASSERT(rc == 0); 797 CU_ASSERT(prev_lun == &lun[19]); 798 prev_lun = NULL; 799 800 rc = scsi_dev_find_free_lun(&dev, 21, &prev_lun); 801 CU_ASSERT(rc == 0); 802 CU_ASSERT(prev_lun == &lun[19]); 803 prev_lun = NULL; 804 805 free(lun); 806 } 807 808 int 809 main(int argc, char **argv) 810 { 811 CU_pSuite suite = NULL; 812 unsigned int num_failures; 813 814 CU_set_error_action(CUEA_ABORT); 815 CU_initialize_registry(); 816 817 suite = CU_add_suite("dev_suite", NULL, NULL); 818 819 CU_ADD_TEST(suite, dev_destruct_null_dev); 820 CU_ADD_TEST(suite, dev_destruct_zero_luns); 821 CU_ADD_TEST(suite, dev_destruct_null_lun); 822 CU_ADD_TEST(suite, dev_destruct_success); 823 CU_ADD_TEST(suite, dev_construct_num_luns_zero); 824 CU_ADD_TEST(suite, dev_construct_no_lun_zero); 825 CU_ADD_TEST(suite, dev_construct_null_lun); 826 CU_ADD_TEST(suite, dev_construct_name_too_long); 827 CU_ADD_TEST(suite, dev_construct_success); 828 CU_ADD_TEST(suite, dev_construct_success_lun_zero_not_first); 829 CU_ADD_TEST(suite, dev_queue_mgmt_task_success); 830 CU_ADD_TEST(suite, dev_queue_task_success); 831 CU_ADD_TEST(suite, dev_stop_success); 832 CU_ADD_TEST(suite, dev_add_port_max_ports); 833 CU_ADD_TEST(suite, dev_add_port_construct_failure1); 834 CU_ADD_TEST(suite, dev_add_port_construct_failure2); 835 CU_ADD_TEST(suite, dev_add_port_success1); 836 CU_ADD_TEST(suite, dev_add_port_success2); 837 CU_ADD_TEST(suite, dev_add_port_success3); 838 CU_ADD_TEST(suite, dev_find_port_by_id_num_ports_zero); 839 CU_ADD_TEST(suite, dev_find_port_by_id_id_not_found_failure); 840 CU_ADD_TEST(suite, dev_find_port_by_id_success); 841 CU_ADD_TEST(suite, dev_add_lun_bdev_not_found); 842 CU_ADD_TEST(suite, dev_add_lun_no_free_lun_id); 843 CU_ADD_TEST(suite, dev_add_lun_success1); 844 CU_ADD_TEST(suite, dev_add_lun_success2); 845 CU_ADD_TEST(suite, dev_check_pending_tasks); 846 CU_ADD_TEST(suite, dev_iterate_luns); 847 CU_ADD_TEST(suite, dev_find_free_lun); 848 849 CU_basic_set_mode(CU_BRM_VERBOSE); 850 CU_basic_run_tests(); 851 num_failures = CU_get_number_of_failures(); 852 CU_cleanup_registry(); 853 854 return num_failures; 855 } 856