xref: /spdk/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c (revision 1078198e78653b2f39414c1566740018d76ee73d)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2017 Intel Corporation.
3  *   All rights reserved.
4  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5  */
6 
7 #include "spdk/stdinc.h"
8 
9 #include "spdk_internal/cunit.h"
10 #include "spdk_internal/mock.h"
11 
12 #include "common/lib/test_env.c"
13 #include "spdk/bdev_module.h"
14 #include "nvmf/ctrlr_discovery.c"
15 #include "nvmf/subsystem.c"
16 
17 SPDK_LOG_REGISTER_COMPONENT(nvmf)
18 
19 DEFINE_STUB_V(spdk_bdev_module_release_bdev,
20 	      (struct spdk_bdev *bdev));
21 
22 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
23 	    (const struct spdk_bdev *bdev), 512);
24 
25 DEFINE_STUB(spdk_nvmf_transport_stop_listen,
26 	    int,
27 	    (struct spdk_nvmf_transport *transport,
28 	     const struct spdk_nvme_transport_id *trid), 0);
29 
30 DEFINE_STUB(spdk_nvmf_transport_get_first,
31 	    struct spdk_nvmf_transport *,
32 	    (struct spdk_nvmf_tgt *tgt), NULL);
33 
34 DEFINE_STUB(spdk_nvmf_transport_get_next,
35 	    struct spdk_nvmf_transport *,
36 	    (struct spdk_nvmf_transport *transport), NULL);
37 
38 DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
39 
40 DEFINE_STUB_V(nvmf_ctrlr_async_event_discovery_log_change_notice, (void *ctx));
41 
42 DEFINE_STUB(spdk_nvmf_qpair_disconnect, int,
43 	    (struct spdk_nvmf_qpair *qpair,
44 	     nvmf_qpair_disconnect_cb cb_fn, void *ctx), 0);
45 
46 DEFINE_STUB(spdk_bdev_open_ext, int,
47 	    (const char *bdev_name, bool write,	spdk_bdev_event_cb_t event_cb,
48 	     void *event_ctx, struct spdk_bdev_desc **desc), 0);
49 
50 DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *,
51 	    (struct spdk_bdev_desc *desc), NULL);
52 
53 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
54 	    (const struct spdk_bdev *bdev), 0);
55 
56 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
57 	    (const struct spdk_bdev *bdev), false);
58 
59 DEFINE_STUB(spdk_bdev_module_claim_bdev, int,
60 	    (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
61 	     struct spdk_bdev_module *module), 0);
62 
63 DEFINE_STUB(spdk_bdev_io_type_supported, bool,
64 	    (struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type), false);
65 
66 DEFINE_STUB_V(nvmf_ctrlr_reservation_notice_log,
67 	      (struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvmf_ns *ns,
68 	       enum spdk_nvme_reservation_notification_log_page_type type));
69 
70 DEFINE_STUB(spdk_nvmf_request_complete, int,
71 	    (struct spdk_nvmf_request *req), -1);
72 
73 DEFINE_STUB(nvmf_ctrlr_async_event_ana_change_notice, int,
74 	    (struct spdk_nvmf_ctrlr *ctrlr), 0);
75 
76 DEFINE_STUB(spdk_nvme_transport_id_trtype_str, const char *,
77 	    (enum spdk_nvme_transport_type trtype), NULL);
78 
79 DEFINE_STUB(spdk_bdev_is_zoned, bool, (const struct spdk_bdev *bdev), false);
80 
81 DEFINE_STUB(spdk_bdev_get_max_zone_append_size, uint32_t,
82 	    (const struct spdk_bdev *bdev), 0);
83 
84 const char *
85 spdk_bdev_get_name(const struct spdk_bdev *bdev)
86 {
87 	return "test";
88 }
89 
90 const struct spdk_uuid *
91 spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
92 {
93 	return &bdev->uuid;
94 }
95 
96 int
97 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1,
98 			       const struct spdk_nvme_transport_id *trid2)
99 {
100 	return !(trid1->trtype == trid2->trtype && strcasecmp(trid1->traddr, trid2->traddr) == 0 &&
101 		 strcasecmp(trid1->trsvcid, trid2->trsvcid) == 0);
102 }
103 
104 int
105 spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport,
106 			   const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *opts)
107 {
108 	return 0;
109 }
110 
111 static struct spdk_nvmf_listener g_listener = {};
112 
113 struct spdk_nvmf_listener *
114 nvmf_transport_find_listener(struct spdk_nvmf_transport *transport,
115 			     const struct spdk_nvme_transport_id *trid)
116 {
117 	struct spdk_nvmf_listener *listener;
118 
119 	if (TAILQ_EMPTY(&transport->listeners)) {
120 		return &g_listener;
121 	}
122 
123 	TAILQ_FOREACH(listener, &transport->listeners, link) {
124 		if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) {
125 			return listener;
126 		}
127 	}
128 
129 	return NULL;
130 }
131 
132 void
133 nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport,
134 				 struct spdk_nvme_transport_id *trid,
135 				 struct spdk_nvmf_discovery_log_page_entry *entry)
136 {
137 	transport->ops->listener_discover(transport, trid, entry);
138 }
139 
140 static void
141 test_dummy_listener_discover(struct spdk_nvmf_transport *transport,
142 			     struct spdk_nvme_transport_id *trid, struct spdk_nvmf_discovery_log_page_entry *entry)
143 {
144 	entry->trtype = 42;
145 }
146 
147 struct spdk_nvmf_transport_ops g_transport_ops = { .listener_discover = test_dummy_listener_discover };
148 
149 static struct spdk_nvmf_transport g_transport = {
150 	.ops = &g_transport_ops
151 };
152 
153 int
154 spdk_nvmf_transport_create_async(const char *transport_name,
155 				 struct spdk_nvmf_transport_opts *tprt_opts,
156 				 spdk_nvmf_transport_create_done_cb cb_fn, void *cb_arg)
157 {
158 	if (strcasecmp(transport_name, spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA))) {
159 		cb_fn(cb_arg, &g_transport);
160 		return 0;
161 	}
162 
163 	return -1;
164 }
165 
166 struct spdk_nvmf_subsystem *
167 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn)
168 {
169 	return NULL;
170 }
171 
172 DEFINE_RETURN_MOCK(spdk_nvmf_tgt_get_transport, struct spdk_nvmf_transport *);
173 struct spdk_nvmf_transport *
174 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name)
175 {
176 	HANDLE_RETURN_MOCK(spdk_nvmf_tgt_get_transport);
177 	return &g_transport;
178 }
179 
180 int
181 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str)
182 {
183 	if (trtype == NULL || str == NULL) {
184 		return -EINVAL;
185 	}
186 
187 	if (strcasecmp(str, "PCIe") == 0) {
188 		*trtype = SPDK_NVME_TRANSPORT_PCIE;
189 	} else if (strcasecmp(str, "RDMA") == 0) {
190 		*trtype = SPDK_NVME_TRANSPORT_RDMA;
191 	} else {
192 		return -ENOENT;
193 	}
194 	return 0;
195 }
196 
197 void
198 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
199 {
200 }
201 
202 void
203 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
204 {
205 }
206 
207 int
208 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group,
209 				 struct spdk_nvmf_subsystem *subsystem)
210 {
211 	return 0;
212 }
213 
214 int
215 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
216 			      struct spdk_nvmf_subsystem *subsystem,
217 			      spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
218 {
219 	return 0;
220 }
221 
222 void
223 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
224 				 struct spdk_nvmf_subsystem *subsystem,
225 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
226 {
227 }
228 
229 void
230 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group,
231 				struct spdk_nvmf_subsystem *subsystem,
232 				uint32_t nsid,
233 				spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
234 {
235 }
236 
237 void
238 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group,
239 				 struct spdk_nvmf_subsystem *subsystem,
240 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
241 {
242 }
243 
244 static void
245 _subsystem_add_listen_done(void *cb_arg, int status)
246 {
247 	SPDK_CU_ASSERT_FATAL(status == 0);
248 }
249 
250 static void
251 test_gen_trid(struct spdk_nvme_transport_id *trid, enum spdk_nvme_transport_type trtype,
252 	      enum spdk_nvmf_adrfam adrfam, const char *tradd, const char *trsvcid)
253 {
254 	snprintf(trid->traddr, sizeof(trid->traddr), "%s", tradd);
255 	snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%s", trsvcid);
256 	trid->adrfam = adrfam;
257 	trid->trtype = trtype;
258 	switch (trtype) {
259 	case SPDK_NVME_TRANSPORT_RDMA:
260 		snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", SPDK_NVME_TRANSPORT_NAME_RDMA);
261 		break;
262 	case SPDK_NVME_TRANSPORT_TCP:
263 		snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", SPDK_NVME_TRANSPORT_NAME_TCP);
264 		break;
265 	default:
266 		SPDK_CU_ASSERT_FATAL(0 && "not supported by test");
267 	}
268 }
269 
270 static void
271 test_discovery_log(void)
272 {
273 	struct spdk_nvmf_tgt tgt = {};
274 	struct spdk_nvmf_subsystem *subsystem;
275 	uint8_t buffer[8192];
276 	struct iovec iov;
277 	struct spdk_nvmf_discovery_log_page *disc_log;
278 	struct spdk_nvmf_discovery_log_page_entry *entry;
279 	struct spdk_nvme_transport_id trid = {};
280 	const char *hostnqn = "nqn.2016-06.io.spdk:host1";
281 	int rc;
282 
283 	iov.iov_base = buffer;
284 	iov.iov_len = 8192;
285 
286 	tgt.max_subsystems = 1024;
287 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
288 	RB_INIT(&tgt.subsystems);
289 
290 	/* Add one subsystem and verify that the discovery log contains it */
291 	subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1",
292 					       SPDK_NVMF_SUBTYPE_NVME, 0);
293 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
294 
295 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL);
296 	CU_ASSERT(rc == 0);
297 
298 	/* Get only genctr (first field in the header) */
299 	memset(buffer, 0xCC, sizeof(buffer));
300 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
301 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(disc_log->genctr),
302 				    &trid);
303 	/* No listeners yet on new subsystem, so genctr should still be 0. */
304 	CU_ASSERT(disc_log->genctr == 0);
305 
306 	test_gen_trid(&trid, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "1234", "5678");
307 	spdk_nvmf_subsystem_add_listener(subsystem, &trid, _subsystem_add_listen_done, NULL);
308 	subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
309 
310 	/* Get only genctr (first field in the header) */
311 	memset(buffer, 0xCC, sizeof(buffer));
312 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
313 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(disc_log->genctr),
314 				    &trid);
315 	CU_ASSERT(disc_log->genctr == 1); /* one added subsystem and listener */
316 
317 	/* Get only the header, no entries */
318 	memset(buffer, 0xCC, sizeof(buffer));
319 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
320 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log),
321 				    &trid);
322 	CU_ASSERT(disc_log->genctr == 1);
323 	CU_ASSERT(disc_log->numrec == 1);
324 
325 	/* Offset 0, exact size match */
326 	memset(buffer, 0xCC, sizeof(buffer));
327 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
328 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0,
329 				    sizeof(*disc_log) + sizeof(disc_log->entries[0]), &trid);
330 	CU_ASSERT(disc_log->genctr != 0);
331 	CU_ASSERT(disc_log->numrec == 1);
332 	CU_ASSERT(disc_log->entries[0].trtype == 42);
333 
334 	/* Offset 0, oversize buffer */
335 	memset(buffer, 0xCC, sizeof(buffer));
336 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
337 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(buffer), &trid);
338 	CU_ASSERT(disc_log->genctr != 0);
339 	CU_ASSERT(disc_log->numrec == 1);
340 	CU_ASSERT(disc_log->entries[0].trtype == 42);
341 	CU_ASSERT(spdk_mem_all_zero(buffer + sizeof(*disc_log) + sizeof(disc_log->entries[0]),
342 				    sizeof(buffer) - (sizeof(*disc_log) + sizeof(disc_log->entries[0]))));
343 
344 	/* Get just the first entry, no header */
345 	memset(buffer, 0xCC, sizeof(buffer));
346 	entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer;
347 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1,
348 				    offsetof(struct spdk_nvmf_discovery_log_page, entries[0]), sizeof(*entry), &trid);
349 	CU_ASSERT(entry->trtype == 42);
350 
351 	/* remove the host and verify that the discovery log contains nothing */
352 	rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn);
353 	CU_ASSERT(rc == 0);
354 
355 	/* Get only the header, no entries */
356 	memset(buffer, 0xCC, sizeof(buffer));
357 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
358 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log),
359 				    &trid);
360 	CU_ASSERT(disc_log->genctr != 0);
361 	CU_ASSERT(disc_log->numrec == 0);
362 
363 	/* destroy the subsystem and verify that the discovery log contains nothing */
364 	subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE;
365 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
366 	CU_ASSERT(rc == 0);
367 
368 	/* Get only the header, no entries */
369 	memset(buffer, 0xCC, sizeof(buffer));
370 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
371 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log),
372 				    &trid);
373 	CU_ASSERT(disc_log->genctr != 0);
374 	CU_ASSERT(disc_log->numrec == 0);
375 
376 	spdk_bit_array_free(&tgt.subsystem_ids);
377 }
378 
379 static void
380 test_rdma_discover(struct spdk_nvmf_transport *transport, struct spdk_nvme_transport_id *trid,
381 		   struct spdk_nvmf_discovery_log_page_entry *entry)
382 {
383 	entry->trtype = SPDK_NVMF_TRTYPE_RDMA;
384 	entry->adrfam = trid->adrfam;
385 	memcpy(entry->traddr, trid->traddr, sizeof(entry->traddr));
386 	memcpy(entry->trsvcid, trid->trsvcid, sizeof(entry->trsvcid));
387 }
388 
389 static void
390 test_tcp_discover(struct spdk_nvmf_transport *transport, struct spdk_nvme_transport_id *trid,
391 		  struct spdk_nvmf_discovery_log_page_entry *entry)
392 {
393 	entry->trtype = SPDK_NVMF_TRTYPE_TCP;
394 	entry->adrfam = trid->adrfam;
395 	memcpy(entry->traddr, trid->traddr, sizeof(entry->traddr));
396 	memcpy(entry->trsvcid, trid->trsvcid, sizeof(entry->trsvcid));
397 }
398 
399 static void
400 test_discovery_log_with_filters(void)
401 {
402 	struct spdk_nvmf_tgt tgt = {};
403 	struct spdk_nvmf_transport_ops rdma_tr_ops = { .listener_discover = test_rdma_discover }, tcp_tr_ops
404 		= { .listener_discover = test_tcp_discover };
405 	struct spdk_nvmf_transport rdma_tr = {.ops = &rdma_tr_ops }, tcp_tr = { .ops = &tcp_tr_ops };
406 	struct spdk_nvmf_subsystem *subsystem;
407 	const char *hostnqn = "nqn.2016-06.io.spdk:host1";
408 	uint8_t buffer[8192];
409 	struct iovec iov;
410 	struct spdk_nvmf_discovery_log_page *disc_log;
411 	struct spdk_nvmf_listener rdma_listener_1 = {}, rdma_listener_2 = {}, rdma_listener_3 = {},
412 	tcp_listener_1 = {}, tcp_listener_2 = {}, tcp_listener_3 = {};
413 	struct spdk_nvme_transport_id rdma_trid_1 = {}, rdma_trid_2 = {}, rdma_trid_3 = {}, rdma_trid_4 = {},
414 	tcp_trid_1 = {}, tcp_trid_2 = {}, tcp_trid_3 = {}, tcp_trid_4 = {};
415 	struct spdk_nvmf_referral ref1 = {}, ref2 = {};
416 
417 	iov.iov_base = buffer;
418 	iov.iov_len = 8192;
419 
420 	tgt.max_subsystems = 4;
421 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
422 	RB_INIT(&tgt.subsystems);
423 
424 	subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1",
425 					       SPDK_NVMF_SUBTYPE_NVME, 0);
426 	subsystem->flags.allow_any_host = true;
427 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
428 
429 	TAILQ_INIT(&tgt.referrals);
430 
431 	test_gen_trid(&rdma_trid_1, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4420");
432 	test_gen_trid(&rdma_trid_2, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4420");
433 	test_gen_trid(&rdma_trid_3, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4421");
434 	test_gen_trid(&rdma_trid_4, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4430");
435 	test_gen_trid(&tcp_trid_1, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4421");
436 	test_gen_trid(&tcp_trid_2, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4422");
437 	test_gen_trid(&tcp_trid_3, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4422");
438 	test_gen_trid(&tcp_trid_4, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4430");
439 
440 	rdma_listener_1.trid = rdma_trid_1;
441 	rdma_listener_2.trid = rdma_trid_2;
442 	rdma_listener_3.trid = rdma_trid_3;
443 	TAILQ_INIT(&rdma_tr.listeners);
444 	TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_1, link);
445 	TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_2, link);
446 	TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_3, link);
447 
448 	tcp_listener_1.trid = tcp_trid_1;
449 	tcp_listener_2.trid = tcp_trid_2;
450 	tcp_listener_3.trid = tcp_trid_3;
451 	TAILQ_INIT(&tcp_tr.listeners);
452 	TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_1, link);
453 	TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_2, link);
454 	TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_3, link);
455 
456 	MOCK_SET(spdk_nvmf_tgt_get_transport, &rdma_tr);
457 	spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_1, _subsystem_add_listen_done, NULL);
458 	spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_2, _subsystem_add_listen_done, NULL);
459 	spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_3, _subsystem_add_listen_done, NULL);
460 	MOCK_SET(spdk_nvmf_tgt_get_transport, &tcp_tr);
461 	spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_1, _subsystem_add_listen_done, NULL);
462 	spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_2, _subsystem_add_listen_done, NULL);
463 	spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_3, _subsystem_add_listen_done, NULL);
464 	MOCK_CLEAR(spdk_nvmf_tgt_get_transport);
465 
466 	subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
467 
468 	ref1.trid = rdma_trid_4;
469 
470 	ref1.entry.trtype = rdma_trid_4.trtype;
471 	ref1.entry.adrfam = rdma_trid_4.adrfam;
472 	ref1.entry.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY;
473 	ref1.entry.treq.secure_channel = SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED;
474 	ref1.entry.cntlid = 0xffff;
475 	memcpy(ref1.entry.trsvcid, rdma_trid_4.trsvcid, sizeof(ref1.entry.trsvcid));
476 	memcpy(ref1.entry.traddr, rdma_trid_4.traddr, sizeof(ref1.entry.traddr));
477 	snprintf(ref1.entry.subnqn, sizeof(ref1.entry.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
478 
479 	ref2.trid = tcp_trid_4;
480 
481 	ref2.entry.trtype = tcp_trid_4.trtype;
482 	ref2.entry.adrfam = tcp_trid_4.adrfam;
483 	ref2.entry.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY;
484 	ref2.entry.treq.secure_channel = SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED;
485 	ref2.entry.cntlid = 0xffff;
486 	memcpy(ref2.entry.trsvcid, tcp_trid_4.trsvcid, sizeof(ref2.entry.trsvcid));
487 	memcpy(ref2.entry.traddr, tcp_trid_4.traddr, sizeof(ref2.entry.traddr));
488 	snprintf(ref2.entry.subnqn, sizeof(ref2.entry.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
489 
490 	TAILQ_INSERT_HEAD(&tgt.referrals, &ref1, link);
491 	TAILQ_INSERT_HEAD(&tgt.referrals, &ref2, link);
492 
493 	nvmf_update_discovery_log(&tgt, NULL);
494 
495 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
496 	memset(buffer, 0, sizeof(buffer));
497 
498 	/* Test case 1 - check that all trids are reported */
499 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY;
500 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
501 	CU_ASSERT(disc_log->numrec == 8);
502 
503 	/* Test case 2 - check that only entries of the same transport type are returned */
504 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE;
505 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
506 	CU_ASSERT(disc_log->numrec == 5);
507 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
508 	CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype);
509 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_1.trtype);
510 	CU_ASSERT(disc_log->entries[3].trtype == tcp_trid_4.trtype);
511 	CU_ASSERT(disc_log->entries[4].trtype == rdma_trid_4.trtype);
512 
513 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
514 	CU_ASSERT(disc_log->numrec == 5);
515 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
516 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype);
517 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_1.trtype);
518 	CU_ASSERT(disc_log->entries[3].trtype == tcp_trid_1.trtype);
519 	CU_ASSERT(disc_log->entries[4].trtype == rdma_trid_4.trtype);
520 
521 	/* Test case 3 - check that only entries of the same transport address are returned */
522 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS;
523 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
524 	CU_ASSERT(disc_log->numrec == 5);
525 	/* 1 tcp and 3 rdma  */
526 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
527 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0);
528 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_1.traddr) == 0);
529 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, tcp_trid_4.traddr) == 0);
530 	CU_ASSERT(strcasecmp(disc_log->entries[4].traddr, rdma_trid_4.traddr) == 0);
531 
532 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
533 	CU_ASSERT(disc_log->numrec == 5);
534 	/* 1 rdma and 3 tcp */
535 	CU_ASSERT((disc_log->entries[0].trtype ^ disc_log->entries[1].trtype ^ disc_log->entries[2].trtype)
536 		  != 0);
537 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
538 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0);
539 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_1.traddr) == 0);
540 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, tcp_trid_1.traddr) == 0);
541 	CU_ASSERT(strcasecmp(disc_log->entries[4].traddr, rdma_trid_4.traddr) == 0);
542 
543 	/* Test case 4 - check that only entries of the same transport address and type returned */
544 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE |
545 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS;
546 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
547 	CU_ASSERT(disc_log->numrec == 4);
548 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
549 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0);
550 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_4.traddr) == 0);
551 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, rdma_trid_4.traddr) == 0);
552 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
553 	CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype);
554 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
555 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
556 
557 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
558 	CU_ASSERT(disc_log->numrec == 3);
559 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
560 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
561 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
562 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
563 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
564 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
565 
566 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
567 	CU_ASSERT(disc_log->numrec == 4);
568 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
569 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0);
570 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_4.traddr) == 0);
571 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, rdma_trid_4.traddr) == 0);
572 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
573 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype);
574 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
575 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
576 
577 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
578 	CU_ASSERT(disc_log->numrec == 3);
579 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
580 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
581 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
582 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
583 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
584 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
585 
586 	/* Test case 5 - check that only entries of the same transport address and type returned */
587 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE |
588 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
589 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
590 	CU_ASSERT(disc_log->numrec == 4);
591 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0);
592 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, rdma_trid_2.trsvcid) == 0);
593 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, tcp_trid_4.trsvcid) == 0);
594 	CU_ASSERT(strcasecmp(disc_log->entries[3].trsvcid, rdma_trid_4.trsvcid) == 0);
595 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
596 	CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_2.trtype);
597 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
598 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
599 
600 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3);
601 	CU_ASSERT(disc_log->numrec == 3);
602 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0);
603 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
604 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
605 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype);
606 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
607 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
608 
609 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
610 	CU_ASSERT(disc_log->numrec == 3);
611 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0);
612 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
613 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
614 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
615 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
616 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
617 
618 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2);
619 	CU_ASSERT(disc_log->numrec == 4);
620 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0);
621 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_2.trsvcid) == 0);
622 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, tcp_trid_4.trsvcid) == 0);
623 	CU_ASSERT(strcasecmp(disc_log->entries[3].trsvcid, rdma_trid_4.trsvcid) == 0);
624 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype);
625 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_2.trtype);
626 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
627 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
628 
629 	/* Test case 6 - check that only entries of the same transport address and type returned.
630 	 * That also implies trtype since RDMA and TCP listeners can't occupy the same socket */
631 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS |
632 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
633 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
634 	CU_ASSERT(disc_log->numrec == 3);
635 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
636 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
637 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
638 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0);
639 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
640 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
641 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
642 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
643 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
644 
645 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
646 	CU_ASSERT(disc_log->numrec == 3);
647 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
648 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
649 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
650 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0);
651 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
652 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
653 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
654 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
655 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
656 
657 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3);
658 	CU_ASSERT(disc_log->numrec == 3);
659 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0);
660 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
661 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
662 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0);
663 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
664 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
665 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype);
666 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
667 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
668 
669 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
670 	CU_ASSERT(disc_log->numrec == 3);
671 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
672 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
673 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
674 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0);
675 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
676 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
677 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
678 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
679 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
680 
681 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2);
682 	CU_ASSERT(disc_log->numrec == 3);
683 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0);
684 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
685 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
686 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0);
687 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
688 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
689 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype);
690 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
691 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
692 
693 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3);
694 	CU_ASSERT(disc_log->numrec == 3);
695 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0);
696 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
697 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
698 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0);
699 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
700 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
701 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype);
702 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
703 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
704 
705 	/* Test case 7 - check that only entries of the same transport address, svcid and type returned */
706 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE |
707 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS |
708 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
709 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
710 	CU_ASSERT(disc_log->numrec == 3);
711 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
712 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
713 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
714 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0);
715 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
716 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
717 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
718 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
719 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
720 
721 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
722 	CU_ASSERT(disc_log->numrec == 3);
723 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
724 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
725 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
726 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0);
727 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
728 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
729 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
730 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
731 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
732 
733 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3);
734 	CU_ASSERT(disc_log->numrec == 3);
735 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0);
736 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
737 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
738 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0);
739 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
740 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
741 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype);
742 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
743 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
744 
745 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
746 	CU_ASSERT(disc_log->numrec == 3);
747 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
748 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
749 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
750 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0);
751 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
752 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
753 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
754 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
755 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
756 
757 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2);
758 	CU_ASSERT(disc_log->numrec == 3);
759 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0);
760 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
761 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
762 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0);
763 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
764 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
765 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype);
766 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
767 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
768 
769 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3);
770 	CU_ASSERT(disc_log->numrec == 3);
771 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0);
772 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
773 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
774 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0);
775 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
776 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
777 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype);
778 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
779 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
780 
781 	subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE;
782 	spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
783 	spdk_bit_array_free(&tgt.subsystem_ids);
784 }
785 
786 int
787 main(int argc, char **argv)
788 {
789 	CU_pSuite	suite = NULL;
790 	unsigned int	num_failures;
791 
792 	CU_initialize_registry();
793 
794 	suite = CU_add_suite("nvmf", NULL, NULL);
795 
796 	CU_ADD_TEST(suite, test_discovery_log);
797 	CU_ADD_TEST(suite, test_discovery_log_with_filters);
798 
799 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
800 	CU_cleanup_registry();
801 	return num_failures;
802 }
803