xref: /spdk/test/unit/lib/scsi/lun.c/lun_ut.c (revision d453c9400ef7738fa7e1f2cb8bc52bdb9bf10fdf)
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(spdk_scsi_pr_check, int, (struct spdk_scsi_task *task), 0);
110 
111 void
112 spdk_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 	spdk_scsi_lun_complete_reset_task(task->lun, task);
118 }
119 
120 int
121 spdk_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 _spdk_scsi_lun *
142 lun_construct(void)
143 {
144 	struct spdk_scsi_lun		*lun;
145 	struct spdk_bdev		bdev;
146 
147 	lun = spdk_scsi_lun_construct(&bdev, 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 	spdk_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 	spdk_scsi_lun_append_task(lun, &task);
186 	spdk_scsi_lun_execute_tasks(lun);
187 
188 	/* task should now be on the tasks list */
189 	CU_ASSERT(!TAILQ_EMPTY(&lun->tasks));
190 
191 	spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task);
192 	spdk_scsi_lun_execute_mgmt_task(lun);
193 
194 	/* task abort is not supported */
195 	CU_ASSERT(mgmt_task.response == SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED);
196 
197 	/* task is still on the tasks list */
198 	CU_ASSERT_EQUAL(g_task_count, 1);
199 
200 	spdk_scsi_lun_complete_task(lun, &task);
201 	CU_ASSERT_EQUAL(g_task_count, 0);
202 
203 	lun_destruct(lun);
204 }
205 
206 static void
207 lun_task_mgmt_execute_abort_task_all_not_supported(void)
208 {
209 	struct spdk_scsi_lun *lun;
210 	struct spdk_scsi_task task = { 0 };
211 	struct spdk_scsi_task mgmt_task = { 0 };
212 	struct spdk_scsi_port initiator_port = { 0 };
213 	struct spdk_scsi_dev dev = { 0 };
214 	uint8_t cdb[6] = { 0 };
215 
216 	lun = lun_construct();
217 	lun->dev = &dev;
218 
219 	ut_init_task(&mgmt_task);
220 	mgmt_task.lun = lun;
221 	mgmt_task.initiator_port = &initiator_port;
222 	mgmt_task.function = SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET;
223 
224 	/* Params to add regular task to the lun->tasks */
225 	ut_init_task(&task);
226 	task.initiator_port = &initiator_port;
227 	task.lun = lun;
228 	task.cdb = cdb;
229 
230 	spdk_scsi_lun_append_task(lun, &task);
231 	spdk_scsi_lun_execute_tasks(lun);
232 
233 	/* task should now be on the tasks list */
234 	CU_ASSERT(!TAILQ_EMPTY(&lun->tasks));
235 
236 	spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task);
237 	spdk_scsi_lun_execute_mgmt_task(lun);
238 
239 	/* task abort is not supported */
240 	CU_ASSERT(mgmt_task.response == SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED);
241 
242 	/* task is still on the tasks list */
243 	CU_ASSERT_EQUAL(g_task_count, 1);
244 
245 	spdk_scsi_lun_complete_task(lun, &task);
246 
247 	CU_ASSERT_EQUAL(g_task_count, 0);
248 
249 	lun_destruct(lun);
250 }
251 
252 static void
253 lun_task_mgmt_execute_lun_reset(void)
254 {
255 	struct spdk_scsi_lun *lun;
256 	struct spdk_scsi_task mgmt_task = { 0 };
257 	struct spdk_scsi_dev dev = { 0 };
258 
259 	lun = lun_construct();
260 	lun->dev = &dev;
261 
262 	ut_init_task(&mgmt_task);
263 	mgmt_task.lun = lun;
264 	mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
265 
266 	spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task);
267 	spdk_scsi_lun_execute_mgmt_task(lun);
268 
269 	/* Returns success */
270 	CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD);
271 	CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS);
272 
273 	lun_destruct(lun);
274 
275 	CU_ASSERT_EQUAL(g_task_count, 0);
276 }
277 
278 static void
279 lun_task_mgmt_execute_invalid_case(void)
280 {
281 	struct spdk_scsi_lun *lun;
282 	struct spdk_scsi_task mgmt_task = { 0 };
283 	struct spdk_scsi_dev dev = { 0 };
284 
285 	lun = lun_construct();
286 	lun->dev = &dev;
287 
288 	ut_init_task(&mgmt_task);
289 	mgmt_task.function = 5;
290 
291 	/* Pass an invalid value to the switch statement */
292 	spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task);
293 	spdk_scsi_lun_execute_mgmt_task(lun);
294 
295 	/* function code is invalid */
296 	CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED);
297 
298 	lun_destruct(lun);
299 
300 	CU_ASSERT_EQUAL(g_task_count, 0);
301 }
302 
303 static void
304 lun_append_task_null_lun_task_cdb_spc_inquiry(void)
305 {
306 	struct spdk_scsi_task task = { 0 };
307 	uint8_t cdb[6] = { 0 };
308 
309 	ut_init_task(&task);
310 	task.cdb = cdb;
311 	task.cdb[0] = SPDK_SPC_INQUIRY;
312 	/* alloc_len >= 4096 */
313 	task.cdb[3] = 0xFF;
314 	task.cdb[4] = 0xFF;
315 	task.lun = NULL;
316 
317 	spdk_scsi_task_process_null_lun(&task);
318 
319 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD);
320 
321 	spdk_scsi_task_put(&task);
322 
323 	/* spdk_scsi_task_process_null_lun() does not call cpl_fn */
324 	CU_ASSERT_EQUAL(g_task_count, 1);
325 	g_task_count = 0;
326 }
327 
328 static void
329 lun_append_task_null_lun_alloc_len_lt_4096(void)
330 {
331 	struct spdk_scsi_task task = { 0 };
332 	uint8_t cdb[6] = { 0 };
333 
334 	ut_init_task(&task);
335 	task.cdb = cdb;
336 	task.cdb[0] = SPDK_SPC_INQUIRY;
337 	/* alloc_len < 4096 */
338 	task.cdb[3] = 0;
339 	task.cdb[4] = 0;
340 	/* alloc_len is set to a minimal value of 4096
341 	 * Hence, buf of size 4096 is allocated */
342 	spdk_scsi_task_process_null_lun(&task);
343 
344 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD);
345 
346 	spdk_scsi_task_put(&task);
347 
348 	/* spdk_scsi_task_process_null_lun() does not call cpl_fn */
349 	CU_ASSERT_EQUAL(g_task_count, 1);
350 	g_task_count = 0;
351 }
352 
353 static void
354 lun_append_task_null_lun_not_supported(void)
355 {
356 	struct spdk_scsi_task task = { 0 };
357 	uint8_t cdb[6] = { 0 };
358 
359 	ut_init_task(&task);
360 	task.cdb = cdb;
361 	task.lun = NULL;
362 
363 	spdk_scsi_task_process_null_lun(&task);
364 
365 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
366 	/* LUN not supported; task's data transferred should be 0 */
367 	CU_ASSERT_EQUAL(task.data_transferred, 0);
368 
369 	/* spdk_scsi_task_process_null_lun() does not call cpl_fn */
370 	CU_ASSERT_EQUAL(g_task_count, 1);
371 	g_task_count = 0;
372 }
373 
374 static void
375 lun_execute_scsi_task_pending(void)
376 {
377 	struct spdk_scsi_lun *lun;
378 	struct spdk_scsi_task task = { 0 };
379 	struct spdk_scsi_dev dev = { 0 };
380 
381 	lun = lun_construct();
382 
383 	ut_init_task(&task);
384 	task.lun = lun;
385 	lun->dev = &dev;
386 
387 	g_lun_execute_fail = false;
388 	g_lun_execute_status = SPDK_SCSI_TASK_PENDING;
389 
390 	/* the tasks list should still be empty since it has not been
391 	   executed yet
392 	 */
393 	CU_ASSERT(TAILQ_EMPTY(&lun->tasks));
394 
395 	spdk_scsi_lun_append_task(lun, &task);
396 	spdk_scsi_lun_execute_tasks(lun);
397 
398 	/* Assert the task has been successfully added to the tasks queue */
399 	CU_ASSERT(!TAILQ_EMPTY(&lun->tasks));
400 
401 	/* task is still on the tasks list */
402 	CU_ASSERT_EQUAL(g_task_count, 1);
403 
404 	/* Need to complete task so LUN might be removed right now */
405 	spdk_scsi_lun_complete_task(lun, &task);
406 
407 	CU_ASSERT_EQUAL(g_task_count, 0);
408 
409 	lun_destruct(lun);
410 }
411 
412 static void
413 lun_execute_scsi_task_complete(void)
414 {
415 	struct spdk_scsi_lun *lun;
416 	struct spdk_scsi_task task = { 0 };
417 	struct spdk_scsi_dev dev = { 0 };
418 
419 	lun = lun_construct();
420 
421 	ut_init_task(&task);
422 	task.lun = lun;
423 	lun->dev = &dev;
424 
425 	g_lun_execute_fail = false;
426 	g_lun_execute_status = SPDK_SCSI_TASK_COMPLETE;
427 
428 	/* the tasks list should still be empty since it has not been
429 	   executed yet
430 	 */
431 	CU_ASSERT(TAILQ_EMPTY(&lun->tasks));
432 
433 	spdk_scsi_lun_append_task(lun, &task);
434 	spdk_scsi_lun_execute_tasks(lun);
435 
436 	/* Assert the task has not been added to the tasks queue */
437 	CU_ASSERT(TAILQ_EMPTY(&lun->tasks));
438 
439 	lun_destruct(lun);
440 
441 	CU_ASSERT_EQUAL(g_task_count, 0);
442 }
443 
444 static void
445 lun_destruct_success(void)
446 {
447 	struct spdk_scsi_lun *lun;
448 
449 	lun = lun_construct();
450 
451 	spdk_scsi_lun_destruct(lun);
452 
453 	CU_ASSERT_EQUAL(g_task_count, 0);
454 }
455 
456 static void
457 lun_construct_null_ctx(void)
458 {
459 	struct spdk_scsi_lun		*lun;
460 
461 	lun = spdk_scsi_lun_construct(NULL, NULL, NULL);
462 
463 	/* lun should be NULL since we passed NULL for the ctx pointer. */
464 	CU_ASSERT(lun == NULL);
465 	CU_ASSERT_EQUAL(g_task_count, 0);
466 }
467 
468 static void
469 lun_construct_success(void)
470 {
471 	struct spdk_scsi_lun *lun = lun_construct();
472 
473 	lun_destruct(lun);
474 
475 	CU_ASSERT_EQUAL(g_task_count, 0);
476 }
477 
478 static void
479 lun_reset_task_wait_scsi_task_complete(void)
480 {
481 	struct spdk_scsi_lun *lun;
482 	struct spdk_scsi_task task = { 0 };
483 	struct spdk_scsi_task mgmt_task = { 0 };
484 	struct spdk_scsi_dev dev = { 0 };
485 
486 	lun = lun_construct();
487 	lun->dev = &dev;
488 
489 	ut_init_task(&task);
490 	task.lun = lun;
491 
492 	g_lun_execute_fail = false;
493 	g_lun_execute_status = SPDK_SCSI_TASK_PENDING;
494 
495 	ut_init_task(&mgmt_task);
496 	mgmt_task.lun = lun;
497 	mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
498 
499 	/* Append a task to the pending task list. */
500 	spdk_scsi_lun_append_task(lun, &task);
501 
502 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks));
503 
504 	/* Execute the task but it is still in the task list. */
505 	spdk_scsi_lun_execute_tasks(lun);
506 
507 	CU_ASSERT(TAILQ_EMPTY(&lun->pending_tasks));
508 	CU_ASSERT(!TAILQ_EMPTY(&lun->tasks));
509 
510 	/* Append a reset task to the pending mgmt task list. */
511 	spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task);
512 
513 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks));
514 
515 	/* Execute the reset task */
516 	spdk_scsi_lun_execute_mgmt_task(lun);
517 
518 	/* The reset task should be still on the submitted mgmt task list and
519 	 * a poller is created because the task prior to the reset task is pending.
520 	 */
521 	CU_ASSERT(!TAILQ_EMPTY(&lun->mgmt_tasks));
522 	CU_ASSERT(lun->reset_poller != NULL);
523 
524 	/* Execute the poller to check if the task prior to the reset task complete. */
525 	scsi_lun_reset_check_outstanding_tasks(&mgmt_task);
526 
527 	CU_ASSERT(!TAILQ_EMPTY(&lun->mgmt_tasks));
528 	CU_ASSERT(lun->reset_poller != NULL);
529 
530 	/* Complete the task. */
531 	spdk_scsi_lun_complete_task(lun, &task);
532 
533 	CU_ASSERT(TAILQ_EMPTY(&lun->tasks));
534 
535 	/* Execute the poller to check if the task prior to the reset task complete. */
536 	scsi_lun_reset_check_outstanding_tasks(&mgmt_task);
537 
538 	CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks));
539 	CU_ASSERT(lun->reset_poller == NULL);
540 	CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD);
541 	CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS);
542 
543 	lun_destruct(lun);
544 
545 	CU_ASSERT_EQUAL(g_task_count, 0);
546 }
547 
548 static void
549 lun_reset_task_suspend_scsi_task(void)
550 {
551 	struct spdk_scsi_lun *lun;
552 	struct spdk_scsi_task task = { 0 };
553 	struct spdk_scsi_task mgmt_task = { 0 };
554 	struct spdk_scsi_dev dev = { 0 };
555 
556 	lun = lun_construct();
557 	lun->dev = &dev;
558 
559 	ut_init_task(&task);
560 	task.lun = lun;
561 
562 	g_lun_execute_fail = false;
563 	g_lun_execute_status = SPDK_SCSI_TASK_COMPLETE;
564 
565 	ut_init_task(&mgmt_task);
566 	mgmt_task.lun = lun;
567 	mgmt_task.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
568 
569 	/* Append a reset task to the pending mgmt task list. */
570 	spdk_scsi_lun_append_mgmt_task(lun, &mgmt_task);
571 
572 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks));
573 
574 	/* Append a task to the pending task list. */
575 	spdk_scsi_lun_append_task(lun, &task);
576 
577 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks));
578 
579 	/* Execute the task but it is still on the pending task list. */
580 	spdk_scsi_lun_execute_tasks(lun);
581 
582 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_tasks));
583 
584 	/* Execute the reset task. The task will be executed then. */
585 	spdk_scsi_lun_execute_mgmt_task(lun);
586 
587 	CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks));
588 	CU_ASSERT(lun->reset_poller == NULL);
589 	CU_ASSERT_EQUAL(mgmt_task.status, SPDK_SCSI_STATUS_GOOD);
590 	CU_ASSERT_EQUAL(mgmt_task.response, SPDK_SCSI_TASK_MGMT_RESP_SUCCESS);
591 
592 	CU_ASSERT(TAILQ_EMPTY(&lun->pending_tasks));
593 	CU_ASSERT(TAILQ_EMPTY(&lun->tasks));
594 
595 	lun_destruct(lun);
596 
597 	CU_ASSERT_EQUAL(g_task_count, 0);
598 }
599 
600 static void
601 lun_check_pending_tasks_only_for_specific_initiator(void)
602 {
603 	struct spdk_bdev bdev = {};
604 	struct spdk_scsi_lun *lun;
605 	struct spdk_scsi_task task1 = {};
606 	struct spdk_scsi_task task2 = {};
607 	struct spdk_scsi_port initiator_port1 = {};
608 	struct spdk_scsi_port initiator_port2 = {};
609 	struct spdk_scsi_port initiator_port3 = {};
610 
611 	lun = spdk_scsi_lun_construct(&bdev, NULL, NULL);
612 
613 	task1.initiator_port = &initiator_port1;
614 	task2.initiator_port = &initiator_port2;
615 
616 	TAILQ_INSERT_TAIL(&lun->tasks, &task1, scsi_link);
617 	TAILQ_INSERT_TAIL(&lun->tasks, &task2, scsi_link);
618 	CU_ASSERT(scsi_lun_has_outstanding_tasks(lun) == true);
619 	CU_ASSERT(scsi_lun_has_pending_tasks(lun) == true);
620 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == true);
621 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port1) == true);
622 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port2) == true);
623 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port3) == false);
624 	TAILQ_REMOVE(&lun->tasks, &task1, scsi_link);
625 	TAILQ_REMOVE(&lun->tasks, &task2, scsi_link);
626 	CU_ASSERT(scsi_lun_has_pending_tasks(lun) == false);
627 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == false);
628 
629 	TAILQ_INSERT_TAIL(&lun->pending_tasks, &task1, scsi_link);
630 	TAILQ_INSERT_TAIL(&lun->pending_tasks, &task2, scsi_link);
631 	CU_ASSERT(scsi_lun_has_outstanding_tasks(lun) == false);
632 	CU_ASSERT(scsi_lun_has_pending_tasks(lun) == true);
633 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == true);
634 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port1) == true);
635 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port2) == true);
636 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port3) == false);
637 	TAILQ_REMOVE(&lun->pending_tasks, &task1, scsi_link);
638 	TAILQ_REMOVE(&lun->pending_tasks, &task2, scsi_link);
639 	CU_ASSERT(scsi_lun_has_pending_tasks(lun) == false);
640 	CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == false);
641 
642 	TAILQ_INSERT_TAIL(&lun->mgmt_tasks, &task1, scsi_link);
643 	TAILQ_INSERT_TAIL(&lun->mgmt_tasks, &task2, scsi_link);
644 	CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == true);
645 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == true);
646 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port1) == true);
647 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port2) == true);
648 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port3) == false);
649 	TAILQ_REMOVE(&lun->mgmt_tasks, &task1, scsi_link);
650 	TAILQ_REMOVE(&lun->mgmt_tasks, &task2, scsi_link);
651 	CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == false);
652 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == false);
653 
654 	TAILQ_INSERT_TAIL(&lun->pending_mgmt_tasks, &task1, scsi_link);
655 	TAILQ_INSERT_TAIL(&lun->pending_mgmt_tasks, &task2, scsi_link);
656 	CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == true);
657 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == true);
658 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port1) == true);
659 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port2) == true);
660 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port3) == false);
661 	TAILQ_REMOVE(&lun->pending_mgmt_tasks, &task1, scsi_link);
662 	TAILQ_REMOVE(&lun->pending_mgmt_tasks, &task2, scsi_link);
663 	CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == false);
664 	CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == false);
665 
666 	scsi_lun_remove(lun);
667 }
668 
669 static void
670 abort_pending_mgmt_tasks_when_lun_is_removed(void)
671 {
672 	struct spdk_bdev bdev = {};
673 	struct spdk_scsi_lun *lun;
674 	struct spdk_scsi_task task1, task2, task3;
675 
676 	lun = spdk_scsi_lun_construct(&bdev, NULL, NULL);
677 
678 	/* Normal case */
679 	ut_init_task(&task1);
680 	ut_init_task(&task2);
681 	ut_init_task(&task3);
682 	task1.lun = lun;
683 	task2.lun = lun;
684 	task3.lun = lun;
685 	task1.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
686 	task2.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
687 	task3.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
688 
689 	CU_ASSERT(g_task_count == 3);
690 
691 	spdk_scsi_lun_append_mgmt_task(lun, &task1);
692 	spdk_scsi_lun_append_mgmt_task(lun, &task2);
693 	spdk_scsi_lun_append_mgmt_task(lun, &task3);
694 
695 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks));
696 
697 	spdk_scsi_lun_execute_mgmt_task(lun);
698 
699 	CU_ASSERT(TAILQ_EMPTY(&lun->pending_mgmt_tasks));
700 	CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks));
701 	CU_ASSERT(g_task_count == 0);
702 	CU_ASSERT(task1.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS);
703 	CU_ASSERT(task2.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS);
704 	CU_ASSERT(task3.response == SPDK_SCSI_TASK_MGMT_RESP_SUCCESS);
705 
706 	/* LUN hotplug case */
707 	ut_init_task(&task1);
708 	ut_init_task(&task2);
709 	ut_init_task(&task3);
710 	task1.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
711 	task2.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
712 	task3.function = SPDK_SCSI_TASK_FUNC_LUN_RESET;
713 
714 	CU_ASSERT(g_task_count == 3);
715 
716 	spdk_scsi_lun_append_mgmt_task(lun, &task1);
717 	spdk_scsi_lun_append_mgmt_task(lun, &task2);
718 	spdk_scsi_lun_append_mgmt_task(lun, &task3);
719 
720 	CU_ASSERT(!TAILQ_EMPTY(&lun->pending_mgmt_tasks));
721 
722 	lun->removed = true;
723 
724 	spdk_scsi_lun_execute_mgmt_task(lun);
725 
726 	CU_ASSERT(TAILQ_EMPTY(&lun->pending_mgmt_tasks));
727 	CU_ASSERT(TAILQ_EMPTY(&lun->mgmt_tasks));
728 	CU_ASSERT(g_task_count == 0);
729 	CU_ASSERT(task1.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN);
730 	CU_ASSERT(task2.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN);
731 	CU_ASSERT(task3.response == SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN);
732 
733 	scsi_lun_remove(lun);
734 }
735 
736 int
737 main(int argc, char **argv)
738 {
739 	CU_pSuite	suite = NULL;
740 	unsigned int	num_failures;
741 
742 	if (CU_initialize_registry() != CUE_SUCCESS) {
743 		return CU_get_error();
744 	}
745 
746 	suite = CU_add_suite("lun_suite", NULL, NULL);
747 	if (suite == NULL) {
748 		CU_cleanup_registry();
749 		return CU_get_error();
750 	}
751 
752 	if (
753 		CU_add_test(suite, "task management abort task - not supported",
754 			    lun_task_mgmt_execute_abort_task_not_supported) == NULL
755 		|| CU_add_test(suite, "task management abort task set - success",
756 			       lun_task_mgmt_execute_abort_task_all_not_supported) == NULL
757 		|| CU_add_test(suite, "task management - lun reset success",
758 			       lun_task_mgmt_execute_lun_reset) == NULL
759 		|| CU_add_test(suite, "task management - invalid option",
760 			       lun_task_mgmt_execute_invalid_case) == NULL
761 		|| CU_add_test(suite, "append task - null lun SPDK_SPC_INQUIRY",
762 			       lun_append_task_null_lun_task_cdb_spc_inquiry) == NULL
763 		|| CU_add_test(suite, "append task - allocated length less than 4096",
764 			       lun_append_task_null_lun_alloc_len_lt_4096) == NULL
765 		|| CU_add_test(suite, "append task - unsupported lun",
766 			       lun_append_task_null_lun_not_supported) == NULL
767 		|| CU_add_test(suite, "execute task - scsi task pending",
768 			       lun_execute_scsi_task_pending) == NULL
769 		|| CU_add_test(suite, "execute task - scsi task complete",
770 			       lun_execute_scsi_task_complete) == NULL
771 		|| CU_add_test(suite, "destruct task - success", lun_destruct_success) == NULL
772 		|| CU_add_test(suite, "construct - null ctx", lun_construct_null_ctx) == NULL
773 		|| CU_add_test(suite, "construct - success", lun_construct_success) == NULL
774 		|| CU_add_test(suite, "reset task wait for prior task completion",
775 			       lun_reset_task_wait_scsi_task_complete) == NULL
776 		|| CU_add_test(suite, "reset task suspend subsequent scsi task",
777 			       lun_reset_task_suspend_scsi_task) == NULL
778 		|| CU_add_test(suite, "check pending tasks only for specific initiator",
779 			       lun_check_pending_tasks_only_for_specific_initiator) == NULL
780 		|| CU_add_test(suite, "abort_pending_mgmt_tasks_when_lun_is_removed",
781 			       abort_pending_mgmt_tasks_when_lun_is_removed) == NULL
782 	) {
783 		CU_cleanup_registry();
784 		return CU_get_error();
785 	}
786 
787 	CU_basic_set_mode(CU_BRM_VERBOSE);
788 	allocate_threads(1);
789 	set_thread(0);
790 	CU_basic_run_tests();
791 	free_threads();
792 	num_failures = CU_get_number_of_failures();
793 	CU_cleanup_registry();
794 	return num_failures;
795 }
796