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