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