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