xref: /spdk/test/unit/lib/iscsi/conn.c/conn_ut.c (revision d453c9400ef7738fa7e1f2cb8bc52bdb9bf10fdf)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "common/lib/test_env.c"
37 #include "spdk_cunit.h"
38 
39 #include "iscsi/conn.c"
40 
41 #include "spdk_internal/mock.h"
42 
43 SPDK_LOG_REGISTER_COMPONENT("iscsi", SPDK_LOG_ISCSI)
44 
45 #define DMIN32(A,B) ((uint32_t) ((uint32_t)(A) > (uint32_t)(B) ? (uint32_t)(B) : (uint32_t)(A)))
46 
47 struct spdk_scsi_lun {
48 	uint8_t reserved;
49 };
50 
51 struct spdk_iscsi_globals g_spdk_iscsi;
52 static TAILQ_HEAD(read_tasks_head, spdk_iscsi_task) g_ut_read_tasks =
53 	TAILQ_HEAD_INITIALIZER(g_ut_read_tasks);
54 static ssize_t g_sock_writev_bytes = 0;
55 
56 DEFINE_STUB(spdk_app_get_shm_id, int, (void), 0);
57 
58 DEFINE_STUB(spdk_sock_getaddr, int,
59 	    (struct spdk_sock *sock, char *saddr, int slen, uint16_t *sport,
60 	     char *caddr, int clen, uint16_t *cport),
61 	    0);
62 
63 int
64 spdk_sock_close(struct spdk_sock **sock)
65 {
66 	*sock = NULL;
67 	return 0;
68 }
69 
70 DEFINE_STUB(spdk_sock_recv, ssize_t,
71 	    (struct spdk_sock *sock, void *buf, size_t len), 0);
72 
73 DEFINE_STUB(spdk_sock_readv, ssize_t,
74 	    (struct spdk_sock *sock, struct iovec *iov, int iovcnt), 0);
75 
76 ssize_t
77 spdk_sock_writev(struct spdk_sock *sock, struct iovec *iov, int iovcnt)
78 {
79 	return g_sock_writev_bytes;
80 }
81 
82 DEFINE_STUB(spdk_sock_set_recvlowat, int, (struct spdk_sock *s, int nbytes), 0);
83 
84 DEFINE_STUB(spdk_sock_set_recvbuf, int, (struct spdk_sock *sock, int sz), 0);
85 
86 DEFINE_STUB(spdk_sock_set_sendbuf, int, (struct spdk_sock *sock, int sz), 0);
87 
88 DEFINE_STUB(spdk_sock_group_add_sock, int,
89 	    (struct spdk_sock_group *group, struct spdk_sock *sock,
90 	     spdk_sock_cb cb_fn, void *cb_arg),
91 	    0);
92 
93 DEFINE_STUB(spdk_sock_group_remove_sock, int,
94 	    (struct spdk_sock_group *group, struct spdk_sock *sock), 0);
95 
96 void
97 spdk_scsi_task_put(struct spdk_scsi_task *task)
98 {
99 	task->ref--;
100 }
101 
102 DEFINE_STUB(spdk_scsi_dev_get_lun, struct spdk_scsi_lun *,
103 	    (struct spdk_scsi_dev *dev, int lun_id), NULL);
104 
105 DEFINE_STUB(spdk_scsi_dev_has_pending_tasks, bool,
106 	    (const struct spdk_scsi_dev *dev, const struct spdk_scsi_port *initiator_port),
107 	    true);
108 
109 DEFINE_STUB(spdk_scsi_lun_open, int,
110 	    (struct spdk_scsi_lun *lun, spdk_scsi_lun_remove_cb_t hotremove_cb,
111 	     void *hotremove_ctx, struct spdk_scsi_lun_desc **desc),
112 	    0);
113 
114 DEFINE_STUB_V(spdk_scsi_lun_close, (struct spdk_scsi_lun_desc *desc));
115 
116 DEFINE_STUB(spdk_scsi_lun_allocate_io_channel, int,
117 	    (struct spdk_scsi_lun_desc *desc), 0);
118 
119 DEFINE_STUB_V(spdk_scsi_lun_free_io_channel, (struct spdk_scsi_lun_desc *desc));
120 
121 DEFINE_STUB(spdk_scsi_lun_get_id, int, (const struct spdk_scsi_lun *lun), 0);
122 
123 DEFINE_STUB(spdk_scsi_port_get_name, const char *,
124 	    (const struct spdk_scsi_port *port), NULL);
125 
126 void
127 spdk_scsi_task_copy_status(struct spdk_scsi_task *dst,
128 			   struct spdk_scsi_task *src)
129 {
130 	dst->status = src->status;
131 }
132 
133 DEFINE_STUB_V(spdk_put_pdu, (struct spdk_iscsi_pdu *pdu));
134 
135 DEFINE_STUB_V(spdk_iscsi_param_free, (struct iscsi_param *params));
136 
137 DEFINE_STUB(spdk_iscsi_conn_params_init, int, (struct iscsi_param **params), 0);
138 
139 DEFINE_STUB_V(spdk_clear_all_transfer_task,
140 	      (struct spdk_iscsi_conn *conn, struct spdk_scsi_lun *lun,
141 	       struct spdk_iscsi_pdu *pdu));
142 
143 DEFINE_STUB(spdk_iscsi_build_iovs, int,
144 	    (struct spdk_iscsi_conn *conn, struct iovec *iov, int num_iovs,
145 	     struct spdk_iscsi_pdu *pdu, uint32_t *mapped_length),
146 	    0);
147 
148 DEFINE_STUB(spdk_iscsi_is_deferred_free_pdu, bool,
149 	    (struct spdk_iscsi_pdu *pdu), false);
150 
151 DEFINE_STUB_V(spdk_iscsi_task_response,
152 	      (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task));
153 
154 DEFINE_STUB_V(spdk_iscsi_task_mgmt_response,
155 	      (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task));
156 
157 DEFINE_STUB_V(spdk_iscsi_send_nopin, (struct spdk_iscsi_conn *conn));
158 
159 DEFINE_STUB(spdk_del_transfer_task, bool,
160 	    (struct spdk_iscsi_conn *conn, uint32_t task_tag), true);
161 
162 int
163 spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn)
164 {
165 	CU_ASSERT(TAILQ_EMPTY(&conn->write_pdu_list));
166 	return 0;
167 }
168 
169 DEFINE_STUB(spdk_iscsi_handle_incoming_pdus, int, (struct spdk_iscsi_conn *conn), 0);
170 
171 DEFINE_STUB_V(spdk_free_sess, (struct spdk_iscsi_sess *sess));
172 
173 DEFINE_STUB(spdk_iscsi_tgt_node_cleanup_luns, int,
174 	    (struct spdk_iscsi_conn *conn, struct spdk_iscsi_tgt_node *target),
175 	    0);
176 
177 DEFINE_STUB(spdk_iscsi_pdu_calc_header_digest, uint32_t,
178 	    (struct spdk_iscsi_pdu *pdu), 0);
179 
180 DEFINE_STUB(spdk_iscsi_pdu_calc_data_digest, uint32_t,
181 	    (struct spdk_iscsi_pdu *pdu), 0);
182 
183 DEFINE_STUB_V(spdk_shutdown_iscsi_conns_done, (void));
184 
185 static struct spdk_iscsi_task *
186 ut_conn_task_get(struct spdk_iscsi_task *parent)
187 {
188 	struct spdk_iscsi_task *task;
189 
190 	task = calloc(1, sizeof(*task));
191 	SPDK_CU_ASSERT_FATAL(task != NULL);
192 
193 	if (parent) {
194 		task->parent = parent;
195 	}
196 	return task;
197 }
198 
199 static void
200 ut_conn_create_read_tasks(int transfer_len)
201 {
202 	struct spdk_iscsi_task *task, *subtask;
203 	int32_t remaining_size = 0;
204 
205 	task = ut_conn_task_get(NULL);
206 
207 	TAILQ_INIT(&task->subtask_list);
208 	task->scsi.transfer_len = transfer_len;
209 	task->scsi.offset = 0;
210 	task->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, task->scsi.transfer_len);
211 	task->scsi.status = SPDK_SCSI_STATUS_GOOD;
212 
213 	remaining_size = task->scsi.transfer_len - task->scsi.length;
214 	task->current_datain_offset = 0;
215 
216 	if (remaining_size == 0) {
217 		TAILQ_INSERT_TAIL(&g_ut_read_tasks, task, link);
218 		return;
219 	}
220 
221 	while (1) {
222 		if (task->current_datain_offset == 0) {
223 			task->current_datain_offset = task->scsi.length;
224 			TAILQ_INSERT_TAIL(&g_ut_read_tasks, task, link);
225 			continue;
226 		}
227 
228 		if (task->current_datain_offset < task->scsi.transfer_len) {
229 			remaining_size = task->scsi.transfer_len - task->current_datain_offset;
230 
231 			subtask = ut_conn_task_get(task);
232 
233 			subtask->scsi.offset = task->current_datain_offset;
234 			subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size);
235 			subtask->scsi.status = SPDK_SCSI_STATUS_GOOD;
236 
237 			task->current_datain_offset += subtask->scsi.length;
238 
239 			TAILQ_INSERT_TAIL(&g_ut_read_tasks, subtask, link);
240 		}
241 
242 		if (task->current_datain_offset == task->scsi.transfer_len) {
243 			break;
244 		}
245 	}
246 }
247 
248 static void
249 read_task_split_in_order_case(void)
250 {
251 	struct spdk_iscsi_task *primary, *task, *tmp;
252 
253 	ut_conn_create_read_tasks(SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8);
254 
255 	TAILQ_FOREACH(task, &g_ut_read_tasks, link) {
256 		primary = spdk_iscsi_task_get_primary(task);
257 		process_read_task_completion(NULL, task, primary);
258 	}
259 
260 	primary = TAILQ_FIRST(&g_ut_read_tasks);
261 	SPDK_CU_ASSERT_FATAL(primary != NULL);
262 
263 	CU_ASSERT(primary->bytes_completed == primary->scsi.transfer_len);
264 
265 	TAILQ_FOREACH_SAFE(task, &g_ut_read_tasks, link, tmp) {
266 		TAILQ_REMOVE(&g_ut_read_tasks, task, link);
267 		free(task);
268 	}
269 
270 	CU_ASSERT(TAILQ_EMPTY(&g_ut_read_tasks));
271 }
272 
273 static void
274 read_task_split_reverse_order_case(void)
275 {
276 	struct spdk_iscsi_task *primary, *task, *tmp;
277 
278 	ut_conn_create_read_tasks(SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8);
279 
280 	TAILQ_FOREACH_REVERSE(task, &g_ut_read_tasks, read_tasks_head, link) {
281 		primary = spdk_iscsi_task_get_primary(task);
282 		process_read_task_completion(NULL, task, primary);
283 	}
284 
285 	primary = TAILQ_FIRST(&g_ut_read_tasks);
286 	SPDK_CU_ASSERT_FATAL(primary != NULL);
287 
288 	CU_ASSERT(primary->bytes_completed == primary->scsi.transfer_len);
289 
290 	TAILQ_FOREACH_SAFE(task, &g_ut_read_tasks, link, tmp) {
291 		TAILQ_REMOVE(&g_ut_read_tasks, task, link);
292 		free(task);
293 	}
294 
295 	CU_ASSERT(TAILQ_EMPTY(&g_ut_read_tasks));
296 }
297 
298 static void
299 propagate_scsi_error_status_for_split_read_tasks(void)
300 {
301 	struct spdk_iscsi_task primary, task1, task2, task3, task4, task5, task6;
302 
303 	memset(&primary, 0, sizeof(struct spdk_iscsi_task));
304 	primary.scsi.length = 512;
305 	primary.scsi.status = SPDK_SCSI_STATUS_GOOD;
306 	primary.rsp_scsi_status = SPDK_SCSI_STATUS_GOOD;
307 	TAILQ_INIT(&primary.subtask_list);
308 
309 	memset(&task1, 0, sizeof(struct spdk_iscsi_task));
310 	task1.scsi.offset = 512;
311 	task1.scsi.length = 512;
312 	task1.scsi.status = SPDK_SCSI_STATUS_GOOD;
313 
314 	memset(&task2, 0, sizeof(struct spdk_iscsi_task));
315 	task2.scsi.offset = 512 * 2;
316 	task2.scsi.length = 512;
317 	task2.scsi.status = SPDK_SCSI_STATUS_CHECK_CONDITION;
318 
319 	memset(&task3, 0, sizeof(struct spdk_iscsi_task));
320 	task3.scsi.offset = 512 * 3;
321 	task3.scsi.length = 512;
322 	task3.scsi.status = SPDK_SCSI_STATUS_GOOD;
323 
324 	memset(&task4, 0, sizeof(struct spdk_iscsi_task));
325 	task4.scsi.offset = 512 * 4;
326 	task4.scsi.length = 512;
327 	task4.scsi.status = SPDK_SCSI_STATUS_GOOD;
328 
329 	memset(&task5, 0, sizeof(struct spdk_iscsi_task));
330 	task5.scsi.offset = 512 * 5;
331 	task5.scsi.length = 512;
332 	task5.scsi.status = SPDK_SCSI_STATUS_GOOD;
333 
334 	memset(&task6, 0, sizeof(struct spdk_iscsi_task));
335 	task6.scsi.offset = 512 * 6;
336 	task6.scsi.length = 512;
337 	task6.scsi.status = SPDK_SCSI_STATUS_GOOD;
338 
339 	/* task2 has check condition status, and verify if the check condition
340 	 * status is propagated to remaining tasks correctly when these tasks complete
341 	 * by the following order, task4, task3, task2, task1, primary, task5, and task6.
342 	 */
343 	process_read_task_completion(NULL, &task4, &primary);
344 	process_read_task_completion(NULL, &task3, &primary);
345 	process_read_task_completion(NULL, &task2, &primary);
346 	process_read_task_completion(NULL, &task1, &primary);
347 	process_read_task_completion(NULL, &primary, &primary);
348 	process_read_task_completion(NULL, &task5, &primary);
349 	process_read_task_completion(NULL, &task6, &primary);
350 
351 	CU_ASSERT(primary.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
352 	CU_ASSERT(task1.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
353 	CU_ASSERT(task2.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
354 	CU_ASSERT(task3.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
355 	CU_ASSERT(task4.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
356 	CU_ASSERT(task5.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
357 	CU_ASSERT(task6.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
358 	CU_ASSERT(TAILQ_EMPTY(&primary.subtask_list));
359 }
360 
361 static void
362 process_non_read_task_completion_test(void)
363 {
364 	struct spdk_iscsi_conn conn = {};
365 	struct spdk_iscsi_task primary = {};
366 	struct spdk_iscsi_task task = {};
367 
368 	TAILQ_INIT(&conn.active_r2t_tasks);
369 
370 	primary.bytes_completed = 0;
371 	primary.scsi.transfer_len = 4096 * 3;
372 	primary.rsp_scsi_status = SPDK_SCSI_STATUS_GOOD;
373 	TAILQ_INSERT_TAIL(&conn.active_r2t_tasks, &primary, link);
374 
375 	/* First subtask which failed. */
376 	task.scsi.length = 4096;
377 	task.scsi.data_transferred = 4096;
378 	task.scsi.status = SPDK_SCSI_STATUS_CHECK_CONDITION;
379 
380 	process_non_read_task_completion(&conn, &task, &primary);
381 	CU_ASSERT(!TAILQ_EMPTY(&conn.active_r2t_tasks));
382 	CU_ASSERT(primary.bytes_completed == 4096);
383 	CU_ASSERT(primary.scsi.data_transferred == 0);
384 	CU_ASSERT(primary.rsp_scsi_status == SPDK_SCSI_STATUS_CHECK_CONDITION);
385 
386 	/* Second subtask which succeeded. */
387 	task.scsi.length = 4096;
388 	task.scsi.data_transferred = 4096;
389 	task.scsi.status = SPDK_SCSI_STATUS_GOOD;
390 
391 	process_non_read_task_completion(&conn, &task, &primary);
392 	CU_ASSERT(!TAILQ_EMPTY(&conn.active_r2t_tasks));
393 	CU_ASSERT(primary.bytes_completed == 4096 * 2);
394 	CU_ASSERT(primary.scsi.data_transferred == 4096);
395 	CU_ASSERT(primary.rsp_scsi_status == SPDK_SCSI_STATUS_CHECK_CONDITION);
396 
397 	/* Third and final subtask which succeeded. */
398 	task.scsi.length = 4096;
399 	task.scsi.data_transferred = 4096;
400 	task.scsi.status = SPDK_SCSI_STATUS_GOOD;
401 
402 	process_non_read_task_completion(&conn, &task, &primary);
403 	CU_ASSERT(TAILQ_EMPTY(&conn.active_r2t_tasks));
404 	CU_ASSERT(primary.bytes_completed == 4096 * 3);
405 	CU_ASSERT(primary.scsi.data_transferred == 4096 * 2);
406 	CU_ASSERT(primary.rsp_scsi_status == SPDK_SCSI_STATUS_CHECK_CONDITION);
407 
408 	/* Tricky case when the last task completed was the initial task. */
409 	primary.scsi.length = 4096;
410 	primary.bytes_completed = 4096 * 2;
411 	primary.scsi.data_transferred = 4096 * 2;
412 	primary.scsi.transfer_len = 4096 * 3;
413 	primary.scsi.status = SPDK_SCSI_STATUS_GOOD;
414 	primary.rsp_scsi_status = SPDK_SCSI_STATUS_GOOD;
415 	TAILQ_INSERT_TAIL(&conn.active_r2t_tasks, &primary, link);
416 
417 	process_non_read_task_completion(&conn, &primary, &primary);
418 	CU_ASSERT(TAILQ_EMPTY(&conn.active_r2t_tasks));
419 	CU_ASSERT(primary.bytes_completed == 4096 * 3);
420 	CU_ASSERT(primary.scsi.data_transferred == 4096 * 2);
421 	CU_ASSERT(primary.rsp_scsi_status == SPDK_SCSI_STATUS_GOOD);
422 }
423 
424 static void
425 recursive_flush_pdus_calls(void)
426 {
427 	struct spdk_iscsi_pdu pdu1 = {}, pdu2 = {}, pdu3 = {};
428 	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {};
429 	struct spdk_iscsi_conn conn = {};
430 	int rc;
431 
432 	TAILQ_INIT(&conn.write_pdu_list);
433 	conn.data_in_cnt = 3;
434 
435 	task1.scsi.offset = 512;
436 	task2.scsi.offset = 512 * 2;
437 	task3.scsi.offset = 512 * 3;
438 
439 	pdu1.task = &task1;
440 	pdu2.task = &task2;
441 	pdu3.task = &task3;
442 
443 	pdu1.bhs.opcode = ISCSI_OP_SCSI_DATAIN;
444 	pdu2.bhs.opcode = ISCSI_OP_SCSI_DATAIN;
445 	pdu3.bhs.opcode = ISCSI_OP_SCSI_DATAIN;
446 
447 	DSET24(&pdu1.bhs.data_segment_len, 512);
448 	DSET24(&pdu2.bhs.data_segment_len, 512);
449 	DSET24(&pdu3.bhs.data_segment_len, 512);
450 
451 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu1, tailq);
452 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu2, tailq);
453 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu3, tailq);
454 
455 	g_sock_writev_bytes = (512 + ISCSI_BHS_LEN) * 3;
456 
457 	rc = iscsi_conn_flush_pdus_internal(&conn);
458 	CU_ASSERT(rc == 0);
459 }
460 
461 static bool
462 dequeue_pdu(void *_head, struct spdk_iscsi_pdu *pdu)
463 {
464 	TAILQ_HEAD(queued_pdus, spdk_iscsi_pdu) *head = _head;
465 	struct spdk_iscsi_pdu *tmp;
466 
467 	TAILQ_FOREACH(tmp, head, tailq) {
468 		if (tmp == pdu) {
469 			TAILQ_REMOVE(head, tmp, tailq);
470 			return true;
471 		}
472 	}
473 	return false;
474 }
475 
476 static bool
477 dequeue_task(void *_head, struct spdk_iscsi_task *task)
478 {
479 	TAILQ_HEAD(queued_tasks, spdk_iscsi_task) *head = _head;
480 	struct spdk_iscsi_task *tmp;
481 
482 	TAILQ_FOREACH(tmp, head, link) {
483 		if (tmp == task) {
484 			TAILQ_REMOVE(head, tmp, link);
485 			return true;
486 		}
487 	}
488 	return false;
489 }
490 
491 static void
492 free_tasks_on_connection(void)
493 {
494 	struct spdk_iscsi_conn conn = {};
495 	struct spdk_iscsi_pdu pdu1 = {}, pdu2 = {}, pdu3 = {}, pdu4 = {};
496 	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {};
497 	struct spdk_scsi_lun lun1 = {}, lun2 = {};
498 
499 	TAILQ_INIT(&conn.write_pdu_list);
500 	TAILQ_INIT(&conn.snack_pdu_list);
501 	TAILQ_INIT(&conn.queued_datain_tasks);
502 
503 	pdu1.task = &task1;
504 	pdu2.task = &task2;
505 	pdu3.task = &task3;
506 
507 	task1.scsi.lun = &lun1;
508 	task2.scsi.lun = &lun2;
509 
510 	task1.is_queued = false;
511 	task2.is_queued = false;
512 	task3.is_queued = true;
513 
514 	/* Test conn->write_pdu_list. */
515 
516 	task1.scsi.ref = 1;
517 	task2.scsi.ref = 1;
518 	task3.scsi.ref = 1;
519 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu1, tailq);
520 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu2, tailq);
521 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu3, tailq);
522 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu4, tailq);
523 
524 	/* Free all PDUs when exiting connection. */
525 	_iscsi_conn_free_tasks(&conn, NULL);
526 
527 	CU_ASSERT(TAILQ_EMPTY(&conn.write_pdu_list));
528 	CU_ASSERT(task1.scsi.ref == 0);
529 	CU_ASSERT(task2.scsi.ref == 0);
530 	CU_ASSERT(task3.scsi.ref == 0);
531 
532 	task1.scsi.ref = 1;
533 	task2.scsi.ref = 1;
534 	task3.scsi.ref = 1;
535 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu1, tailq);
536 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu2, tailq);
537 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu3, tailq);
538 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu4, tailq);
539 
540 	/* Free PDUs whose LUN matches the passed LUN or is NULL. */
541 	_iscsi_conn_free_tasks(&conn, &lun1);
542 
543 	CU_ASSERT(!dequeue_pdu(&conn.write_pdu_list, &pdu1));
544 	CU_ASSERT(dequeue_pdu(&conn.write_pdu_list, &pdu2));
545 	CU_ASSERT(!dequeue_pdu(&conn.write_pdu_list, &pdu3));
546 	CU_ASSERT(dequeue_pdu(&conn.write_pdu_list, &pdu4));
547 	CU_ASSERT(task1.scsi.ref == 0);
548 	CU_ASSERT(task2.scsi.ref == 1);
549 	CU_ASSERT(task3.scsi.ref == 0);
550 
551 	/* Test conn->snack_pdu_list */
552 
553 	task1.scsi.ref = 1;
554 	task2.scsi.ref = 1;
555 	task3.scsi.ref = 1;
556 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu1, tailq);
557 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu2, tailq);
558 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu3, tailq);
559 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu4, tailq);
560 
561 	/* Free all PDUs and associated tasks when exiting connection. */
562 	_iscsi_conn_free_tasks(&conn, NULL);
563 
564 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu1));
565 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu2));
566 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu3));
567 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu4));
568 	CU_ASSERT(task1.scsi.ref == 0);
569 	CU_ASSERT(task2.scsi.ref == 0);
570 	CU_ASSERT(task3.scsi.ref == 0);
571 
572 	task1.scsi.ref = 1;
573 	task2.scsi.ref = 1;
574 	task3.scsi.ref = 1;
575 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu1, tailq);
576 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu2, tailq);
577 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu3, tailq);
578 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu4, tailq);
579 
580 	/* Free all PDUs and free associated tasks whose lun matches the passed LUN. */
581 	_iscsi_conn_free_tasks(&conn, &lun1);
582 
583 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu1));
584 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu2));
585 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu3));
586 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu4));
587 	CU_ASSERT(task1.scsi.ref == 0);
588 	CU_ASSERT(task2.scsi.ref == 1);
589 	CU_ASSERT(task3.scsi.ref == 1);
590 
591 	/* Test conn->queued_datain_tasks */
592 
593 	task1.scsi.ref = 1;
594 	task2.scsi.ref = 1;
595 	task3.scsi.ref = 1;
596 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task1, link);
597 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task2, link);
598 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task3, link);
599 
600 	/* Free all tasks which is not queued when exiting connection. */
601 	_iscsi_conn_free_tasks(&conn, NULL);
602 
603 	CU_ASSERT(!dequeue_task(&conn.queued_datain_tasks, &task1));
604 	CU_ASSERT(!dequeue_task(&conn.queued_datain_tasks, &task2));
605 	CU_ASSERT(dequeue_task(&conn.queued_datain_tasks, &task3));
606 	CU_ASSERT(task1.scsi.ref == 0);
607 	CU_ASSERT(task2.scsi.ref == 0);
608 	CU_ASSERT(task3.scsi.ref == 1);
609 
610 	task1.scsi.ref = 1;
611 	task2.scsi.ref = 1;
612 	task3.scsi.ref = 1;
613 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task1, link);
614 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task2, link);
615 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task3, link);
616 
617 	/* Free all tasks which is not queued and.whose LUN matches the passed LUN. */
618 	_iscsi_conn_free_tasks(&conn, &lun1);
619 
620 	CU_ASSERT(!dequeue_task(&conn.queued_datain_tasks, &task1));
621 	CU_ASSERT(dequeue_task(&conn.queued_datain_tasks, &task2));
622 	CU_ASSERT(dequeue_task(&conn.queued_datain_tasks, &task3));
623 	CU_ASSERT(task1.scsi.ref == 0);
624 	CU_ASSERT(task2.scsi.ref == 1);
625 	CU_ASSERT(task3.scsi.ref == 1);
626 }
627 
628 int
629 main(int argc, char **argv)
630 {
631 	CU_pSuite	suite = NULL;
632 	unsigned int	num_failures;
633 
634 	if (CU_initialize_registry() != CUE_SUCCESS) {
635 		return CU_get_error();
636 	}
637 
638 	suite = CU_add_suite("conn_suite", NULL, NULL);
639 	if (suite == NULL) {
640 		CU_cleanup_registry();
641 		return CU_get_error();
642 	}
643 
644 	if (
645 		CU_add_test(suite, "read task split in order", read_task_split_in_order_case) == NULL ||
646 		CU_add_test(suite, "read task split reverse order",
647 			    read_task_split_reverse_order_case) == NULL ||
648 		CU_add_test(suite, "propagate_scsi_error_status_for_split_read_tasks",
649 			    propagate_scsi_error_status_for_split_read_tasks) == NULL ||
650 		CU_add_test(suite, "process_non_read_task_completion_test",
651 			    process_non_read_task_completion_test) == NULL ||
652 		CU_add_test(suite, "recursive_flush_pdus_calls", recursive_flush_pdus_calls) == NULL ||
653 		CU_add_test(suite, "free_tasks_on_connection", free_tasks_on_connection) == NULL
654 	) {
655 		CU_cleanup_registry();
656 		return CU_get_error();
657 	}
658 
659 	CU_basic_set_mode(CU_BRM_VERBOSE);
660 	CU_basic_run_tests();
661 	num_failures = CU_get_number_of_failures();
662 	CU_cleanup_registry();
663 	return num_failures;
664 }
665