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