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(scsi_pr_check, int, (struct spdk_scsi_task *task), 0); 110 111 void 112 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 scsi_lun_complete_reset_task(task->lun, task); 118 } 119 120 int 121 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 struct spdk_scsi_lun *lun_construct(void) 142 { 143 struct spdk_scsi_lun *lun; 144 struct spdk_bdev bdev; 145 146 lun = scsi_lun_construct(&bdev, NULL, NULL); 147 148 SPDK_CU_ASSERT_FATAL(lun != NULL); 149 return lun; 150 } 151 152 static void 153 lun_destruct(struct spdk_scsi_lun *lun) 154 { 155 /* LUN will defer its removal if there are any unfinished tasks */ 156 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&lun->tasks)); 157 158 scsi_lun_destruct(lun); 159 } 160 161 static void 162 lun_task_mgmt_execute_abort_task_not_supported(void) 163 { 164 struct spdk_scsi_lun *lun; 165 struct spdk_scsi_task task = { 0 }; 166 struct spdk_scsi_task mgmt_task = { 0 }; 167 struct spdk_scsi_port initiator_port = { 0 }; 168 struct spdk_scsi_dev dev = { 0 }; 169 uint8_t cdb[6] = { 0 }; 170 171 lun = lun_construct(); 172 lun->dev = &dev; 173 174 ut_init_task(&mgmt_task); 175 mgmt_task.lun = lun; 176 mgmt_task.initiator_port = &initiator_port; 177 mgmt_task.function = SPDK_SCSI_TASK_FUNC_ABORT_TASK; 178 179 /* Params to add regular task to the lun->tasks */ 180 ut_init_task(&task); 181 task.lun = lun; 182 task.cdb = cdb; 183 184 scsi_lun_execute_task(lun, &task); 185 186 /* task should now be on the tasks list */ 187 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 188 189 scsi_lun_execute_mgmt_task(lun, &mgmt_task); 190 191 /* task abort is not supported */ 192 CU_ASSERT(mgmt_task.response == SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED); 193 194 /* task is still on the tasks list */ 195 CU_ASSERT_EQUAL(g_task_count, 1); 196 197 scsi_lun_complete_task(lun, &task); 198 CU_ASSERT_EQUAL(g_task_count, 0); 199 200 lun_destruct(lun); 201 } 202 203 static void 204 lun_task_mgmt_execute_abort_task_all_not_supported(void) 205 { 206 struct spdk_scsi_lun *lun; 207 struct spdk_scsi_task task = { 0 }; 208 struct spdk_scsi_task mgmt_task = { 0 }; 209 struct spdk_scsi_port initiator_port = { 0 }; 210 struct spdk_scsi_dev dev = { 0 }; 211 uint8_t cdb[6] = { 0 }; 212 213 lun = lun_construct(); 214 lun->dev = &dev; 215 216 ut_init_task(&mgmt_task); 217 mgmt_task.lun = lun; 218 mgmt_task.initiator_port = &initiator_port; 219 mgmt_task.function = SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET; 220 221 /* Params to add regular task to the lun->tasks */ 222 ut_init_task(&task); 223 task.initiator_port = &initiator_port; 224 task.lun = lun; 225 task.cdb = cdb; 226 227 scsi_lun_execute_task(lun, &task); 228 229 /* task should now be on the tasks list */ 230 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 231 232 scsi_lun_execute_mgmt_task(lun, &mgmt_task); 233 234 /* task abort is not supported */ 235 CU_ASSERT(mgmt_task.response == SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED); 236 237 /* task is still on the tasks list */ 238 CU_ASSERT_EQUAL(g_task_count, 1); 239 240 scsi_lun_complete_task(lun, &task); 241 242 CU_ASSERT_EQUAL(g_task_count, 0); 243 244 lun_destruct(lun); 245 } 246 247 static void 248 lun_task_mgmt_execute_lun_reset(void) 249 { 250 struct spdk_scsi_lun *lun; 251 struct spdk_scsi_task mgmt_task = { 0 }; 252 struct spdk_scsi_dev dev = { 0 }; 253 254 lun = lun_construct(); 255 lun->dev = &dev; 256 257 ut_init_task(&mgmt_task); 258 mgmt_task.lun = lun; 259 mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 260 261 scsi_lun_execute_mgmt_task(lun, &mgmt_task); 262 263 /* Returns success */ 264 CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD); 265 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 266 267 lun_destruct(lun); 268 269 CU_ASSERT_EQUAL(g_task_count, 0); 270 } 271 272 static void 273 lun_task_mgmt_execute_invalid_case(void) 274 { 275 struct spdk_scsi_lun *lun; 276 struct spdk_scsi_task mgmt_task = { 0 }; 277 struct spdk_scsi_dev dev = { 0 }; 278 279 lun = lun_construct(); 280 lun->dev = &dev; 281 282 ut_init_task(&mgmt_task); 283 mgmt_task.function = 5; 284 285 /* Pass an invalid value to the switch statement */ 286 scsi_lun_execute_mgmt_task(lun, &mgmt_task); 287 288 /* function code is invalid */ 289 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED); 290 291 lun_destruct(lun); 292 293 CU_ASSERT_EQUAL(g_task_count, 0); 294 } 295 296 static void 297 lun_append_task_null_lun_task_cdb_spc_inquiry(void) 298 { 299 struct spdk_scsi_task task = { 0 }; 300 uint8_t cdb[6] = { 0 }; 301 302 ut_init_task(&task); 303 task.cdb = cdb; 304 task.cdb[0] = SPDK_SPC_INQUIRY; 305 /* alloc_len >= 4096 */ 306 task.cdb[3] = 0xFF; 307 task.cdb[4] = 0xFF; 308 task.lun = NULL; 309 310 spdk_scsi_task_process_null_lun(&task); 311 312 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 313 314 spdk_scsi_task_put(&task); 315 316 /* spdk_scsi_task_process_null_lun() does not call cpl_fn */ 317 CU_ASSERT_EQUAL(g_task_count, 1); 318 g_task_count = 0; 319 } 320 321 static void 322 lun_append_task_null_lun_alloc_len_lt_4096(void) 323 { 324 struct spdk_scsi_task task = { 0 }; 325 uint8_t cdb[6] = { 0 }; 326 327 ut_init_task(&task); 328 task.cdb = cdb; 329 task.cdb[0] = SPDK_SPC_INQUIRY; 330 /* alloc_len < 4096 */ 331 task.cdb[3] = 0; 332 task.cdb[4] = 0; 333 /* alloc_len is set to a minimal value of 4096 334 * Hence, buf of size 4096 is allocated */ 335 spdk_scsi_task_process_null_lun(&task); 336 337 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 338 339 spdk_scsi_task_put(&task); 340 341 /* spdk_scsi_task_process_null_lun() does not call cpl_fn */ 342 CU_ASSERT_EQUAL(g_task_count, 1); 343 g_task_count = 0; 344 } 345 346 static void 347 lun_append_task_null_lun_not_supported(void) 348 { 349 struct spdk_scsi_task task = { 0 }; 350 uint8_t cdb[6] = { 0 }; 351 352 ut_init_task(&task); 353 task.cdb = cdb; 354 task.lun = NULL; 355 356 spdk_scsi_task_process_null_lun(&task); 357 358 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 359 /* LUN not supported; task's data transferred should be 0 */ 360 CU_ASSERT_EQUAL(task.data_transferred, 0); 361 362 /* spdk_scsi_task_process_null_lun() does not call cpl_fn */ 363 CU_ASSERT_EQUAL(g_task_count, 1); 364 g_task_count = 0; 365 } 366 367 static void 368 lun_execute_scsi_task_pending(void) 369 { 370 struct spdk_scsi_lun *lun; 371 struct spdk_scsi_task task = { 0 }; 372 struct spdk_scsi_dev dev = { 0 }; 373 374 lun = lun_construct(); 375 376 ut_init_task(&task); 377 task.lun = lun; 378 lun->dev = &dev; 379 380 g_lun_execute_fail = false; 381 g_lun_execute_status = SPDK_SCSI_TASK_PENDING; 382 383 /* the tasks list should still be empty since it has not been 384 executed yet 385 */ 386 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 387 388 scsi_lun_execute_task(lun, &task); 389 390 /* Assert the task has been successfully added to the tasks queue */ 391 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 392 393 /* task is still on the tasks list */ 394 CU_ASSERT_EQUAL(g_task_count, 1); 395 396 /* Need to complete task so LUN might be removed right now */ 397 scsi_lun_complete_task(lun, &task); 398 399 CU_ASSERT_EQUAL(g_task_count, 0); 400 401 lun_destruct(lun); 402 } 403 404 static void 405 lun_execute_scsi_task_complete(void) 406 { 407 struct spdk_scsi_lun *lun; 408 struct spdk_scsi_task task = { 0 }; 409 struct spdk_scsi_dev dev = { 0 }; 410 411 lun = lun_construct(); 412 413 ut_init_task(&task); 414 task.lun = lun; 415 lun->dev = &dev; 416 417 g_lun_execute_fail = false; 418 g_lun_execute_status = SPDK_SCSI_TASK_COMPLETE; 419 420 /* the tasks list should still be empty since it has not been 421 executed yet 422 */ 423 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 424 425 scsi_lun_execute_task(lun, &task); 426 427 /* Assert the task has not been added to the tasks queue */ 428 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 429 430 lun_destruct(lun); 431 432 CU_ASSERT_EQUAL(g_task_count, 0); 433 } 434 435 static void 436 lun_destruct_success(void) 437 { 438 struct spdk_scsi_lun *lun; 439 440 lun = lun_construct(); 441 442 scsi_lun_destruct(lun); 443 444 CU_ASSERT_EQUAL(g_task_count, 0); 445 } 446 447 static void 448 lun_construct_null_ctx(void) 449 { 450 struct spdk_scsi_lun *lun; 451 452 lun = scsi_lun_construct(NULL, NULL, NULL); 453 454 /* lun should be NULL since we passed NULL for the ctx pointer. */ 455 CU_ASSERT(lun == NULL); 456 CU_ASSERT_EQUAL(g_task_count, 0); 457 } 458 459 static void 460 lun_construct_success(void) 461 { 462 struct spdk_scsi_lun *lun = lun_construct(); 463 464 lun_destruct(lun); 465 466 CU_ASSERT_EQUAL(g_task_count, 0); 467 } 468 469 static void 470 lun_reset_task_wait_scsi_task_complete(void) 471 { 472 struct spdk_scsi_lun *lun; 473 struct spdk_scsi_task task = { 0 }; 474 struct spdk_scsi_task mgmt_task = { 0 }; 475 struct spdk_scsi_dev dev = { 0 }; 476 477 lun = lun_construct(); 478 lun->dev = &dev; 479 480 ut_init_task(&task); 481 task.lun = lun; 482 483 g_lun_execute_fail = false; 484 g_lun_execute_status = SPDK_SCSI_TASK_PENDING; 485 486 ut_init_task(&mgmt_task); 487 mgmt_task.lun = lun; 488 mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 489 490 /* Execute the task but it is still in the task list. */ 491 scsi_lun_execute_task(lun, &task); 492 493 CU_ASSERT(TAILQ_EMPTY(&lun->pending_tasks)); 494 CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); 495 496 /* Execute the reset task */ 497 scsi_lun_execute_mgmt_task(lun, &mgmt_task); 498 499 /* The reset task should be on the submitted mgmt task list and 500 * a poller is created because the task prior to the reset task is pending. 501 */ 502 CU_ASSERT(!TAILQ_EMPTY(&lun->mgmt_tasks)); 503 CU_ASSERT(lun->reset_poller != NULL); 504 505 /* Execute the poller to check if the task prior to the reset task complete. */ 506 scsi_lun_reset_check_outstanding_tasks(&mgmt_task); 507 508 CU_ASSERT(!TAILQ_EMPTY(&lun->mgmt_tasks)); 509 CU_ASSERT(lun->reset_poller != NULL); 510 511 /* Complete the task. */ 512 scsi_lun_complete_task(lun, &task); 513 514 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 515 516 /* Execute the poller to check if the task prior to the reset task complete. */ 517 scsi_lun_reset_check_outstanding_tasks(&mgmt_task); 518 519 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 520 CU_ASSERT(lun->reset_poller == NULL); 521 CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD); 522 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 523 524 lun_destruct(lun); 525 526 CU_ASSERT_EQUAL(g_task_count, 0); 527 } 528 529 static void 530 lun_reset_task_suspend_scsi_task(void) 531 { 532 struct spdk_scsi_lun *lun; 533 struct spdk_scsi_task task = { 0 }; 534 struct spdk_scsi_task mgmt_task = { 0 }; 535 struct spdk_scsi_dev dev = { 0 }; 536 537 lun = lun_construct(); 538 lun->dev = &dev; 539 540 ut_init_task(&task); 541 task.lun = lun; 542 543 g_lun_execute_fail = false; 544 g_lun_execute_status = SPDK_SCSI_TASK_COMPLETE; 545 546 ut_init_task(&mgmt_task); 547 mgmt_task.lun = lun; 548 mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 549 550 /* Append a reset task to the pending mgmt task list. */ 551 scsi_lun_append_mgmt_task(lun, &mgmt_task); 552 553 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 554 555 /* Execute the task but it is on the pending task list. */ 556 scsi_lun_execute_task(lun, &task); 557 558 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks)); 559 560 /* Execute the reset task. The task will be executed then. */ 561 _scsi_lun_execute_mgmt_task(lun); 562 563 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 564 CU_ASSERT(lun->reset_poller == NULL); 565 CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD); 566 CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 567 568 CU_ASSERT(TAILQ_EMPTY(&lun->pending_tasks)); 569 CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); 570 571 lun_destruct(lun); 572 573 CU_ASSERT_EQUAL(g_task_count, 0); 574 } 575 576 static void 577 lun_check_pending_tasks_only_for_specific_initiator(void) 578 { 579 struct spdk_bdev bdev = {}; 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(&bdev, 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_bdev bdev = {}; 650 struct spdk_scsi_lun *lun; 651 struct spdk_scsi_task task1, task2, task3; 652 653 lun = scsi_lun_construct(&bdev, NULL, NULL); 654 655 /* Normal case */ 656 ut_init_task(&task1); 657 ut_init_task(&task2); 658 ut_init_task(&task3); 659 task1.lun = lun; 660 task2.lun = lun; 661 task3.lun = lun; 662 task1.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 663 task2.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 664 task3.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 665 666 CU_ASSERT(g_task_count == 3); 667 668 scsi_lun_append_mgmt_task(lun, &task1); 669 scsi_lun_append_mgmt_task(lun, &task2); 670 scsi_lun_append_mgmt_task(lun, &task3); 671 672 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 673 674 _scsi_lun_execute_mgmt_task(lun); 675 676 CU_ASSERT(TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 677 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 678 CU_ASSERT(g_task_count == 0); 679 CU_ASSERT(task1.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 680 CU_ASSERT(task2.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 681 CU_ASSERT(task3.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS); 682 683 /* LUN hotplug case */ 684 ut_init_task(&task1); 685 ut_init_task(&task2); 686 ut_init_task(&task3); 687 task1.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 688 task2.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 689 task3.function = SPDK_SCSI_TASK_FUNC_LUN_RESET; 690 691 CU_ASSERT(g_task_count == 3); 692 693 scsi_lun_append_mgmt_task(lun, &task1); 694 scsi_lun_append_mgmt_task(lun, &task2); 695 scsi_lun_append_mgmt_task(lun, &task3); 696 697 CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 698 699 lun->removed = true; 700 701 _scsi_lun_execute_mgmt_task(lun); 702 703 CU_ASSERT(TAILQ_EMPTY(&lun->pending_mgmt_tasks)); 704 CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks)); 705 CU_ASSERT(g_task_count == 0); 706 CU_ASSERT(task1.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN); 707 CU_ASSERT(task2.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN); 708 CU_ASSERT(task3.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN); 709 710 scsi_lun_remove(lun); 711 } 712 713 int 714 main(int argc, char **argv) 715 { 716 CU_pSuite suite = NULL; 717 unsigned int num_failures; 718 719 CU_set_error_action(CUEA_ABORT); 720 CU_initialize_registry(); 721 722 suite = CU_add_suite("lun_suite", NULL, NULL); 723 724 CU_ADD_TEST(suite, lun_task_mgmt_execute_abort_task_not_supported); 725 CU_ADD_TEST(suite, lun_task_mgmt_execute_abort_task_all_not_supported); 726 CU_ADD_TEST(suite, lun_task_mgmt_execute_lun_reset); 727 CU_ADD_TEST(suite, lun_task_mgmt_execute_invalid_case); 728 CU_ADD_TEST(suite, lun_append_task_null_lun_task_cdb_spc_inquiry); 729 CU_ADD_TEST(suite, lun_append_task_null_lun_alloc_len_lt_4096); 730 CU_ADD_TEST(suite, lun_append_task_null_lun_not_supported); 731 CU_ADD_TEST(suite, lun_execute_scsi_task_pending); 732 CU_ADD_TEST(suite, lun_execute_scsi_task_complete); 733 CU_ADD_TEST(suite, lun_destruct_success); 734 CU_ADD_TEST(suite, lun_construct_null_ctx); 735 CU_ADD_TEST(suite, lun_construct_success); 736 CU_ADD_TEST(suite, lun_reset_task_wait_scsi_task_complete); 737 CU_ADD_TEST(suite, lun_reset_task_suspend_scsi_task); 738 CU_ADD_TEST(suite, lun_check_pending_tasks_only_for_specific_initiator); 739 CU_ADD_TEST(suite, abort_pending_mgmt_tasks_when_lun_is_removed); 740 741 CU_basic_set_mode(CU_BRM_VERBOSE); 742 allocate_threads(1); 743 set_thread(0); 744 CU_basic_run_tests(); 745 free_threads(); 746 num_failures = CU_get_number_of_failures(); 747 CU_cleanup_registry(); 748 return num_failures; 749 } 750