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