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