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