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