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