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