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