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