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 "spdk_cunit.h" 37 38 #include "scsi/task.c" 39 #include "scsi/lun.c" 40 41 #include "spdk_internal/mock.h" 42 /* These unit tests aren't multithreads, but we need to allocate threads since 43 * the lun.c code will register pollers. 44 */ 45 #include "common/lib/ut_multithread.c" 46 47 /* Unit test bdev mockup */ 48 struct spdk_bdev { 49 int x; 50 }; 51 52 SPDK_LOG_REGISTER_COMPONENT("scsi", SPDK_LOG_SCSI) 53 54 struct spdk_scsi_globals g_spdk_scsi; 55 56 static bool g_lun_execute_fail = false; 57 static int g_lun_execute_status = SPDK_SCSI_TASK_PENDING; 58 static uint32_t g_task_count = 0; 59 60 struct spdk_trace_histories *g_trace_histories; 61 62 DEFINE_STUB_V(_spdk_trace_record, 63 (uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, 64 uint32_t size, uint64_t object_id, uint64_t arg1)); 65 66 static void 67 spdk_lun_ut_cpl_task(struct spdk_scsi_task *task) 68 { 69 SPDK_CU_ASSERT_FATAL(g_task_count > 0); 70 g_task_count--; 71 } 72 73 static void 74 spdk_lun_ut_free_task(struct spdk_scsi_task *task) 75 { 76 } 77 78 static void 79 ut_init_task(struct spdk_scsi_task *task) 80 { 81 memset(task, 0, sizeof(*task)); 82 spdk_scsi_task_construct(task, spdk_lun_ut_cpl_task, 83 spdk_lun_ut_free_task); 84 g_task_count++; 85 } 86 87 void 88 spdk_bdev_free_io(struct spdk_bdev_io *bdev_io) 89 { 90 CU_ASSERT(0); 91 } 92 93 DEFINE_STUB(spdk_bdev_open, int, 94 (struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb, 95 void *remove_ctx, struct spdk_bdev_desc **desc), 96 0); 97 98 DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc)); 99 100 DEFINE_STUB(spdk_bdev_get_name, const char *, 101 (const struct spdk_bdev *bdev), "test"); 102 103 DEFINE_STUB_V(spdk_scsi_dev_queue_mgmt_task, 104 (struct spdk_scsi_dev *dev, struct spdk_scsi_task *task)); 105 106 DEFINE_STUB_V(spdk_scsi_dev_delete_lun, 107 (struct spdk_scsi_dev *dev, struct spdk_scsi_lun *lun)); 108 109 DEFINE_STUB(spdk_scsi_pr_check, int, (struct spdk_scsi_task *task), 0); 110 111 void 112 spdk_bdev_scsi_reset(struct spdk_scsi_task *task) 113 { 114 task->status = SPDK_SCSI_STATUS_GOOD; 115 task->response = SPDK_SCSI_TASK_MGMT_RESP_SUCCESS; 116 117 spdk_scsi_lun_complete_reset_task(task->lun, task); 118 } 119 120 int 121 spdk_bdev_scsi_execute(struct spdk_scsi_task *task) 122 { 123 if (g_lun_execute_fail) { 124 return -EINVAL; 125 } else { 126 task->status = SPDK_SCSI_STATUS_GOOD; 127 128 if (g_lun_execute_status == SPDK_SCSI_TASK_PENDING) { 129 return g_lun_execute_status; 130 } else if (g_lun_execute_status == SPDK_SCSI_TASK_COMPLETE) { 131 return g_lun_execute_status; 132 } else { 133 return 0; 134 } 135 } 136 } 137 138 DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *, 139 (struct spdk_bdev_desc *desc), NULL); 140 141 static _spdk_scsi_lun * 142 lun_construct(void) 143 { 144 struct spdk_scsi_lun *lun; 145 struct spdk_bdev bdev; 146 147 lun = spdk_scsi_lun_construct(&bdev, NULL, NULL); 148 149 SPDK_CU_ASSERT_FATAL(lun != NULL); 150 return lun; 151 } 152 153 static void 154 lun_destruct(struct spdk_scsi_lun *lun) 155 { 156 /* LUN will defer its removal if there are any unfinished tasks */ 157 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&lun->tasks)); 158 159 spdk_scsi_lun_destruct(lun); 160 } 161 162 static void 163 lun_task_mgmt_execute_abort_task_not_supported(void) 164 { 165 struct spdk_scsi_lun *lun; 166 struct spdk_scsi_task task = { 0 }; 167 struct spdk_scsi_task mgmt_task = { 0 }; 168 struct spdk_scsi_port initiator_port = { 0 }; 169 struct spdk_scsi_dev dev = { 0 }; 170 uint8_t cdb[6] = { 0 }; 171 172 lun = lun_construct(); 173 lun->dev = &dev; 174 175 ut_init_task(&mgmt_task); 176 mgmt_task.lun = lun; 177 mgmt_task.initiator_port = &initiator_port; 178 mgmt_task.function = SPDK_SCSI_TASK_FUNC_ABORT_TASK; 179 180 /* Params to add regular task to the lun->tasks */ 181 ut_init_task(&task); 182 task.lun = lun; 183 task.cdb = cdb; 184 185 spdk_scsi_lun_append_task(lun, &task); 186 spdk_scsi_lun_execute_tasks(lun); 187 188 /* task should now be on the tasks list */ 189 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 190 191 spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task); 192 spdk_scsi_lun_execute_mgmt_task(lun); 193 194 /* task abort is not supported */ 195 CU_ASSERT(mgmt_task.response == SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED); 196 197 /* task is still on the tasks list */ 198 CU_ASSERT_EQUAL(g_task_count, 1); 199 200 spdk_scsi_lun_complete_task(lun, &task); 201 CU_ASSERT_EQUAL(g_task_count, 0); 202 203 lun_destruct(lun); 204 } 205 206 static void 207 lun_task_mgmt_execute_abort_task_all_not_supported(void) 208 { 209 struct spdk_scsi_lun *lun; 210 struct spdk_scsi_task task = { 0 }; 211 struct spdk_scsi_task mgmt_task = { 0 }; 212 struct spdk_scsi_port initiator_port = { 0 }; 213 struct spdk_scsi_dev dev = { 0 }; 214 uint8_t cdb[6] = { 0 }; 215 216 lun = lun_construct(); 217 lun->dev = &dev; 218 219 ut_init_task(&mgmt_task); 220 mgmt_task.lun = lun; 221 mgmt_task.initiator_port = &initiator_port; 222 mgmt_task.function = SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET; 223 224 /* Params to add regular task to the lun->tasks */ 225 ut_init_task(&task); 226 task.initiator_port = &initiator_port; 227 task.lun = lun; 228 task.cdb = cdb; 229 230 spdk_scsi_lun_append_task(lun, &task); 231 spdk_scsi_lun_execute_tasks(lun); 232 233 /* task should now be on the tasks list */ 234 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 235 236 spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task); 237 spdk_scsi_lun_execute_mgmt_task(lun); 238 239 /* task abort is not supported */ 240 CU_ASSERT(mgmt_task.response == SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED); 241 242 /* task is still on the tasks list */ 243 CU_ASSERT_EQUAL(g_task_count, 1); 244 245 spdk_scsi_lun_complete_task(lun, &task); 246 247 CU_ASSERT_EQUAL(g_task_count, 0); 248 249 lun_destruct(lun); 250 } 251 252 static void 253 lun_task_mgmt_execute_lun_reset(void) 254 { 255 struct spdk_scsi_lun *lun; 256 struct spdk_scsi_task mgmt_task = { 0 }; 257 struct spdk_scsi_dev dev = { 0 }; 258 259 lun = lun_construct(); 260 lun->dev = &dev; 261 262 ut_init_task(&mgmt_task); 263 mgmt_task.lun = lun; 264 mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 265 266 spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task); 267 spdk_scsi_lun_execute_mgmt_task(lun); 268 269 /* Returns success */ 270 CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD); 271 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 272 273 lun_destruct(lun); 274 275 CU_ASSERT_EQUAL(g_task_count, 0); 276 } 277 278 static void 279 lun_task_mgmt_execute_invalid_case(void) 280 { 281 struct spdk_scsi_lun *lun; 282 struct spdk_scsi_task mgmt_task = { 0 }; 283 struct spdk_scsi_dev dev = { 0 }; 284 285 lun = lun_construct(); 286 lun->dev = &dev; 287 288 ut_init_task(&mgmt_task); 289 mgmt_task.function = 5; 290 291 /* Pass an invalid value to the switch statement */ 292 spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task); 293 spdk_scsi_lun_execute_mgmt_task(lun); 294 295 /* function code is invalid */ 296 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED); 297 298 lun_destruct(lun); 299 300 CU_ASSERT_EQUAL(g_task_count, 0); 301 } 302 303 static void 304 lun_append_task_null_lun_task_cdb_spc_inquiry(void) 305 { 306 struct spdk_scsi_task task = { 0 }; 307 uint8_t cdb[6] = { 0 }; 308 309 ut_init_task(&task); 310 task.cdb = cdb; 311 task.cdb[0] = SPDK_SPC_INQUIRY; 312 /* alloc_len >= 4096 */ 313 task.cdb[3] = 0xFF; 314 task.cdb[4] = 0xFF; 315 task.lun = NULL; 316 317 spdk_scsi_task_process_null_lun(&task); 318 319 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 320 321 spdk_scsi_task_put(&task); 322 323 /* spdk_scsi_task_process_null_lun() does not call cpl_fn */ 324 CU_ASSERT_EQUAL(g_task_count, 1); 325 g_task_count = 0; 326 } 327 328 static void 329 lun_append_task_null_lun_alloc_len_lt_4096(void) 330 { 331 struct spdk_scsi_task task = { 0 }; 332 uint8_t cdb[6] = { 0 }; 333 334 ut_init_task(&task); 335 task.cdb = cdb; 336 task.cdb[0] = SPDK_SPC_INQUIRY; 337 /* alloc_len < 4096 */ 338 task.cdb[3] = 0; 339 task.cdb[4] = 0; 340 /* alloc_len is set to a minimal value of 4096 341 * Hence, buf of size 4096 is allocated */ 342 spdk_scsi_task_process_null_lun(&task); 343 344 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 345 346 spdk_scsi_task_put(&task); 347 348 /* spdk_scsi_task_process_null_lun() does not call cpl_fn */ 349 CU_ASSERT_EQUAL(g_task_count, 1); 350 g_task_count = 0; 351 } 352 353 static void 354 lun_append_task_null_lun_not_supported(void) 355 { 356 struct spdk_scsi_task task = { 0 }; 357 uint8_t cdb[6] = { 0 }; 358 359 ut_init_task(&task); 360 task.cdb = cdb; 361 task.lun = NULL; 362 363 spdk_scsi_task_process_null_lun(&task); 364 365 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 366 /* LUN not supported; task's data transferred should be 0 */ 367 CU_ASSERT_EQUAL(task.data_transferred, 0); 368 369 /* spdk_scsi_task_process_null_lun() does not call cpl_fn */ 370 CU_ASSERT_EQUAL(g_task_count, 1); 371 g_task_count = 0; 372 } 373 374 static void 375 lun_execute_scsi_task_pending(void) 376 { 377 struct spdk_scsi_lun *lun; 378 struct spdk_scsi_task task = { 0 }; 379 struct spdk_scsi_dev dev = { 0 }; 380 381 lun = lun_construct(); 382 383 ut_init_task(&task); 384 task.lun = lun; 385 lun->dev = &dev; 386 387 g_lun_execute_fail = false; 388 g_lun_execute_status = SPDK_SCSI_TASK_PENDING; 389 390 /* the tasks list should still be empty since it has not been 391 executed yet 392 */ 393 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 394 395 spdk_scsi_lun_append_task(lun, &task); 396 spdk_scsi_lun_execute_tasks(lun); 397 398 /* Assert the task has been successfully added to the tasks queue */ 399 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 400 401 /* task is still on the tasks list */ 402 CU_ASSERT_EQUAL(g_task_count, 1); 403 404 /* Need to complete task so LUN might be removed right now */ 405 spdk_scsi_lun_complete_task(lun, &task); 406 407 CU_ASSERT_EQUAL(g_task_count, 0); 408 409 lun_destruct(lun); 410 } 411 412 static void 413 lun_execute_scsi_task_complete(void) 414 { 415 struct spdk_scsi_lun *lun; 416 struct spdk_scsi_task task = { 0 }; 417 struct spdk_scsi_dev dev = { 0 }; 418 419 lun = lun_construct(); 420 421 ut_init_task(&task); 422 task.lun = lun; 423 lun->dev = &dev; 424 425 g_lun_execute_fail = false; 426 g_lun_execute_status = SPDK_SCSI_TASK_COMPLETE; 427 428 /* the tasks list should still be empty since it has not been 429 executed yet 430 */ 431 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 432 433 spdk_scsi_lun_append_task(lun, &task); 434 spdk_scsi_lun_execute_tasks(lun); 435 436 /* Assert the task has not been added to the tasks queue */ 437 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 438 439 lun_destruct(lun); 440 441 CU_ASSERT_EQUAL(g_task_count, 0); 442 } 443 444 static void 445 lun_destruct_success(void) 446 { 447 struct spdk_scsi_lun *lun; 448 449 lun = lun_construct(); 450 451 spdk_scsi_lun_destruct(lun); 452 453 CU_ASSERT_EQUAL(g_task_count, 0); 454 } 455 456 static void 457 lun_construct_null_ctx(void) 458 { 459 struct spdk_scsi_lun *lun; 460 461 lun = spdk_scsi_lun_construct(NULL, NULL, NULL); 462 463 /* lun should be NULL since we passed NULL for the ctx pointer. */ 464 CU_ASSERT(lun == NULL); 465 CU_ASSERT_EQUAL(g_task_count, 0); 466 } 467 468 static void 469 lun_construct_success(void) 470 { 471 struct spdk_scsi_lun *lun = lun_construct(); 472 473 lun_destruct(lun); 474 475 CU_ASSERT_EQUAL(g_task_count, 0); 476 } 477 478 static void 479 lun_reset_task_wait_scsi_task_complete(void) 480 { 481 struct spdk_scsi_lun *lun; 482 struct spdk_scsi_task task = { 0 }; 483 struct spdk_scsi_task mgmt_task = { 0 }; 484 struct spdk_scsi_dev dev = { 0 }; 485 486 lun = lun_construct(); 487 lun->dev = &dev; 488 489 ut_init_task(&task); 490 task.lun = lun; 491 492 g_lun_execute_fail = false; 493 g_lun_execute_status = SPDK_SCSI_TASK_PENDING; 494 495 ut_init_task(&mgmt_task); 496 mgmt_task.lun = lun; 497 mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 498 499 /* Append a task to the pending task list. */ 500 spdk_scsi_lun_append_task(lun, &task); 501 502 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks)); 503 504 /* Execute the task but it is still in the task list. */ 505 spdk_scsi_lun_execute_tasks(lun); 506 507 CU_ASSERT(TAILQ_EMPTY(&lun->pending_tasks)); 508 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 509 510 /* Append a reset task to the pending mgmt task list. */ 511 spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task); 512 513 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 514 515 /* Execute the reset task */ 516 spdk_scsi_lun_execute_mgmt_task(lun); 517 518 /* The reset task should be still on the submitted mgmt task list and 519 * a poller is created because the task prior to the reset task is pending. 520 */ 521 CU_ASSERT(!TAILQ_EMPTY(&lun->mgmt_tasks)); 522 CU_ASSERT(lun->reset_poller != NULL); 523 524 /* Execute the poller to check if the task prior to the reset task complete. */ 525 scsi_lun_reset_check_outstanding_tasks(&mgmt_task); 526 527 CU_ASSERT(!TAILQ_EMPTY(&lun->mgmt_tasks)); 528 CU_ASSERT(lun->reset_poller != NULL); 529 530 /* Complete the task. */ 531 spdk_scsi_lun_complete_task(lun, &task); 532 533 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 534 535 /* Execute the poller to check if the task prior to the reset task complete. */ 536 scsi_lun_reset_check_outstanding_tasks(&mgmt_task); 537 538 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 539 CU_ASSERT(lun->reset_poller == NULL); 540 CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD); 541 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 542 543 lun_destruct(lun); 544 545 CU_ASSERT_EQUAL(g_task_count, 0); 546 } 547 548 static void 549 lun_reset_task_suspend_scsi_task(void) 550 { 551 struct spdk_scsi_lun *lun; 552 struct spdk_scsi_task task = { 0 }; 553 struct spdk_scsi_task mgmt_task = { 0 }; 554 struct spdk_scsi_dev dev = { 0 }; 555 556 lun = lun_construct(); 557 lun->dev = &dev; 558 559 ut_init_task(&task); 560 task.lun = lun; 561 562 g_lun_execute_fail = false; 563 g_lun_execute_status = SPDK_SCSI_TASK_COMPLETE; 564 565 ut_init_task(&mgmt_task); 566 mgmt_task.lun = lun; 567 mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 568 569 /* Append a reset task to the pending mgmt task list. */ 570 spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task); 571 572 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 573 574 /* Append a task to the pending task list. */ 575 spdk_scsi_lun_append_task(lun, &task); 576 577 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks)); 578 579 /* Execute the task but it is still on the pending task list. */ 580 spdk_scsi_lun_execute_tasks(lun); 581 582 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks)); 583 584 /* Execute the reset task. The task will be executed then. */ 585 spdk_scsi_lun_execute_mgmt_task(lun); 586 587 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 588 CU_ASSERT(lun->reset_poller == NULL); 589 CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD); 590 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 591 592 CU_ASSERT(TAILQ_EMPTY(&lun->pending_tasks)); 593 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 594 595 lun_destruct(lun); 596 597 CU_ASSERT_EQUAL(g_task_count, 0); 598 } 599 600 static void 601 lun_check_pending_tasks_only_for_specific_initiator(void) 602 { 603 struct spdk_bdev bdev = {}; 604 struct spdk_scsi_lun *lun; 605 struct spdk_scsi_task task1 = {}; 606 struct spdk_scsi_task task2 = {}; 607 struct spdk_scsi_port initiator_port1 = {}; 608 struct spdk_scsi_port initiator_port2 = {}; 609 struct spdk_scsi_port initiator_port3 = {}; 610 611 lun = spdk_scsi_lun_construct(&bdev, NULL, NULL); 612 613 task1.initiator_port = &initiator_port1; 614 task2.initiator_port = &initiator_port2; 615 616 TAILQ_INSERT_TAIL(&lun->tasks, &task1, scsi_link); 617 TAILQ_INSERT_TAIL(&lun->tasks, &task2, scsi_link); 618 CU_ASSERT(scsi_lun_has_outstanding_tasks(lun) == true); 619 CU_ASSERT(scsi_lun_has_pending_tasks(lun) == true); 620 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == true); 621 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port1) == true); 622 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port2) == true); 623 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port3) == false); 624 TAILQ_REMOVE(&lun->tasks, &task1, scsi_link); 625 TAILQ_REMOVE(&lun->tasks, &task2, scsi_link); 626 CU_ASSERT(scsi_lun_has_pending_tasks(lun) == false); 627 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == false); 628 629 TAILQ_INSERT_TAIL(&lun->pending_tasks, &task1, scsi_link); 630 TAILQ_INSERT_TAIL(&lun->pending_tasks, &task2, scsi_link); 631 CU_ASSERT(scsi_lun_has_outstanding_tasks(lun) == false); 632 CU_ASSERT(scsi_lun_has_pending_tasks(lun) == true); 633 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == true); 634 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port1) == true); 635 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port2) == true); 636 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port3) == false); 637 TAILQ_REMOVE(&lun->pending_tasks, &task1, scsi_link); 638 TAILQ_REMOVE(&lun->pending_tasks, &task2, scsi_link); 639 CU_ASSERT(scsi_lun_has_pending_tasks(lun) == false); 640 CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == false); 641 642 TAILQ_INSERT_TAIL(&lun->mgmt_tasks, &task1, scsi_link); 643 TAILQ_INSERT_TAIL(&lun->mgmt_tasks, &task2, scsi_link); 644 CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == true); 645 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == true); 646 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port1) == true); 647 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port2) == true); 648 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port3) == false); 649 TAILQ_REMOVE(&lun->mgmt_tasks, &task1, scsi_link); 650 TAILQ_REMOVE(&lun->mgmt_tasks, &task2, scsi_link); 651 CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == false); 652 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == false); 653 654 TAILQ_INSERT_TAIL(&lun->pending_mgmt_tasks, &task1, scsi_link); 655 TAILQ_INSERT_TAIL(&lun->pending_mgmt_tasks, &task2, scsi_link); 656 CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == true); 657 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == true); 658 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port1) == true); 659 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port2) == true); 660 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port3) == false); 661 TAILQ_REMOVE(&lun->pending_mgmt_tasks, &task1, scsi_link); 662 TAILQ_REMOVE(&lun->pending_mgmt_tasks, &task2, scsi_link); 663 CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == false); 664 CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == false); 665 666 scsi_lun_remove(lun); 667 } 668 669 static void 670 abort_pending_mgmt_tasks_when_lun_is_removed(void) 671 { 672 struct spdk_bdev bdev = {}; 673 struct spdk_scsi_lun *lun; 674 struct spdk_scsi_task task1, task2, task3; 675 676 lun = spdk_scsi_lun_construct(&bdev, NULL, NULL); 677 678 /* Normal case */ 679 ut_init_task(&task1); 680 ut_init_task(&task2); 681 ut_init_task(&task3); 682 task1.lun = lun; 683 task2.lun = lun; 684 task3.lun = lun; 685 task1.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 686 task2.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 687 task3.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 688 689 CU_ASSERT(g_task_count == 3); 690 691 spdk_scsi_lun_append_mgmt_task(lun, &task1); 692 spdk_scsi_lun_append_mgmt_task(lun, &task2); 693 spdk_scsi_lun_append_mgmt_task(lun, &task3); 694 695 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 696 697 spdk_scsi_lun_execute_mgmt_task(lun); 698 699 CU_ASSERT(TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 700 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 701 CU_ASSERT(g_task_count == 0); 702 CU_ASSERT(task1.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 703 CU_ASSERT(task2.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 704 CU_ASSERT(task3.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 705 706 /* LUN hotplug case */ 707 ut_init_task(&task1); 708 ut_init_task(&task2); 709 ut_init_task(&task3); 710 task1.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 711 task2.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 712 task3.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 713 714 CU_ASSERT(g_task_count == 3); 715 716 spdk_scsi_lun_append_mgmt_task(lun, &task1); 717 spdk_scsi_lun_append_mgmt_task(lun, &task2); 718 spdk_scsi_lun_append_mgmt_task(lun, &task3); 719 720 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 721 722 lun->removed = true; 723 724 spdk_scsi_lun_execute_mgmt_task(lun); 725 726 CU_ASSERT(TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 727 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 728 CU_ASSERT(g_task_count == 0); 729 CU_ASSERT(task1.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN); 730 CU_ASSERT(task2.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN); 731 CU_ASSERT(task3.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN); 732 733 scsi_lun_remove(lun); 734 } 735 736 int 737 main(int argc, char **argv) 738 { 739 CU_pSuite suite = NULL; 740 unsigned int num_failures; 741 742 if (CU_initialize_registry() != CUE_SUCCESS) { 743 return CU_get_error(); 744 } 745 746 suite = CU_add_suite("lun_suite", NULL, NULL); 747 if (suite == NULL) { 748 CU_cleanup_registry(); 749 return CU_get_error(); 750 } 751 752 if ( 753 CU_add_test(suite, "task management abort task - not supported", 754 lun_task_mgmt_execute_abort_task_not_supported) == NULL 755 || CU_add_test(suite, "task management abort task set - success", 756 lun_task_mgmt_execute_abort_task_all_not_supported) == NULL 757 || CU_add_test(suite, "task management - lun reset success", 758 lun_task_mgmt_execute_lun_reset) == NULL 759 || CU_add_test(suite, "task management - invalid option", 760 lun_task_mgmt_execute_invalid_case) == NULL 761 || CU_add_test(suite, "append task - null lun SPDK_SPC_INQUIRY", 762 lun_append_task_null_lun_task_cdb_spc_inquiry) == NULL 763 || CU_add_test(suite, "append task - allocated length less than 4096", 764 lun_append_task_null_lun_alloc_len_lt_4096) == NULL 765 || CU_add_test(suite, "append task - unsupported lun", 766 lun_append_task_null_lun_not_supported) == NULL 767 || CU_add_test(suite, "execute task - scsi task pending", 768 lun_execute_scsi_task_pending) == NULL 769 || CU_add_test(suite, "execute task - scsi task complete", 770 lun_execute_scsi_task_complete) == NULL 771 || CU_add_test(suite, "destruct task - success", lun_destruct_success) == NULL 772 || CU_add_test(suite, "construct - null ctx", lun_construct_null_ctx) == NULL 773 || CU_add_test(suite, "construct - success", lun_construct_success) == NULL 774 || CU_add_test(suite, "reset task wait for prior task completion", 775 lun_reset_task_wait_scsi_task_complete) == NULL 776 || CU_add_test(suite, "reset task suspend subsequent scsi task", 777 lun_reset_task_suspend_scsi_task) == NULL 778 || CU_add_test(suite, "check pending tasks only for specific initiator", 779 lun_check_pending_tasks_only_for_specific_initiator) == NULL 780 || CU_add_test(suite, "abort_pending_mgmt_tasks_when_lun_is_removed", 781 abort_pending_mgmt_tasks_when_lun_is_removed) == NULL 782 ) { 783 CU_cleanup_registry(); 784 return CU_get_error(); 785 } 786 787 CU_basic_set_mode(CU_BRM_VERBOSE); 788 allocate_threads(1); 789 set_thread(0); 790 CU_basic_run_tests(); 791 free_threads(); 792 num_failures = CU_get_number_of_failures(); 793 CU_cleanup_registry(); 794 return num_failures; 795 } 796