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