1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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_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 const char * 80 spdk_bdev_get_name(const struct spdk_bdev *bdev) 81 { 82 return "test"; 83 } 84 85 const struct spdk_uuid * 86 spdk_bdev_get_uuid(const struct spdk_bdev *bdev) 87 { 88 return &bdev->uuid; 89 } 90 91 int 92 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 93 const struct spdk_nvme_transport_id *trid2) 94 { 95 return !(trid1->trtype == trid2->trtype && strcasecmp(trid1->traddr, trid2->traddr) == 0 && 96 strcasecmp(trid1->trsvcid, trid2->trsvcid) == 0); 97 } 98 99 int 100 spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport, 101 const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *opts) 102 { 103 return 0; 104 } 105 106 static struct spdk_nvmf_listener g_listener = {}; 107 108 struct spdk_nvmf_listener * 109 nvmf_transport_find_listener(struct spdk_nvmf_transport *transport, 110 const struct spdk_nvme_transport_id *trid) 111 { 112 struct spdk_nvmf_listener *listener; 113 114 if (TAILQ_EMPTY(&transport->listeners)) { 115 return &g_listener; 116 } 117 118 TAILQ_FOREACH(listener, &transport->listeners, link) { 119 if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) { 120 return listener; 121 } 122 } 123 124 return NULL; 125 } 126 127 void 128 nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport, 129 struct spdk_nvme_transport_id *trid, 130 struct spdk_nvmf_discovery_log_page_entry *entry) 131 { 132 transport->ops->listener_discover(transport, trid, entry); 133 } 134 135 static void 136 test_dummy_listener_discover(struct spdk_nvmf_transport *transport, 137 struct spdk_nvme_transport_id *trid, struct spdk_nvmf_discovery_log_page_entry *entry) 138 { 139 entry->trtype = 42; 140 } 141 142 struct spdk_nvmf_transport_ops g_transport_ops = { .listener_discover = test_dummy_listener_discover }; 143 144 static struct spdk_nvmf_transport g_transport = { 145 .ops = &g_transport_ops 146 }; 147 148 struct spdk_nvmf_transport * 149 spdk_nvmf_transport_create(const char *transport_name, 150 struct spdk_nvmf_transport_opts *tprt_opts) 151 { 152 if (strcasecmp(transport_name, spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA))) { 153 return &g_transport; 154 } 155 156 return NULL; 157 } 158 159 struct spdk_nvmf_subsystem * 160 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) 161 { 162 return NULL; 163 } 164 165 DEFINE_RETURN_MOCK(spdk_nvmf_tgt_get_transport, struct spdk_nvmf_transport *); 166 struct spdk_nvmf_transport * 167 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name) 168 { 169 HANDLE_RETURN_MOCK(spdk_nvmf_tgt_get_transport); 170 return &g_transport; 171 } 172 173 int 174 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str) 175 { 176 if (trtype == NULL || str == NULL) { 177 return -EINVAL; 178 } 179 180 if (strcasecmp(str, "PCIe") == 0) { 181 *trtype = SPDK_NVME_TRANSPORT_PCIE; 182 } else if (strcasecmp(str, "RDMA") == 0) { 183 *trtype = SPDK_NVME_TRANSPORT_RDMA; 184 } else { 185 return -ENOENT; 186 } 187 return 0; 188 } 189 190 void 191 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) 192 { 193 } 194 195 void 196 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) 197 { 198 } 199 200 int 201 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group, 202 struct spdk_nvmf_subsystem *subsystem) 203 { 204 return 0; 205 } 206 207 int 208 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, 209 struct spdk_nvmf_subsystem *subsystem, 210 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 211 { 212 return 0; 213 } 214 215 void 216 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, 217 struct spdk_nvmf_subsystem *subsystem, 218 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 219 { 220 } 221 222 void 223 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, 224 struct spdk_nvmf_subsystem *subsystem, 225 uint32_t nsid, 226 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 227 { 228 } 229 230 void 231 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, 232 struct spdk_nvmf_subsystem *subsystem, 233 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 234 { 235 } 236 237 static void 238 _subsystem_add_listen_done(void *cb_arg, int status) 239 { 240 SPDK_CU_ASSERT_FATAL(status == 0); 241 } 242 243 static void 244 test_gen_trid(struct spdk_nvme_transport_id *trid, enum spdk_nvme_transport_type trtype, 245 enum spdk_nvmf_adrfam adrfam, const char *tradd, const char *trsvcid) 246 { 247 snprintf(trid->traddr, sizeof(trid->traddr), "%s", tradd); 248 snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%s", trsvcid); 249 trid->adrfam = adrfam; 250 trid->trtype = trtype; 251 switch (trtype) { 252 case SPDK_NVME_TRANSPORT_RDMA: 253 snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", SPDK_NVME_TRANSPORT_NAME_RDMA); 254 break; 255 case SPDK_NVME_TRANSPORT_TCP: 256 snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", SPDK_NVME_TRANSPORT_NAME_TCP); 257 break; 258 default: 259 SPDK_CU_ASSERT_FATAL(0 && "not supported by test"); 260 } 261 } 262 263 static void 264 test_discovery_log(void) 265 { 266 struct spdk_nvmf_tgt tgt = {}; 267 struct spdk_nvmf_subsystem *subsystem; 268 uint8_t buffer[8192]; 269 struct iovec iov; 270 struct spdk_nvmf_discovery_log_page *disc_log; 271 struct spdk_nvmf_discovery_log_page_entry *entry; 272 struct spdk_nvme_transport_id trid = {}; 273 const char *hostnqn = "nqn.2016-06.io.spdk:host1"; 274 int rc; 275 276 iov.iov_base = buffer; 277 iov.iov_len = 8192; 278 279 tgt.max_subsystems = 1024; 280 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 281 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 282 283 /* Add one subsystem and verify that the discovery log contains it */ 284 subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", 285 SPDK_NVMF_SUBTYPE_NVME, 0); 286 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 287 288 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn); 289 CU_ASSERT(rc == 0); 290 291 /* Get only genctr (first field in the header) */ 292 memset(buffer, 0xCC, sizeof(buffer)); 293 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 294 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(disc_log->genctr), 295 &trid); 296 /* No listeners yet on new subsystem, so genctr should still be 0. */ 297 CU_ASSERT(disc_log->genctr == 0); 298 299 test_gen_trid(&trid, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "1234", "5678"); 300 spdk_nvmf_subsystem_add_listener(subsystem, &trid, _subsystem_add_listen_done, NULL); 301 subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 302 303 /* Get only genctr (first field in the header) */ 304 memset(buffer, 0xCC, sizeof(buffer)); 305 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 306 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(disc_log->genctr), 307 &trid); 308 CU_ASSERT(disc_log->genctr == 1); /* one added subsystem and listener */ 309 310 /* Get only the header, no entries */ 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), 314 &trid); 315 CU_ASSERT(disc_log->genctr == 1); 316 CU_ASSERT(disc_log->numrec == 1); 317 318 /* Offset 0, exact size match */ 319 memset(buffer, 0xCC, sizeof(buffer)); 320 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 321 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 322 sizeof(*disc_log) + sizeof(disc_log->entries[0]), &trid); 323 CU_ASSERT(disc_log->genctr != 0); 324 CU_ASSERT(disc_log->numrec == 1); 325 CU_ASSERT(disc_log->entries[0].trtype == 42); 326 327 /* Offset 0, oversize buffer */ 328 memset(buffer, 0xCC, sizeof(buffer)); 329 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 330 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(buffer), &trid); 331 CU_ASSERT(disc_log->genctr != 0); 332 CU_ASSERT(disc_log->numrec == 1); 333 CU_ASSERT(disc_log->entries[0].trtype == 42); 334 CU_ASSERT(spdk_mem_all_zero(buffer + sizeof(*disc_log) + sizeof(disc_log->entries[0]), 335 sizeof(buffer) - (sizeof(*disc_log) + sizeof(disc_log->entries[0])))); 336 337 /* Get just the first entry, no header */ 338 memset(buffer, 0xCC, sizeof(buffer)); 339 entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer; 340 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 341 offsetof(struct spdk_nvmf_discovery_log_page, entries[0]), sizeof(*entry), &trid); 342 CU_ASSERT(entry->trtype == 42); 343 344 /* remove the host and verify that the discovery log contains nothing */ 345 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 346 CU_ASSERT(rc == 0); 347 348 /* Get only the header, no entries */ 349 memset(buffer, 0xCC, sizeof(buffer)); 350 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 351 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log), 352 &trid); 353 CU_ASSERT(disc_log->genctr != 0); 354 CU_ASSERT(disc_log->numrec == 0); 355 356 /* destroy the subsystem and verify that the discovery log contains nothing */ 357 subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 358 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 359 CU_ASSERT(rc == 0); 360 361 /* Get only the header, no entries */ 362 memset(buffer, 0xCC, sizeof(buffer)); 363 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 364 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log), 365 &trid); 366 CU_ASSERT(disc_log->genctr != 0); 367 CU_ASSERT(disc_log->numrec == 0); 368 369 free(tgt.subsystems); 370 } 371 372 static void 373 test_rdma_discover(struct spdk_nvmf_transport *transport, struct spdk_nvme_transport_id *trid, 374 struct spdk_nvmf_discovery_log_page_entry *entry) 375 { 376 entry->trtype = SPDK_NVMF_TRTYPE_RDMA; 377 entry->adrfam = trid->adrfam; 378 memcpy(entry->traddr, trid->traddr, sizeof(entry->traddr)); 379 memcpy(entry->trsvcid, trid->trsvcid, sizeof(entry->trsvcid)); 380 } 381 382 static void 383 test_tcp_discover(struct spdk_nvmf_transport *transport, struct spdk_nvme_transport_id *trid, 384 struct spdk_nvmf_discovery_log_page_entry *entry) 385 { 386 entry->trtype = SPDK_NVMF_TRTYPE_TCP; 387 entry->adrfam = trid->adrfam; 388 memcpy(entry->traddr, trid->traddr, sizeof(entry->traddr)); 389 memcpy(entry->trsvcid, trid->trsvcid, sizeof(entry->trsvcid)); 390 } 391 392 static void 393 test_discovery_log_with_filters(void) 394 { 395 struct spdk_nvmf_tgt tgt = {}; 396 struct spdk_nvmf_transport_ops rdma_tr_ops = { .listener_discover = test_rdma_discover }, tcp_tr_ops 397 = { .listener_discover = test_tcp_discover }; 398 struct spdk_nvmf_transport rdma_tr = {.ops = &rdma_tr_ops }, tcp_tr = { .ops = &tcp_tr_ops }; 399 struct spdk_nvmf_subsystem *subsystem; 400 const char *hostnqn = "nqn.2016-06.io.spdk:host1"; 401 uint8_t buffer[8192]; 402 struct iovec iov; 403 struct spdk_nvmf_discovery_log_page *disc_log; 404 struct spdk_nvmf_listener rdma_listener_1 = {}, rdma_listener_2 = {}, rdma_listener_3 = {}, 405 tcp_listener_1 = {}, tcp_listener_2 = {}, tcp_listener_3 = {}; 406 struct spdk_nvme_transport_id rdma_trid_1 = {}, rdma_trid_2 = {}, rdma_trid_3 = {}, tcp_trid_1 = {}, 407 tcp_trid_2 = {}, tcp_trid_3 = {}; 408 409 iov.iov_base = buffer; 410 iov.iov_len = 8192; 411 412 tgt.max_subsystems = 4; 413 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 414 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 415 416 subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", 417 SPDK_NVMF_SUBTYPE_NVME, 0); 418 subsystem->flags.allow_any_host = true; 419 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 420 421 test_gen_trid(&rdma_trid_1, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4420"); 422 test_gen_trid(&rdma_trid_2, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4420"); 423 test_gen_trid(&rdma_trid_3, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4421"); 424 test_gen_trid(&tcp_trid_1, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4421"); 425 test_gen_trid(&tcp_trid_2, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4422"); 426 test_gen_trid(&tcp_trid_3, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4422"); 427 428 rdma_listener_1.trid = rdma_trid_1; 429 rdma_listener_2.trid = rdma_trid_2; 430 rdma_listener_3.trid = rdma_trid_3; 431 TAILQ_INIT(&rdma_tr.listeners); 432 TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_1, link); 433 TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_2, link); 434 TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_3, link); 435 436 tcp_listener_1.trid = tcp_trid_1; 437 tcp_listener_2.trid = tcp_trid_2; 438 tcp_listener_3.trid = tcp_trid_3; 439 TAILQ_INIT(&tcp_tr.listeners); 440 TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_1, link); 441 TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_2, link); 442 TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_3, link); 443 444 MOCK_SET(spdk_nvmf_tgt_get_transport, &rdma_tr); 445 spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_1, _subsystem_add_listen_done, NULL); 446 spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_2, _subsystem_add_listen_done, NULL); 447 spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_3, _subsystem_add_listen_done, NULL); 448 MOCK_SET(spdk_nvmf_tgt_get_transport, &tcp_tr); 449 spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_1, _subsystem_add_listen_done, NULL); 450 spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_2, _subsystem_add_listen_done, NULL); 451 spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_3, _subsystem_add_listen_done, NULL); 452 MOCK_CLEAR(spdk_nvmf_tgt_get_transport); 453 454 subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 455 456 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 457 memset(buffer, 0, sizeof(buffer)); 458 459 /* Test case 1 - check that all trids are reported */ 460 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY; 461 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 462 CU_ASSERT(disc_log->numrec == 6); 463 464 /* Test case 2 - check that only entries of the same transport type are returned */ 465 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE; 466 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 467 CU_ASSERT(disc_log->numrec == 3); 468 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 469 CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype); 470 CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_1.trtype); 471 472 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 473 CU_ASSERT(disc_log->numrec == 3); 474 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 475 CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype); 476 CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_1.trtype); 477 478 /* Test case 3 - check that only entries of the same transport address are returned */ 479 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS; 480 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 481 CU_ASSERT(disc_log->numrec == 3); 482 /* one tcp and 2 rdma */ 483 CU_ASSERT((disc_log->entries[0].trtype ^ disc_log->entries[1].trtype ^ disc_log->entries[2].trtype) 484 != 0); 485 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 486 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0); 487 CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_1.traddr) == 0); 488 489 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 490 CU_ASSERT(disc_log->numrec == 3); 491 /* one rdma and two tcp */ 492 CU_ASSERT((disc_log->entries[0].trtype ^ disc_log->entries[1].trtype ^ disc_log->entries[2].trtype) 493 != 0); 494 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 495 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0); 496 CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_1.traddr) == 0); 497 498 /* Test case 4 - check that only entries of the same transport address and type returned */ 499 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE | 500 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS; 501 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 502 CU_ASSERT(disc_log->numrec == 2); 503 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 504 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0); 505 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 506 CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype); 507 508 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 509 CU_ASSERT(disc_log->numrec == 1); 510 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 511 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 512 513 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 514 CU_ASSERT(disc_log->numrec == 2); 515 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 516 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0); 517 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 518 CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype); 519 520 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 521 CU_ASSERT(disc_log->numrec == 1); 522 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 523 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 524 525 /* Test case 5 - check that only entries of the same transport address and type returned */ 526 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE | 527 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID; 528 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 529 CU_ASSERT(disc_log->numrec == 2); 530 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0); 531 CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, rdma_trid_2.trsvcid) == 0); 532 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 533 CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_2.trtype); 534 535 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3); 536 CU_ASSERT(disc_log->numrec == 1); 537 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0); 538 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype); 539 540 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 541 CU_ASSERT(disc_log->numrec == 1); 542 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0); 543 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 544 545 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2); 546 CU_ASSERT(disc_log->numrec == 2); 547 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0); 548 CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_2.trsvcid) == 0); 549 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype); 550 CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_2.trtype); 551 552 /* Test case 6 - check that only entries of the same transport address and type returned. 553 * That also implies trtype since RDMA and TCP listeners can't occupy the same socket */ 554 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS | 555 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID; 556 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 557 CU_ASSERT(disc_log->numrec == 1); 558 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 559 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0); 560 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 561 562 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 563 CU_ASSERT(disc_log->numrec == 1); 564 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 565 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0); 566 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 567 568 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3); 569 CU_ASSERT(disc_log->numrec == 1); 570 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0); 571 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0); 572 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype); 573 574 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 575 CU_ASSERT(disc_log->numrec == 1); 576 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 577 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0); 578 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 579 580 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2); 581 CU_ASSERT(disc_log->numrec == 1); 582 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0); 583 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0); 584 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype); 585 586 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3); 587 CU_ASSERT(disc_log->numrec == 1); 588 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0); 589 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0); 590 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype); 591 592 /* Test case 7 - check that only entries of the same transport address, svcid and type returned */ 593 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE | 594 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS | 595 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID; 596 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 597 CU_ASSERT(disc_log->numrec == 1); 598 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 599 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0); 600 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 601 602 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 603 CU_ASSERT(disc_log->numrec == 1); 604 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 605 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0); 606 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 607 608 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3); 609 CU_ASSERT(disc_log->numrec == 1); 610 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0); 611 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0); 612 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype); 613 614 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 615 CU_ASSERT(disc_log->numrec == 1); 616 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 617 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0); 618 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 619 620 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2); 621 CU_ASSERT(disc_log->numrec == 1); 622 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0); 623 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0); 624 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype); 625 626 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3); 627 CU_ASSERT(disc_log->numrec == 1); 628 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0); 629 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0); 630 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype); 631 632 subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 633 spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 634 free(tgt.subsystems); 635 } 636 637 int 638 main(int argc, char **argv) 639 { 640 CU_pSuite suite = NULL; 641 unsigned int num_failures; 642 643 CU_set_error_action(CUEA_ABORT); 644 CU_initialize_registry(); 645 646 suite = CU_add_suite("nvmf", NULL, NULL); 647 648 CU_ADD_TEST(suite, test_discovery_log); 649 CU_ADD_TEST(suite, test_discovery_log_with_filters); 650 651 CU_basic_set_mode(CU_BRM_VERBOSE); 652 CU_basic_run_tests(); 653 num_failures = CU_get_number_of_failures(); 654 CU_cleanup_registry(); 655 return num_failures; 656 } 657