1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. All rights reserved. 5 * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "common/lib/ut_multithread.c" 37 #include "spdk_cunit.h" 38 #include "spdk_internal/mock.h" 39 #include "spdk_internal/thread.h" 40 41 #include "nvmf/subsystem.c" 42 43 SPDK_LOG_REGISTER_COMPONENT(nvmf) 44 45 DEFINE_STUB(spdk_bdev_module_claim_bdev, 46 int, 47 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 48 struct spdk_bdev_module *module), 0); 49 50 DEFINE_STUB_V(spdk_bdev_module_release_bdev, 51 (struct spdk_bdev *bdev)); 52 53 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, 54 (const struct spdk_bdev *bdev), 512); 55 56 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, 57 (const struct spdk_bdev *bdev), 0); 58 59 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, 60 (const struct spdk_bdev *bdev), false); 61 62 DEFINE_STUB(spdk_nvmf_transport_stop_listen, 63 int, 64 (struct spdk_nvmf_transport *transport, 65 const struct spdk_nvme_transport_id *trid), 0); 66 67 int 68 spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport, 69 const struct spdk_nvme_transport_id *trid) 70 { 71 return 0; 72 } 73 74 void 75 nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport, 76 struct spdk_nvme_transport_id *trid, 77 struct spdk_nvmf_discovery_log_page_entry *entry) 78 { 79 entry->trtype = 42; 80 } 81 82 static struct spdk_nvmf_transport g_transport = {}; 83 84 struct spdk_nvmf_transport * 85 spdk_nvmf_transport_create(const char *transport_name, 86 struct spdk_nvmf_transport_opts *tprt_opts) 87 { 88 if (strcasecmp(transport_name, spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA))) { 89 return &g_transport; 90 } 91 92 return NULL; 93 } 94 95 struct spdk_nvmf_subsystem * 96 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) 97 { 98 return NULL; 99 } 100 101 struct spdk_nvmf_transport * 102 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name) 103 { 104 if (strncmp(transport_name, SPDK_NVME_TRANSPORT_NAME_RDMA, SPDK_NVMF_TRSTRING_MAX_LEN)) { 105 return &g_transport; 106 } 107 108 return NULL; 109 } 110 111 int 112 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group, 113 struct spdk_nvmf_subsystem *subsystem) 114 { 115 return 0; 116 } 117 118 int 119 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, 120 struct spdk_nvmf_subsystem *subsystem, 121 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 122 { 123 return 0; 124 } 125 126 void 127 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, 128 struct spdk_nvmf_subsystem *subsystem, 129 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 130 { 131 } 132 133 void 134 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, 135 struct spdk_nvmf_subsystem *subsystem, 136 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 137 { 138 } 139 140 void 141 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, 142 struct spdk_nvmf_subsystem *subsystem, 143 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg) 144 { 145 } 146 147 int 148 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str) 149 { 150 if (trtype == NULL || str == NULL) { 151 return -EINVAL; 152 } 153 154 if (strcasecmp(str, "PCIe") == 0) { 155 *trtype = SPDK_NVME_TRANSPORT_PCIE; 156 } else if (strcasecmp(str, "RDMA") == 0) { 157 *trtype = SPDK_NVME_TRANSPORT_RDMA; 158 } else { 159 return -ENOENT; 160 } 161 return 0; 162 } 163 164 int 165 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 166 const struct spdk_nvme_transport_id *trid2) 167 { 168 return 0; 169 } 170 171 int32_t 172 spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr) 173 { 174 return -1; 175 } 176 177 int32_t 178 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) 179 { 180 return -1; 181 } 182 183 int 184 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr) 185 { 186 return -1; 187 } 188 189 void 190 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) 191 { 192 } 193 194 static struct spdk_nvmf_ctrlr *g_ns_changed_ctrlr = NULL; 195 static uint32_t g_ns_changed_nsid = 0; 196 void 197 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) 198 { 199 g_ns_changed_ctrlr = ctrlr; 200 g_ns_changed_nsid = nsid; 201 } 202 203 static struct spdk_bdev g_bdevs[] = { 204 { .name = "bdev1" }, 205 { .name = "bdev2" }, 206 }; 207 208 struct spdk_bdev_desc { 209 struct spdk_bdev *bdev; 210 }; 211 212 int 213 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, 214 void *event_ctx, struct spdk_bdev_desc **_desc) 215 { 216 struct spdk_bdev_desc *desc; 217 size_t i; 218 219 for (i = 0; i < sizeof(g_bdevs); i++) { 220 if (strcmp(bdev_name, g_bdevs[i].name) == 0) { 221 222 desc = calloc(1, sizeof(*desc)); 223 SPDK_CU_ASSERT_FATAL(desc != NULL); 224 225 desc->bdev = &g_bdevs[i]; 226 *_desc = desc; 227 return 0; 228 } 229 } 230 231 return -EINVAL; 232 } 233 234 void 235 spdk_bdev_close(struct spdk_bdev_desc *desc) 236 { 237 free(desc); 238 } 239 240 struct spdk_bdev * 241 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 242 { 243 return desc->bdev; 244 } 245 246 const char * 247 spdk_bdev_get_name(const struct spdk_bdev *bdev) 248 { 249 return "test"; 250 } 251 252 const struct spdk_uuid * 253 spdk_bdev_get_uuid(const struct spdk_bdev *bdev) 254 { 255 return &bdev->uuid; 256 } 257 258 static void 259 test_spdk_nvmf_subsystem_add_ns(void) 260 { 261 struct spdk_nvmf_tgt tgt = {}; 262 struct spdk_nvmf_subsystem subsystem = { 263 .max_nsid = 0, 264 .ns = NULL, 265 .tgt = &tgt 266 }; 267 struct spdk_nvmf_ns_opts ns_opts; 268 uint32_t nsid; 269 int rc; 270 271 tgt.max_subsystems = 1024; 272 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 273 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 274 275 /* Allow NSID to be assigned automatically */ 276 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 277 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL); 278 /* NSID 1 is the first unused ID */ 279 CU_ASSERT(nsid == 1); 280 CU_ASSERT(subsystem.max_nsid == 1); 281 SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 282 SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL); 283 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]); 284 285 /* Request a specific NSID */ 286 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 287 ns_opts.nsid = 5; 288 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 289 CU_ASSERT(nsid == 5); 290 CU_ASSERT(subsystem.max_nsid == 5); 291 SPDK_CU_ASSERT_FATAL(subsystem.ns[nsid - 1] != NULL); 292 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[1]); 293 294 /* Request an NSID that is already in use */ 295 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 296 ns_opts.nsid = 5; 297 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 298 CU_ASSERT(nsid == 0); 299 CU_ASSERT(subsystem.max_nsid == 5); 300 301 /* Request 0xFFFFFFFF (invalid NSID, reserved for broadcast) */ 302 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 303 ns_opts.nsid = 0xFFFFFFFF; 304 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev2", &ns_opts, sizeof(ns_opts), NULL); 305 CU_ASSERT(nsid == 0); 306 CU_ASSERT(subsystem.max_nsid == 5); 307 308 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 1); 309 CU_ASSERT(rc == 0); 310 rc = spdk_nvmf_subsystem_remove_ns(&subsystem, 5); 311 CU_ASSERT(rc == 0); 312 313 free(subsystem.ns); 314 free(tgt.subsystems); 315 } 316 317 static void 318 nvmf_test_create_subsystem(void) 319 { 320 struct spdk_nvmf_tgt tgt = {}; 321 char nqn[256]; 322 struct spdk_nvmf_subsystem *subsystem; 323 324 tgt.max_subsystems = 1024; 325 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 326 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 327 328 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 329 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 330 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 331 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 332 spdk_nvmf_subsystem_destroy(subsystem); 333 334 /* valid name with complex reverse domain */ 335 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-full--rev-domain.name:subsystem1"); 336 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 337 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 338 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 339 spdk_nvmf_subsystem_destroy(subsystem); 340 341 /* Valid name discovery controller */ 342 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 343 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 344 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 345 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 346 spdk_nvmf_subsystem_destroy(subsystem); 347 348 349 /* Invalid name, no user supplied string */ 350 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 351 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 352 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 353 354 /* Valid name, only contains top-level domain name */ 355 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:subsystem1"); 356 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 357 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 358 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 359 spdk_nvmf_subsystem_destroy(subsystem); 360 361 /* Invalid name, domain label > 63 characters */ 362 snprintf(nqn, sizeof(nqn), 363 "nqn.2016-06.io.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz:sub"); 364 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 365 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 366 367 /* Invalid name, domain label starts with digit */ 368 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.3spdk:sub"); 369 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 370 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 371 372 /* Invalid name, domain label starts with - */ 373 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.-spdk:subsystem1"); 374 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 375 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 376 377 /* Invalid name, domain label ends with - */ 378 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk-:subsystem1"); 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 with multiple consecutive periods */ 383 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io..spdk:subsystem1"); 384 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 385 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 386 387 /* Longest valid name */ 388 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 389 memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn)); 390 nqn[223] = '\0'; 391 CU_ASSERT(strlen(nqn) == 223); 392 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 393 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 394 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 395 spdk_nvmf_subsystem_destroy(subsystem); 396 397 /* Invalid name, too long */ 398 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:"); 399 memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn)); 400 nqn[224] = '\0'; 401 CU_ASSERT(strlen(nqn) == 224); 402 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 403 CU_ASSERT(subsystem == NULL); 404 405 /* Valid name using uuid format */ 406 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:11111111-aaaa-bbdd-FFEE-123456789abc"); 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 spdk_nvmf_subsystem_destroy(subsystem); 411 412 /* Invalid name user string contains an invalid utf-8 character */ 413 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xFFsubsystem1"); 414 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 415 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 416 417 /* Valid name with non-ascii but valid utf-8 characters */ 418 snprintf(nqn, sizeof(nqn), "nqn.2016-06.io.spdk:\xe1\x8a\x88subsystem1\xca\x80"); 419 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 420 SPDK_CU_ASSERT_FATAL(subsystem != NULL); 421 CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); 422 spdk_nvmf_subsystem_destroy(subsystem); 423 424 /* Invalid uuid (too long) */ 425 snprintf(nqn, sizeof(nqn), 426 "nqn.2014-08.org.nvmexpress:uuid:11111111-aaaa-bbdd-FFEE-123456789abcdef"); 427 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 428 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 429 430 /* Invalid uuid (dashes placed incorrectly) */ 431 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:111111-11aaaa-bbdd-FFEE-123456789abc"); 432 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 433 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 434 435 /* Invalid uuid (invalid characters in uuid) */ 436 snprintf(nqn, sizeof(nqn), "nqn.2014-08.org.nvmexpress:uuid:111hg111-aaaa-bbdd-FFEE-123456789abc"); 437 subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); 438 SPDK_CU_ASSERT_FATAL(subsystem == NULL); 439 440 free(tgt.subsystems); 441 } 442 443 static void 444 test_spdk_nvmf_subsystem_set_sn(void) 445 { 446 struct spdk_nvmf_subsystem subsystem = {}; 447 448 /* Basic valid serial number */ 449 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd xyz") == 0); 450 CU_ASSERT(strcmp(subsystem.sn, "abcd xyz") == 0); 451 452 /* Exactly 20 characters (valid) */ 453 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "12345678901234567890") == 0); 454 CU_ASSERT(strcmp(subsystem.sn, "12345678901234567890") == 0); 455 456 /* 21 characters (too long, invalid) */ 457 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "123456789012345678901") < 0); 458 459 /* Non-ASCII characters (invalid) */ 460 CU_ASSERT(spdk_nvmf_subsystem_set_sn(&subsystem, "abcd\txyz") < 0); 461 } 462 463 /* 464 * Reservation Unit Test Configuration 465 * -------- -------- -------- 466 * | Host A | | Host B | | Host C | 467 * -------- -------- -------- 468 * / \ | | 469 * -------- -------- ------- ------- 470 * |Ctrlr1_A| |Ctrlr2_A| |Ctrlr_B| |Ctrlr_C| 471 * -------- -------- ------- ------- 472 * \ \ / / 473 * \ \ / / 474 * \ \ / / 475 * -------------------------------------- 476 * | NAMESPACE 1 | 477 * -------------------------------------- 478 */ 479 static struct spdk_nvmf_subsystem g_subsystem; 480 static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C; 481 static struct spdk_nvmf_ns g_ns; 482 static struct spdk_bdev g_bdev; 483 struct spdk_nvmf_subsystem_pg_ns_info g_ns_info; 484 485 void 486 nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr) 487 { 488 } 489 490 static void 491 ut_reservation_init(void) 492 { 493 494 TAILQ_INIT(&g_subsystem.ctrlrs); 495 496 memset(&g_ns, 0, sizeof(g_ns)); 497 TAILQ_INIT(&g_ns.registrants); 498 g_ns.subsystem = &g_subsystem; 499 g_ns.ptpl_file = NULL; 500 g_ns.ptpl_activated = false; 501 spdk_uuid_generate(&g_bdev.uuid); 502 g_ns.bdev = &g_bdev; 503 504 /* Host A has two controllers */ 505 spdk_uuid_generate(&g_ctrlr1_A.hostid); 506 TAILQ_INIT(&g_ctrlr1_A.log_head); 507 g_ctrlr1_A.subsys = &g_subsystem; 508 g_ctrlr1_A.num_avail_log_pages = 0; 509 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr1_A, link); 510 spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid); 511 TAILQ_INIT(&g_ctrlr2_A.log_head); 512 g_ctrlr2_A.subsys = &g_subsystem; 513 g_ctrlr2_A.num_avail_log_pages = 0; 514 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr2_A, link); 515 516 /* Host B has 1 controller */ 517 spdk_uuid_generate(&g_ctrlr_B.hostid); 518 TAILQ_INIT(&g_ctrlr_B.log_head); 519 g_ctrlr_B.subsys = &g_subsystem; 520 g_ctrlr_B.num_avail_log_pages = 0; 521 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_B, link); 522 523 /* Host C has 1 controller */ 524 spdk_uuid_generate(&g_ctrlr_C.hostid); 525 TAILQ_INIT(&g_ctrlr_C.log_head); 526 g_ctrlr_C.subsys = &g_subsystem; 527 g_ctrlr_C.num_avail_log_pages = 0; 528 TAILQ_INSERT_TAIL(&g_subsystem.ctrlrs, &g_ctrlr_C, link); 529 } 530 531 static void 532 ut_reservation_deinit(void) 533 { 534 struct spdk_nvmf_registrant *reg, *tmp; 535 struct spdk_nvmf_reservation_log *log, *log_tmp; 536 struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp; 537 538 TAILQ_FOREACH_SAFE(reg, &g_ns.registrants, link, tmp) { 539 TAILQ_REMOVE(&g_ns.registrants, reg, link); 540 free(reg); 541 } 542 TAILQ_FOREACH_SAFE(log, &g_ctrlr1_A.log_head, link, log_tmp) { 543 TAILQ_REMOVE(&g_ctrlr1_A.log_head, log, link); 544 free(log); 545 } 546 g_ctrlr1_A.num_avail_log_pages = 0; 547 TAILQ_FOREACH_SAFE(log, &g_ctrlr2_A.log_head, link, log_tmp) { 548 TAILQ_REMOVE(&g_ctrlr2_A.log_head, log, link); 549 free(log); 550 } 551 g_ctrlr2_A.num_avail_log_pages = 0; 552 TAILQ_FOREACH_SAFE(log, &g_ctrlr_B.log_head, link, log_tmp) { 553 TAILQ_REMOVE(&g_ctrlr_B.log_head, log, link); 554 free(log); 555 } 556 g_ctrlr_B.num_avail_log_pages = 0; 557 TAILQ_FOREACH_SAFE(log, &g_ctrlr_C.log_head, link, log_tmp) { 558 TAILQ_REMOVE(&g_ctrlr_C.log_head, log, link); 559 free(log); 560 } 561 g_ctrlr_C.num_avail_log_pages = 0; 562 563 TAILQ_FOREACH_SAFE(ctrlr, &g_subsystem.ctrlrs, link, ctrlr_tmp) { 564 TAILQ_REMOVE(&g_subsystem.ctrlrs, ctrlr, link); 565 } 566 } 567 568 static struct spdk_nvmf_request * 569 ut_reservation_build_req(uint32_t length) 570 { 571 struct spdk_nvmf_request *req; 572 573 req = calloc(1, sizeof(*req)); 574 assert(req != NULL); 575 576 req->data = calloc(1, length); 577 assert(req->data != NULL); 578 req->length = length; 579 580 req->cmd = (union nvmf_h2c_msg *)calloc(1, sizeof(union nvmf_h2c_msg)); 581 assert(req->cmd != NULL); 582 583 req->rsp = (union nvmf_c2h_msg *)calloc(1, sizeof(union nvmf_c2h_msg)); 584 assert(req->rsp != NULL); 585 586 return req; 587 } 588 589 static void 590 ut_reservation_free_req(struct spdk_nvmf_request *req) 591 { 592 free(req->cmd); 593 free(req->rsp); 594 free(req->data); 595 free(req); 596 } 597 598 static void 599 ut_reservation_build_register_request(struct spdk_nvmf_request *req, 600 uint8_t rrega, uint8_t iekey, 601 uint8_t cptpl, uint64_t crkey, 602 uint64_t nrkey) 603 { 604 struct spdk_nvme_reservation_register_data key; 605 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 606 607 key.crkey = crkey; 608 key.nrkey = nrkey; 609 cmd->cdw10 = 0; 610 cmd->cdw10_bits.resv_register.rrega = rrega; 611 cmd->cdw10_bits.resv_register.iekey = iekey; 612 cmd->cdw10_bits.resv_register.cptpl = cptpl; 613 memcpy(req->data, &key, sizeof(key)); 614 } 615 616 static void 617 ut_reservation_build_acquire_request(struct spdk_nvmf_request *req, 618 uint8_t racqa, uint8_t iekey, 619 uint8_t rtype, uint64_t crkey, 620 uint64_t prkey) 621 { 622 struct spdk_nvme_reservation_acquire_data key; 623 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 624 625 key.crkey = crkey; 626 key.prkey = prkey; 627 cmd->cdw10 = 0; 628 cmd->cdw10_bits.resv_acquire.racqa = racqa; 629 cmd->cdw10_bits.resv_acquire.iekey = iekey; 630 cmd->cdw10_bits.resv_acquire.rtype = rtype; 631 memcpy(req->data, &key, sizeof(key)); 632 } 633 634 static void 635 ut_reservation_build_release_request(struct spdk_nvmf_request *req, 636 uint8_t rrela, uint8_t iekey, 637 uint8_t rtype, uint64_t crkey) 638 { 639 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 640 641 cmd->cdw10 = 0; 642 cmd->cdw10_bits.resv_release.rrela = rrela; 643 cmd->cdw10_bits.resv_release.iekey = iekey; 644 cmd->cdw10_bits.resv_release.rtype = rtype; 645 memcpy(req->data, &crkey, sizeof(crkey)); 646 } 647 648 /* 649 * Construct four registrants for other test cases. 650 * 651 * g_ctrlr1_A register with key 0xa1. 652 * g_ctrlr2_A register with key 0xa1. 653 * g_ctrlr_B register with key 0xb1. 654 * g_ctrlr_C register with key 0xc1. 655 * */ 656 static void 657 ut_reservation_build_registrants(void) 658 { 659 struct spdk_nvmf_request *req; 660 struct spdk_nvme_cpl *rsp; 661 struct spdk_nvmf_registrant *reg; 662 uint32_t gen; 663 664 req = ut_reservation_build_req(16); 665 rsp = &req->rsp->nvme_cpl; 666 SPDK_CU_ASSERT_FATAL(req != NULL); 667 gen = g_ns.gen; 668 669 /* TEST CASE: g_ctrlr1_A register with a new key */ 670 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 671 0, 0, 0, 0xa1); 672 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 673 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 674 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 675 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1); 676 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 1); 677 678 /* TEST CASE: g_ctrlr2_A register with a new key, because it has same 679 * Host Identifier with g_ctrlr1_A, so the register key should same. 680 */ 681 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 682 0, 0, 0, 0xa2); 683 nvmf_ns_reservation_register(&g_ns, &g_ctrlr2_A, req); 684 /* Reservation conflict for other key than 0xa1 */ 685 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 686 687 /* g_ctrlr_B register with a new key */ 688 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 689 0, 0, 0, 0xb1); 690 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 691 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 692 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 693 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb1); 694 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 2); 695 696 /* g_ctrlr_C register with a new key */ 697 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 698 0, 0, 0, 0xc1); 699 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 700 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 701 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 702 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc1); 703 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen + 3); 704 705 ut_reservation_free_req(req); 706 } 707 708 static void 709 test_reservation_register(void) 710 { 711 struct spdk_nvmf_request *req; 712 struct spdk_nvme_cpl *rsp; 713 struct spdk_nvmf_registrant *reg; 714 uint32_t gen; 715 716 ut_reservation_init(); 717 718 req = ut_reservation_build_req(16); 719 rsp = &req->rsp->nvme_cpl; 720 SPDK_CU_ASSERT_FATAL(req != NULL); 721 722 ut_reservation_build_registrants(); 723 724 /* TEST CASE: Replace g_ctrlr1_A with a new key */ 725 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REPLACE_KEY, 726 0, 0, 0xa1, 0xa11); 727 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 728 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 729 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 730 SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa11); 731 732 /* TEST CASE: Host A with g_ctrlr1_A get reservation with 733 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 734 */ 735 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 736 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xa11, 0x0); 737 gen = g_ns.gen; 738 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 739 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 740 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 741 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 742 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa11); 743 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 744 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 745 746 /* TEST CASE: g_ctrlr_C unregister with IEKEY enabled */ 747 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 748 1, 0, 0, 0); 749 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_C, req); 750 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 751 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 752 SPDK_CU_ASSERT_FATAL(reg == NULL); 753 754 /* TEST CASE: g_ctrlr_B unregister with correct key */ 755 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 756 0, 0, 0xb1, 0); 757 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 758 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 759 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 760 SPDK_CU_ASSERT_FATAL(reg == NULL); 761 762 /* TEST CASE: g_ctrlr1_A unregister with correct key, 763 * reservation should be removed as well. 764 */ 765 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 766 0, 0, 0xa11, 0); 767 nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 768 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 769 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 770 SPDK_CU_ASSERT_FATAL(reg == NULL); 771 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 772 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 773 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 774 775 ut_reservation_free_req(req); 776 ut_reservation_deinit(); 777 } 778 779 static void 780 test_reservation_register_with_ptpl(void) 781 { 782 struct spdk_nvmf_request *req; 783 struct spdk_nvme_cpl *rsp; 784 struct spdk_nvmf_registrant *reg; 785 bool update_sgroup = false; 786 int rc; 787 struct spdk_nvmf_reservation_info info; 788 789 ut_reservation_init(); 790 791 req = ut_reservation_build_req(16); 792 rsp = &req->rsp->nvme_cpl; 793 SPDK_CU_ASSERT_FATAL(req != NULL); 794 795 /* TEST CASE: No persistent file, register with PTPL enabled will fail */ 796 g_ns.ptpl_file = NULL; 797 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 798 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 799 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 800 SPDK_CU_ASSERT_FATAL(update_sgroup == false); 801 SPDK_CU_ASSERT_FATAL(rsp->status.sc != SPDK_NVME_SC_SUCCESS); 802 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 803 SPDK_CU_ASSERT_FATAL(reg == NULL); 804 805 /* TEST CASE: Enable PTPL */ 806 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 807 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 808 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 809 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 810 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 811 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 812 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 813 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 814 SPDK_CU_ASSERT_FATAL(reg != NULL); 815 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 816 /* Load reservation information from configuration file */ 817 memset(&info, 0, sizeof(info)); 818 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 819 SPDK_CU_ASSERT_FATAL(rc == 0); 820 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 821 822 /* TEST CASE: Disable PTPL */ 823 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 824 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 825 SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON, 0, 0xa1); 826 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 827 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 828 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 829 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == false); 830 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 831 SPDK_CU_ASSERT_FATAL(rc < 0); 832 unlink(g_ns.ptpl_file); 833 834 ut_reservation_free_req(req); 835 ut_reservation_deinit(); 836 } 837 838 static void 839 test_reservation_acquire_preempt_1(void) 840 { 841 struct spdk_nvmf_request *req; 842 struct spdk_nvme_cpl *rsp; 843 struct spdk_nvmf_registrant *reg; 844 uint32_t gen; 845 846 ut_reservation_init(); 847 848 req = ut_reservation_build_req(16); 849 rsp = &req->rsp->nvme_cpl; 850 SPDK_CU_ASSERT_FATAL(req != NULL); 851 852 ut_reservation_build_registrants(); 853 854 gen = g_ns.gen; 855 /* ACQUIRE: Host A with g_ctrlr1_A acquire reservation with 856 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE. 857 */ 858 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 859 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 860 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 861 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 862 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 863 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 864 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0xa1); 865 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 866 SPDK_CU_ASSERT_FATAL(g_ns.gen == gen); 867 868 /* TEST CASE: g_ctrlr1_A holds the reservation, g_ctrlr_B preempt g_ctrl1_A, 869 * g_ctrl1_A registrant is unregistred. 870 */ 871 gen = g_ns.gen; 872 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 873 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1, 0xa1); 874 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 875 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 876 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 877 SPDK_CU_ASSERT_FATAL(reg == NULL); 878 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 879 SPDK_CU_ASSERT_FATAL(reg != NULL); 880 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 881 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 882 SPDK_CU_ASSERT_FATAL(reg != NULL); 883 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 884 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 885 886 /* TEST CASE: g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B 887 * with valid key and PRKEY set to 0, all registrants other the host that issued 888 * the command are unregistered. 889 */ 890 gen = g_ns.gen; 891 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 892 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0x0); 893 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 894 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 895 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 896 SPDK_CU_ASSERT_FATAL(reg == NULL); 897 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 898 SPDK_CU_ASSERT_FATAL(reg == NULL); 899 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 900 SPDK_CU_ASSERT_FATAL(reg != NULL); 901 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 902 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 903 SPDK_CU_ASSERT_FATAL(g_ns.gen > gen); 904 905 ut_reservation_free_req(req); 906 ut_reservation_deinit(); 907 } 908 909 static void 910 test_reservation_acquire_release_with_ptpl(void) 911 { 912 struct spdk_nvmf_request *req; 913 struct spdk_nvme_cpl *rsp; 914 struct spdk_nvmf_registrant *reg; 915 bool update_sgroup = false; 916 struct spdk_uuid holder_uuid; 917 int rc; 918 struct spdk_nvmf_reservation_info info; 919 920 ut_reservation_init(); 921 922 req = ut_reservation_build_req(16); 923 rsp = &req->rsp->nvme_cpl; 924 SPDK_CU_ASSERT_FATAL(req != NULL); 925 926 /* TEST CASE: Enable PTPL */ 927 g_ns.ptpl_file = "/tmp/Ns1PR.cfg"; 928 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_REGISTER_KEY, 0, 929 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS, 0, 0xa1); 930 update_sgroup = nvmf_ns_reservation_register(&g_ns, &g_ctrlr1_A, req); 931 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 932 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 933 SPDK_CU_ASSERT_FATAL(g_ns.ptpl_activated == true); 934 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 935 SPDK_CU_ASSERT_FATAL(reg != NULL); 936 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, ®->hostid)); 937 /* Load reservation information from configuration file */ 938 memset(&info, 0, sizeof(info)); 939 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 940 SPDK_CU_ASSERT_FATAL(rc == 0); 941 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 942 943 /* TEST CASE: Acquire the reservation */ 944 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 945 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 946 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1, 0x0); 947 update_sgroup = nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 948 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 949 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 950 memset(&info, 0, sizeof(info)); 951 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 952 SPDK_CU_ASSERT_FATAL(rc == 0); 953 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 954 SPDK_CU_ASSERT_FATAL(info.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 955 SPDK_CU_ASSERT_FATAL(info.crkey == 0xa1); 956 spdk_uuid_parse(&holder_uuid, info.holder_uuid); 957 SPDK_CU_ASSERT_FATAL(!spdk_uuid_compare(&g_ctrlr1_A.hostid, &holder_uuid)); 958 959 /* TEST CASE: Release the reservation */ 960 rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; 961 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 962 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xa1); 963 update_sgroup = nvmf_ns_reservation_release(&g_ns, &g_ctrlr1_A, req); 964 SPDK_CU_ASSERT_FATAL(update_sgroup == true); 965 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 966 memset(&info, 0, sizeof(info)); 967 rc = nvmf_ns_load_reservation(g_ns.ptpl_file, &info); 968 SPDK_CU_ASSERT_FATAL(rc == 0); 969 SPDK_CU_ASSERT_FATAL(info.rtype == 0); 970 SPDK_CU_ASSERT_FATAL(info.crkey == 0); 971 SPDK_CU_ASSERT_FATAL(info.ptpl_activated == true); 972 unlink(g_ns.ptpl_file); 973 974 ut_reservation_free_req(req); 975 ut_reservation_deinit(); 976 } 977 978 static void 979 test_reservation_release(void) 980 { 981 struct spdk_nvmf_request *req; 982 struct spdk_nvme_cpl *rsp; 983 struct spdk_nvmf_registrant *reg; 984 985 ut_reservation_init(); 986 987 req = ut_reservation_build_req(16); 988 rsp = &req->rsp->nvme_cpl; 989 SPDK_CU_ASSERT_FATAL(req != NULL); 990 991 ut_reservation_build_registrants(); 992 993 /* ACQUIRE: Host A with g_ctrlr1_A get reservation with 994 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS 995 */ 996 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 997 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xa1, 0x0); 998 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr1_A, req); 999 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1000 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1001 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1002 SPDK_CU_ASSERT_FATAL(g_ns.holder == reg); 1003 1004 /* Test Case: Host B release the reservation */ 1005 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1006 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xb1); 1007 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1008 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1009 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1010 SPDK_CU_ASSERT_FATAL(g_ns.crkey == 0); 1011 SPDK_CU_ASSERT_FATAL(g_ns.holder == NULL); 1012 1013 /* Test Case: Host C clear the registrants */ 1014 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1015 0, 0xc1); 1016 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_C, req); 1017 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1018 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr1_A.hostid); 1019 SPDK_CU_ASSERT_FATAL(reg == NULL); 1020 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr2_A.hostid); 1021 SPDK_CU_ASSERT_FATAL(reg == NULL); 1022 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_B.hostid); 1023 SPDK_CU_ASSERT_FATAL(reg == NULL); 1024 reg = nvmf_ns_reservation_get_registrant(&g_ns, &g_ctrlr_C.hostid); 1025 SPDK_CU_ASSERT_FATAL(reg == NULL); 1026 1027 ut_reservation_free_req(req); 1028 ut_reservation_deinit(); 1029 } 1030 1031 void 1032 nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr, 1033 struct spdk_nvmf_ns *ns, 1034 enum spdk_nvme_reservation_notification_log_page_type type) 1035 { 1036 ctrlr->num_avail_log_pages++; 1037 } 1038 1039 static void 1040 test_reservation_unregister_notification(void) 1041 { 1042 struct spdk_nvmf_request *req; 1043 struct spdk_nvme_cpl *rsp; 1044 1045 ut_reservation_init(); 1046 1047 req = ut_reservation_build_req(16); 1048 SPDK_CU_ASSERT_FATAL(req != NULL); 1049 rsp = &req->rsp->nvme_cpl; 1050 1051 ut_reservation_build_registrants(); 1052 1053 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1054 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1055 */ 1056 rsp->status.sc = 0xff; 1057 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1058 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1059 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1060 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1061 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1062 1063 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B unregister the registration. 1064 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C only for 1065 * SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY or SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY 1066 * type. 1067 */ 1068 rsp->status.sc = 0xff; 1069 g_ctrlr1_A.num_avail_log_pages = 0; 1070 g_ctrlr2_A.num_avail_log_pages = 0; 1071 g_ctrlr_B.num_avail_log_pages = 5; 1072 g_ctrlr_C.num_avail_log_pages = 0; 1073 ut_reservation_build_register_request(req, SPDK_NVME_RESERVE_UNREGISTER_KEY, 1074 0, 0, 0xb1, 0); 1075 nvmf_ns_reservation_register(&g_ns, &g_ctrlr_B, req); 1076 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1077 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1078 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1079 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1080 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1081 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1082 1083 ut_reservation_free_req(req); 1084 ut_reservation_deinit(); 1085 } 1086 1087 static void 1088 test_reservation_release_notification(void) 1089 { 1090 struct spdk_nvmf_request *req; 1091 struct spdk_nvme_cpl *rsp; 1092 1093 ut_reservation_init(); 1094 1095 req = ut_reservation_build_req(16); 1096 SPDK_CU_ASSERT_FATAL(req != NULL); 1097 rsp = &req->rsp->nvme_cpl; 1098 1099 ut_reservation_build_registrants(); 1100 1101 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1102 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1103 */ 1104 rsp->status.sc = 0xff; 1105 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1106 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1107 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1108 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1109 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1110 1111 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1112 * Reservation release notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1113 */ 1114 rsp->status.sc = 0xff; 1115 g_ctrlr1_A.num_avail_log_pages = 0; 1116 g_ctrlr2_A.num_avail_log_pages = 0; 1117 g_ctrlr_B.num_avail_log_pages = 5; 1118 g_ctrlr_C.num_avail_log_pages = 0; 1119 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1120 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1); 1121 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1122 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1123 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1124 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1125 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1126 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1127 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1128 1129 ut_reservation_free_req(req); 1130 ut_reservation_deinit(); 1131 } 1132 1133 static void 1134 test_reservation_release_notification_write_exclusive(void) 1135 { 1136 struct spdk_nvmf_request *req; 1137 struct spdk_nvme_cpl *rsp; 1138 1139 ut_reservation_init(); 1140 1141 req = ut_reservation_build_req(16); 1142 SPDK_CU_ASSERT_FATAL(req != NULL); 1143 rsp = &req->rsp->nvme_cpl; 1144 1145 ut_reservation_build_registrants(); 1146 1147 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1148 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE 1149 */ 1150 rsp->status.sc = 0xff; 1151 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1152 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1, 0x0); 1153 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1154 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1155 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 1156 1157 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B release the reservation. 1158 * Because the reservation type is SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 1159 * no reservation notification occurs. 1160 */ 1161 rsp->status.sc = 0xff; 1162 g_ctrlr1_A.num_avail_log_pages = 5; 1163 g_ctrlr2_A.num_avail_log_pages = 5; 1164 g_ctrlr_B.num_avail_log_pages = 5; 1165 g_ctrlr_C.num_avail_log_pages = 5; 1166 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_RELEASE, 0, 1167 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE, 0xb1); 1168 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1169 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1170 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1171 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr1_A.num_avail_log_pages); 1172 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr2_A.num_avail_log_pages); 1173 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1174 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1175 1176 ut_reservation_free_req(req); 1177 ut_reservation_deinit(); 1178 } 1179 1180 static void 1181 test_reservation_clear_notification(void) 1182 { 1183 struct spdk_nvmf_request *req; 1184 struct spdk_nvme_cpl *rsp; 1185 1186 ut_reservation_init(); 1187 1188 req = ut_reservation_build_req(16); 1189 SPDK_CU_ASSERT_FATAL(req != NULL); 1190 rsp = &req->rsp->nvme_cpl; 1191 1192 ut_reservation_build_registrants(); 1193 1194 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1195 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1196 */ 1197 rsp->status.sc = 0xff; 1198 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1199 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1200 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1201 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1202 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1203 1204 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_B clear the reservation. 1205 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A/g_ctrlr_C. 1206 */ 1207 rsp->status.sc = 0xff; 1208 g_ctrlr1_A.num_avail_log_pages = 0; 1209 g_ctrlr2_A.num_avail_log_pages = 0; 1210 g_ctrlr_B.num_avail_log_pages = 5; 1211 g_ctrlr_C.num_avail_log_pages = 0; 1212 ut_reservation_build_release_request(req, SPDK_NVME_RESERVE_CLEAR, 0, 1213 0, 0xb1); 1214 nvmf_ns_reservation_release(&g_ns, &g_ctrlr_B, req); 1215 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1216 SPDK_CU_ASSERT_FATAL(g_ns.rtype == 0); 1217 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1218 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1219 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_B.num_avail_log_pages); 1220 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_C.num_avail_log_pages); 1221 1222 ut_reservation_free_req(req); 1223 ut_reservation_deinit(); 1224 } 1225 1226 static void 1227 test_reservation_preempt_notification(void) 1228 { 1229 struct spdk_nvmf_request *req; 1230 struct spdk_nvme_cpl *rsp; 1231 1232 ut_reservation_init(); 1233 1234 req = ut_reservation_build_req(16); 1235 SPDK_CU_ASSERT_FATAL(req != NULL); 1236 rsp = &req->rsp->nvme_cpl; 1237 1238 ut_reservation_build_registrants(); 1239 1240 /* ACQUIRE: Host B with g_ctrlr_B get reservation with 1241 * type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY 1242 */ 1243 rsp->status.sc = 0xff; 1244 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_ACQUIRE, 0, 1245 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY, 0xb1, 0x0); 1246 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_B, req); 1247 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1248 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 1249 1250 /* Test Case : g_ctrlr_B holds the reservation, g_ctrlr_C preempt g_ctrlr_B, 1251 * g_ctrlr_B registrant is unregistred, and reservation is preempted. 1252 * Registration Preempted notification sends to g_ctrlr_B. 1253 * Reservation Preempted notification sends to g_ctrlr1_A/g_ctrlr2_A. 1254 */ 1255 rsp->status.sc = 0xff; 1256 g_ctrlr1_A.num_avail_log_pages = 0; 1257 g_ctrlr2_A.num_avail_log_pages = 0; 1258 g_ctrlr_B.num_avail_log_pages = 0; 1259 g_ctrlr_C.num_avail_log_pages = 5; 1260 ut_reservation_build_acquire_request(req, SPDK_NVME_RESERVE_PREEMPT, 0, 1261 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS, 0xc1, 0xb1); 1262 nvmf_ns_reservation_acquire(&g_ns, &g_ctrlr_C, req); 1263 SPDK_CU_ASSERT_FATAL(rsp->status.sc == SPDK_NVME_SC_SUCCESS); 1264 SPDK_CU_ASSERT_FATAL(g_ns.rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 1265 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr1_A.num_avail_log_pages); 1266 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr2_A.num_avail_log_pages); 1267 SPDK_CU_ASSERT_FATAL(1 == g_ctrlr_B.num_avail_log_pages); 1268 SPDK_CU_ASSERT_FATAL(5 == g_ctrlr_C.num_avail_log_pages); 1269 1270 ut_reservation_free_req(req); 1271 ut_reservation_deinit(); 1272 } 1273 1274 static void 1275 test_spdk_nvmf_ns_event(void) 1276 { 1277 struct spdk_nvmf_tgt tgt = {}; 1278 struct spdk_nvmf_subsystem subsystem = { 1279 .max_nsid = 0, 1280 .ns = NULL, 1281 .tgt = &tgt 1282 }; 1283 struct spdk_nvmf_ctrlr ctrlr = { 1284 .subsys = &subsystem 1285 }; 1286 struct spdk_nvmf_ns_opts ns_opts; 1287 uint32_t nsid; 1288 struct spdk_bdev *bdev; 1289 1290 tgt.max_subsystems = 1024; 1291 tgt.subsystems = calloc(tgt.max_subsystems, sizeof(struct spdk_nvmf_subsystem *)); 1292 SPDK_CU_ASSERT_FATAL(tgt.subsystems != NULL); 1293 1294 /* Add one namespace */ 1295 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 1296 nsid = spdk_nvmf_subsystem_add_ns_ext(&subsystem, "bdev1", &ns_opts, sizeof(ns_opts), NULL); 1297 CU_ASSERT(nsid == 1); 1298 CU_ASSERT(NULL != subsystem.ns[0]); 1299 CU_ASSERT(subsystem.ns[nsid - 1]->bdev == &g_bdevs[nsid - 1]); 1300 1301 bdev = subsystem.ns[nsid - 1]->bdev; 1302 1303 /* Add one controller */ 1304 TAILQ_INIT(&subsystem.ctrlrs); 1305 TAILQ_INSERT_TAIL(&subsystem.ctrlrs, &ctrlr, link); 1306 1307 /* Namespace resize event */ 1308 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1309 g_ns_changed_nsid = 0xFFFFFFFF; 1310 g_ns_changed_ctrlr = NULL; 1311 nvmf_ns_event(SPDK_BDEV_EVENT_RESIZE, bdev, subsystem.ns[0]); 1312 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1313 1314 poll_threads(); 1315 CU_ASSERT(1 == g_ns_changed_nsid); 1316 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1317 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1318 1319 /* Namespace remove event */ 1320 subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 1321 g_ns_changed_nsid = 0xFFFFFFFF; 1322 g_ns_changed_ctrlr = NULL; 1323 nvmf_ns_event(SPDK_BDEV_EVENT_REMOVE, bdev, subsystem.ns[0]); 1324 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_PAUSING == subsystem.state); 1325 CU_ASSERT(0xFFFFFFFF == g_ns_changed_nsid); 1326 CU_ASSERT(NULL == g_ns_changed_ctrlr); 1327 1328 poll_threads(); 1329 CU_ASSERT(1 == g_ns_changed_nsid); 1330 CU_ASSERT(&ctrlr == g_ns_changed_ctrlr); 1331 CU_ASSERT(NULL == subsystem.ns[0]); 1332 CU_ASSERT(SPDK_NVMF_SUBSYSTEM_ACTIVE == subsystem.state); 1333 1334 free(subsystem.ns); 1335 free(tgt.subsystems); 1336 } 1337 1338 1339 int main(int argc, char **argv) 1340 { 1341 CU_pSuite suite = NULL; 1342 unsigned int num_failures; 1343 1344 CU_set_error_action(CUEA_ABORT); 1345 CU_initialize_registry(); 1346 1347 suite = CU_add_suite("nvmf", NULL, NULL); 1348 1349 CU_ADD_TEST(suite, nvmf_test_create_subsystem); 1350 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_add_ns); 1351 CU_ADD_TEST(suite, test_spdk_nvmf_subsystem_set_sn); 1352 CU_ADD_TEST(suite, test_reservation_register); 1353 CU_ADD_TEST(suite, test_reservation_register_with_ptpl); 1354 CU_ADD_TEST(suite, test_reservation_acquire_preempt_1); 1355 CU_ADD_TEST(suite, test_reservation_acquire_release_with_ptpl); 1356 CU_ADD_TEST(suite, test_reservation_release); 1357 CU_ADD_TEST(suite, test_reservation_unregister_notification); 1358 CU_ADD_TEST(suite, test_reservation_release_notification); 1359 CU_ADD_TEST(suite, test_reservation_release_notification_write_exclusive); 1360 CU_ADD_TEST(suite, test_reservation_clear_notification); 1361 CU_ADD_TEST(suite, test_reservation_preempt_notification); 1362 CU_ADD_TEST(suite, test_spdk_nvmf_ns_event); 1363 1364 allocate_threads(1); 1365 set_thread(0); 1366 1367 CU_basic_set_mode(CU_BRM_VERBOSE); 1368 CU_basic_run_tests(); 1369 num_failures = CU_get_number_of_failures(); 1370 CU_cleanup_registry(); 1371 1372 free_threads(); 1373 1374 return num_failures; 1375 } 1376