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
spdk_lun_ut_cpl_task(struct spdk_scsi_task * task)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
spdk_lun_ut_free_task(struct spdk_scsi_task * task)42 spdk_lun_ut_free_task(struct spdk_scsi_task *task)
43 {
44 }
45
46 static void
ut_init_task(struct spdk_scsi_task * task)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
spdk_bdev_free_io(struct spdk_bdev_io * bdev_io)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
bdev_scsi_reset(struct spdk_scsi_task * task)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
bdev_scsi_execute(struct spdk_scsi_task * task)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 *
lun_construct(void)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
lun_destruct(struct spdk_scsi_lun * lun)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
lun_task_mgmt_execute_abort_task_not_supported(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
lun_task_mgmt_execute_abort_task_all_not_supported(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
lun_task_mgmt_execute_lun_reset(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
lun_task_mgmt_execute_target_reset(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
lun_task_mgmt_execute_invalid_case(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
lun_append_task_null_lun_task_cdb_spc_inquiry(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
lun_append_task_null_lun_alloc_len_lt_4096(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
lun_append_task_null_lun_not_supported(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
lun_execute_scsi_task_pending(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
lun_execute_scsi_task_complete(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
lun_execute_scsi_task_resize(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
lun_destruct_success(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
lun_construct_null_ctx(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
lun_construct_success(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
lun_reset_task_wait_scsi_task_complete(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
lun_reset_task_suspend_scsi_task(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
lun_check_pending_tasks_only_for_specific_initiator(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
abort_pending_mgmt_tasks_when_lun_is_removed(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
main(int argc,char ** argv)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