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