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