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