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