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