1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * 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_cunit.h" 35 36 #include "common/lib/test_env.c" 37 #include "unit/lib/json_mock.c" 38 39 /* HACK: disable VTune integration so the unit test doesn't need VTune headers and libs to build */ 40 #undef SPDK_CONFIG_VTUNE 41 42 #include "bdev/bdev.c" 43 44 DEFINE_STUB(spdk_conf_find_section, struct spdk_conf_section *, (struct spdk_conf *cp, 45 const char *name), NULL); 46 DEFINE_STUB(spdk_conf_section_get_nmval, char *, 47 (struct spdk_conf_section *sp, const char *key, int idx1, int idx2), NULL); 48 DEFINE_STUB(spdk_conf_section_get_intval, int, (struct spdk_conf_section *sp, const char *key), -1); 49 50 static void 51 _bdev_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 52 { 53 fn(ctx); 54 } 55 56 void 57 spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, 58 int *sc, int *sk, int *asc, int *ascq) 59 { 60 } 61 62 static int 63 null_init(void) 64 { 65 return 0; 66 } 67 68 static int 69 null_clean(void) 70 { 71 return 0; 72 } 73 74 static int 75 stub_destruct(void *ctx) 76 { 77 return 0; 78 } 79 80 struct bdev_ut_channel { 81 TAILQ_HEAD(, spdk_bdev_io) outstanding_io; 82 uint32_t outstanding_io_count; 83 uint8_t expected_iotype; 84 uint64_t expected_offset; 85 uint64_t expected_length; 86 int expected_iovcnt; 87 struct iovec expected_iov[32]; 88 }; 89 90 static bool g_io_done; 91 static uint32_t g_bdev_ut_io_device; 92 static struct bdev_ut_channel *g_bdev_ut_channel; 93 94 static void 95 stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 96 { 97 struct bdev_ut_channel *ch = spdk_io_channel_get_ctx(_ch); 98 struct iovec *iov, *expected_iov; 99 int i; 100 101 TAILQ_INSERT_TAIL(&ch->outstanding_io, bdev_io, module_link); 102 ch->outstanding_io_count++; 103 104 if (ch->expected_iotype != SPDK_BDEV_IO_TYPE_INVALID) { 105 CU_ASSERT(bdev_io->type == ch->expected_iotype); 106 } 107 108 if (ch->expected_length == 0) { 109 return; 110 } 111 112 CU_ASSERT(ch->expected_offset == bdev_io->u.bdev.offset_blocks); 113 CU_ASSERT(ch->expected_length = bdev_io->u.bdev.num_blocks); 114 115 if (ch->expected_iovcnt == 0) { 116 /* UNMAP, WRITE_ZEROES and FLUSH don't have iovs, so we can just return now. */ 117 return; 118 } 119 120 CU_ASSERT(ch->expected_iovcnt == bdev_io->u.bdev.iovcnt); 121 for (i = 0; i < ch->expected_iovcnt; i++) { 122 iov = &bdev_io->u.bdev.iovs[i]; 123 expected_iov = &ch->expected_iov[i]; 124 CU_ASSERT(iov->iov_len == expected_iov->iov_len); 125 CU_ASSERT(iov->iov_base == expected_iov->iov_base); 126 } 127 } 128 129 static uint32_t 130 stub_complete_io(uint32_t num_to_complete) 131 { 132 struct bdev_ut_channel *ch = g_bdev_ut_channel; 133 struct spdk_bdev_io *bdev_io; 134 uint32_t num_completed = 0; 135 136 while (num_completed < num_to_complete) { 137 if (TAILQ_EMPTY(&ch->outstanding_io)) { 138 break; 139 } 140 bdev_io = TAILQ_FIRST(&ch->outstanding_io); 141 TAILQ_REMOVE(&ch->outstanding_io, bdev_io, module_link); 142 ch->outstanding_io_count--; 143 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS); 144 num_completed++; 145 } 146 147 return num_completed; 148 } 149 150 static struct spdk_io_channel * 151 bdev_ut_get_io_channel(void *ctx) 152 { 153 return spdk_get_io_channel(&g_bdev_ut_io_device); 154 } 155 156 static bool 157 stub_io_type_supported(void *_bdev, enum spdk_bdev_io_type io_type) 158 { 159 return true; 160 } 161 162 static struct spdk_bdev_fn_table fn_table = { 163 .destruct = stub_destruct, 164 .submit_request = stub_submit_request, 165 .get_io_channel = bdev_ut_get_io_channel, 166 .io_type_supported = stub_io_type_supported, 167 }; 168 169 static int 170 bdev_ut_create_ch(void *io_device, void *ctx_buf) 171 { 172 struct bdev_ut_channel *ch = ctx_buf; 173 174 CU_ASSERT(g_bdev_ut_channel == NULL); 175 g_bdev_ut_channel = ch; 176 177 TAILQ_INIT(&ch->outstanding_io); 178 ch->outstanding_io_count = 0; 179 return 0; 180 } 181 182 static void 183 bdev_ut_destroy_ch(void *io_device, void *ctx_buf) 184 { 185 CU_ASSERT(g_bdev_ut_channel != NULL); 186 g_bdev_ut_channel = NULL; 187 } 188 189 static int 190 bdev_ut_module_init(void) 191 { 192 spdk_io_device_register(&g_bdev_ut_io_device, bdev_ut_create_ch, bdev_ut_destroy_ch, 193 sizeof(struct bdev_ut_channel)); 194 return 0; 195 } 196 197 static void 198 bdev_ut_module_fini(void) 199 { 200 spdk_io_device_unregister(&g_bdev_ut_io_device, NULL); 201 } 202 203 struct spdk_bdev_module bdev_ut_if = { 204 .name = "bdev_ut", 205 .module_init = bdev_ut_module_init, 206 .module_fini = bdev_ut_module_fini, 207 }; 208 209 static void vbdev_ut_examine(struct spdk_bdev *bdev); 210 211 static int 212 vbdev_ut_module_init(void) 213 { 214 return 0; 215 } 216 217 static void 218 vbdev_ut_module_fini(void) 219 { 220 } 221 222 struct spdk_bdev_module vbdev_ut_if = { 223 .name = "vbdev_ut", 224 .module_init = vbdev_ut_module_init, 225 .module_fini = vbdev_ut_module_fini, 226 .examine_config = vbdev_ut_examine, 227 }; 228 229 SPDK_BDEV_MODULE_REGISTER(&bdev_ut_if) 230 SPDK_BDEV_MODULE_REGISTER(&vbdev_ut_if) 231 232 static void 233 vbdev_ut_examine(struct spdk_bdev *bdev) 234 { 235 spdk_bdev_module_examine_done(&vbdev_ut_if); 236 } 237 238 static struct spdk_bdev * 239 allocate_bdev(char *name) 240 { 241 struct spdk_bdev *bdev; 242 int rc; 243 244 bdev = calloc(1, sizeof(*bdev)); 245 SPDK_CU_ASSERT_FATAL(bdev != NULL); 246 247 bdev->name = name; 248 bdev->fn_table = &fn_table; 249 bdev->module = &bdev_ut_if; 250 bdev->blockcnt = 256; 251 bdev->blocklen = 512; 252 253 rc = spdk_bdev_register(bdev); 254 CU_ASSERT(rc == 0); 255 256 return bdev; 257 } 258 259 static struct spdk_bdev * 260 allocate_vbdev(char *name, struct spdk_bdev *base1, struct spdk_bdev *base2) 261 { 262 struct spdk_bdev *bdev; 263 struct spdk_bdev *array[2]; 264 int rc; 265 266 bdev = calloc(1, sizeof(*bdev)); 267 SPDK_CU_ASSERT_FATAL(bdev != NULL); 268 269 bdev->name = name; 270 bdev->fn_table = &fn_table; 271 bdev->module = &vbdev_ut_if; 272 273 /* vbdev must have at least one base bdev */ 274 CU_ASSERT(base1 != NULL); 275 276 array[0] = base1; 277 array[1] = base2; 278 279 rc = spdk_vbdev_register(bdev, array, base2 == NULL ? 1 : 2); 280 CU_ASSERT(rc == 0); 281 282 return bdev; 283 } 284 285 static void 286 free_bdev(struct spdk_bdev *bdev) 287 { 288 spdk_bdev_unregister(bdev, NULL, NULL); 289 memset(bdev, 0xFF, sizeof(*bdev)); 290 free(bdev); 291 } 292 293 static void 294 free_vbdev(struct spdk_bdev *bdev) 295 { 296 spdk_bdev_unregister(bdev, NULL, NULL); 297 memset(bdev, 0xFF, sizeof(*bdev)); 298 free(bdev); 299 } 300 301 static void 302 get_device_stat_cb(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) 303 { 304 const char *bdev_name; 305 306 CU_ASSERT(bdev != NULL); 307 CU_ASSERT(rc == 0); 308 bdev_name = spdk_bdev_get_name(bdev); 309 CU_ASSERT_STRING_EQUAL(bdev_name, "bdev0"); 310 311 free(stat); 312 free_bdev(bdev); 313 } 314 315 static void 316 get_device_stat_test(void) 317 { 318 struct spdk_bdev *bdev; 319 struct spdk_bdev_io_stat *stat; 320 321 bdev = allocate_bdev("bdev0"); 322 stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); 323 if (stat == NULL) { 324 free_bdev(bdev); 325 return; 326 } 327 spdk_bdev_get_device_stat(bdev, stat, get_device_stat_cb, NULL); 328 } 329 330 static void 331 open_write_test(void) 332 { 333 struct spdk_bdev *bdev[9]; 334 struct spdk_bdev_desc *desc[9] = {}; 335 int rc; 336 337 /* 338 * Create a tree of bdevs to test various open w/ write cases. 339 * 340 * bdev0 through bdev3 are physical block devices, such as NVMe 341 * namespaces or Ceph block devices. 342 * 343 * bdev4 is a virtual bdev with multiple base bdevs. This models 344 * caching or RAID use cases. 345 * 346 * bdev5 through bdev7 are all virtual bdevs with the same base 347 * bdev (except bdev7). This models partitioning or logical volume 348 * use cases. 349 * 350 * bdev7 is a virtual bdev with multiple base bdevs. One of base bdevs 351 * (bdev2) is shared with other virtual bdevs: bdev5 and bdev6. This 352 * models caching, RAID, partitioning or logical volumes use cases. 353 * 354 * bdev8 is a virtual bdev with multiple base bdevs, but these 355 * base bdevs are themselves virtual bdevs. 356 * 357 * bdev8 358 * | 359 * +----------+ 360 * | | 361 * bdev4 bdev5 bdev6 bdev7 362 * | | | | 363 * +---+---+ +---+ + +---+---+ 364 * | | \ | / \ 365 * bdev0 bdev1 bdev2 bdev3 366 */ 367 368 bdev[0] = allocate_bdev("bdev0"); 369 rc = spdk_bdev_module_claim_bdev(bdev[0], NULL, &bdev_ut_if); 370 CU_ASSERT(rc == 0); 371 372 bdev[1] = allocate_bdev("bdev1"); 373 rc = spdk_bdev_module_claim_bdev(bdev[1], NULL, &bdev_ut_if); 374 CU_ASSERT(rc == 0); 375 376 bdev[2] = allocate_bdev("bdev2"); 377 rc = spdk_bdev_module_claim_bdev(bdev[2], NULL, &bdev_ut_if); 378 CU_ASSERT(rc == 0); 379 380 bdev[3] = allocate_bdev("bdev3"); 381 rc = spdk_bdev_module_claim_bdev(bdev[3], NULL, &bdev_ut_if); 382 CU_ASSERT(rc == 0); 383 384 bdev[4] = allocate_vbdev("bdev4", bdev[0], bdev[1]); 385 rc = spdk_bdev_module_claim_bdev(bdev[4], NULL, &bdev_ut_if); 386 CU_ASSERT(rc == 0); 387 388 bdev[5] = allocate_vbdev("bdev5", bdev[2], NULL); 389 rc = spdk_bdev_module_claim_bdev(bdev[5], NULL, &bdev_ut_if); 390 CU_ASSERT(rc == 0); 391 392 bdev[6] = allocate_vbdev("bdev6", bdev[2], NULL); 393 394 bdev[7] = allocate_vbdev("bdev7", bdev[2], bdev[3]); 395 396 bdev[8] = allocate_vbdev("bdev8", bdev[4], bdev[5]); 397 398 /* Open bdev0 read-only. This should succeed. */ 399 rc = spdk_bdev_open(bdev[0], false, NULL, NULL, &desc[0]); 400 CU_ASSERT(rc == 0); 401 SPDK_CU_ASSERT_FATAL(desc[0] != NULL); 402 spdk_bdev_close(desc[0]); 403 404 /* 405 * Open bdev1 read/write. This should fail since bdev1 has been claimed 406 * by a vbdev module. 407 */ 408 rc = spdk_bdev_open(bdev[1], true, NULL, NULL, &desc[1]); 409 CU_ASSERT(rc == -EPERM); 410 411 /* 412 * Open bdev4 read/write. This should fail since bdev3 has been claimed 413 * by a vbdev module. 414 */ 415 rc = spdk_bdev_open(bdev[4], true, NULL, NULL, &desc[4]); 416 CU_ASSERT(rc == -EPERM); 417 418 /* Open bdev4 read-only. This should succeed. */ 419 rc = spdk_bdev_open(bdev[4], false, NULL, NULL, &desc[4]); 420 CU_ASSERT(rc == 0); 421 SPDK_CU_ASSERT_FATAL(desc[4] != NULL); 422 spdk_bdev_close(desc[4]); 423 424 /* 425 * Open bdev8 read/write. This should succeed since it is a leaf 426 * bdev. 427 */ 428 rc = spdk_bdev_open(bdev[8], true, NULL, NULL, &desc[8]); 429 CU_ASSERT(rc == 0); 430 SPDK_CU_ASSERT_FATAL(desc[8] != NULL); 431 spdk_bdev_close(desc[8]); 432 433 /* 434 * Open bdev5 read/write. This should fail since bdev4 has been claimed 435 * by a vbdev module. 436 */ 437 rc = spdk_bdev_open(bdev[5], true, NULL, NULL, &desc[5]); 438 CU_ASSERT(rc == -EPERM); 439 440 /* Open bdev4 read-only. This should succeed. */ 441 rc = spdk_bdev_open(bdev[5], false, NULL, NULL, &desc[5]); 442 CU_ASSERT(rc == 0); 443 SPDK_CU_ASSERT_FATAL(desc[5] != NULL); 444 spdk_bdev_close(desc[5]); 445 446 free_vbdev(bdev[8]); 447 448 free_vbdev(bdev[5]); 449 free_vbdev(bdev[6]); 450 free_vbdev(bdev[7]); 451 452 free_vbdev(bdev[4]); 453 454 free_bdev(bdev[0]); 455 free_bdev(bdev[1]); 456 free_bdev(bdev[2]); 457 free_bdev(bdev[3]); 458 } 459 460 static void 461 bytes_to_blocks_test(void) 462 { 463 struct spdk_bdev bdev; 464 uint64_t offset_blocks, num_blocks; 465 466 memset(&bdev, 0, sizeof(bdev)); 467 468 bdev.blocklen = 512; 469 470 /* All parameters valid */ 471 offset_blocks = 0; 472 num_blocks = 0; 473 CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 1024, &num_blocks) == 0); 474 CU_ASSERT(offset_blocks == 1); 475 CU_ASSERT(num_blocks == 2); 476 477 /* Offset not a block multiple */ 478 CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 3, &offset_blocks, 512, &num_blocks) != 0); 479 480 /* Length not a block multiple */ 481 CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 3, &num_blocks) != 0); 482 } 483 484 static void 485 num_blocks_test(void) 486 { 487 struct spdk_bdev bdev; 488 struct spdk_bdev_desc *desc = NULL; 489 int rc; 490 491 memset(&bdev, 0, sizeof(bdev)); 492 bdev.name = "num_blocks"; 493 bdev.fn_table = &fn_table; 494 bdev.module = &bdev_ut_if; 495 spdk_bdev_register(&bdev); 496 spdk_bdev_notify_blockcnt_change(&bdev, 50); 497 498 /* Growing block number */ 499 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 70) == 0); 500 /* Shrinking block number */ 501 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 30) == 0); 502 503 /* In case bdev opened */ 504 rc = spdk_bdev_open(&bdev, false, NULL, NULL, &desc); 505 CU_ASSERT(rc == 0); 506 SPDK_CU_ASSERT_FATAL(desc != NULL); 507 508 /* Growing block number */ 509 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 80) == 0); 510 /* Shrinking block number */ 511 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 20) != 0); 512 513 spdk_bdev_close(desc); 514 spdk_bdev_unregister(&bdev, NULL, NULL); 515 } 516 517 static void 518 io_valid_test(void) 519 { 520 struct spdk_bdev bdev; 521 522 memset(&bdev, 0, sizeof(bdev)); 523 524 bdev.blocklen = 512; 525 spdk_bdev_notify_blockcnt_change(&bdev, 100); 526 527 /* All parameters valid */ 528 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 1, 2) == true); 529 530 /* Last valid block */ 531 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 99, 1) == true); 532 533 /* Offset past end of bdev */ 534 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 100, 1) == false); 535 536 /* Offset + length past end of bdev */ 537 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 99, 2) == false); 538 539 /* Offset near end of uint64_t range (2^64 - 1) */ 540 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 18446744073709551615ULL, 1) == false); 541 } 542 543 static void 544 alias_add_del_test(void) 545 { 546 struct spdk_bdev *bdev[3]; 547 int rc; 548 549 /* Creating and registering bdevs */ 550 bdev[0] = allocate_bdev("bdev0"); 551 SPDK_CU_ASSERT_FATAL(bdev[0] != 0); 552 553 bdev[1] = allocate_bdev("bdev1"); 554 SPDK_CU_ASSERT_FATAL(bdev[1] != 0); 555 556 bdev[2] = allocate_bdev("bdev2"); 557 SPDK_CU_ASSERT_FATAL(bdev[2] != 0); 558 559 /* 560 * Trying adding an alias identical to name. 561 * Alias is identical to name, so it can not be added to aliases list 562 */ 563 rc = spdk_bdev_alias_add(bdev[0], bdev[0]->name); 564 CU_ASSERT(rc == -EEXIST); 565 566 /* 567 * Trying to add empty alias, 568 * this one should fail 569 */ 570 rc = spdk_bdev_alias_add(bdev[0], NULL); 571 CU_ASSERT(rc == -EINVAL); 572 573 /* Trying adding same alias to two different registered bdevs */ 574 575 /* Alias is used first time, so this one should pass */ 576 rc = spdk_bdev_alias_add(bdev[0], "proper alias 0"); 577 CU_ASSERT(rc == 0); 578 579 /* Alias was added to another bdev, so this one should fail */ 580 rc = spdk_bdev_alias_add(bdev[1], "proper alias 0"); 581 CU_ASSERT(rc == -EEXIST); 582 583 /* Alias is used first time, so this one should pass */ 584 rc = spdk_bdev_alias_add(bdev[1], "proper alias 1"); 585 CU_ASSERT(rc == 0); 586 587 /* Trying removing an alias from registered bdevs */ 588 589 /* Alias is not on a bdev aliases list, so this one should fail */ 590 rc = spdk_bdev_alias_del(bdev[0], "not existing"); 591 CU_ASSERT(rc == -ENOENT); 592 593 /* Alias is present on a bdev aliases list, so this one should pass */ 594 rc = spdk_bdev_alias_del(bdev[0], "proper alias 0"); 595 CU_ASSERT(rc == 0); 596 597 /* Alias is present on a bdev aliases list, so this one should pass */ 598 rc = spdk_bdev_alias_del(bdev[1], "proper alias 1"); 599 CU_ASSERT(rc == 0); 600 601 /* Trying to remove name instead of alias, so this one should fail, name cannot be changed or removed */ 602 rc = spdk_bdev_alias_del(bdev[0], bdev[0]->name); 603 CU_ASSERT(rc != 0); 604 605 /* Trying to del all alias from empty alias list */ 606 spdk_bdev_alias_del_all(bdev[2]); 607 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&bdev[2]->aliases)); 608 609 /* Trying to del all alias from non-empty alias list */ 610 rc = spdk_bdev_alias_add(bdev[2], "alias0"); 611 CU_ASSERT(rc == 0); 612 rc = spdk_bdev_alias_add(bdev[2], "alias1"); 613 CU_ASSERT(rc == 0); 614 spdk_bdev_alias_del_all(bdev[2]); 615 CU_ASSERT(TAILQ_EMPTY(&bdev[2]->aliases)); 616 617 /* Unregister and free bdevs */ 618 spdk_bdev_unregister(bdev[0], NULL, NULL); 619 spdk_bdev_unregister(bdev[1], NULL, NULL); 620 spdk_bdev_unregister(bdev[2], NULL, NULL); 621 622 free(bdev[0]); 623 free(bdev[1]); 624 free(bdev[2]); 625 } 626 627 static void 628 io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 629 { 630 g_io_done = true; 631 spdk_bdev_free_io(bdev_io); 632 } 633 634 static void 635 bdev_init_cb(void *arg, int rc) 636 { 637 CU_ASSERT(rc == 0); 638 } 639 640 static void 641 bdev_fini_cb(void *arg) 642 { 643 } 644 645 struct bdev_ut_io_wait_entry { 646 struct spdk_bdev_io_wait_entry entry; 647 struct spdk_io_channel *io_ch; 648 struct spdk_bdev_desc *desc; 649 bool submitted; 650 }; 651 652 static void 653 io_wait_cb(void *arg) 654 { 655 struct bdev_ut_io_wait_entry *entry = arg; 656 int rc; 657 658 rc = spdk_bdev_read_blocks(entry->desc, entry->io_ch, NULL, 0, 1, io_done, NULL); 659 CU_ASSERT(rc == 0); 660 entry->submitted = true; 661 } 662 663 static void 664 bdev_io_wait_test(void) 665 { 666 struct spdk_bdev *bdev; 667 struct spdk_bdev_desc *desc; 668 struct spdk_io_channel *io_ch; 669 struct spdk_bdev_opts bdev_opts = { 670 .bdev_io_pool_size = 4, 671 .bdev_io_cache_size = 2, 672 }; 673 struct bdev_ut_io_wait_entry io_wait_entry; 674 struct bdev_ut_io_wait_entry io_wait_entry2; 675 int rc; 676 677 rc = spdk_bdev_set_opts(&bdev_opts); 678 CU_ASSERT(rc == 0); 679 spdk_bdev_initialize(bdev_init_cb, NULL); 680 681 bdev = allocate_bdev("bdev0"); 682 683 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 684 CU_ASSERT(rc == 0); 685 CU_ASSERT(desc != NULL); 686 io_ch = spdk_bdev_get_io_channel(desc); 687 CU_ASSERT(io_ch != NULL); 688 689 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 690 CU_ASSERT(rc == 0); 691 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 692 CU_ASSERT(rc == 0); 693 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 694 CU_ASSERT(rc == 0); 695 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 696 CU_ASSERT(rc == 0); 697 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 698 699 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 700 CU_ASSERT(rc == -ENOMEM); 701 702 io_wait_entry.entry.bdev = bdev; 703 io_wait_entry.entry.cb_fn = io_wait_cb; 704 io_wait_entry.entry.cb_arg = &io_wait_entry; 705 io_wait_entry.io_ch = io_ch; 706 io_wait_entry.desc = desc; 707 io_wait_entry.submitted = false; 708 /* Cannot use the same io_wait_entry for two different calls. */ 709 memcpy(&io_wait_entry2, &io_wait_entry, sizeof(io_wait_entry)); 710 io_wait_entry2.entry.cb_arg = &io_wait_entry2; 711 712 /* Queue two I/O waits. */ 713 rc = spdk_bdev_queue_io_wait(bdev, io_ch, &io_wait_entry.entry); 714 CU_ASSERT(rc == 0); 715 CU_ASSERT(io_wait_entry.submitted == false); 716 rc = spdk_bdev_queue_io_wait(bdev, io_ch, &io_wait_entry2.entry); 717 CU_ASSERT(rc == 0); 718 CU_ASSERT(io_wait_entry2.submitted == false); 719 720 stub_complete_io(1); 721 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 722 CU_ASSERT(io_wait_entry.submitted == true); 723 CU_ASSERT(io_wait_entry2.submitted == false); 724 725 stub_complete_io(1); 726 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 727 CU_ASSERT(io_wait_entry2.submitted == true); 728 729 stub_complete_io(4); 730 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 731 732 spdk_put_io_channel(io_ch); 733 spdk_bdev_close(desc); 734 free_bdev(bdev); 735 spdk_bdev_finish(bdev_fini_cb, NULL); 736 } 737 738 static void 739 bdev_io_spans_boundary_test(void) 740 { 741 struct spdk_bdev bdev; 742 struct spdk_bdev_io bdev_io; 743 744 memset(&bdev, 0, sizeof(bdev)); 745 746 bdev.optimal_io_boundary = 0; 747 bdev_io.bdev = &bdev; 748 749 /* bdev has no optimal_io_boundary set - so this should return false. */ 750 CU_ASSERT(_spdk_bdev_io_spans_boundary(&bdev_io) == false); 751 752 bdev.optimal_io_boundary = 32; 753 bdev_io.type = SPDK_BDEV_IO_TYPE_RESET; 754 755 /* RESETs are not based on LBAs - so this should return false. */ 756 CU_ASSERT(_spdk_bdev_io_spans_boundary(&bdev_io) == false); 757 758 bdev_io.type = SPDK_BDEV_IO_TYPE_READ; 759 bdev_io.u.bdev.offset_blocks = 0; 760 bdev_io.u.bdev.num_blocks = 32; 761 762 /* This I/O run right up to, but does not cross, the boundary - so this should return false. */ 763 CU_ASSERT(_spdk_bdev_io_spans_boundary(&bdev_io) == false); 764 765 bdev_io.u.bdev.num_blocks = 33; 766 767 /* This I/O spans a boundary. */ 768 CU_ASSERT(_spdk_bdev_io_spans_boundary(&bdev_io) == true); 769 } 770 771 static void 772 bdev_io_split(void) 773 { 774 struct spdk_bdev *bdev; 775 struct spdk_bdev_desc *desc; 776 struct spdk_io_channel *io_ch; 777 struct spdk_bdev_opts bdev_opts = { 778 .bdev_io_pool_size = 512, 779 .bdev_io_cache_size = 64, 780 }; 781 struct iovec iov[4]; 782 int rc; 783 784 rc = spdk_bdev_set_opts(&bdev_opts); 785 CU_ASSERT(rc == 0); 786 spdk_bdev_initialize(bdev_init_cb, NULL); 787 788 bdev = allocate_bdev("bdev0"); 789 790 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 791 CU_ASSERT(rc == 0); 792 CU_ASSERT(desc != NULL); 793 io_ch = spdk_bdev_get_io_channel(desc); 794 CU_ASSERT(io_ch != NULL); 795 796 bdev->optimal_io_boundary = 16; 797 bdev->split_on_optimal_io_boundary = false; 798 799 g_io_done = false; 800 801 /* First test that the I/O does not get split if split_on_optimal_io_boundary == false. */ 802 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_READ; 803 g_bdev_ut_channel->expected_offset = 14; 804 g_bdev_ut_channel->expected_length = 8; 805 g_bdev_ut_channel->expected_iovcnt = 1; 806 g_bdev_ut_channel->expected_iov[0].iov_base = (void *)0xF000; 807 g_bdev_ut_channel->expected_iov[0].iov_len = 8 * 512; 808 809 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 810 CU_ASSERT(rc == 0); 811 CU_ASSERT(g_io_done == false); 812 813 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 814 stub_complete_io(1); 815 CU_ASSERT(g_io_done == true); 816 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 817 818 bdev->split_on_optimal_io_boundary = true; 819 820 /* Now test that a single-vector command is split correctly. 821 * Offset 14, length 8, payload 0xF000 822 * Child - Offset 14, length 2, payload 0xF000 823 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 824 * 825 * Set up the expected values before calling spdk_bdev_read_blocks, since this call 826 * will submit the first child immediately. 827 */ 828 g_io_done = false; 829 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_READ; 830 g_bdev_ut_channel->expected_offset = 14; 831 g_bdev_ut_channel->expected_length = 2; 832 g_bdev_ut_channel->expected_iovcnt = 1; 833 g_bdev_ut_channel->expected_iov[0].iov_base = (void *)0xF000; 834 g_bdev_ut_channel->expected_iov[0].iov_len = 2 * 512; 835 836 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 837 CU_ASSERT(rc == 0); 838 CU_ASSERT(g_io_done == false); 839 840 /* Now set up the expected values for the second child. The second child will 841 * get submitted once the first child is completed by stub_complete_io(). 842 */ 843 g_bdev_ut_channel->expected_offset = 16; 844 g_bdev_ut_channel->expected_length = 6; 845 g_bdev_ut_channel->expected_iovcnt = 1; 846 g_bdev_ut_channel->expected_iov[0].iov_base = (void *)(0xF000 + 2 * 512); 847 g_bdev_ut_channel->expected_iov[0].iov_len = 6 * 512; 848 849 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 850 stub_complete_io(1); 851 CU_ASSERT(g_io_done == false); 852 853 /* Complete the second child I/O. This should result in our callback getting 854 * invoked since the parent I/O is now complete. 855 */ 856 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 857 stub_complete_io(1); 858 CU_ASSERT(g_io_done == true); 859 860 /* Now set up a more complex, multi-vector command that needs to be split, 861 * including splitting iovecs. 862 */ 863 iov[0].iov_base = (void *)0x10000; 864 iov[0].iov_len = 512; 865 iov[1].iov_base = (void *)0x20000; 866 iov[1].iov_len = 20 * 512; 867 iov[2].iov_base = (void *)0x30000; 868 iov[2].iov_len = 11 * 512; 869 870 g_io_done = false; 871 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_WRITE; 872 g_bdev_ut_channel->expected_offset = 14; 873 g_bdev_ut_channel->expected_length = 2; 874 g_bdev_ut_channel->expected_iovcnt = 2; 875 g_bdev_ut_channel->expected_iov[0].iov_base = (void *)0x10000; 876 g_bdev_ut_channel->expected_iov[0].iov_len = 512; 877 g_bdev_ut_channel->expected_iov[1].iov_base = (void *)0x20000; 878 g_bdev_ut_channel->expected_iov[1].iov_len = 512; 879 880 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 3, 14, 32, io_done, NULL); 881 CU_ASSERT(rc == 0); 882 CU_ASSERT(g_io_done == false); 883 884 g_bdev_ut_channel->expected_offset = 16; 885 g_bdev_ut_channel->expected_length = 16; 886 g_bdev_ut_channel->expected_iovcnt = 1; 887 g_bdev_ut_channel->expected_iov[0].iov_base = (void *)(0x20000 + 512); 888 g_bdev_ut_channel->expected_iov[0].iov_len = 16 * 512; 889 890 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 891 stub_complete_io(1); 892 CU_ASSERT(g_io_done == false); 893 894 g_bdev_ut_channel->expected_offset = 32; 895 g_bdev_ut_channel->expected_length = 14; 896 g_bdev_ut_channel->expected_iovcnt = 2; 897 g_bdev_ut_channel->expected_iov[0].iov_base = (void *)(0x20000 + 17 * 512); 898 g_bdev_ut_channel->expected_iov[0].iov_len = 3 * 512; 899 g_bdev_ut_channel->expected_iov[1].iov_base = (void *)0x30000; 900 g_bdev_ut_channel->expected_iov[1].iov_len = 11 * 512; 901 902 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 903 stub_complete_io(1); 904 CU_ASSERT(g_io_done == false); 905 906 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 907 stub_complete_io(1); 908 CU_ASSERT(g_io_done == true); 909 910 /* Test a WRITE_ZEROES that needs to be split. This is an I/O type that does not have iovecs. 911 * Have this I/O end right on a boundary. Use a non-standard optimal_io_boundary to test the 912 * non-power-of-2 path. 913 */ 914 bdev->optimal_io_boundary = 15; 915 g_io_done = false; 916 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_WRITE_ZEROES; 917 g_bdev_ut_channel->expected_offset = 9; 918 g_bdev_ut_channel->expected_length = 6; 919 g_bdev_ut_channel->expected_iovcnt = 0; 920 921 rc = spdk_bdev_write_zeroes_blocks(desc, io_ch, 9, 36, io_done, NULL); 922 CU_ASSERT(rc == 0); 923 CU_ASSERT(g_io_done == false); 924 925 g_bdev_ut_channel->expected_offset = 15; 926 g_bdev_ut_channel->expected_length = 15; 927 928 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 929 stub_complete_io(1); 930 CU_ASSERT(g_io_done == false); 931 932 g_bdev_ut_channel->expected_offset = 30; 933 g_bdev_ut_channel->expected_length = 15; 934 935 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 936 stub_complete_io(1); 937 CU_ASSERT(g_io_done == false); 938 939 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 940 stub_complete_io(1); 941 CU_ASSERT(g_io_done == true); 942 943 /* Test an UNMAP that needs to be split. This is an I/O type that does not have iovecs. */ 944 bdev->optimal_io_boundary = 16; 945 g_io_done = false; 946 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_UNMAP; 947 g_bdev_ut_channel->expected_offset = 15; 948 g_bdev_ut_channel->expected_length = 1; 949 g_bdev_ut_channel->expected_iovcnt = 0; 950 951 rc = spdk_bdev_unmap_blocks(desc, io_ch, 15, 2, io_done, NULL); 952 CU_ASSERT(rc == 0); 953 CU_ASSERT(g_io_done == false); 954 955 g_bdev_ut_channel->expected_offset = 16; 956 g_bdev_ut_channel->expected_length = 1; 957 958 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 959 stub_complete_io(1); 960 CU_ASSERT(g_io_done == false); 961 962 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 963 stub_complete_io(1); 964 CU_ASSERT(g_io_done == true); 965 966 /* Test an FLUSH that needs to be split. This is an I/O type that does not have iovecs. */ 967 bdev->optimal_io_boundary = 16; 968 g_io_done = false; 969 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_FLUSH; 970 g_bdev_ut_channel->expected_offset = 15; 971 g_bdev_ut_channel->expected_length = 1; 972 g_bdev_ut_channel->expected_iovcnt = 0; 973 974 rc = spdk_bdev_flush_blocks(desc, io_ch, 15, 2, io_done, NULL); 975 CU_ASSERT(rc == 0); 976 CU_ASSERT(g_io_done == false); 977 978 g_bdev_ut_channel->expected_offset = 16; 979 g_bdev_ut_channel->expected_length = 1; 980 981 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 982 stub_complete_io(1); 983 CU_ASSERT(g_io_done == false); 984 985 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 986 stub_complete_io(1); 987 CU_ASSERT(g_io_done == true); 988 989 /* Reset values so next test is not affected by leftover values. */ 990 g_bdev_ut_channel->expected_iotype = SPDK_BDEV_IO_TYPE_INVALID; 991 g_bdev_ut_channel->expected_offset = 0; 992 g_bdev_ut_channel->expected_length = 0; 993 g_bdev_ut_channel->expected_iovcnt = 0; 994 995 spdk_put_io_channel(io_ch); 996 spdk_bdev_close(desc); 997 free_bdev(bdev); 998 spdk_bdev_finish(bdev_fini_cb, NULL); 999 } 1000 1001 int 1002 main(int argc, char **argv) 1003 { 1004 CU_pSuite suite = NULL; 1005 unsigned int num_failures; 1006 1007 if (CU_initialize_registry() != CUE_SUCCESS) { 1008 return CU_get_error(); 1009 } 1010 1011 suite = CU_add_suite("bdev", null_init, null_clean); 1012 if (suite == NULL) { 1013 CU_cleanup_registry(); 1014 return CU_get_error(); 1015 } 1016 1017 if ( 1018 CU_add_test(suite, "bytes_to_blocks_test", bytes_to_blocks_test) == NULL || 1019 CU_add_test(suite, "num_blocks_test", num_blocks_test) == NULL || 1020 CU_add_test(suite, "io_valid", io_valid_test) == NULL || 1021 CU_add_test(suite, "open_write", open_write_test) == NULL || 1022 CU_add_test(suite, "alias_add_del", alias_add_del_test) == NULL || 1023 CU_add_test(suite, "get_device_stat", get_device_stat_test) == NULL || 1024 CU_add_test(suite, "bdev_io_wait", bdev_io_wait_test) == NULL || 1025 CU_add_test(suite, "bdev_io_spans_boundary", bdev_io_spans_boundary_test) == NULL || 1026 CU_add_test(suite, "bdev_io_split", bdev_io_split) == NULL 1027 ) { 1028 CU_cleanup_registry(); 1029 return CU_get_error(); 1030 } 1031 1032 spdk_allocate_thread(_bdev_send_msg, NULL, NULL, NULL, "thread0"); 1033 CU_basic_set_mode(CU_BRM_VERBOSE); 1034 CU_basic_run_tests(); 1035 num_failures = CU_get_number_of_failures(); 1036 CU_cleanup_registry(); 1037 spdk_free_thread(); 1038 return num_failures; 1039 } 1040