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