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_cunit.h" 10 #include "spdk_internal/mock.h" 11 12 #include "spdk/bdev_module.h" 13 #include "nvmf/subsystem.c" 14 #include <uuid/uuid.h> 15 16 SPDK_LOG_REGISTER_COMPONENT(nvmf) 17 18 DEFINE_STUB(spdk_bdev_module_claim_bdev, 19 int, 20 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 21 struct spdk_bdev_module *module), 0); 22 23 DEFINE_STUB_V(spdk_bdev_module_release_bdev, 24 (struct spdk_bdev *bdev)); 25 26 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, 27 (const struct spdk_bdev *bdev), 512); 28 29 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, 30 (const struct spdk_bdev *bdev), 0); 31 32 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, 33 (const struct spdk_bdev *bdev), false); 34 35 DEFINE_STUB(spdk_bdev_io_type_supported, bool, 36 (struct spdk_bdev *bdev, 37 enum spdk_bdev_io_type io_type), false); 38 39 DEFINE_STUB(spdk_nvmf_transport_stop_listen, 40 int, 41 (struct spdk_nvmf_transport *transport, 42 const struct spdk_nvme_transport_id *trid), 0); 43 44 DEFINE_STUB_V(nvmf_update_discovery_log, 45 (struct spdk_nvmf_tgt *tgt, const char *hostnqn)); 46 47 DEFINE_STUB(spdk_nvmf_qpair_disconnect, 48 int, 49 (struct spdk_nvmf_qpair *qpair, 50 nvmf_qpair_disconnect_cb cb_fn, void *ctx), 0); 51 52 DEFINE_STUB(nvmf_transport_find_listener, 53 struct spdk_nvmf_listener *, 54 (struct spdk_nvmf_transport *transport, 55 const struct spdk_nvme_transport_id *trid), NULL); 56 57 DEFINE_STUB(spdk_nvmf_transport_get_first, 58 struct spdk_nvmf_transport *, 59 (struct spdk_nvmf_tgt *tgt), NULL); 60 61 DEFINE_STUB(spdk_nvmf_transport_get_next, 62 struct spdk_nvmf_transport *, 63 (struct spdk_nvmf_transport *transport), NULL); 64 65 DEFINE_STUB(spdk_nvmf_request_complete, 66 int, 67 (struct spdk_nvmf_request *req), 0); 68 69 DEFINE_STUB(nvmf_ctrlr_async_event_ana_change_notice, 70 int, 71 (struct spdk_nvmf_ctrlr *ctrlr), 0); 72 73 DEFINE_STUB(spdk_nvme_transport_id_trtype_str, 74 const char *, 75 (enum spdk_nvme_transport_type trtype), NULL); 76 77 DEFINE_STUB(spdk_bdev_is_zoned, bool, 78 (const struct spdk_bdev *bdev), false); 79 80 DEFINE_STUB(spdk_bdev_get_max_zone_append_size, uint32_t, 81 (const struct spdk_bdev *bdev), 0); 82 83 int 84 spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport, 85 const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *opts) 86 { 87 return 0; 88 } 89 90 void 91 nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport, 92 struct spdk_nvme_transport_id *trid, 93 struct spdk_nvmf_discovery_log_page_entry *entry) 94 { 95 entry->trtype = 42; 96 } 97 98 static struct spdk_nvmf_transport g_transport = {}; 99 100 struct spdk_nvmf_transport * 101 spdk_nvmf_transport_create(const char *transport_name, 102 struct spdk_nvmf_transport_opts *tprt_opts) 103 { 104 if (strcasecmp(transport_name, spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA))) { 105 return &g_transport; 106 } 107 108 return NULL; 109 } 110 111 struct spdk_nvmf_subsystem * 112 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) 113 { 114 return NULL; 115 } 116 117 struct spdk_nvmf_transport * 118 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name) 119 { 120 if (strncmp(transport_name, SPDK_NVME_TRANSPORT_NAME_RDMA, SPDK_NVMF_TRSTRING_MAX_LEN)) { 121 return &g_transport; 122 } 123 124 return NULL; 125 } 126 127 int 128 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group, 129 struct spdk_nvmf_subsystem *subsystem) 130 { 131 return 0; 132 } 133 134 int 135 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, 136 struct spdk_nvmf_subsystem *subsystem, 137 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 138 { 139 return 0; 140 } 141 142 void 143 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, 144 struct spdk_nvmf_subsystem *subsystem, 145 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 146 { 147 } 148 149 void 150 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, 151 struct spdk_nvmf_subsystem *subsystem, 152 uint32_t nsid, 153 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 154 { 155 } 156 157 void 158 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, 159 struct spdk_nvmf_subsystem *subsystem, 160 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 161 { 162 } 163 164 int 165 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str) 166 { 167 if (trtype == NULL || str == NULL) { 168 return -EINVAL; 169 } 170 171 if (strcasecmp(str, "PCIe") == 0) { 172 *trtype = SPDK_NVME_TRANSPORT_PCIE; 173 } else if (strcasecmp(str, "RDMA") == 0) { 174 *trtype = SPDK_NVME_TRANSPORT_RDMA; 175 } else { 176 return -ENOENT; 177 } 178 return 0; 179 } 180 181 int 182 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 183 const struct spdk_nvme_transport_id *trid2) 184 { 185 return 0; 186 } 187 188 int32_t 189 spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr) 190 { 191 return -1; 192 } 193 194 int32_t 195 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) 196 { 197 return -1; 198 } 199 200 int 201 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr) 202 { 203 return -1; 204 } 205 206 void 207 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) 208 { 209 } 210 211 static struct spdk_nvmf_ctrlr *g_ns_changed_ctrlr = NULL; 212 static uint32_t g_ns_changed_nsid = 0; 213 void 214 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) 215 { 216 g_ns_changed_ctrlr = ctrlr; 217 g_ns_changed_nsid = nsid; 218 } 219 220 static struct spdk_bdev g_bdevs[] = { 221 { .name = "bdev1" }, 222 { .name = "bdev2" }, 223 }; 224 225 struct spdk_bdev_desc { 226 struct spdk_bdev *bdev; 227 }; 228 229 int 230 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, 231 void *event_ctx, struct spdk_bdev_desc **_desc) 232 { 233 struct spdk_bdev_desc *desc; 234 size_t i; 235 236 for (i = 0; i < sizeof(g_bdevs); i++) { 237 if (strcmp(bdev_name, g_bdevs[i].name) == 0) { 238 239 desc = calloc(1, sizeof(*desc)); 240 SPDK_CU_ASSERT_FATAL(desc != NULL); 241 242 desc->bdev = &g_bdevs[i]; 243 *_desc = desc; 244 return 0; 245 } 246 } 247 248 return -EINVAL; 249 } 250 251 void 252 spdk_bdev_close(struct spdk_bdev_desc *desc) 253 { 254 free(desc); 255 } 256 257 struct spdk_bdev * 258 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 259 { 260 return desc->bdev; 261 } 262 263 const char * 264 spdk_bdev_get_name(const struct spdk_bdev *bdev) 265 { 266 return "test"; 267 } 268 269 const struct spdk_uuid * 270 spdk_bdev_get_uuid(const struct spdk_bdev *bdev) 271 { 272 return &bdev->uuid; 273 } 274 275 static void 276 test_spdk_nvmf_subsystem_add_ns(void) 277 { 278 struct spdk_nvmf_tgt tgt = {}; 279 struct spdk_nvmf_subsystem subsystem = { 280 .max_nsid = 1024, 281 .ns = NULL, 282 .tgt = &tgt, 283 }; 284 struct spdk_nvmf_ns_opts ns_opts; 285 uint32_t nsid; 286 int rc; 287 288 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 289 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 290 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 291 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 292 293 tgt.max_subsystems = 1024; 294 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 295 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 296 297 /* Request a specific NSID */ 298 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 299 ns_opts.nsid = 5; 300 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 301 CU_ASSERT(nsid == 5); 302 CU_ASSERT(subsystem.max_nsid == 1024); 303 SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL); 304 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[1]); 305 306 /* Request an NSID that is already in use */ 307 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 308 ns_opts.nsid = 5; 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 /* Request 0xFFFFFFFF (invalid NSID, reserved for broadcast) */ 314 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 315 ns_opts.nsid = 0xFFFFFFFF; 316 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 317 CU_ASSERT(nsid == 0); 318 CU_ASSERT(subsystem.max_nsid == 1024); 319 320 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 5); 321 CU_ASSERT(rc == 0); 322 323 free(subsystem.ns); 324 free(subsystem.ana_group); 325 free(tgt.subsystems); 326 } 327 328 static void 329 nvmf_test_create_subsystem(void) 330 { 331 struct spdk_nvmf_tgt tgt = {}; 332 char nqn[256]; 333 struct spdk_nvmf_subsystem *subsystem; 334 int rc; 335 336 tgt.max_subsystems = 1024; 337 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 338 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 339 340 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 341 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 342 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 343 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 344 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 345 CU_ASSERT(rc == 0); 346 347 /* valid name with complex reverse domain */ 348 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-full--rev-domain.name:subsystem1"); 349 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 350 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 351 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 352 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 353 CU_ASSERT(rc == 0); 354 355 /* Valid name discovery controller */ 356 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 357 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 358 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 359 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 360 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 361 CU_ASSERT(rc == 0); 362 363 /* Invalid name, no user supplied string */ 364 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 365 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 366 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 367 368 /* Valid name, only contains top-level domain name */ 369 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 370 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 371 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 372 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 373 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 374 CU_ASSERT(rc == 0); 375 376 /* Invalid name, domain label > 63 characters */ 377 snprintf(nqn, sizeof(nqn), 378 "nqn.2016-06.io.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz:sub"); 379 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 380 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 381 382 /* Invalid name, domain label starts with digit */ 383 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.3spdk:sub"); 384 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 385 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 386 387 /* Invalid name, domain label starts with - */ 388 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.-spdk:subsystem1"); 389 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 390 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 391 392 /* Invalid name, domain label ends with - */ 393 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-:subsystem1"); 394 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 395 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 396 397 /* Invalid name, domain label with multiple consecutive periods */ 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 402 /* Longest valid name */ 403 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 404 memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn)); 405 nqn[223] = '\0'; 406 CU_ASSERT(strlen(nqn) == 223); 407 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 408 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 409 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 410 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 411 CU_ASSERT(rc == 0); 412 413 /* Invalid name, too long */ 414 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 415 memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn)); 416 nqn[224] = '\0'; 417 CU_ASSERT(strlen(nqn) == 224); 418 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 419 CU_ASSERT(subsystem == NULL); 420 421 /* Valid name using uuid format */ 422 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:11111111-aaaa-bbdd-FFEE-123456789abc"); 423 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 424 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 425 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 426 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 427 CU_ASSERT(rc == 0); 428 429 /* Invalid name user string contains an invalid utf-8 character */ 430 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xFFsubsystem1"); 431 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 432 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 433 434 /* Valid name with non-ascii but valid utf-8 characters */ 435 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xe1\x8a\x88subsystem1\xca\x80"); 436 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 437 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 438 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 439 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 440 CU_ASSERT(rc == 0); 441 442 /* Invalid uuid (too long) */ 443 snprintf(nqn, sizeof(nqn), 444 "nqn.2014-08.org.nvmexpress:uuid:11111111-aaaa-bbdd-FFEE-123456789abcdef"); 445 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 446 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 447 448 /* Invalid uuid (dashes placed incorrectly) */ 449 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:111111-11aaaa-bbdd-FFEE-123456789abc"); 450 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 451 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 452 453 /* Invalid uuid (invalid characters in uuid) */ 454 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:111hg111-aaaa-bbdd-FFEE-123456789abc"); 455 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 456 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 457 458 free(tgt.subsystems); 459 } 460 461 static void 462 test_spdk_nvmf_subsystem_set_sn(void) 463 { 464 struct spdk_nvmf_subsystem subsystem = {}; 465 466 /* Basic valid serial number */ 467 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd xyz") == 0); 468 CU_ASSERT(strcmp(subsystem.sn, "abcd xyz") == 0); 469 470 /* Exactly 20 characters (valid) */ 471 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "12345678901234567890") == 0); 472 CU_ASSERT(strcmp(subsystem.sn, "12345678901234567890") == 0); 473 474 /* 21 characters (too long, invalid) */ 475 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "123456789012345678901") < 0); 476 477 /* Non-ASCII characters (invalid) */ 478 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd\txyz") < 0); 479 } 480 481 /* 482 * Reservation Unit Test Configuration 483 * -------- -------- -------- 484 * | Host A | | Host B | | Host C | 485 * -------- -------- -------- 486 * / \ | | 487 * -------- -------- ------- ------- 488 * |Ctrlr1_A| |Ctrlr2_A| |Ctrlr_B| |Ctrlr_C| 489 * -------- -------- ------- ------- 490 * \ \ / / 491 * \ \ / / 492 * \ \ / / 493 * -------------------------------------- 494 * | NAMESPACE 1 | 495 * -------------------------------------- 496 */ 497 static struct spdk_nvmf_subsystem g_subsystem; 498 static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C; 499 static struct spdk_nvmf_ns g_ns; 500 static struct spdk_bdev g_bdev; 501 struct spdk_nvmf_subsystem_pg_ns_info g_ns_info; 502 503 void 504 nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr) 505 { 506 } 507 508 static void 509 ut_reservation_init(void) 510 { 511 512 TAILQ_INIT(&g_subsystem.ctrlrs); 513 514 memset(&g_ns, 0, sizeof(g_ns)); 515 TAILQ_INIT(&g_ns.registrants); 516 g_ns.subsystem = &g_subsystem; 517 g_ns.ptpl_file = NULL; 518 g_ns.ptpl_activated = false; 519 spdk_uuid_generate(&g_bdev.uuid); 520 g_ns.bdev = &g_bdev; 521 522 /* Host A has two controllers */ 523 spdk_uuid_generate(&g_ctrlr1_A.hostid); 524 TAILQ_INIT(&g_ctrlr1_A.log_head); 525 g_ctrlr1_A.subsys = &g_subsystem; 526 g_ctrlr1_A.num_avail_log_pages = 0; 527 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr1_A, link); 528 spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid); 529 TAILQ_INIT(&g_ctrlr2_A.log_head); 530 g_ctrlr2_A.subsys = &g_subsystem; 531 g_ctrlr2_A.num_avail_log_pages = 0; 532 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr2_A, link); 533 534 /* Host B has 1 controller */ 535 spdk_uuid_generate(&g_ctrlr_B.hostid); 536 TAILQ_INIT(&g_ctrlr_B.log_head); 537 g_ctrlr_B.subsys = &g_subsystem; 538 g_ctrlr_B.num_avail_log_pages = 0; 539 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_B, link); 540 541 /* Host C has 1 controller */ 542 spdk_uuid_generate(&g_ctrlr_C.hostid); 543 TAILQ_INIT(&g_ctrlr_C.log_head); 544 g_ctrlr_C.subsys = &g_subsystem; 545 g_ctrlr_C.num_avail_log_pages = 0; 546 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_C, link); 547 } 548 549 static void 550 ut_reservation_deinit(void) 551 { 552 struct spdk_nvmf_registrant *reg, *tmp; 553 struct spdk_nvmf_reservation_log *log, *log_tmp; 554 struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp; 555 556 TAILQ_FOREACH_SAFE(reg, &g_ns.registrants, link, tmp) { 557 TAILQ_REMOVE(&g_ns.registrants, reg, link); 558 free(reg); 559 } 560 TAILQ_FOREACH_SAFE(log, &g_ctrlr1_A.log_head, link, log_tmp) { 561 TAILQ_REMOVE(&g_ctrlr1_A.log_head, log, link); 562 free(log); 563 } 564 g_ctrlr1_A.num_avail_log_pages = 0; 565 TAILQ_FOREACH_SAFE(log, &g_ctrlr2_A.log_head, link, log_tmp) { 566 TAILQ_REMOVE(&g_ctrlr2_A.log_head, log, link); 567 free(log); 568 } 569 g_ctrlr2_A.num_avail_log_pages = 0; 570 TAILQ_FOREACH_SAFE(log, &g_ctrlr_B.log_head, link, log_tmp) { 571 TAILQ_REMOVE(&g_ctrlr_B.log_head, log, link); 572 free(log); 573 } 574 g_ctrlr_B.num_avail_log_pages = 0; 575 TAILQ_FOREACH_SAFE(log, &g_ctrlr_C.log_head, link, log_tmp) { 576 TAILQ_REMOVE(&g_ctrlr_C.log_head, log, link); 577 free(log); 578 } 579 g_ctrlr_C.num_avail_log_pages = 0; 580 581 TAILQ_FOREACH_SAFE(ctrlr, &g_subsystem.ctrlrs, link, ctrlr_tmp) { 582 TAILQ_REMOVE(&g_subsystem.ctrlrs, ctrlr, link); 583 } 584 } 585 586 static struct spdk_nvmf_request * 587 ut_reservation_build_req(uint32_t length) 588 { 589 struct spdk_nvmf_request *req; 590 591 req = calloc(1, sizeof(*req)); 592 assert(req != NULL); 593 594 spdk_iov_one(req->iov, &req->iovcnt, calloc(1, length), length); 595 assert(req->iov[0].iov_base != NULL); 596 req->data = req->iov[0].iov_base; 597 req->length = length; 598 599 req->cmd = (union nvmf_h2c_msg *)calloc(1, sizeof(union nvmf_h2c_msg)); 600 assert(req->cmd != NULL); 601 602 req->rsp = (union nvmf_c2h_msg *)calloc(1, sizeof(union nvmf_c2h_msg)); 603 assert(req->rsp != NULL); 604 605 return req; 606 } 607 608 static void 609 ut_reservation_free_req(struct spdk_nvmf_request *req) 610 { 611 free(req->cmd); 612 free(req->rsp); 613 free(req->data); 614 free(req); 615 } 616 617 static void 618 ut_reservation_build_register_request(struct spdk_nvmf_request *req, 619 uint8_t rrega, uint8_t iekey, 620 uint8_t cptpl, uint64_t crkey, 621 uint64_t nrkey) 622 { 623 struct spdk_nvme_reservation_register_data key; 624 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 625 626 key.crkey = crkey; 627 key.nrkey = nrkey; 628 cmd->cdw10 = 0; 629 cmd->cdw10_bits.resv_register.rrega = rrega; 630 cmd->cdw10_bits.resv_register.iekey = iekey; 631 cmd->cdw10_bits.resv_register.cptpl = cptpl; 632 memcpy(req->data, &key, sizeof(key)); 633 } 634 635 static void 636 ut_reservation_build_acquire_request(struct spdk_nvmf_request *req, 637 uint8_t racqa, uint8_t iekey, 638 uint8_t rtype, uint64_t crkey, 639 uint64_t prkey) 640 { 641 struct spdk_nvme_reservation_acquire_data key; 642 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 643 644 key.crkey = crkey; 645 key.prkey = prkey; 646 cmd->cdw10 = 0; 647 cmd->cdw10_bits.resv_acquire.racqa = racqa; 648 cmd->cdw10_bits.resv_acquire.iekey = iekey; 649 cmd->cdw10_bits.resv_acquire.rtype = rtype; 650 memcpy(req->data, &key, sizeof(key)); 651 } 652 653 static void 654 ut_reservation_build_release_request(struct spdk_nvmf_request *req, 655 uint8_t rrela, uint8_t iekey, 656 uint8_t rtype, uint64_t crkey) 657 { 658 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 659 660 cmd->cdw10 = 0; 661 cmd->cdw10_bits.resv_release.rrela = rrela; 662 cmd->cdw10_bits.resv_release.iekey = iekey; 663 cmd->cdw10_bits.resv_release.rtype = rtype; 664 memcpy(req->data, &crkey, sizeof(crkey)); 665 } 666 667 /* 668 * Construct four registrants for other test cases. 669 * 670 * g_ctrlr1_A register with key 0xa1. 671 * g_ctrlr2_A register with key 0xa1. 672 * g_ctrlr_B register with key 0xb1. 673 * g_ctrlr_C register with key 0xc1. 674 * */ 675 static void 676 ut_reservation_build_registrants(void) 677 { 678 struct spdk_nvmf_request *req; 679 struct spdk_nvme_cpl *rsp; 680 struct spdk_nvmf_registrant *reg; 681 uint32_t gen; 682 683 req = ut_reservation_build_req(16); 684 rsp = &req->rsp->nvme_cpl; 685 SPDK_CU_ASSERT_FATAL(req != NULL); 686 gen = g_ns.gen; 687 688 /* TEST CASE: g_ctrlr1_A register with a new key */ 689 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 690 0, 0, 0, 0xa1); 691 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 692 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 693 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 694 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1); 695 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 1); 696 697 /* TEST CASE: g_ctrlr2_A register with a new key, because it has same 698 * Host Identifier with g_ctrlr1_A, so the register key should same. 699 */ 700 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 701 0, 0, 0, 0xa2); 702 nvmf_ns_reservation_register(&g_ns, &g_ctrlr2_A, req); 703 /* Reservation conflict for other key than 0xa1 */ 704 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 705 706 /* g_ctrlr_B register with a new key */ 707 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 708 0, 0, 0, 0xb1); 709 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 710 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 711 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 712 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb1); 713 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 2); 714 715 /* g_ctrlr_C register with a new key */ 716 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 717 0, 0, 0, 0xc1); 718 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 719 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 720 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 721 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc1); 722 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 3); 723 724 ut_reservation_free_req(req); 725 } 726 727 static void 728 test_reservation_register(void) 729 { 730 struct spdk_nvmf_request *req; 731 struct spdk_nvme_cpl *rsp; 732 struct spdk_nvmf_registrant *reg; 733 uint32_t gen; 734 735 ut_reservation_init(); 736 737 req = ut_reservation_build_req(16); 738 rsp = &req->rsp->nvme_cpl; 739 SPDK_CU_ASSERT_FATAL(req != NULL); 740 741 ut_reservation_build_registrants(); 742 743 /* TEST CASE: Replace g_ctrlr1_A with a new key */ 744 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 745 0, 0, 0xa1, 0xa11); 746 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 747 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 748 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 749 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa11); 750 751 /* TEST CASE: Host A with g_ctrlr1_A get reservation with 752 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 753 */ 754 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 755 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xa11, 0x0); 756 gen = g_ns.gen; 757 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 758 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 759 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 760 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 761 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa11); 762 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 763 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 764 765 /* TEST CASE: g_ctrlr_C unregister with IEKEY enabled */ 766 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 767 1, 0, 0, 0); 768 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 769 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 770 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 771 SPDK_CU_ASSERT_FATAL(reg == NULL); 772 773 /* TEST CASE: g_ctrlr_B unregister with correct key */ 774 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 775 0, 0, 0xb1, 0); 776 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 777 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 778 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 779 SPDK_CU_ASSERT_FATAL(reg == NULL); 780 781 /* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY disabled */ 782 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 783 0, 0, 0, 0xb1); 784 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 785 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 786 787 /* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY enabled */ 788 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 789 1, 0, 0, 0xb1); 790 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 791 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 792 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 793 SPDK_CU_ASSERT_FATAL(reg != NULL); 794 795 /* TEST CASE: g_ctrlr_B replace new key with IEKEY enabled and wrong crkey */ 796 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 797 1, 0, 0xff, 0xb2); 798 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 799 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 800 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 801 SPDK_CU_ASSERT_FATAL(reg != NULL); 802 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb2); 803 804 /* TEST CASE: g_ctrlr1_A unregister with correct key, 805 * reservation should be removed as well. 806 */ 807 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 808 0, 0, 0xa11, 0); 809 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 810 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 811 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 812 SPDK_CU_ASSERT_FATAL(reg == NULL); 813 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 814 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 815 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 816 817 ut_reservation_free_req(req); 818 ut_reservation_deinit(); 819 } 820 821 static void 822 test_reservation_register_with_ptpl(void) 823 { 824 struct spdk_nvmf_request *req; 825 struct spdk_nvme_cpl *rsp; 826 struct spdk_nvmf_registrant *reg; 827 bool update_sgroup = false; 828 int rc; 829 struct spdk_nvmf_reservation_info info; 830 831 ut_reservation_init(); 832 833 req = ut_reservation_build_req(16); 834 rsp = &req->rsp->nvme_cpl; 835 SPDK_CU_ASSERT_FATAL(req != NULL); 836 837 /* TEST CASE: No persistent file, register with PTPL enabled will fail */ 838 g_ns.ptpl_file = NULL; 839 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 840 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 841 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 842 SPDK_CU_ASSERT_FATAL(update_sgroup == false); 843 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 844 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 845 SPDK_CU_ASSERT_FATAL(reg == NULL); 846 847 /* TEST CASE: Enable PTPL */ 848 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 849 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 850 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 851 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 852 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 853 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 854 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 855 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 856 SPDK_CU_ASSERT_FATAL(reg != NULL); 857 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 858 /* Load reservation information from configuration file */ 859 memset(&info, 0, sizeof(info)); 860 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 861 SPDK_CU_ASSERT_FATAL(rc == 0); 862 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 863 864 /* TEST CASE: Disable PTPL */ 865 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 866 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 867 SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON, 0, 0xa1); 868 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 869 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 870 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 871 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == false); 872 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 873 SPDK_CU_ASSERT_FATAL(rc < 0); 874 unlink(g_ns.ptpl_file); 875 876 ut_reservation_free_req(req); 877 ut_reservation_deinit(); 878 } 879 880 static void 881 test_reservation_acquire_preempt_1(void) 882 { 883 struct spdk_nvmf_request *req; 884 struct spdk_nvme_cpl *rsp; 885 struct spdk_nvmf_registrant *reg; 886 uint32_t gen; 887 888 ut_reservation_init(); 889 890 req = ut_reservation_build_req(16); 891 rsp = &req->rsp->nvme_cpl; 892 SPDK_CU_ASSERT_FATAL(req != NULL); 893 894 ut_reservation_build_registrants(); 895 896 gen = g_ns.gen; 897 /* ACQUIRE: Host A with g_ctrlr1_A acquire reservation with 898 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE. 899 */ 900 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 901 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 902 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 903 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 904 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 905 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 906 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa1); 907 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 908 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 909 910 /* TEST CASE: g_ctrlr1_A holds the reservation, g_ctrlr_B preempt g_ctrl1_A, 911 * g_ctrl1_A registrant is unregistered. 912 */ 913 gen = g_ns.gen; 914 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 915 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1, 0xa1); 916 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 917 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 918 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 919 SPDK_CU_ASSERT_FATAL(reg == NULL); 920 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 921 SPDK_CU_ASSERT_FATAL(reg != NULL); 922 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 923 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 924 SPDK_CU_ASSERT_FATAL(reg != NULL); 925 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 926 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 927 928 /* TEST CASE: g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B 929 * with valid key and PRKEY set to 0, all registrants other the host that issued 930 * the command are unregistered. 931 */ 932 gen = g_ns.gen; 933 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 934 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0x0); 935 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 936 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 937 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 938 SPDK_CU_ASSERT_FATAL(reg == NULL); 939 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 940 SPDK_CU_ASSERT_FATAL(reg == NULL); 941 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 942 SPDK_CU_ASSERT_FATAL(reg != NULL); 943 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 944 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 945 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 946 947 ut_reservation_free_req(req); 948 ut_reservation_deinit(); 949 } 950 951 static void 952 test_reservation_acquire_release_with_ptpl(void) 953 { 954 struct spdk_nvmf_request *req; 955 struct spdk_nvme_cpl *rsp; 956 struct spdk_nvmf_registrant *reg; 957 bool update_sgroup = false; 958 struct spdk_uuid holder_uuid; 959 int rc; 960 struct spdk_nvmf_reservation_info info; 961 962 ut_reservation_init(); 963 964 req = ut_reservation_build_req(16); 965 rsp = &req->rsp->nvme_cpl; 966 SPDK_CU_ASSERT_FATAL(req != NULL); 967 968 /* TEST CASE: Enable PTPL */ 969 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 970 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 971 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 972 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 973 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 974 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 975 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 976 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 977 SPDK_CU_ASSERT_FATAL(reg != NULL); 978 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 979 /* Load reservation information from configuration file */ 980 memset(&info, 0, sizeof(info)); 981 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 982 SPDK_CU_ASSERT_FATAL(rc == 0); 983 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 984 985 /* TEST CASE: Acquire the reservation */ 986 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 987 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 988 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 989 update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 990 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 991 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 992 memset(&info, 0, sizeof(info)); 993 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 994 SPDK_CU_ASSERT_FATAL(rc == 0); 995 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 996 SPDK_CU_ASSERT_FATAL(info.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 997 SPDK_CU_ASSERT_FATAL(info.crkey == 0xa1); 998 spdk_uuid_parse(&holder_uuid, info.holder_uuid); 999 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &holder_uuid)); 1000 1001 /* TEST CASE: Release the reservation */ 1002 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 1003 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1004 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1); 1005 update_sgroup = nvmf_ns_reservation_release(&g_ns, &g_ctrlr1_A, req); 1006 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1007 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1008 memset(&info, 0, sizeof(info)); 1009 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 1010 SPDK_CU_ASSERT_FATAL(rc == 0); 1011 SPDK_CU_ASSERT_FATAL(info.rtype == 0); 1012 SPDK_CU_ASSERT_FATAL(info.crkey == 0); 1013 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 1014 unlink(g_ns.ptpl_file); 1015 1016 ut_reservation_free_req(req); 1017 ut_reservation_deinit(); 1018 } 1019 1020 static void 1021 test_reservation_release(void) 1022 { 1023 struct spdk_nvmf_request *req; 1024 struct spdk_nvme_cpl *rsp; 1025 struct spdk_nvmf_registrant *reg; 1026 1027 ut_reservation_init(); 1028 1029 req = ut_reservation_build_req(16); 1030 rsp = &req->rsp->nvme_cpl; 1031 SPDK_CU_ASSERT_FATAL(req != NULL); 1032 1033 ut_reservation_build_registrants(); 1034 1035 /* ACQUIRE: Host A with g_ctrlr1_A get reservation with 1036 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS 1037 */ 1038 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1039 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xa1, 0x0); 1040 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 1041 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1042 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1043 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1044 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1045 1046 /* Test Case: Host B release the reservation */ 1047 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1048 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1); 1049 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1050 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1051 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1052 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 1053 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 1054 1055 /* Test Case: Host C clear the registrants */ 1056 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1057 0, 0xc1); 1058 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_C, req); 1059 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1060 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1061 SPDK_CU_ASSERT_FATAL(reg == NULL); 1062 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 1063 SPDK_CU_ASSERT_FATAL(reg == NULL); 1064 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1065 SPDK_CU_ASSERT_FATAL(reg == NULL); 1066 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1067 SPDK_CU_ASSERT_FATAL(reg == NULL); 1068 1069 ut_reservation_free_req(req); 1070 ut_reservation_deinit(); 1071 } 1072 1073 void 1074 nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr, 1075 struct spdk_nvmf_ns *ns, 1076 enum spdk_nvme_reservation_notification_log_page_type type) 1077 { 1078 ctrlr->num_avail_log_pages++; 1079 } 1080 1081 static void 1082 test_reservation_unregister_notification(void) 1083 { 1084 struct spdk_nvmf_request *req; 1085 struct spdk_nvme_cpl *rsp; 1086 1087 ut_reservation_init(); 1088 1089 req = ut_reservation_build_req(16); 1090 SPDK_CU_ASSERT_FATAL(req != NULL); 1091 rsp = &req->rsp->nvme_cpl; 1092 1093 ut_reservation_build_registrants(); 1094 1095 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1096 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1097 */ 1098 rsp->status.sc = 0xff; 1099 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1100 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1101 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1102 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1103 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1104 1105 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B unregister the registration. 1106 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C only for 1107 * SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY or SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY 1108 * type. 1109 */ 1110 rsp->status.sc = 0xff; 1111 g_ctrlr1_A.num_avail_log_pages = 0; 1112 g_ctrlr2_A.num_avail_log_pages = 0; 1113 g_ctrlr_B.num_avail_log_pages = 5; 1114 g_ctrlr_C.num_avail_log_pages = 0; 1115 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1116 0, 0, 0xb1, 0); 1117 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1118 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1119 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1120 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1121 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1122 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1123 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1124 1125 ut_reservation_free_req(req); 1126 ut_reservation_deinit(); 1127 } 1128 1129 static void 1130 test_reservation_release_notification(void) 1131 { 1132 struct spdk_nvmf_request *req; 1133 struct spdk_nvme_cpl *rsp; 1134 1135 ut_reservation_init(); 1136 1137 req = ut_reservation_build_req(16); 1138 SPDK_CU_ASSERT_FATAL(req != NULL); 1139 rsp = &req->rsp->nvme_cpl; 1140 1141 ut_reservation_build_registrants(); 1142 1143 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1144 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1145 */ 1146 rsp->status.sc = 0xff; 1147 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1148 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1149 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1150 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1151 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1152 1153 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1154 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1155 */ 1156 rsp->status.sc = 0xff; 1157 g_ctrlr1_A.num_avail_log_pages = 0; 1158 g_ctrlr2_A.num_avail_log_pages = 0; 1159 g_ctrlr_B.num_avail_log_pages = 5; 1160 g_ctrlr_C.num_avail_log_pages = 0; 1161 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1162 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1); 1163 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1164 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1165 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1166 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1167 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1168 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1169 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1170 1171 ut_reservation_free_req(req); 1172 ut_reservation_deinit(); 1173 } 1174 1175 static void 1176 test_reservation_release_notification_write_exclusive(void) 1177 { 1178 struct spdk_nvmf_request *req; 1179 struct spdk_nvme_cpl *rsp; 1180 1181 ut_reservation_init(); 1182 1183 req = ut_reservation_build_req(16); 1184 SPDK_CU_ASSERT_FATAL(req != NULL); 1185 rsp = &req->rsp->nvme_cpl; 1186 1187 ut_reservation_build_registrants(); 1188 1189 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1190 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 1191 */ 1192 rsp->status.sc = 0xff; 1193 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1194 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1, 0x0); 1195 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1196 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1197 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1198 1199 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1200 * Because the reservation type is SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 1201 * no reservation notification occurs. 1202 */ 1203 rsp->status.sc = 0xff; 1204 g_ctrlr1_A.num_avail_log_pages = 5; 1205 g_ctrlr2_A.num_avail_log_pages = 5; 1206 g_ctrlr_B.num_avail_log_pages = 5; 1207 g_ctrlr_C.num_avail_log_pages = 5; 1208 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1209 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1); 1210 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1211 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1212 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1213 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr1_A.num_avail_log_pages); 1214 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr2_A.num_avail_log_pages); 1215 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1216 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1217 1218 ut_reservation_free_req(req); 1219 ut_reservation_deinit(); 1220 } 1221 1222 static void 1223 test_reservation_clear_notification(void) 1224 { 1225 struct spdk_nvmf_request *req; 1226 struct spdk_nvme_cpl *rsp; 1227 1228 ut_reservation_init(); 1229 1230 req = ut_reservation_build_req(16); 1231 SPDK_CU_ASSERT_FATAL(req != NULL); 1232 rsp = &req->rsp->nvme_cpl; 1233 1234 ut_reservation_build_registrants(); 1235 1236 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1237 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1238 */ 1239 rsp->status.sc = 0xff; 1240 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1241 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1242 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1243 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1244 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1245 1246 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B clear the reservation. 1247 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1248 */ 1249 rsp->status.sc = 0xff; 1250 g_ctrlr1_A.num_avail_log_pages = 0; 1251 g_ctrlr2_A.num_avail_log_pages = 0; 1252 g_ctrlr_B.num_avail_log_pages = 5; 1253 g_ctrlr_C.num_avail_log_pages = 0; 1254 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1255 0, 0xb1); 1256 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1257 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1258 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1259 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1260 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1261 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1262 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1263 1264 ut_reservation_free_req(req); 1265 ut_reservation_deinit(); 1266 } 1267 1268 static void 1269 test_reservation_preempt_notification(void) 1270 { 1271 struct spdk_nvmf_request *req; 1272 struct spdk_nvme_cpl *rsp; 1273 1274 ut_reservation_init(); 1275 1276 req = ut_reservation_build_req(16); 1277 SPDK_CU_ASSERT_FATAL(req != NULL); 1278 rsp = &req->rsp->nvme_cpl; 1279 1280 ut_reservation_build_registrants(); 1281 1282 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1283 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1284 */ 1285 rsp->status.sc = 0xff; 1286 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1287 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1288 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1289 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1290 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1291 1292 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B, 1293 * g_ctrlr_B registrant is unregistered, and reservation is preempted. 1294 * Registration Preempted notification sends to g_ctrlr_B. 1295 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A. 1296 */ 1297 rsp->status.sc = 0xff; 1298 g_ctrlr1_A.num_avail_log_pages = 0; 1299 g_ctrlr2_A.num_avail_log_pages = 0; 1300 g_ctrlr_B.num_avail_log_pages = 0; 1301 g_ctrlr_C.num_avail_log_pages = 5; 1302 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 1303 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0xb1); 1304 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 1305 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1306 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1307 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1308 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1309 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_B.num_avail_log_pages); 1310 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1311 1312 ut_reservation_free_req(req); 1313 ut_reservation_deinit(); 1314 } 1315 1316 static int 1317 nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf) 1318 { 1319 return 0; 1320 } 1321 1322 static void 1323 nvmf_tgt_destroy_poll_group(void *io_device, void *ctx_buf) 1324 { 1325 } 1326 1327 static void 1328 test_spdk_nvmf_ns_event(void) 1329 { 1330 struct spdk_nvmf_tgt tgt = {}; 1331 struct spdk_nvmf_subsystem subsystem = { 1332 .max_nsid = 1024, 1333 .ns = NULL, 1334 .tgt = &tgt, 1335 }; 1336 struct spdk_nvmf_ctrlr ctrlr = { 1337 .subsys = &subsystem 1338 }; 1339 struct spdk_nvmf_ns_opts ns_opts; 1340 uint32_t nsid; 1341 struct spdk_bdev *bdev; 1342 1343 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 1344 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 1345 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 1346 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 1347 1348 tgt.max_subsystems = 1024; 1349 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1350 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1351 1352 spdk_io_device_register(&tgt, 1353 nvmf_tgt_create_poll_group, 1354 nvmf_tgt_destroy_poll_group, 1355 sizeof(struct spdk_nvmf_poll_group), 1356 NULL); 1357 1358 /* Add one namespace */ 1359 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 1360 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL); 1361 CU_ASSERT(nsid == 1); 1362 CU_ASSERT(NULL != subsystem.ns[0]); 1363 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]); 1364 1365 bdev = subsystem.ns[nsid - 1]->bdev; 1366 1367 /* Add one controller */ 1368 TAILQ_INIT(&subsystem.ctrlrs); 1369 TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlr, link); 1370 1371 /* Namespace resize event */ 1372 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1373 g_ns_changed_nsid = 0xFFFFFFFF; 1374 g_ns_changed_ctrlr = NULL; 1375 nvmf_ns_event(SPDK_BDEV_EVENT_RESIZE, bdev, subsystem.ns[0]); 1376 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1377 1378 poll_threads(); 1379 CU_ASSERT(1 == g_ns_changed_nsid); 1380 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1381 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1382 1383 /* Namespace remove event */ 1384 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1385 g_ns_changed_nsid = 0xFFFFFFFF; 1386 g_ns_changed_ctrlr = NULL; 1387 nvmf_ns_event(SPDK_BDEV_EVENT_REMOVE, bdev, subsystem.ns[0]); 1388 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1389 CU_ASSERT(0xFFFFFFFF == g_ns_changed_nsid); 1390 CU_ASSERT(NULL == g_ns_changed_ctrlr); 1391 1392 poll_threads(); 1393 CU_ASSERT(1 == g_ns_changed_nsid); 1394 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1395 CU_ASSERT(NULL == subsystem.ns[0]); 1396 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1397 1398 spdk_io_device_unregister(&tgt, NULL); 1399 1400 poll_threads(); 1401 1402 free(subsystem.ns); 1403 free(subsystem.ana_group); 1404 free(tgt.subsystems); 1405 } 1406 1407 static void 1408 test_nvmf_ns_reservation_add_remove_registrant(void) 1409 { 1410 struct spdk_nvmf_ns ns = {}; 1411 struct spdk_nvmf_ctrlr ctrlr = {}; 1412 struct spdk_nvmf_registrant *reg = NULL; 1413 int rc; 1414 1415 TAILQ_INIT(&ns.registrants); 1416 spdk_uuid_generate(&ctrlr.hostid); 1417 1418 rc = nvmf_ns_reservation_add_registrant(&ns, &ctrlr, 0xa11); 1419 CU_ASSERT(rc == 0); 1420 reg = TAILQ_FIRST(&ns.registrants); 1421 SPDK_CU_ASSERT_FATAL(reg != NULL); 1422 CU_ASSERT(ns.gen == 1); 1423 CU_ASSERT(reg->rkey == 0xa11); 1424 CU_ASSERT(!strncmp((uint8_t *)®->hostid, (uint8_t *)&ctrlr.hostid, sizeof(ctrlr.hostid))); 1425 1426 nvmf_ns_reservation_remove_registrant(&ns, reg); 1427 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 1428 CU_ASSERT(ns.gen == 2); 1429 } 1430 1431 static void 1432 test_nvmf_subsystem_destroy_cb(void *cb_arg) 1433 { 1434 } 1435 1436 static void 1437 test_nvmf_subsystem_add_ctrlr(void) 1438 { 1439 int rc; 1440 struct spdk_nvmf_ctrlr ctrlr = {}; 1441 struct spdk_nvmf_tgt tgt = {}; 1442 char nqn[256] = "nqn.2016-06.io.spdk:subsystem1"; 1443 struct spdk_nvmf_subsystem *subsystem = NULL; 1444 1445 tgt.max_subsystems = 1024; 1446 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1447 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1448 1449 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 1450 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1451 ctrlr.subsys = subsystem; 1452 1453 ctrlr.dynamic_ctrlr = true; 1454 rc = nvmf_subsystem_add_ctrlr(subsystem, &ctrlr); 1455 CU_ASSERT(rc == 0); 1456 CU_ASSERT(!TAILQ_EMPTY(&subsystem->ctrlrs)); 1457 CU_ASSERT(ctrlr.cntlid == 1); 1458 CU_ASSERT(nvmf_subsystem_get_ctrlr(subsystem, 1) == &ctrlr); 1459 1460 nvmf_subsystem_remove_ctrlr(subsystem, &ctrlr); 1461 CU_ASSERT(TAILQ_EMPTY(&subsystem->ctrlrs)); 1462 rc = spdk_nvmf_subsystem_destroy(subsystem, test_nvmf_subsystem_destroy_cb, NULL); 1463 CU_ASSERT(rc == 0); 1464 free(tgt.subsystems); 1465 } 1466 1467 static void 1468 test_spdk_nvmf_subsystem_add_host(void) 1469 { 1470 struct spdk_nvmf_tgt tgt = {}; 1471 struct spdk_nvmf_subsystem *subsystem = NULL; 1472 int rc; 1473 const char hostnqn[] = "nqn.2016-06.io.spdk:host1"; 1474 const char subsystemnqn[] = "nqn.2016-06.io.spdk:subsystem1"; 1475 1476 tgt.max_subsystems = 1024; 1477 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1478 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1479 1480 subsystem = spdk_nvmf_subsystem_create(&tgt, subsystemnqn, SPDK_NVMF_SUBTYPE_NVME, 0); 1481 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1482 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, subsystemnqn); 1483 1484 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn); 1485 CU_ASSERT(rc == 0); 1486 CU_ASSERT(!TAILQ_EMPTY(&subsystem->hosts)); 1487 1488 /* Add existing nqn, this function is allowed to be called if the nqn was previously added. */ 1489 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn); 1490 CU_ASSERT(rc == 0); 1491 1492 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 1493 CU_ASSERT(rc == 0); 1494 CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts)); 1495 1496 /* No available nqn */ 1497 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 1498 CU_ASSERT(rc == -ENOENT); 1499 1500 spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 1501 free(tgt.subsystems); 1502 } 1503 1504 static void 1505 test_nvmf_ns_reservation_report(void) 1506 { 1507 struct spdk_nvmf_ns ns = {}; 1508 struct spdk_nvmf_ctrlr ctrlr = {}; 1509 struct spdk_nvmf_request req = {}; 1510 union nvmf_h2c_msg cmd = {}; 1511 union nvmf_c2h_msg rsp = {}; 1512 struct spdk_nvme_registered_ctrlr_extended_data *ctrlr_data; 1513 struct spdk_nvme_reservation_status_extended_data *status_data; 1514 struct spdk_nvmf_registrant *reg; 1515 1516 req.length = sizeof(*status_data) + sizeof(*ctrlr_data) * 2; 1517 req.data = calloc(1, req.length); 1518 reg = calloc(2, sizeof(struct spdk_nvmf_registrant)); 1519 SPDK_CU_ASSERT_FATAL(req.data != NULL && reg != NULL); 1520 1521 spdk_iov_one(req.iov, &req.iovcnt, req.data, req.length); 1522 1523 req.cmd = &cmd; 1524 req.rsp = &rsp; 1525 ns.gen = 1; 1526 ns.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE; 1527 ns.ptpl_activated = true; 1528 cmd.nvme_cmd.cdw11_bits.resv_report.eds = true; 1529 cmd.nvme_cmd.cdw10 = 100; 1530 reg[0].rkey = 0xa; 1531 reg[1].rkey = 0xb; 1532 spdk_uuid_generate(®[0].hostid); 1533 spdk_uuid_generate(®[1].hostid); 1534 TAILQ_INIT(&ns.registrants); 1535 TAILQ_INSERT_TAIL(&ns.registrants, ®[0], link); 1536 TAILQ_INSERT_TAIL(&ns.registrants, ®[1], link); 1537 1538 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1539 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1540 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 1541 /* Get ctrlr data and status data pointers */ 1542 ctrlr_data = (void *)((uint64_t)req.data + sizeof(*status_data)); 1543 status_data = (void *)req.data; 1544 SPDK_CU_ASSERT_FATAL(status_data != NULL && ctrlr_data != NULL); 1545 CU_ASSERT(status_data->data.gen == 1); 1546 CU_ASSERT(status_data->data.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1547 CU_ASSERT(status_data->data.ptpls == true); 1548 CU_ASSERT(status_data->data.regctl == 2); 1549 CU_ASSERT(ctrlr_data->cntlid == 0xffff); 1550 CU_ASSERT(ctrlr_data->rcsts.status == false); 1551 CU_ASSERT(ctrlr_data->rkey == 0xa); 1552 CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, ®[0].hostid)); 1553 /* Check second ctrlr data */ 1554 ctrlr_data++; 1555 CU_ASSERT(ctrlr_data->cntlid == 0xffff); 1556 CU_ASSERT(ctrlr_data->rcsts.status == false); 1557 CU_ASSERT(ctrlr_data->rkey == 0xb); 1558 CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, ®[1].hostid)); 1559 1560 /* extended controller data structure */ 1561 spdk_iov_memset(req.iov, req.iovcnt, 0); 1562 memset(req.rsp, 0, sizeof(*req.rsp)); 1563 cmd.nvme_cmd.cdw11_bits.resv_report.eds = false; 1564 1565 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1566 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT); 1567 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1568 1569 /* Transfer length invalid */ 1570 spdk_iov_memset(req.iov, req.iovcnt, 0); 1571 memset(req.rsp, 0, sizeof(*req.rsp)); 1572 cmd.nvme_cmd.cdw11_bits.resv_report.eds = true; 1573 cmd.nvme_cmd.cdw10 = 0; 1574 1575 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1576 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR); 1577 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1578 1579 free(req.data); 1580 free(reg); 1581 } 1582 1583 static void 1584 test_nvmf_valid_nqn(void) 1585 { 1586 bool rc; 1587 char uuid[SPDK_NVMF_UUID_STRING_LEN + 1] = {}; 1588 char nqn[SPDK_NVMF_NQN_MAX_LEN + 1] = {}; 1589 struct spdk_uuid s_uuid = {}; 1590 1591 spdk_uuid_generate(&s_uuid); 1592 uuid_unparse((void *)&s_uuid, uuid); 1593 1594 /* discovery nqn */ 1595 snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_DISCOVERY_NQN); 1596 1597 rc = nvmf_valid_nqn(nqn); 1598 CU_ASSERT(rc == true); 1599 1600 /* nqn with uuid */ 1601 memset(nqn, 0xff, sizeof(nqn)); 1602 snprintf(nqn, sizeof(nqn), "%s%s", SPDK_NVMF_NQN_UUID_PRE, uuid); 1603 1604 rc = nvmf_valid_nqn(nqn); 1605 CU_ASSERT(rc == true); 1606 1607 /* Check nqn valid reverse domain */ 1608 memset(nqn, 0xff, sizeof(nqn)); 1609 snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io.spdk:cnode1"); 1610 1611 rc = nvmf_valid_nqn(nqn); 1612 CU_ASSERT(rc == true); 1613 1614 /* Invalid nqn length */ 1615 memset(nqn, 0xff, sizeof(nqn)); 1616 snprintf(nqn, sizeof(nqn), "%s", "nqn."); 1617 1618 rc = nvmf_valid_nqn(nqn); 1619 CU_ASSERT(rc == false); 1620 1621 /* Copy uuid to the nqn string, but omit the last character to make it invalid */ 1622 memset(nqn, 0, SPDK_NVMF_NQN_MAX_LEN + 1); 1623 snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_NQN_UUID_PRE); 1624 memcpy(&nqn[SPDK_NVMF_NQN_UUID_PRE_LEN], uuid, SPDK_NVMF_UUID_STRING_LEN - 1); 1625 1626 rc = nvmf_valid_nqn(nqn); 1627 CU_ASSERT(rc == false); 1628 1629 /* Invalid domain */ 1630 memset(nqn, 0xff, SPDK_NVMF_NQN_MAX_LEN + 1); 1631 snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io...spdk:cnode1"); 1632 1633 rc = nvmf_valid_nqn(nqn); 1634 CU_ASSERT(rc == false); 1635 } 1636 1637 static void 1638 test_nvmf_ns_reservation_restore(void) 1639 { 1640 struct spdk_nvmf_ns ns = {}; 1641 struct spdk_nvmf_reservation_info info = {}; 1642 struct spdk_bdev bdev = {}; 1643 struct spdk_uuid s_uuid = {}; 1644 struct spdk_nvmf_registrant *reg0, *reg1; 1645 char uuid[SPDK_UUID_STRING_LEN] = {}; 1646 int rc; 1647 1648 ns.bdev = &bdev; 1649 TAILQ_INIT(&ns.registrants); 1650 info.ptpl_activated = true; 1651 info.num_regs = 2; 1652 info.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS; 1653 info.registrants[0].rkey = 0xb; 1654 info.registrants[1].rkey = 0xc; 1655 1656 /* Generate and prepare uuids, make sure bdev and info uuid are the same */ 1657 spdk_uuid_generate(&s_uuid); 1658 uuid_unparse((void *)&s_uuid, uuid); 1659 snprintf(info.holder_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1660 snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1661 snprintf(info.registrants[0].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1662 spdk_uuid_copy(&bdev.uuid, &s_uuid); 1663 spdk_uuid_generate(&s_uuid); 1664 uuid_unparse((void *)&s_uuid, uuid); 1665 snprintf(info.registrants[1].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1666 1667 /* info->rkey not exist in registrants */ 1668 info.crkey = 0xa; 1669 1670 rc = nvmf_ns_reservation_restore(&ns, &info); 1671 CU_ASSERT(rc == -EINVAL); 1672 1673 /* info->rkey exists in registrants */ 1674 info.crkey = 0xb; 1675 1676 rc = nvmf_ns_reservation_restore(&ns, &info); 1677 CU_ASSERT(rc == 0); 1678 CU_ASSERT(ns.crkey == 0xb); 1679 CU_ASSERT(ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1680 CU_ASSERT(ns.ptpl_activated == true); 1681 /* Check two registrant`s rkey */ 1682 reg0 = TAILQ_FIRST(&ns.registrants); 1683 reg1 = TAILQ_NEXT(reg0, link); 1684 CU_ASSERT(ns.holder == reg0); 1685 CU_ASSERT(reg0->rkey = 0xb); 1686 CU_ASSERT(reg1->rkey = 0xc); 1687 1688 rc = nvmf_ns_reservation_clear_all_registrants(&ns); 1689 CU_ASSERT(rc == 2); 1690 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 1691 1692 /* Existing bdev UUID is different with configuration */ 1693 spdk_uuid_generate(&s_uuid); 1694 uuid_unparse((void *)&s_uuid, uuid); 1695 snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1696 spdk_uuid_generate(&s_uuid); 1697 spdk_uuid_copy(&bdev.uuid, &s_uuid); 1698 1699 rc = nvmf_ns_reservation_restore(&ns, &info); 1700 CU_ASSERT(rc == -EINVAL); 1701 } 1702 1703 static void 1704 test_nvmf_subsystem_state_change(void) 1705 { 1706 struct spdk_nvmf_tgt tgt = {}; 1707 struct spdk_nvmf_subsystem *subsystem, *discovery_subsystem; 1708 int rc; 1709 1710 tgt.max_subsystems = 1024; 1711 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1712 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1713 1714 discovery_subsystem = spdk_nvmf_subsystem_create(&tgt, SPDK_NVMF_DISCOVERY_NQN, 1715 SPDK_NVMF_SUBTYPE_DISCOVERY, 0); 1716 SPDK_CU_ASSERT_FATAL(discovery_subsystem != NULL); 1717 subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", 1718 SPDK_NVMF_SUBTYPE_NVME, 0); 1719 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1720 1721 spdk_io_device_register(&tgt, 1722 nvmf_tgt_create_poll_group, 1723 nvmf_tgt_destroy_poll_group, 1724 sizeof(struct spdk_nvmf_poll_group), 1725 NULL); 1726 1727 rc = spdk_nvmf_subsystem_start(discovery_subsystem, NULL, NULL); 1728 CU_ASSERT(rc == 0); 1729 poll_threads(); 1730 CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); 1731 rc = spdk_nvmf_subsystem_start(subsystem, NULL, NULL); 1732 CU_ASSERT(rc == 0); 1733 poll_threads(); 1734 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); 1735 1736 rc = spdk_nvmf_subsystem_pause(subsystem, SPDK_NVME_GLOBAL_NS_TAG, NULL, NULL); 1737 CU_ASSERT(rc == 0); 1738 rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL); 1739 CU_ASSERT(rc == -EBUSY); 1740 poll_threads(); 1741 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED); 1742 1743 rc = spdk_nvmf_subsystem_stop(discovery_subsystem, NULL, NULL); 1744 CU_ASSERT(rc == 0); 1745 poll_threads(); 1746 CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 1747 rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL); 1748 CU_ASSERT(rc == 0); 1749 poll_threads(); 1750 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 1751 1752 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 1753 CU_ASSERT(rc == 0); 1754 rc = spdk_nvmf_subsystem_destroy(discovery_subsystem, NULL, NULL); 1755 CU_ASSERT(rc == 0); 1756 1757 spdk_io_device_unregister(&tgt, NULL); 1758 poll_threads(); 1759 1760 free(tgt.subsystems); 1761 } 1762 1763 int 1764 main(int argc, char **argv) 1765 { 1766 CU_pSuite suite = NULL; 1767 unsigned int num_failures; 1768 1769 CU_set_error_action(CUEA_ABORT); 1770 CU_initialize_registry(); 1771 1772 suite = CU_add_suite("nvmf", NULL, NULL); 1773 1774 CU_ADD_TEST(suite, nvmf_test_create_subsystem); 1775 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_ns); 1776 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_set_sn); 1777 CU_ADD_TEST(suite, test_reservation_register); 1778 CU_ADD_TEST(suite, test_reservation_register_with_ptpl); 1779 CU_ADD_TEST(suite, test_reservation_acquire_preempt_1); 1780 CU_ADD_TEST(suite, test_reservation_acquire_release_with_ptpl); 1781 CU_ADD_TEST(suite, test_reservation_release); 1782 CU_ADD_TEST(suite, test_reservation_unregister_notification); 1783 CU_ADD_TEST(suite, test_reservation_release_notification); 1784 CU_ADD_TEST(suite, test_reservation_release_notification_write_exclusive); 1785 CU_ADD_TEST(suite, test_reservation_clear_notification); 1786 CU_ADD_TEST(suite, test_reservation_preempt_notification); 1787 CU_ADD_TEST(suite, test_spdk_nvmf_ns_event); 1788 CU_ADD_TEST(suite, test_nvmf_ns_reservation_add_remove_registrant); 1789 CU_ADD_TEST(suite, test_nvmf_subsystem_add_ctrlr); 1790 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_host); 1791 CU_ADD_TEST(suite, test_nvmf_ns_reservation_report); 1792 CU_ADD_TEST(suite, test_nvmf_valid_nqn); 1793 CU_ADD_TEST(suite, test_nvmf_ns_reservation_restore); 1794 CU_ADD_TEST(suite, test_nvmf_subsystem_state_change); 1795 1796 allocate_threads(1); 1797 set_thread(0); 1798 1799 CU_basic_set_mode(CU_BRM_VERBOSE); 1800 CU_basic_run_tests(); 1801 num_failures = CU_get_number_of_failures(); 1802 CU_cleanup_registry(); 1803 1804 free_threads(); 1805 1806 return num_failures; 1807 } 1808