1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. All rights reserved. 3 * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "common/lib/ut_multithread.c" 9 #include "spdk_internal/cunit.h" 10 #include "spdk/nvmf.h" 11 #include "spdk_internal/mock.h" 12 13 #include "spdk/bdev_module.h" 14 #include "nvmf/subsystem.c" 15 #include "nvmf/transport.c" 16 17 SPDK_LOG_REGISTER_COMPONENT(nvmf) 18 19 DEFINE_STUB(spdk_bdev_module_claim_bdev, 20 int, 21 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 22 struct spdk_bdev_module *module), 0); 23 24 DEFINE_STUB_V(spdk_bdev_module_release_bdev, 25 (struct spdk_bdev *bdev)); 26 27 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, 28 (const struct spdk_bdev *bdev), 512); 29 30 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, 31 (const struct spdk_bdev *bdev), 0); 32 33 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, 34 (const struct spdk_bdev *bdev), false); 35 36 DEFINE_STUB(spdk_bdev_io_type_supported, bool, 37 (struct spdk_bdev *bdev, 38 enum spdk_bdev_io_type io_type), false); 39 40 DEFINE_STUB_V(nvmf_update_discovery_log, 41 (struct spdk_nvmf_tgt *tgt, const char *hostnqn)); 42 DEFINE_STUB(spdk_nvmf_qpair_disconnect, int, (struct spdk_nvmf_qpair *qpair), 0); 43 44 DEFINE_STUB(spdk_nvmf_request_complete, 45 int, 46 (struct spdk_nvmf_request *req), 0); 47 48 DEFINE_STUB(nvmf_ctrlr_async_event_ana_change_notice, 49 int, 50 (struct spdk_nvmf_ctrlr *ctrlr), 0); 51 52 DEFINE_STUB(spdk_nvme_transport_id_trtype_str, 53 const char *, 54 (enum spdk_nvme_transport_type trtype), NULL); 55 56 DEFINE_STUB(spdk_bdev_is_zoned, bool, 57 (const struct spdk_bdev *bdev), false); 58 59 DEFINE_STUB(spdk_bdev_get_max_zone_append_size, uint32_t, 60 (const struct spdk_bdev *bdev), 0); 61 62 DEFINE_STUB(spdk_mempool_lookup, struct spdk_mempool *, 63 (const char *name), NULL); 64 65 DEFINE_STUB(spdk_nvme_transport_id_adrfam_str, const char *, 66 (enum spdk_nvmf_adrfam adrfam), NULL); 67 68 DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, int, 69 (struct spdk_nvmf_qpair *qpair, 70 struct spdk_nvme_transport_id *trid), 0); 71 72 static struct spdk_nvmf_transport g_transport = {}; 73 74 struct spdk_nvmf_subsystem * 75 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) 76 { 77 return NULL; 78 } 79 80 struct spdk_nvmf_transport * 81 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name) 82 { 83 if (strncmp(transport_name, SPDK_NVME_TRANSPORT_NAME_RDMA, SPDK_NVMF_TRSTRING_MAX_LEN)) { 84 return &g_transport; 85 } 86 87 return NULL; 88 } 89 90 int 91 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group, 92 struct spdk_nvmf_subsystem *subsystem) 93 { 94 return 0; 95 } 96 97 int 98 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, 99 struct spdk_nvmf_subsystem *subsystem, 100 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 101 { 102 return 0; 103 } 104 105 void 106 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, 107 struct spdk_nvmf_subsystem *subsystem, 108 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 109 { 110 } 111 112 void 113 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, 114 struct spdk_nvmf_subsystem *subsystem, 115 uint32_t nsid, 116 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 117 { 118 } 119 120 void 121 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, 122 struct spdk_nvmf_subsystem *subsystem, 123 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 124 { 125 } 126 127 int 128 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str) 129 { 130 if (trtype == NULL || str == NULL) { 131 return -EINVAL; 132 } 133 134 if (strcasecmp(str, "PCIe") == 0) { 135 *trtype = SPDK_NVME_TRANSPORT_PCIE; 136 } else if (strcasecmp(str, "RDMA") == 0) { 137 *trtype = SPDK_NVME_TRANSPORT_RDMA; 138 } else { 139 return -ENOENT; 140 } 141 return 0; 142 } 143 144 int 145 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 146 const struct spdk_nvme_transport_id *trid2) 147 { 148 return 0; 149 } 150 151 int32_t 152 spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr) 153 { 154 return -1; 155 } 156 157 int32_t 158 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) 159 { 160 return -1; 161 } 162 163 int 164 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr) 165 { 166 return -1; 167 } 168 169 void 170 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) 171 { 172 } 173 174 static struct spdk_nvmf_ctrlr *g_ns_changed_ctrlr = NULL; 175 static uint32_t g_ns_changed_nsid = 0; 176 void 177 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) 178 { 179 g_ns_changed_ctrlr = ctrlr; 180 g_ns_changed_nsid = nsid; 181 } 182 183 184 static struct spdk_nvmf_ctrlr *g_async_event_ctrlr = NULL; 185 int 186 nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr) 187 { 188 g_async_event_ctrlr = ctrlr; 189 return 0; 190 } 191 192 static struct spdk_bdev g_bdevs[] = { 193 { .name = "bdev1" }, 194 { .name = "bdev2" }, 195 { .name = "bdev3", .ctratt.raw = 0x80000 }, 196 }; 197 198 struct spdk_bdev_desc { 199 struct spdk_bdev *bdev; 200 }; 201 202 int 203 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, 204 void *event_ctx, struct spdk_bdev_desc **_desc) 205 { 206 struct spdk_bdev_desc *desc; 207 size_t i; 208 209 for (i = 0; i < sizeof(g_bdevs); i++) { 210 if (strcmp(bdev_name, g_bdevs[i].name) == 0) { 211 212 desc = calloc(1, sizeof(*desc)); 213 SPDK_CU_ASSERT_FATAL(desc != NULL); 214 215 desc->bdev = &g_bdevs[i]; 216 *_desc = desc; 217 return 0; 218 } 219 } 220 221 return -EINVAL; 222 } 223 224 void 225 spdk_bdev_close(struct spdk_bdev_desc *desc) 226 { 227 free(desc); 228 } 229 230 struct spdk_bdev * 231 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 232 { 233 return desc->bdev; 234 } 235 236 const char * 237 spdk_bdev_get_name(const struct spdk_bdev *bdev) 238 { 239 return "test"; 240 } 241 242 const struct spdk_uuid * 243 spdk_bdev_get_uuid(const struct spdk_bdev *bdev) 244 { 245 return &bdev->uuid; 246 } 247 248 union spdk_bdev_nvme_ctratt spdk_bdev_get_nvme_ctratt(struct spdk_bdev *bdev) 249 { 250 return bdev->ctratt; 251 } 252 253 static void 254 test_spdk_nvmf_subsystem_add_ns(void) 255 { 256 struct spdk_nvmf_tgt tgt = {}; 257 struct spdk_nvmf_subsystem subsystem = { 258 .max_nsid = 1024, 259 .ns = NULL, 260 .tgt = &tgt, 261 }; 262 struct spdk_nvmf_ns_opts ns_opts; 263 uint32_t nsid; 264 int rc; 265 266 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 267 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 268 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 269 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 270 271 tgt.max_subsystems = 1024; 272 RB_INIT(&tgt.subsystems); 273 274 /* Request a specific NSID */ 275 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 276 ns_opts.nsid = 5; 277 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 278 CU_ASSERT(nsid == 5); 279 CU_ASSERT(subsystem.max_nsid == 1024); 280 SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL); 281 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[1]); 282 283 /* Request an NSID that is already in use */ 284 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 285 ns_opts.nsid = 5; 286 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 287 CU_ASSERT(nsid == 0); 288 CU_ASSERT(subsystem.max_nsid == 1024); 289 290 /* Request 0xFFFFFFFF (invalid NSID, reserved for broadcast) */ 291 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 292 ns_opts.nsid = 0xFFFFFFFF; 293 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 294 CU_ASSERT(nsid == 0); 295 CU_ASSERT(subsystem.max_nsid == 1024); 296 297 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 5); 298 CU_ASSERT(rc == 0); 299 300 free(subsystem.ns); 301 free(subsystem.ana_group); 302 } 303 304 static void 305 test_spdk_nvmf_subsystem_add_fdp_ns(void) 306 { 307 struct spdk_nvmf_tgt tgt = {}; 308 struct spdk_nvmf_subsystem subsystem = { 309 .max_nsid = 1024, 310 .ns = NULL, 311 .tgt = &tgt, 312 }; 313 struct spdk_nvmf_ns_opts ns_opts; 314 uint32_t nsid; 315 int rc; 316 317 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 318 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 319 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 320 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 321 322 tgt.max_subsystems = 1024; 323 RB_INIT(&tgt.subsystems); 324 325 CU_ASSERT(subsystem.fdp_supported == false); 326 327 /* Add a FDP supported namespace to the subsystem */ 328 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 329 ns_opts.nsid = 3; 330 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev3", &ns_opts, sizeof(ns_opts), NULL); 331 CU_ASSERT(nsid == 3); 332 CU_ASSERT(subsystem.max_nsid == 1024); 333 SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL); 334 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[2]); 335 CU_ASSERT(subsystem.fdp_supported == true); 336 337 /* Try to add a non FDP supported namespace to the subsystem */ 338 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 339 ns_opts.nsid = 5; 340 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 341 CU_ASSERT(nsid == 0); 342 CU_ASSERT(subsystem.max_nsid == 1024); 343 CU_ASSERT(subsystem.fdp_supported == true); 344 345 /* Remove last FDP namespace from the subsystem */ 346 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 3); 347 CU_ASSERT(rc == 0); 348 CU_ASSERT(subsystem.fdp_supported == false); 349 350 free(subsystem.ns); 351 free(subsystem.ana_group); 352 } 353 354 static void 355 nvmf_test_create_subsystem(void) 356 { 357 struct spdk_nvmf_tgt tgt = {}; 358 char nqn[256]; 359 struct spdk_nvmf_subsystem *subsystem; 360 int rc; 361 362 tgt.max_subsystems = 1024; 363 tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems); 364 RB_INIT(&tgt.subsystems); 365 366 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 367 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 368 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 369 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 370 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 371 CU_ASSERT(rc == 0); 372 373 /* valid name with complex reverse domain */ 374 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-full--rev-domain.name:subsystem1"); 375 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 376 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 377 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 378 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 379 CU_ASSERT(rc == 0); 380 381 /* Valid name discovery controller */ 382 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 383 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 384 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 385 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 386 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 387 CU_ASSERT(rc == 0); 388 389 /* Invalid name, no user supplied string */ 390 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 391 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 392 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 393 394 /* Valid name, only contains top-level domain name */ 395 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 396 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 397 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 398 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 399 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 400 CU_ASSERT(rc == 0); 401 402 /* Invalid name, domain label > 63 characters */ 403 snprintf(nqn, sizeof(nqn), 404 "nqn.2016-06.io.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz:sub"); 405 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 406 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 407 408 /* Invalid name, domain label starts with digit */ 409 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.3spdk:sub"); 410 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 411 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 412 413 /* Invalid name, domain label starts with - */ 414 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.-spdk:subsystem1"); 415 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 416 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 417 418 /* Invalid name, domain label ends with - */ 419 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-:subsystem1"); 420 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 421 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 422 423 /* Invalid name, domain label with multiple consecutive periods */ 424 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io..spdk:subsystem1"); 425 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 426 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 427 428 /* Longest valid name */ 429 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 430 memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn)); 431 nqn[223] = '\0'; 432 CU_ASSERT(strlen(nqn) == 223); 433 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 434 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 435 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 436 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 437 CU_ASSERT(rc == 0); 438 439 /* Invalid name, too long */ 440 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 441 memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn)); 442 nqn[224] = '\0'; 443 CU_ASSERT(strlen(nqn) == 224); 444 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 445 CU_ASSERT(subsystem == NULL); 446 447 /* Valid name using uuid format */ 448 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:ff9b6406-0fc8-4779-80ca-4dca14bda0d2"); 449 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 450 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 451 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 452 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 453 CU_ASSERT(rc == 0); 454 455 /* Invalid name user string contains an invalid utf-8 character */ 456 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xFFsubsystem1"); 457 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 458 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 459 460 /* Valid name with non-ascii but valid utf-8 characters */ 461 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xe1\x8a\x88subsystem1\xca\x80"); 462 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 463 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 464 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 465 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 466 CU_ASSERT(rc == 0); 467 468 /* Invalid uuid (too long) */ 469 snprintf(nqn, sizeof(nqn), 470 "nqn.2014-08.org.nvmexpress:uuid:ff9b6406-0fc8-4779-80ca-4dca14bda0d2aaaa"); 471 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 472 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 473 474 /* Invalid uuid (dashes placed incorrectly) */ 475 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:ff9b64-060fc8-4779-80ca-4dca14bda0d2"); 476 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 477 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 478 479 /* Invalid uuid (invalid characters in uuid) */ 480 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:ff9hg406-0fc8-4779-80ca-4dca14bda0d2"); 481 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 482 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 483 484 spdk_bit_array_free(&tgt.subsystem_ids); 485 } 486 487 static void 488 test_spdk_nvmf_subsystem_set_sn(void) 489 { 490 struct spdk_nvmf_subsystem subsystem = {}; 491 492 /* Basic valid serial number */ 493 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd xyz") == 0); 494 CU_ASSERT(strcmp(subsystem.sn, "abcd xyz") == 0); 495 496 /* Exactly 20 characters (valid) */ 497 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "12345678901234567890") == 0); 498 CU_ASSERT(strcmp(subsystem.sn, "12345678901234567890") == 0); 499 500 /* 21 characters (too long, invalid) */ 501 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "123456789012345678901") < 0); 502 503 /* Non-ASCII characters (invalid) */ 504 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd\txyz") < 0); 505 } 506 507 static void 508 test_spdk_nvmf_ns_visible(void) 509 { 510 struct spdk_nvmf_subsystem subsystem = {}; 511 struct spdk_nvmf_ns ns1 = { 512 .nsid = 1, 513 .anagrpid = 1, 514 .always_visible = false 515 }; 516 struct spdk_nvmf_ns ns2 = { 517 .nsid = 2, 518 .anagrpid = 2, 519 .always_visible = false 520 }; 521 struct spdk_nvmf_ns *ns3; 522 struct spdk_nvmf_ctrlr ctrlrA = { 523 .subsys = &subsystem 524 }; 525 struct spdk_nvmf_ctrlr ctrlrB = { 526 .subsys = &subsystem 527 }; 528 struct spdk_thread *thread; 529 struct spdk_nvmf_tgt tgt = {}; 530 uint32_t nsid; 531 int rc; 532 533 thread = spdk_get_thread(); 534 SPDK_CU_ASSERT_FATAL(thread != NULL); 535 ctrlrA.thread = thread; 536 ctrlrB.thread = thread; 537 538 subsystem.max_nsid = 1024; 539 subsystem.ns = calloc(subsystem.max_nsid, sizeof(subsystem.ns)); 540 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 541 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 542 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 543 TAILQ_INIT(&tgt.transports); 544 subsystem.tgt = &tgt; 545 546 subsystem.ns[1] = &ns1; 547 subsystem.ns[2] = &ns2; 548 ns3 = calloc(1, sizeof(*ns3)); 549 SPDK_CU_ASSERT_FATAL(ns3 != NULL); 550 ns3->nsid = 3; 551 ns3->anagrpid = 3; 552 subsystem.ana_group[ns3->anagrpid - 1] = 1; 553 subsystem.ns[3] = ns3; 554 555 snprintf(ctrlrA.hostnqn, sizeof(ctrlrA.hostnqn), "nqn.2016-06.io.spdk:host1"); 556 ctrlrA.visible_ns = spdk_bit_array_create(subsystem.max_nsid); 557 SPDK_CU_ASSERT_FATAL(ctrlrA.visible_ns != NULL); 558 snprintf(ctrlrB.hostnqn, sizeof(ctrlrB.hostnqn), "nqn.2016-06.io.spdk:host2"); 559 ctrlrB.visible_ns = spdk_bit_array_create(subsystem.max_nsid); 560 SPDK_CU_ASSERT_FATAL(ctrlrB.visible_ns != NULL); 561 562 /* Add two controllers ctrlrA and ctrlrB */ 563 TAILQ_INIT(&subsystem.ctrlrs); 564 TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlrA, link); 565 TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlrB, link); 566 567 /* Invalid host nqn */ 568 nsid = 1; 569 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, "", 0); 570 CU_ASSERT(rc == -EINVAL); 571 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, NULL, 0); 572 CU_ASSERT(rc == -EINVAL); 573 rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, NULL, 0); 574 CU_ASSERT(rc == -EINVAL); 575 576 /* Invalid nsid */ 577 nsid = 0; 578 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 579 CU_ASSERT(rc == -EINVAL); 580 rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 581 CU_ASSERT(rc == -EINVAL); 582 583 /* Unallocated ns */ 584 nsid = 1; 585 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 586 CU_ASSERT(rc == -ENOENT); 587 rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 588 CU_ASSERT(rc == -ENOENT); 589 590 /* Attach any is active => do not allow individual host control */ 591 ns1.always_visible = true; 592 nsid = 2; 593 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 594 CU_ASSERT(rc == -EPERM); 595 rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 596 CU_ASSERT(rc == -EPERM); 597 ns1.always_visible = false; 598 599 /* Attach ctrlrA to namespace 2 hot + cold */ 600 nsid = 2; 601 g_async_event_ctrlr = NULL; 602 g_ns_changed_ctrlr = NULL; 603 g_ns_changed_nsid = 0; 604 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 605 CU_ASSERT(rc == 0); 606 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) != NULL); 607 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL); 608 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL); 609 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL); 610 CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 611 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 612 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid)); 613 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid)); 614 /* check last ns_changed */ 615 CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA); 616 CU_ASSERT(g_ns_changed_nsid == nsid); 617 /* check async_event */ 618 poll_threads(); 619 CU_ASSERT(g_async_event_ctrlr == &ctrlrA); 620 621 /* Attach ctrlrA to namespace 2 again => should not create any ns change/async event */ 622 g_async_event_ctrlr = NULL; 623 g_ns_changed_ctrlr = NULL; 624 g_ns_changed_nsid = 0; 625 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 626 CU_ASSERT(rc == 0); 627 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) != NULL); 628 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL); 629 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL); 630 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL); 631 CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 632 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 633 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid)); 634 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid)); 635 /* check last ns_changed */ 636 CU_ASSERT(g_ns_changed_ctrlr == NULL); 637 CU_ASSERT(g_ns_changed_nsid == 0); 638 /* check async_event */ 639 poll_threads(); 640 CU_ASSERT(g_async_event_ctrlr == NULL); 641 642 /* Detach ctrlrA from namespace 2 hot + cold */ 643 g_async_event_ctrlr = NULL; 644 g_ns_changed_ctrlr = NULL; 645 g_ns_changed_nsid = 0; 646 rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 647 CU_ASSERT(rc == 0); 648 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 649 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL); 650 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL); 651 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL); 652 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 653 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 654 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid)); 655 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid)); 656 /* check last ns_changed */ 657 CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA); 658 CU_ASSERT(g_ns_changed_nsid == nsid); 659 /* check async_event */ 660 poll_threads(); 661 CU_ASSERT(g_async_event_ctrlr == &ctrlrA); 662 663 /* Detach ctrlrA from namespace 2 again hot + cold */ 664 g_async_event_ctrlr = NULL; 665 g_ns_changed_ctrlr = NULL; 666 g_ns_changed_nsid = 0; 667 rc = spdk_nvmf_ns_remove_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 668 CU_ASSERT(rc == 0); 669 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 670 CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrB.hostnqn) == NULL); 671 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrA.hostnqn) == NULL); 672 CU_ASSERT(nvmf_ns_find_host(&ns2, ctrlrB.hostnqn) == NULL); 673 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 674 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 675 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid)); 676 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid)); 677 /* check last ns_changed */ 678 CU_ASSERT(g_ns_changed_ctrlr == NULL); 679 CU_ASSERT(g_ns_changed_nsid == 0); 680 /* check async_event */ 681 poll_threads(); 682 CU_ASSERT(g_async_event_ctrlr == NULL); 683 684 /* Attach ctrlrA to namespace 4 hot + cold => remove ns */ 685 nsid = 4; 686 g_async_event_ctrlr = NULL; 687 g_ns_changed_ctrlr = NULL; 688 g_ns_changed_nsid = 0; 689 rc = spdk_nvmf_ns_add_host(&subsystem, nsid, ctrlrA.hostnqn, 0); 690 CU_ASSERT(rc == 0); 691 CU_ASSERT(nvmf_ns_find_host(ns3, ctrlrA.hostnqn) != NULL); 692 CU_ASSERT(nvmf_ns_find_host(ns3, ctrlrB.hostnqn) == NULL); 693 CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 694 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 695 /* check last ns_changed */ 696 CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA); 697 CU_ASSERT(g_ns_changed_nsid == nsid); 698 /* check async_event */ 699 poll_threads(); 700 CU_ASSERT(g_async_event_ctrlr == &ctrlrA); 701 702 g_async_event_ctrlr = NULL; 703 g_ns_changed_ctrlr = NULL; 704 g_ns_changed_nsid = 0; 705 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, nsid); 706 CU_ASSERT(rc == 0); 707 CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 708 CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 709 /* check last ns_changed */ 710 CU_ASSERT(g_ns_changed_ctrlr == &ctrlrA); 711 CU_ASSERT(g_ns_changed_nsid == nsid); 712 713 free(ctrlrA.visible_ns); 714 free(ctrlrB.visible_ns); 715 free(subsystem.ana_group); 716 free(subsystem.ns); 717 } 718 719 /* 720 * Reservation Unit Test Configuration 721 * -------- -------- -------- 722 * | Host A | | Host B | | Host C | 723 * -------- -------- -------- 724 * / \ | | 725 * -------- -------- ------- ------- 726 * |Ctrlr1_A| |Ctrlr2_A| |Ctrlr_B| |Ctrlr_C| 727 * -------- -------- ------- ------- 728 * \ \ / / 729 * \ \ / / 730 * \ \ / / 731 * -------------------------------------- 732 * | NAMESPACE 1 | 733 * -------------------------------------- 734 */ 735 static struct spdk_nvmf_subsystem g_subsystem; 736 static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C; 737 static struct spdk_nvmf_ns g_ns; 738 struct spdk_nvmf_subsystem_pg_ns_info g_ns_info; 739 740 void 741 nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr) 742 { 743 } 744 745 static void 746 ut_reservation_init(void) 747 { 748 749 TAILQ_INIT(&g_subsystem.ctrlrs); 750 751 memset(&g_ns, 0, sizeof(g_ns)); 752 TAILQ_INIT(&g_ns.registrants); 753 g_ns.subsystem = &g_subsystem; 754 g_ns.ptpl_file = NULL; 755 g_ns.ptpl_activated = false; 756 spdk_uuid_generate(&g_bdevs[0].uuid); 757 g_ns.bdev = &g_bdevs[0]; 758 759 /* Host A has two controllers */ 760 spdk_uuid_generate(&g_ctrlr1_A.hostid); 761 TAILQ_INIT(&g_ctrlr1_A.log_head); 762 g_ctrlr1_A.subsys = &g_subsystem; 763 g_ctrlr1_A.num_avail_log_pages = 0; 764 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr1_A, link); 765 spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid); 766 TAILQ_INIT(&g_ctrlr2_A.log_head); 767 g_ctrlr2_A.subsys = &g_subsystem; 768 g_ctrlr2_A.num_avail_log_pages = 0; 769 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr2_A, link); 770 771 /* Host B has 1 controller */ 772 spdk_uuid_generate(&g_ctrlr_B.hostid); 773 TAILQ_INIT(&g_ctrlr_B.log_head); 774 g_ctrlr_B.subsys = &g_subsystem; 775 g_ctrlr_B.num_avail_log_pages = 0; 776 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_B, link); 777 778 /* Host C has 1 controller */ 779 spdk_uuid_generate(&g_ctrlr_C.hostid); 780 TAILQ_INIT(&g_ctrlr_C.log_head); 781 g_ctrlr_C.subsys = &g_subsystem; 782 g_ctrlr_C.num_avail_log_pages = 0; 783 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_C, link); 784 } 785 786 static void 787 ut_reservation_deinit(void) 788 { 789 struct spdk_nvmf_registrant *reg, *tmp; 790 struct spdk_nvmf_reservation_log *log, *log_tmp; 791 struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp; 792 793 TAILQ_FOREACH_SAFE(reg, &g_ns.registrants, link, tmp) { 794 TAILQ_REMOVE(&g_ns.registrants, reg, link); 795 free(reg); 796 } 797 TAILQ_FOREACH_SAFE(log, &g_ctrlr1_A.log_head, link, log_tmp) { 798 TAILQ_REMOVE(&g_ctrlr1_A.log_head, log, link); 799 free(log); 800 } 801 g_ctrlr1_A.num_avail_log_pages = 0; 802 TAILQ_FOREACH_SAFE(log, &g_ctrlr2_A.log_head, link, log_tmp) { 803 TAILQ_REMOVE(&g_ctrlr2_A.log_head, log, link); 804 free(log); 805 } 806 g_ctrlr2_A.num_avail_log_pages = 0; 807 TAILQ_FOREACH_SAFE(log, &g_ctrlr_B.log_head, link, log_tmp) { 808 TAILQ_REMOVE(&g_ctrlr_B.log_head, log, link); 809 free(log); 810 } 811 g_ctrlr_B.num_avail_log_pages = 0; 812 TAILQ_FOREACH_SAFE(log, &g_ctrlr_C.log_head, link, log_tmp) { 813 TAILQ_REMOVE(&g_ctrlr_C.log_head, log, link); 814 free(log); 815 } 816 g_ctrlr_C.num_avail_log_pages = 0; 817 818 TAILQ_FOREACH_SAFE(ctrlr, &g_subsystem.ctrlrs, link, ctrlr_tmp) { 819 TAILQ_REMOVE(&g_subsystem.ctrlrs, ctrlr, link); 820 } 821 } 822 823 static struct spdk_nvmf_request * 824 ut_reservation_build_req(uint32_t length) 825 { 826 struct spdk_nvmf_request *req; 827 828 req = calloc(1, sizeof(*req)); 829 assert(req != NULL); 830 831 SPDK_IOV_ONE(req->iov, &req->iovcnt, calloc(1, length), length); 832 assert(req->iov[0].iov_base != NULL); 833 req->length = length; 834 835 req->cmd = (union nvmf_h2c_msg *)calloc(1, sizeof(union nvmf_h2c_msg)); 836 assert(req->cmd != NULL); 837 838 req->rsp = (union nvmf_c2h_msg *)calloc(1, sizeof(union nvmf_c2h_msg)); 839 assert(req->rsp != NULL); 840 841 return req; 842 } 843 844 static void 845 ut_reservation_free_req(struct spdk_nvmf_request *req) 846 { 847 free(req->cmd); 848 free(req->rsp); 849 free(req->iov[0].iov_base); 850 free(req); 851 } 852 853 static void 854 ut_reservation_build_register_request(struct spdk_nvmf_request *req, 855 uint8_t rrega, uint8_t iekey, 856 uint8_t cptpl, uint64_t crkey, 857 uint64_t nrkey) 858 { 859 struct spdk_nvme_reservation_register_data key; 860 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 861 862 key.crkey = crkey; 863 key.nrkey = nrkey; 864 cmd->cdw10 = 0; 865 cmd->cdw10_bits.resv_register.rrega = rrega; 866 cmd->cdw10_bits.resv_register.iekey = iekey; 867 cmd->cdw10_bits.resv_register.cptpl = cptpl; 868 memcpy(req->iov[0].iov_base, &key, sizeof(key)); 869 } 870 871 static void 872 ut_reservation_build_acquire_request(struct spdk_nvmf_request *req, 873 uint8_t racqa, uint8_t iekey, 874 uint8_t rtype, uint64_t crkey, 875 uint64_t prkey) 876 { 877 struct spdk_nvme_reservation_acquire_data key; 878 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 879 880 key.crkey = crkey; 881 key.prkey = prkey; 882 cmd->cdw10 = 0; 883 cmd->cdw10_bits.resv_acquire.racqa = racqa; 884 cmd->cdw10_bits.resv_acquire.iekey = iekey; 885 cmd->cdw10_bits.resv_acquire.rtype = rtype; 886 memcpy(req->iov[0].iov_base, &key, sizeof(key)); 887 } 888 889 static void 890 ut_reservation_build_release_request(struct spdk_nvmf_request *req, 891 uint8_t rrela, uint8_t iekey, 892 uint8_t rtype, uint64_t crkey) 893 { 894 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 895 896 cmd->cdw10 = 0; 897 cmd->cdw10_bits.resv_release.rrela = rrela; 898 cmd->cdw10_bits.resv_release.iekey = iekey; 899 cmd->cdw10_bits.resv_release.rtype = rtype; 900 memcpy(req->iov[0].iov_base, &crkey, sizeof(crkey)); 901 } 902 903 /* 904 * Construct four registrants for other test cases. 905 * 906 * g_ctrlr1_A register with key 0xa1. 907 * g_ctrlr2_A register with key 0xa1. 908 * g_ctrlr_B register with key 0xb1. 909 * g_ctrlr_C register with key 0xc1. 910 * */ 911 static void 912 ut_reservation_build_registrants(void) 913 { 914 struct spdk_nvmf_request *req; 915 struct spdk_nvme_cpl *rsp; 916 struct spdk_nvmf_registrant *reg; 917 uint32_t gen; 918 919 req = ut_reservation_build_req(16); 920 rsp = &req->rsp->nvme_cpl; 921 SPDK_CU_ASSERT_FATAL(req != NULL); 922 gen = g_ns.gen; 923 924 /* TEST CASE: g_ctrlr1_A register with a new key */ 925 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 926 0, 0, 0, 0xa1); 927 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 928 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 929 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 930 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1); 931 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 1); 932 933 /* TEST CASE: g_ctrlr2_A register with a new key, because it has same 934 * Host Identifier with g_ctrlr1_A, so the register key should same. 935 */ 936 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 937 0, 0, 0, 0xa2); 938 nvmf_ns_reservation_register(&g_ns, &g_ctrlr2_A, req); 939 /* Reservation conflict for other key than 0xa1 */ 940 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 941 942 /* g_ctrlr_B register with a new key */ 943 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 944 0, 0, 0, 0xb1); 945 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 946 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 947 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 948 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb1); 949 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 2); 950 951 /* g_ctrlr_C register with a new key */ 952 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 953 0, 0, 0, 0xc1); 954 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 955 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 956 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 957 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc1); 958 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 3); 959 960 ut_reservation_free_req(req); 961 } 962 963 static void 964 test_reservation_register(void) 965 { 966 struct spdk_nvmf_request *req; 967 struct spdk_nvme_cpl *rsp; 968 struct spdk_nvmf_registrant *reg; 969 uint32_t gen; 970 971 ut_reservation_init(); 972 973 req = ut_reservation_build_req(16); 974 rsp = &req->rsp->nvme_cpl; 975 SPDK_CU_ASSERT_FATAL(req != NULL); 976 977 ut_reservation_build_registrants(); 978 979 /* TEST CASE: Replace g_ctrlr1_A with a new key */ 980 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 981 0, 0, 0xa1, 0xa11); 982 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 983 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 984 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 985 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa11); 986 987 /* TEST CASE: Host A with g_ctrlr1_A get reservation with 988 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 989 */ 990 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 991 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xa11, 0x0); 992 gen = g_ns.gen; 993 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 994 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 995 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 996 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 997 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa11); 998 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 999 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 1000 1001 /* TEST CASE: g_ctrlr_C unregister with IEKEY enabled */ 1002 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1003 1, 0, 0, 0); 1004 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 1005 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1006 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1007 SPDK_CU_ASSERT_FATAL(reg == NULL); 1008 1009 /* TEST CASE: g_ctrlr_B unregister with correct key */ 1010 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1011 0, 0, 0xb1, 0); 1012 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1013 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1014 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1015 SPDK_CU_ASSERT_FATAL(reg == NULL); 1016 1017 /* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY disabled */ 1018 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 1019 0, 0, 0, 0xb1); 1020 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1021 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 1022 1023 /* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY enabled */ 1024 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 1025 1, 0, 0, 0xb1); 1026 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1027 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1028 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1029 SPDK_CU_ASSERT_FATAL(reg != NULL); 1030 1031 /* TEST CASE: g_ctrlr_B replace new key with IEKEY enabled and wrong crkey */ 1032 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 1033 1, 0, 0xff, 0xb2); 1034 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1035 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1036 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1037 SPDK_CU_ASSERT_FATAL(reg != NULL); 1038 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb2); 1039 1040 /* TEST CASE: g_ctrlr1_A unregister with correct key, 1041 * reservation should be removed as well. 1042 */ 1043 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1044 0, 0, 0xa11, 0); 1045 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 1046 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1047 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1048 SPDK_CU_ASSERT_FATAL(reg == NULL); 1049 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1050 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 1051 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 1052 1053 ut_reservation_free_req(req); 1054 ut_reservation_deinit(); 1055 } 1056 1057 static void 1058 test_reservation_register_with_ptpl(void) 1059 { 1060 struct spdk_nvmf_request *req; 1061 struct spdk_nvme_cpl *rsp; 1062 struct spdk_nvmf_registrant *reg; 1063 bool update_sgroup = false; 1064 int rc; 1065 struct spdk_nvmf_reservation_info info; 1066 1067 ut_reservation_init(); 1068 1069 req = ut_reservation_build_req(16); 1070 rsp = &req->rsp->nvme_cpl; 1071 SPDK_CU_ASSERT_FATAL(req != NULL); 1072 1073 /* TEST CASE: No persistent file, register with PTPL enabled will fail */ 1074 g_ns.ptpl_file = NULL; 1075 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 1076 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 1077 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 1078 SPDK_CU_ASSERT_FATAL(update_sgroup == false); 1079 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 1080 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1081 SPDK_CU_ASSERT_FATAL(reg == NULL); 1082 1083 /* TEST CASE: Enable PTPL */ 1084 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 1085 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 1086 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 1087 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 1088 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1089 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1090 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 1091 rc = nvmf_ns_update_reservation_info(&g_ns); 1092 SPDK_CU_ASSERT_FATAL(rc == 0); 1093 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1094 SPDK_CU_ASSERT_FATAL(reg != NULL); 1095 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 1096 /* Load reservation information from configuration file */ 1097 memset(&info, 0, sizeof(info)); 1098 rc = nvmf_ns_reservation_load(&g_ns, &info); 1099 SPDK_CU_ASSERT_FATAL(rc == 0); 1100 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 1101 1102 /* TEST CASE: Disable PTPL */ 1103 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 1104 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 1105 SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON, 0, 0xa1); 1106 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 1107 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1108 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1109 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == false); 1110 rc = nvmf_ns_update_reservation_info(&g_ns); 1111 SPDK_CU_ASSERT_FATAL(rc == 0); 1112 rc = nvmf_ns_reservation_load(&g_ns, &info); 1113 SPDK_CU_ASSERT_FATAL(rc < 0); 1114 unlink(g_ns.ptpl_file); 1115 1116 ut_reservation_free_req(req); 1117 ut_reservation_deinit(); 1118 } 1119 1120 static void 1121 test_reservation_acquire_preempt_1(void) 1122 { 1123 struct spdk_nvmf_request *req; 1124 struct spdk_nvme_cpl *rsp; 1125 struct spdk_nvmf_registrant *reg; 1126 uint32_t gen; 1127 1128 ut_reservation_init(); 1129 1130 req = ut_reservation_build_req(16); 1131 rsp = &req->rsp->nvme_cpl; 1132 SPDK_CU_ASSERT_FATAL(req != NULL); 1133 1134 ut_reservation_build_registrants(); 1135 1136 gen = g_ns.gen; 1137 /* ACQUIRE: Host A with g_ctrlr1_A acquire reservation with 1138 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE. 1139 */ 1140 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1141 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 1142 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 1143 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1144 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1145 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1146 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa1); 1147 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1148 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 1149 1150 /* TEST CASE: g_ctrlr1_A holds the reservation, g_ctrlr_B preempt g_ctrl1_A, 1151 * g_ctrl1_A registrant is unregistered. 1152 */ 1153 gen = g_ns.gen; 1154 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 1155 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1, 0xa1); 1156 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1157 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1158 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1159 SPDK_CU_ASSERT_FATAL(reg == NULL); 1160 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1161 SPDK_CU_ASSERT_FATAL(reg != NULL); 1162 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1163 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1164 SPDK_CU_ASSERT_FATAL(reg != NULL); 1165 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1166 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 1167 1168 /* TEST CASE: g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B 1169 * with valid key and PRKEY set to 0, all registrants other the host that issued 1170 * the command are unregistered. 1171 */ 1172 gen = g_ns.gen; 1173 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 1174 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0x0); 1175 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 1176 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1177 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 1178 SPDK_CU_ASSERT_FATAL(reg == NULL); 1179 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1180 SPDK_CU_ASSERT_FATAL(reg == NULL); 1181 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1182 SPDK_CU_ASSERT_FATAL(reg != NULL); 1183 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1184 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1185 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 1186 1187 ut_reservation_free_req(req); 1188 ut_reservation_deinit(); 1189 } 1190 1191 static void 1192 test_reservation_acquire_release_with_ptpl(void) 1193 { 1194 struct spdk_nvmf_request *req; 1195 struct spdk_nvme_cpl *rsp; 1196 struct spdk_nvmf_registrant *reg; 1197 bool update_sgroup = false; 1198 struct spdk_uuid holder_uuid; 1199 int rc; 1200 struct spdk_nvmf_reservation_info info; 1201 1202 ut_reservation_init(); 1203 1204 req = ut_reservation_build_req(16); 1205 rsp = &req->rsp->nvme_cpl; 1206 SPDK_CU_ASSERT_FATAL(req != NULL); 1207 1208 /* TEST CASE: Enable PTPL */ 1209 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 1210 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 1211 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 1212 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 1213 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1214 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1215 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 1216 rc = nvmf_ns_update_reservation_info(&g_ns); 1217 SPDK_CU_ASSERT_FATAL(rc == 0); 1218 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1219 SPDK_CU_ASSERT_FATAL(reg != NULL); 1220 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 1221 /* Load reservation information from configuration file */ 1222 memset(&info, 0, sizeof(info)); 1223 rc = nvmf_ns_reservation_load(&g_ns, &info); 1224 SPDK_CU_ASSERT_FATAL(rc == 0); 1225 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 1226 1227 /* TEST CASE: Acquire the reservation */ 1228 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 1229 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1230 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 1231 update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 1232 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1233 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1234 rc = nvmf_ns_update_reservation_info(&g_ns); 1235 SPDK_CU_ASSERT_FATAL(rc == 0); 1236 memset(&info, 0, sizeof(info)); 1237 rc = nvmf_ns_reservation_load(&g_ns, &info); 1238 SPDK_CU_ASSERT_FATAL(rc == 0); 1239 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 1240 SPDK_CU_ASSERT_FATAL(info.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1241 SPDK_CU_ASSERT_FATAL(info.crkey == 0xa1); 1242 spdk_uuid_parse(&holder_uuid, info.holder_uuid); 1243 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &holder_uuid)); 1244 1245 /* TEST CASE: Release the reservation */ 1246 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 1247 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1248 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1); 1249 update_sgroup = nvmf_ns_reservation_release(&g_ns, &g_ctrlr1_A, req); 1250 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1251 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1252 rc = nvmf_ns_update_reservation_info(&g_ns); 1253 SPDK_CU_ASSERT_FATAL(rc == 0); 1254 memset(&info, 0, sizeof(info)); 1255 rc = nvmf_ns_reservation_load(&g_ns, &info); 1256 SPDK_CU_ASSERT_FATAL(rc == 0); 1257 SPDK_CU_ASSERT_FATAL(info.rtype == 0); 1258 SPDK_CU_ASSERT_FATAL(info.crkey == 0); 1259 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 1260 unlink(g_ns.ptpl_file); 1261 1262 ut_reservation_free_req(req); 1263 ut_reservation_deinit(); 1264 } 1265 1266 static void 1267 test_reservation_release(void) 1268 { 1269 struct spdk_nvmf_request *req; 1270 struct spdk_nvme_cpl *rsp; 1271 struct spdk_nvmf_registrant *reg; 1272 1273 ut_reservation_init(); 1274 1275 req = ut_reservation_build_req(16); 1276 rsp = &req->rsp->nvme_cpl; 1277 SPDK_CU_ASSERT_FATAL(req != NULL); 1278 1279 ut_reservation_build_registrants(); 1280 1281 /* ACQUIRE: Host A with g_ctrlr1_A get reservation with 1282 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS 1283 */ 1284 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1285 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xa1, 0x0); 1286 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 1287 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1288 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1289 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1290 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1291 1292 /* Test Case: Host B release the reservation */ 1293 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1294 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1); 1295 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1296 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1297 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1298 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 1299 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 1300 1301 /* Test Case: Host C clear the registrants */ 1302 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1303 0, 0xc1); 1304 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_C, req); 1305 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1306 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1307 SPDK_CU_ASSERT_FATAL(reg == NULL); 1308 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 1309 SPDK_CU_ASSERT_FATAL(reg == NULL); 1310 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1311 SPDK_CU_ASSERT_FATAL(reg == NULL); 1312 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1313 SPDK_CU_ASSERT_FATAL(reg == NULL); 1314 1315 ut_reservation_free_req(req); 1316 ut_reservation_deinit(); 1317 } 1318 1319 void 1320 nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr, 1321 struct spdk_nvmf_ns *ns, 1322 enum spdk_nvme_reservation_notification_log_page_type type) 1323 { 1324 ctrlr->num_avail_log_pages++; 1325 } 1326 1327 static void 1328 test_reservation_unregister_notification(void) 1329 { 1330 struct spdk_nvmf_request *req; 1331 struct spdk_nvme_cpl *rsp; 1332 1333 ut_reservation_init(); 1334 1335 req = ut_reservation_build_req(16); 1336 SPDK_CU_ASSERT_FATAL(req != NULL); 1337 rsp = &req->rsp->nvme_cpl; 1338 1339 ut_reservation_build_registrants(); 1340 1341 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1342 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1343 */ 1344 rsp->status.sc = 0xff; 1345 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1346 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1347 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1348 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1349 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1350 1351 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B unregister the registration. 1352 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C only for 1353 * SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY or SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY 1354 * type. 1355 */ 1356 rsp->status.sc = 0xff; 1357 g_ctrlr1_A.num_avail_log_pages = 0; 1358 g_ctrlr2_A.num_avail_log_pages = 0; 1359 g_ctrlr_B.num_avail_log_pages = 5; 1360 g_ctrlr_C.num_avail_log_pages = 0; 1361 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1362 0, 0, 0xb1, 0); 1363 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1364 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1365 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1366 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1367 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1368 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1369 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1370 1371 ut_reservation_free_req(req); 1372 ut_reservation_deinit(); 1373 } 1374 1375 static void 1376 test_reservation_release_notification(void) 1377 { 1378 struct spdk_nvmf_request *req; 1379 struct spdk_nvme_cpl *rsp; 1380 1381 ut_reservation_init(); 1382 1383 req = ut_reservation_build_req(16); 1384 SPDK_CU_ASSERT_FATAL(req != NULL); 1385 rsp = &req->rsp->nvme_cpl; 1386 1387 ut_reservation_build_registrants(); 1388 1389 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1390 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1391 */ 1392 rsp->status.sc = 0xff; 1393 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1394 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1395 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1396 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1397 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1398 1399 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1400 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1401 */ 1402 rsp->status.sc = 0xff; 1403 g_ctrlr1_A.num_avail_log_pages = 0; 1404 g_ctrlr2_A.num_avail_log_pages = 0; 1405 g_ctrlr_B.num_avail_log_pages = 5; 1406 g_ctrlr_C.num_avail_log_pages = 0; 1407 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1408 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1); 1409 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1410 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1411 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1412 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1413 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1414 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1415 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1416 1417 ut_reservation_free_req(req); 1418 ut_reservation_deinit(); 1419 } 1420 1421 static void 1422 test_reservation_release_notification_write_exclusive(void) 1423 { 1424 struct spdk_nvmf_request *req; 1425 struct spdk_nvme_cpl *rsp; 1426 1427 ut_reservation_init(); 1428 1429 req = ut_reservation_build_req(16); 1430 SPDK_CU_ASSERT_FATAL(req != NULL); 1431 rsp = &req->rsp->nvme_cpl; 1432 1433 ut_reservation_build_registrants(); 1434 1435 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1436 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 1437 */ 1438 rsp->status.sc = 0xff; 1439 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1440 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1, 0x0); 1441 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1442 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1443 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1444 1445 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1446 * Because the reservation type is SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 1447 * no reservation notification occurs. 1448 */ 1449 rsp->status.sc = 0xff; 1450 g_ctrlr1_A.num_avail_log_pages = 5; 1451 g_ctrlr2_A.num_avail_log_pages = 5; 1452 g_ctrlr_B.num_avail_log_pages = 5; 1453 g_ctrlr_C.num_avail_log_pages = 5; 1454 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1455 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1); 1456 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1457 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1458 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1459 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr1_A.num_avail_log_pages); 1460 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr2_A.num_avail_log_pages); 1461 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1462 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1463 1464 ut_reservation_free_req(req); 1465 ut_reservation_deinit(); 1466 } 1467 1468 static void 1469 test_reservation_clear_notification(void) 1470 { 1471 struct spdk_nvmf_request *req; 1472 struct spdk_nvme_cpl *rsp; 1473 1474 ut_reservation_init(); 1475 1476 req = ut_reservation_build_req(16); 1477 SPDK_CU_ASSERT_FATAL(req != NULL); 1478 rsp = &req->rsp->nvme_cpl; 1479 1480 ut_reservation_build_registrants(); 1481 1482 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1483 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1484 */ 1485 rsp->status.sc = 0xff; 1486 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1487 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1488 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1489 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1490 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1491 1492 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B clear the reservation. 1493 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1494 */ 1495 rsp->status.sc = 0xff; 1496 g_ctrlr1_A.num_avail_log_pages = 0; 1497 g_ctrlr2_A.num_avail_log_pages = 0; 1498 g_ctrlr_B.num_avail_log_pages = 5; 1499 g_ctrlr_C.num_avail_log_pages = 0; 1500 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1501 0, 0xb1); 1502 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1503 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1504 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1505 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1506 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1507 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1508 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1509 1510 ut_reservation_free_req(req); 1511 ut_reservation_deinit(); 1512 } 1513 1514 static void 1515 test_reservation_preempt_notification(void) 1516 { 1517 struct spdk_nvmf_request *req; 1518 struct spdk_nvme_cpl *rsp; 1519 1520 ut_reservation_init(); 1521 1522 req = ut_reservation_build_req(16); 1523 SPDK_CU_ASSERT_FATAL(req != NULL); 1524 rsp = &req->rsp->nvme_cpl; 1525 1526 ut_reservation_build_registrants(); 1527 1528 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1529 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1530 */ 1531 rsp->status.sc = 0xff; 1532 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1533 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1534 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1535 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1536 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1537 1538 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B, 1539 * g_ctrlr_B registrant is unregistered, and reservation is preempted. 1540 * Registration Preempted notification sends to g_ctrlr_B. 1541 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A. 1542 */ 1543 rsp->status.sc = 0xff; 1544 g_ctrlr1_A.num_avail_log_pages = 0; 1545 g_ctrlr2_A.num_avail_log_pages = 0; 1546 g_ctrlr_B.num_avail_log_pages = 0; 1547 g_ctrlr_C.num_avail_log_pages = 5; 1548 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 1549 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0xb1); 1550 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 1551 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1552 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1553 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1554 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1555 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_B.num_avail_log_pages); 1556 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1557 1558 ut_reservation_free_req(req); 1559 ut_reservation_deinit(); 1560 } 1561 1562 static int 1563 nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf) 1564 { 1565 return 0; 1566 } 1567 1568 static void 1569 nvmf_tgt_destroy_poll_group(void *io_device, void *ctx_buf) 1570 { 1571 } 1572 1573 static void 1574 test_spdk_nvmf_ns_event(void) 1575 { 1576 struct spdk_nvmf_tgt tgt = {}; 1577 struct spdk_nvmf_subsystem subsystem = { 1578 .max_nsid = 1024, 1579 .ns = NULL, 1580 .tgt = &tgt, 1581 .state_changes = TAILQ_HEAD_INITIALIZER(subsystem.state_changes), 1582 }; 1583 struct spdk_nvmf_ctrlr ctrlr = { 1584 .subsys = &subsystem 1585 }; 1586 struct spdk_nvmf_ns_opts ns_opts; 1587 uint32_t nsid; 1588 struct spdk_bdev *bdev; 1589 struct spdk_thread *thread; 1590 1591 ctrlr.visible_ns = spdk_bit_array_create(1); 1592 spdk_bit_array_set(ctrlr.visible_ns, 0); 1593 1594 thread = spdk_get_thread(); 1595 SPDK_CU_ASSERT_FATAL(thread != NULL); 1596 1597 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 1598 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 1599 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 1600 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 1601 1602 tgt.max_subsystems = 1024; 1603 tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems); 1604 RB_INIT(&tgt.subsystems); 1605 1606 spdk_io_device_register(&tgt, 1607 nvmf_tgt_create_poll_group, 1608 nvmf_tgt_destroy_poll_group, 1609 sizeof(struct spdk_nvmf_poll_group), 1610 NULL); 1611 1612 /* Add one namespace */ 1613 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 1614 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL); 1615 CU_ASSERT(nsid == 1); 1616 CU_ASSERT(NULL != subsystem.ns[0]); 1617 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]); 1618 1619 bdev = subsystem.ns[nsid - 1]->bdev; 1620 1621 /* Add one controller */ 1622 TAILQ_INIT(&subsystem.ctrlrs); 1623 TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlr, link); 1624 1625 /* Namespace resize event */ 1626 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1627 g_ns_changed_nsid = 0xFFFFFFFF; 1628 g_ns_changed_ctrlr = NULL; 1629 nvmf_ns_event(SPDK_BDEV_EVENT_RESIZE, bdev, subsystem.ns[0]); 1630 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1631 1632 poll_threads(); 1633 CU_ASSERT(1 == g_ns_changed_nsid); 1634 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1635 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1636 1637 /* Namespace remove event */ 1638 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1639 g_ns_changed_nsid = 0xFFFFFFFF; 1640 g_ns_changed_ctrlr = NULL; 1641 nvmf_ns_event(SPDK_BDEV_EVENT_REMOVE, bdev, subsystem.ns[0]); 1642 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1643 CU_ASSERT(0xFFFFFFFF == g_ns_changed_nsid); 1644 CU_ASSERT(NULL == g_ns_changed_ctrlr); 1645 1646 poll_threads(); 1647 CU_ASSERT(1 == g_ns_changed_nsid); 1648 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1649 CU_ASSERT(NULL == subsystem.ns[0]); 1650 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1651 1652 spdk_io_device_unregister(&tgt, NULL); 1653 1654 poll_threads(); 1655 1656 free(subsystem.ns); 1657 free(subsystem.ana_group); 1658 spdk_bit_array_free(&ctrlr.visible_ns); 1659 spdk_bit_array_free(&tgt.subsystem_ids); 1660 } 1661 1662 static void 1663 test_nvmf_ns_reservation_add_remove_registrant(void) 1664 { 1665 struct spdk_nvmf_ns ns = {}; 1666 struct spdk_nvmf_ctrlr ctrlr = {}; 1667 struct spdk_nvmf_registrant *reg = NULL; 1668 int rc; 1669 1670 TAILQ_INIT(&ns.registrants); 1671 spdk_uuid_generate(&ctrlr.hostid); 1672 1673 rc = nvmf_ns_reservation_add_registrant(&ns, &ctrlr, 0xa11); 1674 CU_ASSERT(rc == 0); 1675 reg = TAILQ_FIRST(&ns.registrants); 1676 SPDK_CU_ASSERT_FATAL(reg != NULL); 1677 CU_ASSERT(ns.gen == 1); 1678 CU_ASSERT(reg->rkey == 0xa11); 1679 CU_ASSERT(!strncmp((uint8_t *)®->hostid, (uint8_t *)&ctrlr.hostid, sizeof(ctrlr.hostid))); 1680 1681 nvmf_ns_reservation_remove_registrant(&ns, reg); 1682 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 1683 CU_ASSERT(ns.gen == 2); 1684 } 1685 1686 static void 1687 test_nvmf_subsystem_destroy_cb(void *cb_arg) 1688 { 1689 } 1690 1691 static void 1692 test_nvmf_subsystem_add_ctrlr(void) 1693 { 1694 int rc; 1695 struct spdk_nvmf_ctrlr ctrlr = {}; 1696 struct spdk_nvmf_tgt tgt = {}; 1697 char nqn[256] = "nqn.2016-06.io.spdk:subsystem1"; 1698 struct spdk_nvmf_subsystem *subsystem = NULL; 1699 1700 tgt.max_subsystems = 1024; 1701 tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems); 1702 RB_INIT(&tgt.subsystems); 1703 1704 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 1705 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1706 ctrlr.subsys = subsystem; 1707 1708 ctrlr.dynamic_ctrlr = true; 1709 rc = nvmf_subsystem_add_ctrlr(subsystem, &ctrlr); 1710 CU_ASSERT(rc == 0); 1711 CU_ASSERT(!TAILQ_EMPTY(&subsystem->ctrlrs)); 1712 CU_ASSERT(ctrlr.cntlid == 1); 1713 CU_ASSERT(nvmf_subsystem_get_ctrlr(subsystem, 1) == &ctrlr); 1714 1715 nvmf_subsystem_remove_ctrlr(subsystem, &ctrlr); 1716 CU_ASSERT(TAILQ_EMPTY(&subsystem->ctrlrs)); 1717 rc = spdk_nvmf_subsystem_destroy(subsystem, test_nvmf_subsystem_destroy_cb, NULL); 1718 CU_ASSERT(rc == 0); 1719 spdk_bit_array_free(&tgt.subsystem_ids); 1720 } 1721 1722 static void 1723 _add_transport_cb(void *arg, int status) 1724 { 1725 CU_ASSERT(status == 0); 1726 } 1727 1728 static int 1729 transport_subsystem_add_host_err(struct spdk_nvmf_transport *transport, 1730 const struct spdk_nvmf_subsystem *subsystem, 1731 const char *hostnqn, 1732 const struct spdk_json_val *transport_specific) 1733 { 1734 return -1; 1735 } 1736 1737 void 1738 spdk_nvmf_tgt_add_transport(struct spdk_nvmf_tgt *tgt, 1739 struct spdk_nvmf_transport *transport, 1740 spdk_nvmf_tgt_add_transport_done_fn cb_fn, 1741 void *cb_arg) 1742 { 1743 TAILQ_INSERT_TAIL(&tgt->transports, transport, link); 1744 } 1745 1746 static struct spdk_nvmf_transport * 1747 transport_create(struct spdk_nvmf_transport_opts *opts) 1748 { 1749 return &g_transport; 1750 } 1751 1752 static void 1753 test_spdk_nvmf_subsystem_add_host(void) 1754 { 1755 struct spdk_nvmf_tgt tgt = {}; 1756 struct spdk_nvmf_subsystem *subsystem = NULL; 1757 int rc; 1758 const char hostnqn[] = "nqn.2016-06.io.spdk:host1"; 1759 const char subsystemnqn[] = "nqn.2016-06.io.spdk:subsystem1"; 1760 struct spdk_nvmf_transport_opts opts = { 1761 .opts_size = sizeof(struct spdk_nvmf_transport_opts), 1762 .io_unit_size = 8192 1763 }; 1764 const struct spdk_nvmf_transport_ops test_ops = { 1765 .name = "transport_ut", 1766 .create = transport_create, 1767 .subsystem_add_host = transport_subsystem_add_host_err, 1768 }; 1769 struct spdk_nvmf_transport *transport; 1770 1771 tgt.max_subsystems = 1024; 1772 tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems); 1773 RB_INIT(&tgt.subsystems); 1774 1775 subsystem = spdk_nvmf_subsystem_create(&tgt, subsystemnqn, SPDK_NVMF_SUBTYPE_NVME, 0); 1776 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1777 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, subsystemnqn); 1778 1779 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL); 1780 CU_ASSERT(rc == 0); 1781 CU_ASSERT(!TAILQ_EMPTY(&subsystem->hosts)); 1782 1783 /* Add existing nqn, this function is allowed to be called if the nqn was previously added. */ 1784 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL); 1785 CU_ASSERT(rc == 0); 1786 1787 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 1788 CU_ASSERT(rc == 0); 1789 CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts)); 1790 1791 /* No available nqn */ 1792 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 1793 CU_ASSERT(rc == -ENOENT); 1794 1795 /* Ensure hostnqn list remains empty after transport callback fails */ 1796 spdk_nvmf_transport_register(&test_ops); 1797 transport = spdk_nvmf_transport_create("transport_ut", &opts); 1798 SPDK_CU_ASSERT_FATAL(transport != NULL); 1799 1800 TAILQ_INIT(&tgt.transports); 1801 spdk_nvmf_tgt_add_transport(&tgt, transport, _add_transport_cb, 0); 1802 1803 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL); 1804 CU_ASSERT(rc != 0); 1805 CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts)); 1806 1807 spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 1808 spdk_bit_array_free(&tgt.subsystem_ids); 1809 } 1810 1811 static void 1812 test_nvmf_ns_reservation_report(void) 1813 { 1814 struct spdk_nvmf_ns ns = {}; 1815 struct spdk_nvmf_ctrlr ctrlr = {}; 1816 struct spdk_nvmf_request req = {}; 1817 union nvmf_h2c_msg cmd = {}; 1818 union nvmf_c2h_msg rsp = {}; 1819 struct spdk_nvme_registered_ctrlr_extended_data *ctrlr_data; 1820 struct spdk_nvme_reservation_status_extended_data *status_data; 1821 struct spdk_nvmf_registrant *reg; 1822 void *data; 1823 1824 data = calloc(1, sizeof(*status_data) + sizeof(*ctrlr_data) * 2); 1825 reg = calloc(2, sizeof(struct spdk_nvmf_registrant)); 1826 SPDK_CU_ASSERT_FATAL(data != NULL && reg != NULL); 1827 1828 req.length = sizeof(*status_data) + sizeof(*ctrlr_data) * 2; 1829 SPDK_IOV_ONE(req.iov, &req.iovcnt, data, req.length); 1830 1831 req.cmd = &cmd; 1832 req.rsp = &rsp; 1833 ns.gen = 1; 1834 ns.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE; 1835 ns.ptpl_activated = true; 1836 cmd.nvme_cmd.cdw11_bits.resv_report.eds = true; 1837 cmd.nvme_cmd.cdw10 = 100; 1838 reg[0].rkey = 0xa; 1839 reg[1].rkey = 0xb; 1840 spdk_uuid_generate(®[0].hostid); 1841 spdk_uuid_generate(®[1].hostid); 1842 TAILQ_INIT(&ns.registrants); 1843 TAILQ_INSERT_TAIL(&ns.registrants, ®[0], link); 1844 TAILQ_INSERT_TAIL(&ns.registrants, ®[1], link); 1845 1846 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1847 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1848 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 1849 /* Get ctrlr data and status data pointers */ 1850 ctrlr_data = (void *)((char *)req.iov[0].iov_base + sizeof(*status_data)); 1851 status_data = (void *)req.iov[0].iov_base; 1852 SPDK_CU_ASSERT_FATAL(status_data != NULL && ctrlr_data != NULL); 1853 CU_ASSERT(status_data->data.gen == 1); 1854 CU_ASSERT(status_data->data.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1855 CU_ASSERT(status_data->data.ptpls == true); 1856 CU_ASSERT(status_data->data.regctl == 2); 1857 CU_ASSERT(ctrlr_data->cntlid == 0xffff); 1858 CU_ASSERT(ctrlr_data->rcsts.status == false); 1859 CU_ASSERT(ctrlr_data->rkey == 0xa); 1860 CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, ®[0].hostid)); 1861 /* Check second ctrlr data */ 1862 ctrlr_data++; 1863 CU_ASSERT(ctrlr_data->cntlid == 0xffff); 1864 CU_ASSERT(ctrlr_data->rcsts.status == false); 1865 CU_ASSERT(ctrlr_data->rkey == 0xb); 1866 CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, ®[1].hostid)); 1867 1868 /* extended controller data structure */ 1869 spdk_iov_memset(req.iov, req.iovcnt, 0); 1870 memset(req.rsp, 0, sizeof(*req.rsp)); 1871 cmd.nvme_cmd.cdw11_bits.resv_report.eds = false; 1872 1873 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1874 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT); 1875 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1876 1877 /* Transfer length invalid */ 1878 spdk_iov_memset(req.iov, req.iovcnt, 0); 1879 memset(req.rsp, 0, sizeof(*req.rsp)); 1880 cmd.nvme_cmd.cdw11_bits.resv_report.eds = true; 1881 cmd.nvme_cmd.cdw10 = 0; 1882 1883 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1884 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR); 1885 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1886 1887 free(req.iov[0].iov_base); 1888 free(reg); 1889 } 1890 1891 static void 1892 test_nvmf_nqn_is_valid(void) 1893 { 1894 bool rc; 1895 char uuid[SPDK_NVMF_UUID_STRING_LEN + 1] = {}; 1896 char nqn[SPDK_NVMF_NQN_MAX_LEN + 1] = {}; 1897 struct spdk_uuid s_uuid = {}; 1898 1899 spdk_uuid_generate(&s_uuid); 1900 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid); 1901 1902 /* discovery nqn */ 1903 snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_DISCOVERY_NQN); 1904 1905 rc = nvmf_nqn_is_valid(nqn); 1906 CU_ASSERT(rc == true); 1907 1908 /* nqn with uuid */ 1909 memset(nqn, 0xff, sizeof(nqn)); 1910 snprintf(nqn, sizeof(nqn), "%s%s", SPDK_NVMF_NQN_UUID_PRE, uuid); 1911 1912 rc = nvmf_nqn_is_valid(nqn); 1913 CU_ASSERT(rc == true); 1914 1915 /* Check nqn valid reverse domain */ 1916 memset(nqn, 0xff, sizeof(nqn)); 1917 snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io.spdk:cnode1"); 1918 1919 rc = nvmf_nqn_is_valid(nqn); 1920 CU_ASSERT(rc == true); 1921 1922 /* Invalid nqn length */ 1923 memset(nqn, 0xff, sizeof(nqn)); 1924 snprintf(nqn, sizeof(nqn), "%s", "nqn."); 1925 1926 rc = nvmf_nqn_is_valid(nqn); 1927 CU_ASSERT(rc == false); 1928 1929 /* Copy uuid to the nqn string, but omit the last character to make it invalid */ 1930 memset(nqn, 0, SPDK_NVMF_NQN_MAX_LEN + 1); 1931 snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_NQN_UUID_PRE); 1932 memcpy(&nqn[SPDK_NVMF_NQN_UUID_PRE_LEN], uuid, SPDK_NVMF_UUID_STRING_LEN - 1); 1933 1934 rc = nvmf_nqn_is_valid(nqn); 1935 CU_ASSERT(rc == false); 1936 1937 /* Invalid domain */ 1938 memset(nqn, 0xff, SPDK_NVMF_NQN_MAX_LEN + 1); 1939 snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io...spdk:cnode1"); 1940 1941 rc = nvmf_nqn_is_valid(nqn); 1942 CU_ASSERT(rc == false); 1943 } 1944 1945 static void 1946 test_nvmf_ns_reservation_restore(void) 1947 { 1948 struct spdk_nvmf_ns ns = {}; 1949 struct spdk_nvmf_reservation_info info = {}; 1950 struct spdk_bdev bdev = {}; 1951 struct spdk_uuid s_uuid = {}; 1952 struct spdk_nvmf_registrant *reg0, *reg1; 1953 char uuid[SPDK_UUID_STRING_LEN] = {}; 1954 int rc; 1955 1956 ns.bdev = &bdev; 1957 TAILQ_INIT(&ns.registrants); 1958 info.ptpl_activated = true; 1959 info.num_regs = 2; 1960 info.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS; 1961 info.registrants[0].rkey = 0xb; 1962 info.registrants[1].rkey = 0xc; 1963 1964 /* Generate and prepare uuids, make sure bdev and info uuid are the same */ 1965 spdk_uuid_generate(&s_uuid); 1966 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid); 1967 snprintf(info.holder_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1968 snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1969 snprintf(info.registrants[0].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1970 spdk_uuid_copy(&bdev.uuid, &s_uuid); 1971 spdk_uuid_generate(&s_uuid); 1972 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid); 1973 snprintf(info.registrants[1].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1974 1975 /* info->rkey not exist in registrants */ 1976 info.crkey = 0xa; 1977 1978 rc = nvmf_ns_reservation_restore(&ns, &info); 1979 CU_ASSERT(rc == -EINVAL); 1980 1981 /* info->rkey exists in registrants */ 1982 info.crkey = 0xb; 1983 1984 rc = nvmf_ns_reservation_restore(&ns, &info); 1985 CU_ASSERT(rc == 0); 1986 CU_ASSERT(ns.crkey == 0xb); 1987 CU_ASSERT(ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1988 CU_ASSERT(ns.ptpl_activated == true); 1989 /* Check two registrant`s rkey */ 1990 reg0 = TAILQ_FIRST(&ns.registrants); 1991 reg1 = TAILQ_NEXT(reg0, link); 1992 CU_ASSERT(ns.holder == reg0); 1993 CU_ASSERT(reg0->rkey = 0xb); 1994 CU_ASSERT(reg1->rkey = 0xc); 1995 1996 rc = nvmf_ns_reservation_clear_all_registrants(&ns); 1997 CU_ASSERT(rc == 2); 1998 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 1999 2000 /* Existing bdev UUID is different with configuration */ 2001 spdk_uuid_generate(&s_uuid); 2002 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &s_uuid); 2003 snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 2004 spdk_uuid_generate(&s_uuid); 2005 spdk_uuid_copy(&bdev.uuid, &s_uuid); 2006 2007 rc = nvmf_ns_reservation_restore(&ns, &info); 2008 CU_ASSERT(rc == -EINVAL); 2009 2010 /* Check restore without reservation */ 2011 spdk_uuid_fmt_lower(info.bdev_uuid, sizeof(info.bdev_uuid), &bdev.uuid); 2012 info.rtype = 0; 2013 info.crkey = 0; 2014 memset(info.holder_uuid, 0, SPDK_UUID_STRING_LEN); 2015 2016 rc = nvmf_ns_reservation_restore(&ns, &info); 2017 CU_ASSERT(rc == 0); 2018 CU_ASSERT(ns.crkey == 0); 2019 CU_ASSERT(ns.rtype == 0); 2020 CU_ASSERT(ns.ptpl_activated == true); 2021 CU_ASSERT(ns.holder == NULL); 2022 reg0 = TAILQ_FIRST(&ns.registrants); 2023 reg1 = TAILQ_NEXT(reg0, link); 2024 CU_ASSERT(reg0->rkey = 0xb); 2025 CU_ASSERT(reg1->rkey = 0xc); 2026 2027 rc = nvmf_ns_reservation_clear_all_registrants(&ns); 2028 CU_ASSERT(rc == 2); 2029 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 2030 } 2031 2032 static void 2033 ut_nvmf_subsystem_paused(struct spdk_nvmf_subsystem *subsystem, void *ctx, int status) 2034 { 2035 CU_ASSERT_EQUAL(status, 0); 2036 CU_ASSERT_EQUAL(subsystem->state, SPDK_NVMF_SUBSYSTEM_PAUSED); 2037 } 2038 2039 static void 2040 test_nvmf_subsystem_state_change(void) 2041 { 2042 struct spdk_nvmf_tgt tgt = {}; 2043 struct spdk_nvmf_subsystem *subsystem, *discovery_subsystem; 2044 int rc; 2045 2046 tgt.max_subsystems = 1024; 2047 tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems); 2048 RB_INIT(&tgt.subsystems); 2049 2050 discovery_subsystem = spdk_nvmf_subsystem_create(&tgt, SPDK_NVMF_DISCOVERY_NQN, 2051 SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT, 0); 2052 SPDK_CU_ASSERT_FATAL(discovery_subsystem != NULL); 2053 subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", 2054 SPDK_NVMF_SUBTYPE_NVME, 0); 2055 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 2056 2057 spdk_io_device_register(&tgt, 2058 nvmf_tgt_create_poll_group, 2059 nvmf_tgt_destroy_poll_group, 2060 sizeof(struct spdk_nvmf_poll_group), 2061 NULL); 2062 2063 rc = spdk_nvmf_subsystem_start(discovery_subsystem, NULL, NULL); 2064 CU_ASSERT(rc == 0); 2065 poll_threads(); 2066 CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); 2067 rc = spdk_nvmf_subsystem_start(subsystem, NULL, NULL); 2068 CU_ASSERT(rc == 0); 2069 poll_threads(); 2070 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); 2071 2072 rc = spdk_nvmf_subsystem_pause(subsystem, SPDK_NVME_GLOBAL_NS_TAG, 2073 ut_nvmf_subsystem_paused, NULL); 2074 CU_ASSERT(rc == 0); 2075 rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL); 2076 CU_ASSERT(rc == 0); 2077 poll_threads(); 2078 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 2079 2080 rc = spdk_nvmf_subsystem_stop(discovery_subsystem, NULL, NULL); 2081 CU_ASSERT(rc == 0); 2082 poll_threads(); 2083 CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 2084 rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL); 2085 CU_ASSERT(rc == 0); 2086 poll_threads(); 2087 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 2088 2089 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 2090 CU_ASSERT(rc == 0); 2091 rc = spdk_nvmf_subsystem_destroy(discovery_subsystem, NULL, NULL); 2092 CU_ASSERT(rc == 0); 2093 2094 spdk_io_device_unregister(&tgt, NULL); 2095 poll_threads(); 2096 2097 spdk_bit_array_free(&tgt.subsystem_ids); 2098 } 2099 2100 static bool 2101 ut_is_ptpl_capable(const struct spdk_nvmf_ns *ns) 2102 { 2103 return true; 2104 } 2105 2106 static struct spdk_nvmf_reservation_info g_resv_info; 2107 2108 static int 2109 ut_update_reservation(const struct spdk_nvmf_ns *ns, const struct spdk_nvmf_reservation_info *info) 2110 { 2111 g_resv_info = *info; 2112 2113 return 0; 2114 } 2115 2116 static int 2117 ut_load_reservation(const struct spdk_nvmf_ns *ns, struct spdk_nvmf_reservation_info *info) 2118 { 2119 *info = g_resv_info; 2120 2121 return 0; 2122 } 2123 2124 static void 2125 test_nvmf_reservation_custom_ops(void) 2126 { 2127 struct spdk_nvmf_ns_reservation_ops ops = { 2128 .is_ptpl_capable = ut_is_ptpl_capable, 2129 .update = ut_update_reservation, 2130 .load = ut_load_reservation, 2131 }; 2132 struct spdk_nvmf_request *req; 2133 struct spdk_nvme_cpl *rsp; 2134 struct spdk_nvmf_registrant *reg; 2135 bool update_sgroup = false; 2136 struct spdk_nvmf_tgt tgt = {}; 2137 struct spdk_nvmf_subsystem subsystem = { 2138 .max_nsid = 4, 2139 .tgt = &tgt, 2140 }; 2141 uint32_t nsid; 2142 struct spdk_nvmf_ns *ns; 2143 int rc; 2144 2145 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 2146 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 2147 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 2148 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 2149 2150 spdk_nvmf_set_custom_ns_reservation_ops(&ops); 2151 2152 ut_reservation_init(); 2153 2154 req = ut_reservation_build_req(16); 2155 rsp = &req->rsp->nvme_cpl; 2156 SPDK_CU_ASSERT_FATAL(req != NULL); 2157 2158 /* Add a registrant and activate ptpl */ 2159 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 2160 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 2161 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 2162 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 2163 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 2164 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 2165 rc = nvmf_ns_update_reservation_info(&g_ns); 2166 SPDK_CU_ASSERT_FATAL(rc == 0); 2167 2168 /* Acquire a reservation */ 2169 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 2170 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 2171 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 2172 update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 2173 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 2174 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 2175 rc = nvmf_ns_update_reservation_info(&g_ns); 2176 SPDK_CU_ASSERT_FATAL(rc == 0); 2177 2178 /* Add the namespace using a different subsystem. 2179 * Reservation information should be restored. */ 2180 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, g_ns.bdev->name, NULL, 0, NULL); 2181 CU_ASSERT(nsid == 1); 2182 2183 ns = _nvmf_subsystem_get_ns(&subsystem, nsid); 2184 SPDK_CU_ASSERT_FATAL(ns != NULL); 2185 CU_ASSERT(ns->crkey == 0xa1); 2186 CU_ASSERT(ns->rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 2187 CU_ASSERT(ns->ptpl_activated == true); 2188 2189 reg = nvmf_ns_reservation_get_registrant(ns, &g_ctrlr1_A.hostid); 2190 SPDK_CU_ASSERT_FATAL(reg != NULL); 2191 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 2192 CU_ASSERT(reg == ns->holder); 2193 2194 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, nsid); 2195 CU_ASSERT(rc == 0); 2196 2197 free(subsystem.ns); 2198 free(subsystem.ana_group); 2199 ut_reservation_free_req(req); 2200 ut_reservation_deinit(); 2201 } 2202 2203 int 2204 main(int argc, char **argv) 2205 { 2206 CU_pSuite suite = NULL; 2207 unsigned int num_failures; 2208 2209 CU_initialize_registry(); 2210 2211 suite = CU_add_suite("nvmf", NULL, NULL); 2212 2213 CU_ADD_TEST(suite, nvmf_test_create_subsystem); 2214 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_ns); 2215 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_fdp_ns); 2216 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_set_sn); 2217 CU_ADD_TEST(suite, test_spdk_nvmf_ns_visible); 2218 CU_ADD_TEST(suite, test_reservation_register); 2219 CU_ADD_TEST(suite, test_reservation_register_with_ptpl); 2220 CU_ADD_TEST(suite, test_reservation_acquire_preempt_1); 2221 CU_ADD_TEST(suite, test_reservation_acquire_release_with_ptpl); 2222 CU_ADD_TEST(suite, test_reservation_release); 2223 CU_ADD_TEST(suite, test_reservation_unregister_notification); 2224 CU_ADD_TEST(suite, test_reservation_release_notification); 2225 CU_ADD_TEST(suite, test_reservation_release_notification_write_exclusive); 2226 CU_ADD_TEST(suite, test_reservation_clear_notification); 2227 CU_ADD_TEST(suite, test_reservation_preempt_notification); 2228 CU_ADD_TEST(suite, test_spdk_nvmf_ns_event); 2229 CU_ADD_TEST(suite, test_nvmf_ns_reservation_add_remove_registrant); 2230 CU_ADD_TEST(suite, test_nvmf_subsystem_add_ctrlr); 2231 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_host); 2232 CU_ADD_TEST(suite, test_nvmf_ns_reservation_report); 2233 CU_ADD_TEST(suite, test_nvmf_nqn_is_valid); 2234 CU_ADD_TEST(suite, test_nvmf_ns_reservation_restore); 2235 CU_ADD_TEST(suite, test_nvmf_subsystem_state_change); 2236 CU_ADD_TEST(suite, test_nvmf_reservation_custom_ops); 2237 2238 allocate_threads(1); 2239 set_thread(0); 2240 2241 num_failures = spdk_ut_run_tests(argc, argv, NULL); 2242 CU_cleanup_registry(); 2243 2244 free_threads(); 2245 2246 return num_failures; 2247 } 2248