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