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 = {}, tcp_trid_1 = {}, 414 tcp_trid_2 = {}, tcp_trid_3 = {}; 415 416 iov.iov_base = buffer; 417 iov.iov_len = 8192; 418 419 tgt.max_subsystems = 4; 420 tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems); 421 RB_INIT(&tgt.subsystems); 422 423 subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", 424 SPDK_NVMF_SUBTYPE_NVME, 0); 425 subsystem->flags.allow_any_host = true; 426 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 427 428 test_gen_trid(&rdma_trid_1, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4420"); 429 test_gen_trid(&rdma_trid_2, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4420"); 430 test_gen_trid(&rdma_trid_3, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4421"); 431 test_gen_trid(&tcp_trid_1, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4421"); 432 test_gen_trid(&tcp_trid_2, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4422"); 433 test_gen_trid(&tcp_trid_3, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4422"); 434 435 rdma_listener_1.trid = rdma_trid_1; 436 rdma_listener_2.trid = rdma_trid_2; 437 rdma_listener_3.trid = rdma_trid_3; 438 TAILQ_INIT(&rdma_tr.listeners); 439 TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_1, link); 440 TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_2, link); 441 TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_3, link); 442 443 tcp_listener_1.trid = tcp_trid_1; 444 tcp_listener_2.trid = tcp_trid_2; 445 tcp_listener_3.trid = tcp_trid_3; 446 TAILQ_INIT(&tcp_tr.listeners); 447 TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_1, link); 448 TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_2, link); 449 TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_3, link); 450 451 MOCK_SET(spdk_nvmf_tgt_get_transport, &rdma_tr); 452 spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_1, _subsystem_add_listen_done, NULL); 453 spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_2, _subsystem_add_listen_done, NULL); 454 spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_3, _subsystem_add_listen_done, NULL); 455 MOCK_SET(spdk_nvmf_tgt_get_transport, &tcp_tr); 456 spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_1, _subsystem_add_listen_done, NULL); 457 spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_2, _subsystem_add_listen_done, NULL); 458 spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_3, _subsystem_add_listen_done, NULL); 459 MOCK_CLEAR(spdk_nvmf_tgt_get_transport); 460 461 subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 462 463 disc_log = (struct spdk_nvmf_discovery_log_page *)buffer; 464 memset(buffer, 0, sizeof(buffer)); 465 466 /* Test case 1 - check that all trids are reported */ 467 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY; 468 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 469 CU_ASSERT(disc_log->numrec == 6); 470 471 /* Test case 2 - check that only entries of the same transport type are returned */ 472 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE; 473 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 474 CU_ASSERT(disc_log->numrec == 3); 475 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 476 CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype); 477 CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_1.trtype); 478 479 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 480 CU_ASSERT(disc_log->numrec == 3); 481 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 482 CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype); 483 CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_1.trtype); 484 485 /* Test case 3 - check that only entries of the same transport address are returned */ 486 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS; 487 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 488 CU_ASSERT(disc_log->numrec == 3); 489 /* one tcp and 2 rdma */ 490 CU_ASSERT((disc_log->entries[0].trtype ^ disc_log->entries[1].trtype ^ disc_log->entries[2].trtype) 491 != 0); 492 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 493 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0); 494 CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_1.traddr) == 0); 495 496 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 497 CU_ASSERT(disc_log->numrec == 3); 498 /* one rdma and two tcp */ 499 CU_ASSERT((disc_log->entries[0].trtype ^ disc_log->entries[1].trtype ^ disc_log->entries[2].trtype) 500 != 0); 501 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 502 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0); 503 CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_1.traddr) == 0); 504 505 /* Test case 4 - check that only entries of the same transport address and type returned */ 506 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE | 507 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS; 508 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 509 CU_ASSERT(disc_log->numrec == 2); 510 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 511 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0); 512 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 513 CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype); 514 515 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 516 CU_ASSERT(disc_log->numrec == 1); 517 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 518 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 519 520 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 521 CU_ASSERT(disc_log->numrec == 2); 522 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 523 CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0); 524 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 525 CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype); 526 527 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 528 CU_ASSERT(disc_log->numrec == 1); 529 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 530 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 531 532 /* Test case 5 - check that only entries of the same transport address and type returned */ 533 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE | 534 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID; 535 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 536 CU_ASSERT(disc_log->numrec == 2); 537 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0); 538 CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, rdma_trid_2.trsvcid) == 0); 539 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 540 CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_2.trtype); 541 542 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3); 543 CU_ASSERT(disc_log->numrec == 1); 544 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0); 545 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype); 546 547 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 548 CU_ASSERT(disc_log->numrec == 1); 549 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0); 550 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 551 552 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2); 553 CU_ASSERT(disc_log->numrec == 2); 554 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0); 555 CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_2.trsvcid) == 0); 556 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype); 557 CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_2.trtype); 558 559 /* Test case 6 - check that only entries of the same transport address and type returned. 560 * That also implies trtype since RDMA and TCP listeners can't occupy the same socket */ 561 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS | 562 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID; 563 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 564 CU_ASSERT(disc_log->numrec == 1); 565 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 566 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0); 567 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 568 569 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 570 CU_ASSERT(disc_log->numrec == 1); 571 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 572 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0); 573 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 574 575 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3); 576 CU_ASSERT(disc_log->numrec == 1); 577 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0); 578 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0); 579 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype); 580 581 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 582 CU_ASSERT(disc_log->numrec == 1); 583 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 584 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0); 585 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 586 587 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2); 588 CU_ASSERT(disc_log->numrec == 1); 589 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0); 590 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0); 591 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype); 592 593 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3); 594 CU_ASSERT(disc_log->numrec == 1); 595 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0); 596 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0); 597 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype); 598 599 /* Test case 7 - check that only entries of the same transport address, svcid and type returned */ 600 tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE | 601 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS | 602 SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID; 603 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1); 604 CU_ASSERT(disc_log->numrec == 1); 605 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0); 606 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0); 607 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype); 608 609 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2); 610 CU_ASSERT(disc_log->numrec == 1); 611 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0); 612 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0); 613 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype); 614 615 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3); 616 CU_ASSERT(disc_log->numrec == 1); 617 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0); 618 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0); 619 CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype); 620 621 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1); 622 CU_ASSERT(disc_log->numrec == 1); 623 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0); 624 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0); 625 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype); 626 627 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2); 628 CU_ASSERT(disc_log->numrec == 1); 629 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0); 630 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0); 631 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype); 632 633 nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3); 634 CU_ASSERT(disc_log->numrec == 1); 635 CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0); 636 CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0); 637 CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype); 638 639 subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 640 spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 641 spdk_bit_array_free(&tgt.subsystem_ids); 642 } 643 644 int 645 main(int argc, char **argv) 646 { 647 CU_pSuite suite = NULL; 648 unsigned int num_failures; 649 650 CU_initialize_registry(); 651 652 suite = CU_add_suite("nvmf", NULL, NULL); 653 654 CU_ADD_TEST(suite, test_discovery_log); 655 CU_ADD_TEST(suite, test_discovery_log_with_filters); 656 657 num_failures = spdk_ut_run_tests(argc, argv, NULL); 658 CU_cleanup_registry(); 659 return num_failures; 660 } 661