xref: /spdk/test/unit/lib/scsi/lun.c/lun_ut.c (revision 1fa071d332db21bf893d581a8e93b425ba788a24)
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