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 req->data = calloc(1, length); 595 assert(req->data != NULL); 596 req->length = length; 597 598 req->cmd = (union nvmf_h2c_msg *)calloc(1, sizeof(union nvmf_h2c_msg)); 599 assert(req->cmd != NULL); 600 601 req->rsp = (union nvmf_c2h_msg *)calloc(1, sizeof(union nvmf_c2h_msg)); 602 assert(req->rsp != NULL); 603 604 return req; 605 } 606 607 static void 608 ut_reservation_free_req(struct spdk_nvmf_request *req) 609 { 610 free(req->cmd); 611 free(req->rsp); 612 free(req->data); 613 free(req); 614 } 615 616 static void 617 ut_reservation_build_register_request(struct spdk_nvmf_request *req, 618 uint8_t rrega, uint8_t iekey, 619 uint8_t cptpl, uint64_t crkey, 620 uint64_t nrkey) 621 { 622 struct spdk_nvme_reservation_register_data key; 623 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 624 625 key.crkey = crkey; 626 key.nrkey = nrkey; 627 cmd->cdw10 = 0; 628 cmd->cdw10_bits.resv_register.rrega = rrega; 629 cmd->cdw10_bits.resv_register.iekey = iekey; 630 cmd->cdw10_bits.resv_register.cptpl = cptpl; 631 memcpy(req->data, &key, sizeof(key)); 632 } 633 634 static void 635 ut_reservation_build_acquire_request(struct spdk_nvmf_request *req, 636 uint8_t racqa, uint8_t iekey, 637 uint8_t rtype, uint64_t crkey, 638 uint64_t prkey) 639 { 640 struct spdk_nvme_reservation_acquire_data key; 641 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 642 643 key.crkey = crkey; 644 key.prkey = prkey; 645 cmd->cdw10 = 0; 646 cmd->cdw10_bits.resv_acquire.racqa = racqa; 647 cmd->cdw10_bits.resv_acquire.iekey = iekey; 648 cmd->cdw10_bits.resv_acquire.rtype = rtype; 649 memcpy(req->data, &key, sizeof(key)); 650 } 651 652 static void 653 ut_reservation_build_release_request(struct spdk_nvmf_request *req, 654 uint8_t rrela, uint8_t iekey, 655 uint8_t rtype, uint64_t crkey) 656 { 657 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 658 659 cmd->cdw10 = 0; 660 cmd->cdw10_bits.resv_release.rrela = rrela; 661 cmd->cdw10_bits.resv_release.iekey = iekey; 662 cmd->cdw10_bits.resv_release.rtype = rtype; 663 memcpy(req->data, &crkey, sizeof(crkey)); 664 } 665 666 /* 667 * Construct four registrants for other test cases. 668 * 669 * g_ctrlr1_A register with key 0xa1. 670 * g_ctrlr2_A register with key 0xa1. 671 * g_ctrlr_B register with key 0xb1. 672 * g_ctrlr_C register with key 0xc1. 673 * */ 674 static void 675 ut_reservation_build_registrants(void) 676 { 677 struct spdk_nvmf_request *req; 678 struct spdk_nvme_cpl *rsp; 679 struct spdk_nvmf_registrant *reg; 680 uint32_t gen; 681 682 req = ut_reservation_build_req(16); 683 rsp = &req->rsp->nvme_cpl; 684 SPDK_CU_ASSERT_FATAL(req != NULL); 685 gen = g_ns.gen; 686 687 /* TEST CASE: g_ctrlr1_A register with a new key */ 688 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 689 0, 0, 0, 0xa1); 690 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 691 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 692 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 693 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1); 694 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 1); 695 696 /* TEST CASE: g_ctrlr2_A register with a new key, because it has same 697 * Host Identifier with g_ctrlr1_A, so the register key should same. 698 */ 699 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 700 0, 0, 0, 0xa2); 701 nvmf_ns_reservation_register(&g_ns, &g_ctrlr2_A, req); 702 /* Reservation conflict for other key than 0xa1 */ 703 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 704 705 /* g_ctrlr_B register with a new key */ 706 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 707 0, 0, 0, 0xb1); 708 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 709 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 710 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 711 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb1); 712 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 2); 713 714 /* g_ctrlr_C register with a new key */ 715 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 716 0, 0, 0, 0xc1); 717 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 718 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 719 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 720 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc1); 721 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 3); 722 723 ut_reservation_free_req(req); 724 } 725 726 static void 727 test_reservation_register(void) 728 { 729 struct spdk_nvmf_request *req; 730 struct spdk_nvme_cpl *rsp; 731 struct spdk_nvmf_registrant *reg; 732 uint32_t gen; 733 734 ut_reservation_init(); 735 736 req = ut_reservation_build_req(16); 737 rsp = &req->rsp->nvme_cpl; 738 SPDK_CU_ASSERT_FATAL(req != NULL); 739 740 ut_reservation_build_registrants(); 741 742 /* TEST CASE: Replace g_ctrlr1_A with a new key */ 743 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 744 0, 0, 0xa1, 0xa11); 745 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 746 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 747 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 748 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa11); 749 750 /* TEST CASE: Host A with g_ctrlr1_A get reservation with 751 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 752 */ 753 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 754 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xa11, 0x0); 755 gen = g_ns.gen; 756 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 757 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 758 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 759 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 760 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa11); 761 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 762 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 763 764 /* TEST CASE: g_ctrlr_C unregister with IEKEY enabled */ 765 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 766 1, 0, 0, 0); 767 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 768 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 769 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 770 SPDK_CU_ASSERT_FATAL(reg == NULL); 771 772 /* TEST CASE: g_ctrlr_B unregister with correct key */ 773 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 774 0, 0, 0xb1, 0); 775 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 776 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 777 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 778 SPDK_CU_ASSERT_FATAL(reg == NULL); 779 780 /* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY disabled */ 781 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 782 0, 0, 0, 0xb1); 783 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 784 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 785 786 /* TEST CASE: No registrant now, g_ctrlr_B replace new key with IEKEY enabled */ 787 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 788 1, 0, 0, 0xb1); 789 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 790 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 791 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 792 SPDK_CU_ASSERT_FATAL(reg != NULL); 793 794 /* TEST CASE: g_ctrlr_B replace new key with IEKEY enabled and wrong crkey */ 795 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 796 1, 0, 0xff, 0xb2); 797 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 798 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 799 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 800 SPDK_CU_ASSERT_FATAL(reg != NULL); 801 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb2); 802 803 /* TEST CASE: g_ctrlr1_A unregister with correct key, 804 * reservation should be removed as well. 805 */ 806 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 807 0, 0, 0xa11, 0); 808 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 809 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 810 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 811 SPDK_CU_ASSERT_FATAL(reg == NULL); 812 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 813 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 814 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 815 816 ut_reservation_free_req(req); 817 ut_reservation_deinit(); 818 } 819 820 static void 821 test_reservation_register_with_ptpl(void) 822 { 823 struct spdk_nvmf_request *req; 824 struct spdk_nvme_cpl *rsp; 825 struct spdk_nvmf_registrant *reg; 826 bool update_sgroup = false; 827 int rc; 828 struct spdk_nvmf_reservation_info info; 829 830 ut_reservation_init(); 831 832 req = ut_reservation_build_req(16); 833 rsp = &req->rsp->nvme_cpl; 834 SPDK_CU_ASSERT_FATAL(req != NULL); 835 836 /* TEST CASE: No persistent file, register with PTPL enabled will fail */ 837 g_ns.ptpl_file = NULL; 838 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 839 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 840 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 841 SPDK_CU_ASSERT_FATAL(update_sgroup == false); 842 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 843 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 844 SPDK_CU_ASSERT_FATAL(reg == NULL); 845 846 /* TEST CASE: Enable PTPL */ 847 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 848 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 849 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 850 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 851 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 852 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 853 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 854 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 855 SPDK_CU_ASSERT_FATAL(reg != NULL); 856 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 857 /* Load reservation information from configuration file */ 858 memset(&info, 0, sizeof(info)); 859 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 860 SPDK_CU_ASSERT_FATAL(rc == 0); 861 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 862 863 /* TEST CASE: Disable PTPL */ 864 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 865 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 866 SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON, 0, 0xa1); 867 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 868 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 869 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 870 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == false); 871 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 872 SPDK_CU_ASSERT_FATAL(rc < 0); 873 unlink(g_ns.ptpl_file); 874 875 ut_reservation_free_req(req); 876 ut_reservation_deinit(); 877 } 878 879 static void 880 test_reservation_acquire_preempt_1(void) 881 { 882 struct spdk_nvmf_request *req; 883 struct spdk_nvme_cpl *rsp; 884 struct spdk_nvmf_registrant *reg; 885 uint32_t gen; 886 887 ut_reservation_init(); 888 889 req = ut_reservation_build_req(16); 890 rsp = &req->rsp->nvme_cpl; 891 SPDK_CU_ASSERT_FATAL(req != NULL); 892 893 ut_reservation_build_registrants(); 894 895 gen = g_ns.gen; 896 /* ACQUIRE: Host A with g_ctrlr1_A acquire reservation with 897 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE. 898 */ 899 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 900 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 901 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 902 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 903 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 904 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 905 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa1); 906 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 907 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 908 909 /* TEST CASE: g_ctrlr1_A holds the reservation, g_ctrlr_B preempt g_ctrl1_A, 910 * g_ctrl1_A registrant is unregistered. 911 */ 912 gen = g_ns.gen; 913 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 914 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1, 0xa1); 915 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 916 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 917 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 918 SPDK_CU_ASSERT_FATAL(reg == NULL); 919 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 920 SPDK_CU_ASSERT_FATAL(reg != NULL); 921 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 922 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 923 SPDK_CU_ASSERT_FATAL(reg != NULL); 924 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 925 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 926 927 /* TEST CASE: g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B 928 * with valid key and PRKEY set to 0, all registrants other the host that issued 929 * the command are unregistered. 930 */ 931 gen = g_ns.gen; 932 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 933 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0x0); 934 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 935 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 936 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 937 SPDK_CU_ASSERT_FATAL(reg == NULL); 938 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 939 SPDK_CU_ASSERT_FATAL(reg == NULL); 940 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 941 SPDK_CU_ASSERT_FATAL(reg != NULL); 942 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 943 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 944 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 945 946 ut_reservation_free_req(req); 947 ut_reservation_deinit(); 948 } 949 950 static void 951 test_reservation_acquire_release_with_ptpl(void) 952 { 953 struct spdk_nvmf_request *req; 954 struct spdk_nvme_cpl *rsp; 955 struct spdk_nvmf_registrant *reg; 956 bool update_sgroup = false; 957 struct spdk_uuid holder_uuid; 958 int rc; 959 struct spdk_nvmf_reservation_info info; 960 961 ut_reservation_init(); 962 963 req = ut_reservation_build_req(16); 964 rsp = &req->rsp->nvme_cpl; 965 SPDK_CU_ASSERT_FATAL(req != NULL); 966 967 /* TEST CASE: Enable PTPL */ 968 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 969 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 970 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 971 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 972 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 973 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 974 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 975 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 976 SPDK_CU_ASSERT_FATAL(reg != NULL); 977 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 978 /* Load reservation information from configuration file */ 979 memset(&info, 0, sizeof(info)); 980 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 981 SPDK_CU_ASSERT_FATAL(rc == 0); 982 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 983 984 /* TEST CASE: Acquire the reservation */ 985 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 986 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 987 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 988 update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 989 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 990 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 991 memset(&info, 0, sizeof(info)); 992 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 993 SPDK_CU_ASSERT_FATAL(rc == 0); 994 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 995 SPDK_CU_ASSERT_FATAL(info.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 996 SPDK_CU_ASSERT_FATAL(info.crkey == 0xa1); 997 spdk_uuid_parse(&holder_uuid, info.holder_uuid); 998 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &holder_uuid)); 999 1000 /* TEST CASE: Release the reservation */ 1001 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 1002 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1003 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1); 1004 update_sgroup = nvmf_ns_reservation_release(&g_ns, &g_ctrlr1_A, req); 1005 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 1006 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1007 memset(&info, 0, sizeof(info)); 1008 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 1009 SPDK_CU_ASSERT_FATAL(rc == 0); 1010 SPDK_CU_ASSERT_FATAL(info.rtype == 0); 1011 SPDK_CU_ASSERT_FATAL(info.crkey == 0); 1012 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 1013 unlink(g_ns.ptpl_file); 1014 1015 ut_reservation_free_req(req); 1016 ut_reservation_deinit(); 1017 } 1018 1019 static void 1020 test_reservation_release(void) 1021 { 1022 struct spdk_nvmf_request *req; 1023 struct spdk_nvme_cpl *rsp; 1024 struct spdk_nvmf_registrant *reg; 1025 1026 ut_reservation_init(); 1027 1028 req = ut_reservation_build_req(16); 1029 rsp = &req->rsp->nvme_cpl; 1030 SPDK_CU_ASSERT_FATAL(req != NULL); 1031 1032 ut_reservation_build_registrants(); 1033 1034 /* ACQUIRE: Host A with g_ctrlr1_A get reservation with 1035 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS 1036 */ 1037 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1038 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xa1, 0x0); 1039 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 1040 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1041 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1042 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1043 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1044 1045 /* Test Case: Host B release the reservation */ 1046 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1047 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1); 1048 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1049 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1050 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1051 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 1052 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 1053 1054 /* Test Case: Host C clear the registrants */ 1055 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1056 0, 0xc1); 1057 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_C, req); 1058 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1059 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1060 SPDK_CU_ASSERT_FATAL(reg == NULL); 1061 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 1062 SPDK_CU_ASSERT_FATAL(reg == NULL); 1063 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1064 SPDK_CU_ASSERT_FATAL(reg == NULL); 1065 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1066 SPDK_CU_ASSERT_FATAL(reg == NULL); 1067 1068 ut_reservation_free_req(req); 1069 ut_reservation_deinit(); 1070 } 1071 1072 void 1073 nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr, 1074 struct spdk_nvmf_ns *ns, 1075 enum spdk_nvme_reservation_notification_log_page_type type) 1076 { 1077 ctrlr->num_avail_log_pages++; 1078 } 1079 1080 static void 1081 test_reservation_unregister_notification(void) 1082 { 1083 struct spdk_nvmf_request *req; 1084 struct spdk_nvme_cpl *rsp; 1085 1086 ut_reservation_init(); 1087 1088 req = ut_reservation_build_req(16); 1089 SPDK_CU_ASSERT_FATAL(req != NULL); 1090 rsp = &req->rsp->nvme_cpl; 1091 1092 ut_reservation_build_registrants(); 1093 1094 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1095 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1096 */ 1097 rsp->status.sc = 0xff; 1098 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1099 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1100 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1101 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1102 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1103 1104 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B unregister the registration. 1105 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C only for 1106 * SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY or SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY 1107 * type. 1108 */ 1109 rsp->status.sc = 0xff; 1110 g_ctrlr1_A.num_avail_log_pages = 0; 1111 g_ctrlr2_A.num_avail_log_pages = 0; 1112 g_ctrlr_B.num_avail_log_pages = 5; 1113 g_ctrlr_C.num_avail_log_pages = 0; 1114 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1115 0, 0, 0xb1, 0); 1116 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1117 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1118 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1119 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1120 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1121 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1122 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1123 1124 ut_reservation_free_req(req); 1125 ut_reservation_deinit(); 1126 } 1127 1128 static void 1129 test_reservation_release_notification(void) 1130 { 1131 struct spdk_nvmf_request *req; 1132 struct spdk_nvme_cpl *rsp; 1133 1134 ut_reservation_init(); 1135 1136 req = ut_reservation_build_req(16); 1137 SPDK_CU_ASSERT_FATAL(req != NULL); 1138 rsp = &req->rsp->nvme_cpl; 1139 1140 ut_reservation_build_registrants(); 1141 1142 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1143 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1144 */ 1145 rsp->status.sc = 0xff; 1146 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1147 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1148 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1149 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1150 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1151 1152 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1153 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1154 */ 1155 rsp->status.sc = 0xff; 1156 g_ctrlr1_A.num_avail_log_pages = 0; 1157 g_ctrlr2_A.num_avail_log_pages = 0; 1158 g_ctrlr_B.num_avail_log_pages = 5; 1159 g_ctrlr_C.num_avail_log_pages = 0; 1160 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1161 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1); 1162 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1163 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1164 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1165 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1166 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1167 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1168 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1169 1170 ut_reservation_free_req(req); 1171 ut_reservation_deinit(); 1172 } 1173 1174 static void 1175 test_reservation_release_notification_write_exclusive(void) 1176 { 1177 struct spdk_nvmf_request *req; 1178 struct spdk_nvme_cpl *rsp; 1179 1180 ut_reservation_init(); 1181 1182 req = ut_reservation_build_req(16); 1183 SPDK_CU_ASSERT_FATAL(req != NULL); 1184 rsp = &req->rsp->nvme_cpl; 1185 1186 ut_reservation_build_registrants(); 1187 1188 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1189 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 1190 */ 1191 rsp->status.sc = 0xff; 1192 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1193 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1, 0x0); 1194 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1195 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1196 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1197 1198 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1199 * Because the reservation type is SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 1200 * no reservation notification occurs. 1201 */ 1202 rsp->status.sc = 0xff; 1203 g_ctrlr1_A.num_avail_log_pages = 5; 1204 g_ctrlr2_A.num_avail_log_pages = 5; 1205 g_ctrlr_B.num_avail_log_pages = 5; 1206 g_ctrlr_C.num_avail_log_pages = 5; 1207 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1208 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1); 1209 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1210 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1211 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1212 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr1_A.num_avail_log_pages); 1213 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr2_A.num_avail_log_pages); 1214 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1215 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1216 1217 ut_reservation_free_req(req); 1218 ut_reservation_deinit(); 1219 } 1220 1221 static void 1222 test_reservation_clear_notification(void) 1223 { 1224 struct spdk_nvmf_request *req; 1225 struct spdk_nvme_cpl *rsp; 1226 1227 ut_reservation_init(); 1228 1229 req = ut_reservation_build_req(16); 1230 SPDK_CU_ASSERT_FATAL(req != NULL); 1231 rsp = &req->rsp->nvme_cpl; 1232 1233 ut_reservation_build_registrants(); 1234 1235 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1236 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1237 */ 1238 rsp->status.sc = 0xff; 1239 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1240 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1241 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1242 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1243 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1244 1245 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B clear the reservation. 1246 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1247 */ 1248 rsp->status.sc = 0xff; 1249 g_ctrlr1_A.num_avail_log_pages = 0; 1250 g_ctrlr2_A.num_avail_log_pages = 0; 1251 g_ctrlr_B.num_avail_log_pages = 5; 1252 g_ctrlr_C.num_avail_log_pages = 0; 1253 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1254 0, 0xb1); 1255 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1256 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1257 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1258 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1259 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1260 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1261 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1262 1263 ut_reservation_free_req(req); 1264 ut_reservation_deinit(); 1265 } 1266 1267 static void 1268 test_reservation_preempt_notification(void) 1269 { 1270 struct spdk_nvmf_request *req; 1271 struct spdk_nvme_cpl *rsp; 1272 1273 ut_reservation_init(); 1274 1275 req = ut_reservation_build_req(16); 1276 SPDK_CU_ASSERT_FATAL(req != NULL); 1277 rsp = &req->rsp->nvme_cpl; 1278 1279 ut_reservation_build_registrants(); 1280 1281 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1282 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1283 */ 1284 rsp->status.sc = 0xff; 1285 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1286 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1287 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1288 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1289 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1290 1291 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B, 1292 * g_ctrlr_B registrant is unregistered, and reservation is preempted. 1293 * Registration Preempted notification sends to g_ctrlr_B. 1294 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A. 1295 */ 1296 rsp->status.sc = 0xff; 1297 g_ctrlr1_A.num_avail_log_pages = 0; 1298 g_ctrlr2_A.num_avail_log_pages = 0; 1299 g_ctrlr_B.num_avail_log_pages = 0; 1300 g_ctrlr_C.num_avail_log_pages = 5; 1301 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 1302 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0xb1); 1303 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 1304 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1305 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1306 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1307 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1308 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_B.num_avail_log_pages); 1309 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1310 1311 ut_reservation_free_req(req); 1312 ut_reservation_deinit(); 1313 } 1314 1315 static int 1316 nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf) 1317 { 1318 return 0; 1319 } 1320 1321 static void 1322 nvmf_tgt_destroy_poll_group(void *io_device, void *ctx_buf) 1323 { 1324 } 1325 1326 static void 1327 test_spdk_nvmf_ns_event(void) 1328 { 1329 struct spdk_nvmf_tgt tgt = {}; 1330 struct spdk_nvmf_subsystem subsystem = { 1331 .max_nsid = 1024, 1332 .ns = NULL, 1333 .tgt = &tgt, 1334 }; 1335 struct spdk_nvmf_ctrlr ctrlr = { 1336 .subsys = &subsystem 1337 }; 1338 struct spdk_nvmf_ns_opts ns_opts; 1339 uint32_t nsid; 1340 struct spdk_bdev *bdev; 1341 1342 subsystem.ns = calloc(subsystem.max_nsid, sizeof(struct spdk_nvmf_subsystem_ns *)); 1343 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 1344 subsystem.ana_group = calloc(subsystem.max_nsid, sizeof(uint32_t)); 1345 SPDK_CU_ASSERT_FATAL(subsystem.ana_group != NULL); 1346 1347 tgt.max_subsystems = 1024; 1348 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1349 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1350 1351 spdk_io_device_register(&tgt, 1352 nvmf_tgt_create_poll_group, 1353 nvmf_tgt_destroy_poll_group, 1354 sizeof(struct spdk_nvmf_poll_group), 1355 NULL); 1356 1357 /* Add one namespace */ 1358 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 1359 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL); 1360 CU_ASSERT(nsid == 1); 1361 CU_ASSERT(NULL != subsystem.ns[0]); 1362 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]); 1363 1364 bdev = subsystem.ns[nsid - 1]->bdev; 1365 1366 /* Add one controller */ 1367 TAILQ_INIT(&subsystem.ctrlrs); 1368 TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlr, link); 1369 1370 /* Namespace resize event */ 1371 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1372 g_ns_changed_nsid = 0xFFFFFFFF; 1373 g_ns_changed_ctrlr = NULL; 1374 nvmf_ns_event(SPDK_BDEV_EVENT_RESIZE, bdev, subsystem.ns[0]); 1375 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1376 1377 poll_threads(); 1378 CU_ASSERT(1 == g_ns_changed_nsid); 1379 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1380 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1381 1382 /* Namespace remove event */ 1383 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1384 g_ns_changed_nsid = 0xFFFFFFFF; 1385 g_ns_changed_ctrlr = NULL; 1386 nvmf_ns_event(SPDK_BDEV_EVENT_REMOVE, bdev, subsystem.ns[0]); 1387 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1388 CU_ASSERT(0xFFFFFFFF == g_ns_changed_nsid); 1389 CU_ASSERT(NULL == g_ns_changed_ctrlr); 1390 1391 poll_threads(); 1392 CU_ASSERT(1 == g_ns_changed_nsid); 1393 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1394 CU_ASSERT(NULL == subsystem.ns[0]); 1395 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1396 1397 spdk_io_device_unregister(&tgt, NULL); 1398 1399 poll_threads(); 1400 1401 free(subsystem.ns); 1402 free(subsystem.ana_group); 1403 free(tgt.subsystems); 1404 } 1405 1406 static void 1407 test_nvmf_ns_reservation_add_remove_registrant(void) 1408 { 1409 struct spdk_nvmf_ns ns = {}; 1410 struct spdk_nvmf_ctrlr ctrlr = {}; 1411 struct spdk_nvmf_registrant *reg = NULL; 1412 int rc; 1413 1414 TAILQ_INIT(&ns.registrants); 1415 spdk_uuid_generate(&ctrlr.hostid); 1416 1417 rc = nvmf_ns_reservation_add_registrant(&ns, &ctrlr, 0xa11); 1418 CU_ASSERT(rc == 0); 1419 reg = TAILQ_FIRST(&ns.registrants); 1420 SPDK_CU_ASSERT_FATAL(reg != NULL); 1421 CU_ASSERT(ns.gen == 1); 1422 CU_ASSERT(reg->rkey == 0xa11); 1423 CU_ASSERT(!strncmp((uint8_t *)®->hostid, (uint8_t *)&ctrlr.hostid, sizeof(ctrlr.hostid))); 1424 1425 nvmf_ns_reservation_remove_registrant(&ns, reg); 1426 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 1427 CU_ASSERT(ns.gen == 2); 1428 } 1429 1430 static void 1431 test_nvmf_subsystem_destroy_cb(void *cb_arg) 1432 { 1433 } 1434 1435 static void 1436 test_nvmf_subsystem_add_ctrlr(void) 1437 { 1438 int rc; 1439 struct spdk_nvmf_ctrlr ctrlr = {}; 1440 struct spdk_nvmf_tgt tgt = {}; 1441 char nqn[256] = "nqn.2016-06.io.spdk:subsystem1"; 1442 struct spdk_nvmf_subsystem *subsystem = NULL; 1443 1444 tgt.max_subsystems = 1024; 1445 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1446 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1447 1448 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 1449 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1450 ctrlr.subsys = subsystem; 1451 1452 ctrlr.dynamic_ctrlr = true; 1453 rc = nvmf_subsystem_add_ctrlr(subsystem, &ctrlr); 1454 CU_ASSERT(rc == 0); 1455 CU_ASSERT(!TAILQ_EMPTY(&subsystem->ctrlrs)); 1456 CU_ASSERT(ctrlr.cntlid == 1); 1457 CU_ASSERT(nvmf_subsystem_get_ctrlr(subsystem, 1) == &ctrlr); 1458 1459 nvmf_subsystem_remove_ctrlr(subsystem, &ctrlr); 1460 CU_ASSERT(TAILQ_EMPTY(&subsystem->ctrlrs)); 1461 rc = spdk_nvmf_subsystem_destroy(subsystem, test_nvmf_subsystem_destroy_cb, NULL); 1462 CU_ASSERT(rc == 0); 1463 free(tgt.subsystems); 1464 } 1465 1466 static void 1467 test_spdk_nvmf_subsystem_add_host(void) 1468 { 1469 struct spdk_nvmf_tgt tgt = {}; 1470 struct spdk_nvmf_subsystem *subsystem = NULL; 1471 int rc; 1472 const char hostnqn[] = "nqn.2016-06.io.spdk:host1"; 1473 const char subsystemnqn[] = "nqn.2016-06.io.spdk:subsystem1"; 1474 1475 tgt.max_subsystems = 1024; 1476 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1477 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1478 1479 subsystem = spdk_nvmf_subsystem_create(&tgt, subsystemnqn, SPDK_NVMF_SUBTYPE_NVME, 0); 1480 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1481 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, subsystemnqn); 1482 1483 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn); 1484 CU_ASSERT(rc == 0); 1485 CU_ASSERT(!TAILQ_EMPTY(&subsystem->hosts)); 1486 1487 /* Add existing nqn, this function is allowed to be called if the nqn was previously added. */ 1488 rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn); 1489 CU_ASSERT(rc == 0); 1490 1491 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 1492 CU_ASSERT(rc == 0); 1493 CU_ASSERT(TAILQ_EMPTY(&subsystem->hosts)); 1494 1495 /* No available nqn */ 1496 rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 1497 CU_ASSERT(rc == -ENOENT); 1498 1499 spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 1500 free(tgt.subsystems); 1501 } 1502 1503 static void 1504 test_nvmf_ns_reservation_report(void) 1505 { 1506 struct spdk_nvmf_ns ns = {}; 1507 struct spdk_nvmf_ctrlr ctrlr = {}; 1508 struct spdk_nvmf_request req = {}; 1509 union nvmf_h2c_msg cmd = {}; 1510 union nvmf_c2h_msg rsp = {}; 1511 struct spdk_nvme_registered_ctrlr_extended_data *ctrlr_data; 1512 struct spdk_nvme_reservation_status_extended_data *status_data; 1513 struct spdk_nvmf_registrant *reg; 1514 1515 req.data = calloc(1, sizeof(*status_data) + sizeof(*ctrlr_data) * 2); 1516 reg = calloc(2, sizeof(struct spdk_nvmf_registrant)); 1517 SPDK_CU_ASSERT_FATAL(req.data != NULL && reg != NULL); 1518 1519 req.cmd = &cmd; 1520 req.rsp = &rsp; 1521 ns.gen = 1; 1522 ns.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE; 1523 ns.ptpl_activated = true; 1524 cmd.nvme_cmd.cdw11_bits.resv_report.eds = true; 1525 cmd.nvme_cmd.cdw10 = 100; 1526 reg[0].rkey = 0xa; 1527 reg[1].rkey = 0xb; 1528 spdk_uuid_generate(®[0].hostid); 1529 spdk_uuid_generate(®[1].hostid); 1530 TAILQ_INIT(&ns.registrants); 1531 TAILQ_INSERT_TAIL(&ns.registrants, ®[0], link); 1532 TAILQ_INSERT_TAIL(&ns.registrants, ®[1], link); 1533 1534 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1535 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1536 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 1537 /* Get ctrlr data and status data pointers */ 1538 ctrlr_data = (void *)((uint64_t)req.data + sizeof(*status_data)); 1539 status_data = (void *)req.data; 1540 SPDK_CU_ASSERT_FATAL(status_data != NULL && ctrlr_data != NULL); 1541 CU_ASSERT(status_data->data.gen == 1); 1542 CU_ASSERT(status_data->data.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1543 CU_ASSERT(status_data->data.ptpls == true); 1544 CU_ASSERT(status_data->data.regctl == 2); 1545 CU_ASSERT(ctrlr_data->cntlid == 0xffff); 1546 CU_ASSERT(ctrlr_data->rcsts.status == false); 1547 CU_ASSERT(ctrlr_data->rkey == 0xa); 1548 CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, ®[0].hostid)); 1549 /* Check second ctrlr data */ 1550 ctrlr_data++; 1551 CU_ASSERT(ctrlr_data->cntlid == 0xffff); 1552 CU_ASSERT(ctrlr_data->rcsts.status == false); 1553 CU_ASSERT(ctrlr_data->rkey == 0xb); 1554 CU_ASSERT(!spdk_uuid_compare((struct spdk_uuid *)ctrlr_data->hostid, ®[1].hostid)); 1555 1556 /* extended controller data structure */ 1557 memset(req.data, 0, sizeof(*status_data) + sizeof(*ctrlr_data) * 2); 1558 memset(req.rsp, 0, sizeof(*req.rsp)); 1559 cmd.nvme_cmd.cdw11_bits.resv_report.eds = false; 1560 1561 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1562 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT); 1563 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1564 1565 /* Transfer length invalid */ 1566 memset(req.data, 0, sizeof(*status_data) + sizeof(*ctrlr_data) * 2); 1567 memset(req.rsp, 0, sizeof(*req.rsp)); 1568 cmd.nvme_cmd.cdw11_bits.resv_report.eds = true; 1569 cmd.nvme_cmd.cdw10 = 0; 1570 1571 nvmf_ns_reservation_report(&ns, &ctrlr, &req); 1572 CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR); 1573 CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1574 1575 free(req.data); 1576 free(reg); 1577 } 1578 1579 static void 1580 test_nvmf_valid_nqn(void) 1581 { 1582 bool rc; 1583 char uuid[SPDK_NVMF_UUID_STRING_LEN + 1] = {}; 1584 char nqn[SPDK_NVMF_NQN_MAX_LEN + 1] = {}; 1585 struct spdk_uuid s_uuid = {}; 1586 1587 spdk_uuid_generate(&s_uuid); 1588 uuid_unparse((void *)&s_uuid, uuid); 1589 1590 /* discovery nqn */ 1591 snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_DISCOVERY_NQN); 1592 1593 rc = nvmf_valid_nqn(nqn); 1594 CU_ASSERT(rc == true); 1595 1596 /* nqn with uuid */ 1597 memset(nqn, 0xff, sizeof(nqn)); 1598 snprintf(nqn, sizeof(nqn), "%s%s", SPDK_NVMF_NQN_UUID_PRE, uuid); 1599 1600 rc = nvmf_valid_nqn(nqn); 1601 CU_ASSERT(rc == true); 1602 1603 /* Check nqn valid reverse domain */ 1604 memset(nqn, 0xff, sizeof(nqn)); 1605 snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io.spdk:cnode1"); 1606 1607 rc = nvmf_valid_nqn(nqn); 1608 CU_ASSERT(rc == true); 1609 1610 /* Invalid nqn length */ 1611 memset(nqn, 0xff, sizeof(nqn)); 1612 snprintf(nqn, sizeof(nqn), "%s", "nqn."); 1613 1614 rc = nvmf_valid_nqn(nqn); 1615 CU_ASSERT(rc == false); 1616 1617 /* Copy uuid to the nqn string, but omit the last character to make it invalid */ 1618 memset(nqn, 0, SPDK_NVMF_NQN_MAX_LEN + 1); 1619 snprintf(nqn, sizeof(nqn), "%s", SPDK_NVMF_NQN_UUID_PRE); 1620 memcpy(&nqn[SPDK_NVMF_NQN_UUID_PRE_LEN], uuid, SPDK_NVMF_UUID_STRING_LEN - 1); 1621 1622 rc = nvmf_valid_nqn(nqn); 1623 CU_ASSERT(rc == false); 1624 1625 /* Invalid domain */ 1626 memset(nqn, 0xff, SPDK_NVMF_NQN_MAX_LEN + 1); 1627 snprintf(nqn, sizeof(nqn), "%s", "nqn.2016-06.io...spdk:cnode1"); 1628 1629 rc = nvmf_valid_nqn(nqn); 1630 CU_ASSERT(rc == false); 1631 } 1632 1633 static void 1634 test_nvmf_ns_reservation_restore(void) 1635 { 1636 struct spdk_nvmf_ns ns = {}; 1637 struct spdk_nvmf_reservation_info info = {}; 1638 struct spdk_bdev bdev = {}; 1639 struct spdk_uuid s_uuid = {}; 1640 struct spdk_nvmf_registrant *reg0, *reg1; 1641 char uuid[SPDK_UUID_STRING_LEN] = {}; 1642 int rc; 1643 1644 ns.bdev = &bdev; 1645 TAILQ_INIT(&ns.registrants); 1646 info.ptpl_activated = true; 1647 info.num_regs = 2; 1648 info.rtype = SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS; 1649 info.registrants[0].rkey = 0xb; 1650 info.registrants[1].rkey = 0xc; 1651 1652 /* Generate and prepare uuids, make sure bdev and info uuid are the same */ 1653 spdk_uuid_generate(&s_uuid); 1654 uuid_unparse((void *)&s_uuid, uuid); 1655 snprintf(info.holder_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1656 snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1657 snprintf(info.registrants[0].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1658 spdk_uuid_copy(&bdev.uuid, &s_uuid); 1659 spdk_uuid_generate(&s_uuid); 1660 uuid_unparse((void *)&s_uuid, uuid); 1661 snprintf(info.registrants[1].host_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1662 1663 /* info->rkey not exist in registrants */ 1664 info.crkey = 0xa; 1665 1666 rc = nvmf_ns_reservation_restore(&ns, &info); 1667 CU_ASSERT(rc == -EINVAL); 1668 1669 /* info->rkey exists in registrants */ 1670 info.crkey = 0xb; 1671 1672 rc = nvmf_ns_reservation_restore(&ns, &info); 1673 CU_ASSERT(rc == 0); 1674 CU_ASSERT(ns.crkey == 0xb); 1675 CU_ASSERT(ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1676 CU_ASSERT(ns.ptpl_activated == true); 1677 /* Check two registrant`s rkey */ 1678 reg0 = TAILQ_FIRST(&ns.registrants); 1679 reg1 = TAILQ_NEXT(reg0, link); 1680 CU_ASSERT(ns.holder == reg0); 1681 CU_ASSERT(reg0->rkey = 0xb); 1682 CU_ASSERT(reg1->rkey = 0xc); 1683 1684 rc = nvmf_ns_reservation_clear_all_registrants(&ns); 1685 CU_ASSERT(rc == 2); 1686 CU_ASSERT(TAILQ_EMPTY(&ns.registrants)); 1687 1688 /* Existing bdev UUID is different with configuration */ 1689 spdk_uuid_generate(&s_uuid); 1690 uuid_unparse((void *)&s_uuid, uuid); 1691 snprintf(info.bdev_uuid, SPDK_UUID_STRING_LEN, "%s", uuid); 1692 spdk_uuid_generate(&s_uuid); 1693 spdk_uuid_copy(&bdev.uuid, &s_uuid); 1694 1695 rc = nvmf_ns_reservation_restore(&ns, &info); 1696 CU_ASSERT(rc == -EINVAL); 1697 } 1698 1699 static void 1700 test_nvmf_subsystem_state_change(void) 1701 { 1702 struct spdk_nvmf_tgt tgt = {}; 1703 struct spdk_nvmf_subsystem *subsystem, *discovery_subsystem; 1704 int rc; 1705 1706 tgt.max_subsystems = 1024; 1707 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1708 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1709 1710 discovery_subsystem = spdk_nvmf_subsystem_create(&tgt, SPDK_NVMF_DISCOVERY_NQN, 1711 SPDK_NVMF_SUBTYPE_DISCOVERY, 0); 1712 SPDK_CU_ASSERT_FATAL(discovery_subsystem != NULL); 1713 subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", 1714 SPDK_NVMF_SUBTYPE_NVME, 0); 1715 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 1716 1717 spdk_io_device_register(&tgt, 1718 nvmf_tgt_create_poll_group, 1719 nvmf_tgt_destroy_poll_group, 1720 sizeof(struct spdk_nvmf_poll_group), 1721 NULL); 1722 1723 rc = spdk_nvmf_subsystem_start(discovery_subsystem, NULL, NULL); 1724 CU_ASSERT(rc == 0); 1725 poll_threads(); 1726 CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); 1727 rc = spdk_nvmf_subsystem_start(subsystem, NULL, NULL); 1728 CU_ASSERT(rc == 0); 1729 poll_threads(); 1730 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); 1731 1732 rc = spdk_nvmf_subsystem_pause(subsystem, SPDK_NVME_GLOBAL_NS_TAG, NULL, NULL); 1733 CU_ASSERT(rc == 0); 1734 rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL); 1735 CU_ASSERT(rc == -EBUSY); 1736 poll_threads(); 1737 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED); 1738 1739 rc = spdk_nvmf_subsystem_stop(discovery_subsystem, NULL, NULL); 1740 CU_ASSERT(rc == 0); 1741 poll_threads(); 1742 CU_ASSERT(discovery_subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 1743 rc = spdk_nvmf_subsystem_stop(subsystem, NULL, NULL); 1744 CU_ASSERT(rc == 0); 1745 poll_threads(); 1746 CU_ASSERT(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 1747 1748 rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL); 1749 CU_ASSERT(rc == 0); 1750 rc = spdk_nvmf_subsystem_destroy(discovery_subsystem, NULL, NULL); 1751 CU_ASSERT(rc == 0); 1752 1753 spdk_io_device_unregister(&tgt, NULL); 1754 poll_threads(); 1755 1756 free(tgt.subsystems); 1757 } 1758 1759 int 1760 main(int argc, char **argv) 1761 { 1762 CU_pSuite suite = NULL; 1763 unsigned int num_failures; 1764 1765 CU_set_error_action(CUEA_ABORT); 1766 CU_initialize_registry(); 1767 1768 suite = CU_add_suite("nvmf", NULL, NULL); 1769 1770 CU_ADD_TEST(suite, nvmf_test_create_subsystem); 1771 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_ns); 1772 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_set_sn); 1773 CU_ADD_TEST(suite, test_reservation_register); 1774 CU_ADD_TEST(suite, test_reservation_register_with_ptpl); 1775 CU_ADD_TEST(suite, test_reservation_acquire_preempt_1); 1776 CU_ADD_TEST(suite, test_reservation_acquire_release_with_ptpl); 1777 CU_ADD_TEST(suite, test_reservation_release); 1778 CU_ADD_TEST(suite, test_reservation_unregister_notification); 1779 CU_ADD_TEST(suite, test_reservation_release_notification); 1780 CU_ADD_TEST(suite, test_reservation_release_notification_write_exclusive); 1781 CU_ADD_TEST(suite, test_reservation_clear_notification); 1782 CU_ADD_TEST(suite, test_reservation_preempt_notification); 1783 CU_ADD_TEST(suite, test_spdk_nvmf_ns_event); 1784 CU_ADD_TEST(suite, test_nvmf_ns_reservation_add_remove_registrant); 1785 CU_ADD_TEST(suite, test_nvmf_subsystem_add_ctrlr); 1786 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_host); 1787 CU_ADD_TEST(suite, test_nvmf_ns_reservation_report); 1788 CU_ADD_TEST(suite, test_nvmf_valid_nqn); 1789 CU_ADD_TEST(suite, test_nvmf_ns_reservation_restore); 1790 CU_ADD_TEST(suite, test_nvmf_subsystem_state_change); 1791 1792 allocate_threads(1); 1793 set_thread(0); 1794 1795 CU_basic_set_mode(CU_BRM_VERBOSE); 1796 CU_basic_run_tests(); 1797 num_failures = CU_get_number_of_failures(); 1798 CU_cleanup_registry(); 1799 1800 free_threads(); 1801 1802 return num_failures; 1803 } 1804