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