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