1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk_cunit.h" 35 36 #include "common/lib/test_env.c" 37 #include "unit/lib/json_mock.c" 38 39 /* HACK: disable VTune integration so the unit test doesn't need VTune headers and libs to build */ 40 #undef SPDK_CONFIG_VTUNE 41 42 #include "bdev/bdev.c" 43 44 DEFINE_STUB(spdk_conf_find_section, struct spdk_conf_section *, (struct spdk_conf *cp, 45 const char *name), NULL); 46 DEFINE_STUB(spdk_conf_section_get_nmval, char *, 47 (struct spdk_conf_section *sp, const char *key, int idx1, int idx2), NULL); 48 DEFINE_STUB(spdk_conf_section_get_intval, int, (struct spdk_conf_section *sp, const char *key), -1); 49 50 static void 51 _bdev_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 52 { 53 fn(ctx); 54 } 55 56 void 57 spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, 58 int *sc, int *sk, int *asc, int *ascq) 59 { 60 } 61 62 static int 63 null_init(void) 64 { 65 return 0; 66 } 67 68 static int 69 null_clean(void) 70 { 71 return 0; 72 } 73 74 static int 75 stub_destruct(void *ctx) 76 { 77 return 0; 78 } 79 80 struct bdev_ut_channel { 81 TAILQ_HEAD(, spdk_bdev_io) outstanding_io; 82 uint32_t outstanding_io_count; 83 }; 84 85 static uint32_t g_bdev_ut_io_device; 86 static struct bdev_ut_channel *g_bdev_ut_channel; 87 88 static void 89 stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 90 { 91 struct bdev_ut_channel *ch = spdk_io_channel_get_ctx(_ch); 92 93 TAILQ_INSERT_TAIL(&ch->outstanding_io, bdev_io, module_link); 94 ch->outstanding_io_count++; 95 } 96 97 static uint32_t 98 stub_complete_io(uint32_t num_to_complete) 99 { 100 struct bdev_ut_channel *ch = g_bdev_ut_channel; 101 struct spdk_bdev_io *bdev_io; 102 uint32_t num_completed = 0; 103 104 while (num_completed < num_to_complete) { 105 if (TAILQ_EMPTY(&ch->outstanding_io)) { 106 break; 107 } 108 bdev_io = TAILQ_FIRST(&ch->outstanding_io); 109 TAILQ_REMOVE(&ch->outstanding_io, bdev_io, module_link); 110 ch->outstanding_io_count--; 111 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS); 112 num_completed++; 113 } 114 115 return num_completed; 116 } 117 118 static struct spdk_io_channel * 119 bdev_ut_get_io_channel(void *ctx) 120 { 121 return spdk_get_io_channel(&g_bdev_ut_io_device); 122 } 123 124 static struct spdk_bdev_fn_table fn_table = { 125 .destruct = stub_destruct, 126 .submit_request = stub_submit_request, 127 .get_io_channel = bdev_ut_get_io_channel, 128 }; 129 130 static int 131 bdev_ut_create_ch(void *io_device, void *ctx_buf) 132 { 133 struct bdev_ut_channel *ch = ctx_buf; 134 135 CU_ASSERT(g_bdev_ut_channel == NULL); 136 g_bdev_ut_channel = ch; 137 138 TAILQ_INIT(&ch->outstanding_io); 139 ch->outstanding_io_count = 0; 140 return 0; 141 } 142 143 static void 144 bdev_ut_destroy_ch(void *io_device, void *ctx_buf) 145 { 146 CU_ASSERT(g_bdev_ut_channel != NULL); 147 g_bdev_ut_channel = NULL; 148 } 149 150 static int 151 bdev_ut_module_init(void) 152 { 153 spdk_io_device_register(&g_bdev_ut_io_device, bdev_ut_create_ch, bdev_ut_destroy_ch, 154 sizeof(struct bdev_ut_channel)); 155 return 0; 156 } 157 158 static void 159 bdev_ut_module_fini(void) 160 { 161 } 162 163 struct spdk_bdev_module bdev_ut_if = { 164 .name = "bdev_ut", 165 .module_init = bdev_ut_module_init, 166 .module_fini = bdev_ut_module_fini, 167 }; 168 169 static void vbdev_ut_examine(struct spdk_bdev *bdev); 170 171 static int 172 vbdev_ut_module_init(void) 173 { 174 return 0; 175 } 176 177 static void 178 vbdev_ut_module_fini(void) 179 { 180 } 181 182 struct spdk_bdev_module vbdev_ut_if = { 183 .name = "vbdev_ut", 184 .module_init = vbdev_ut_module_init, 185 .module_fini = vbdev_ut_module_fini, 186 .examine_config = vbdev_ut_examine, 187 }; 188 189 SPDK_BDEV_MODULE_REGISTER(&bdev_ut_if) 190 SPDK_BDEV_MODULE_REGISTER(&vbdev_ut_if) 191 192 static void 193 vbdev_ut_examine(struct spdk_bdev *bdev) 194 { 195 spdk_bdev_module_examine_done(&vbdev_ut_if); 196 } 197 198 static bool 199 is_vbdev(struct spdk_bdev *base, struct spdk_bdev *vbdev) 200 { 201 size_t i; 202 int found = 0; 203 204 for (i = 0; i < base->vbdevs_cnt; i++) { 205 found += base->vbdevs[i] == vbdev; 206 } 207 208 CU_ASSERT(found <= 1); 209 return !!found; 210 } 211 212 static bool 213 is_base_bdev(struct spdk_bdev *base, struct spdk_bdev *vbdev) 214 { 215 size_t i; 216 int found = 0; 217 218 for (i = 0; i < vbdev->internal.base_bdevs_cnt; i++) { 219 found += vbdev->internal.base_bdevs[i] == base; 220 } 221 222 CU_ASSERT(found <= 1); 223 return !!found; 224 } 225 226 static bool 227 check_base_and_vbdev(struct spdk_bdev *base, struct spdk_bdev *vbdev) 228 { 229 bool _is_vbdev = is_vbdev(base, vbdev); 230 bool _is_base = is_base_bdev(base, vbdev); 231 232 CU_ASSERT(_is_vbdev == _is_base); 233 234 return _is_base && _is_vbdev; 235 } 236 237 static struct spdk_bdev * 238 allocate_bdev(char *name) 239 { 240 struct spdk_bdev *bdev; 241 int rc; 242 243 bdev = calloc(1, sizeof(*bdev)); 244 SPDK_CU_ASSERT_FATAL(bdev != NULL); 245 246 bdev->name = name; 247 bdev->fn_table = &fn_table; 248 bdev->module = &bdev_ut_if; 249 bdev->blockcnt = 1; 250 251 rc = spdk_bdev_register(bdev); 252 CU_ASSERT(rc == 0); 253 CU_ASSERT(bdev->internal.base_bdevs_cnt == 0); 254 CU_ASSERT(bdev->vbdevs_cnt == 0); 255 256 return bdev; 257 } 258 259 static struct spdk_bdev * 260 allocate_vbdev(char *name, struct spdk_bdev *base1, struct spdk_bdev *base2) 261 { 262 struct spdk_bdev *bdev; 263 struct spdk_bdev *array[2]; 264 int rc; 265 266 bdev = calloc(1, sizeof(*bdev)); 267 SPDK_CU_ASSERT_FATAL(bdev != NULL); 268 269 bdev->name = name; 270 bdev->fn_table = &fn_table; 271 bdev->module = &vbdev_ut_if; 272 273 /* vbdev must have at least one base bdev */ 274 CU_ASSERT(base1 != NULL); 275 276 array[0] = base1; 277 array[1] = base2; 278 279 rc = spdk_vbdev_register(bdev, array, base2 == NULL ? 1 : 2); 280 CU_ASSERT(rc == 0); 281 CU_ASSERT(bdev->internal.base_bdevs_cnt > 0); 282 CU_ASSERT(bdev->vbdevs_cnt == 0); 283 284 CU_ASSERT(check_base_and_vbdev(base1, bdev) == true); 285 286 if (base2) { 287 CU_ASSERT(check_base_and_vbdev(base2, bdev) == true); 288 } 289 290 return bdev; 291 } 292 293 static void 294 free_bdev(struct spdk_bdev *bdev) 295 { 296 spdk_bdev_unregister(bdev, NULL, NULL); 297 memset(bdev, 0xFF, sizeof(*bdev)); 298 free(bdev); 299 } 300 301 static void 302 free_vbdev(struct spdk_bdev *bdev) 303 { 304 CU_ASSERT(bdev->internal.base_bdevs_cnt != 0); 305 spdk_bdev_unregister(bdev, NULL, NULL); 306 memset(bdev, 0xFF, sizeof(*bdev)); 307 free(bdev); 308 } 309 310 static void 311 get_device_stat_cb(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) 312 { 313 const char *bdev_name; 314 315 CU_ASSERT(bdev != NULL); 316 CU_ASSERT(rc == 0); 317 bdev_name = spdk_bdev_get_name(bdev); 318 CU_ASSERT_STRING_EQUAL(bdev_name, "bdev0"); 319 320 free(stat); 321 free_bdev(bdev); 322 } 323 324 static void 325 get_device_stat_test(void) 326 { 327 struct spdk_bdev *bdev; 328 struct spdk_bdev_io_stat *stat; 329 330 bdev = allocate_bdev("bdev0"); 331 stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); 332 if (stat == NULL) { 333 free_bdev(bdev); 334 return; 335 } 336 spdk_bdev_get_device_stat(bdev, stat, get_device_stat_cb, NULL); 337 } 338 339 static void 340 open_write_test(void) 341 { 342 struct spdk_bdev *bdev[9]; 343 struct spdk_bdev_desc *desc[9] = {}; 344 int rc; 345 346 /* 347 * Create a tree of bdevs to test various open w/ write cases. 348 * 349 * bdev0 through bdev3 are physical block devices, such as NVMe 350 * namespaces or Ceph block devices. 351 * 352 * bdev4 is a virtual bdev with multiple base bdevs. This models 353 * caching or RAID use cases. 354 * 355 * bdev5 through bdev7 are all virtual bdevs with the same base 356 * bdev (except bdev7). This models partitioning or logical volume 357 * use cases. 358 * 359 * bdev7 is a virtual bdev with multiple base bdevs. One of base bdevs 360 * (bdev2) is shared with other virtual bdevs: bdev5 and bdev6. This 361 * models caching, RAID, partitioning or logical volumes use cases. 362 * 363 * bdev8 is a virtual bdev with multiple base bdevs, but these 364 * base bdevs are themselves virtual bdevs. 365 * 366 * bdev8 367 * | 368 * +----------+ 369 * | | 370 * bdev4 bdev5 bdev6 bdev7 371 * | | | | 372 * +---+---+ +---+ + +---+---+ 373 * | | \ | / \ 374 * bdev0 bdev1 bdev2 bdev3 375 */ 376 377 bdev[0] = allocate_bdev("bdev0"); 378 rc = spdk_bdev_module_claim_bdev(bdev[0], NULL, &bdev_ut_if); 379 CU_ASSERT(rc == 0); 380 381 bdev[1] = allocate_bdev("bdev1"); 382 rc = spdk_bdev_module_claim_bdev(bdev[1], NULL, &bdev_ut_if); 383 CU_ASSERT(rc == 0); 384 385 bdev[2] = allocate_bdev("bdev2"); 386 rc = spdk_bdev_module_claim_bdev(bdev[2], NULL, &bdev_ut_if); 387 CU_ASSERT(rc == 0); 388 389 bdev[3] = allocate_bdev("bdev3"); 390 rc = spdk_bdev_module_claim_bdev(bdev[3], NULL, &bdev_ut_if); 391 CU_ASSERT(rc == 0); 392 393 bdev[4] = allocate_vbdev("bdev4", bdev[0], bdev[1]); 394 rc = spdk_bdev_module_claim_bdev(bdev[4], NULL, &bdev_ut_if); 395 CU_ASSERT(rc == 0); 396 397 bdev[5] = allocate_vbdev("bdev5", bdev[2], NULL); 398 rc = spdk_bdev_module_claim_bdev(bdev[5], NULL, &bdev_ut_if); 399 CU_ASSERT(rc == 0); 400 401 bdev[6] = allocate_vbdev("bdev6", bdev[2], NULL); 402 403 bdev[7] = allocate_vbdev("bdev7", bdev[2], bdev[3]); 404 405 bdev[8] = allocate_vbdev("bdev8", bdev[4], bdev[5]); 406 407 /* Check tree */ 408 CU_ASSERT(check_base_and_vbdev(bdev[0], bdev[4]) == true); 409 CU_ASSERT(check_base_and_vbdev(bdev[0], bdev[5]) == false); 410 CU_ASSERT(check_base_and_vbdev(bdev[0], bdev[6]) == false); 411 CU_ASSERT(check_base_and_vbdev(bdev[0], bdev[7]) == false); 412 CU_ASSERT(check_base_and_vbdev(bdev[0], bdev[8]) == false); 413 414 CU_ASSERT(check_base_and_vbdev(bdev[1], bdev[4]) == true); 415 CU_ASSERT(check_base_and_vbdev(bdev[1], bdev[5]) == false); 416 CU_ASSERT(check_base_and_vbdev(bdev[1], bdev[6]) == false); 417 CU_ASSERT(check_base_and_vbdev(bdev[1], bdev[7]) == false); 418 CU_ASSERT(check_base_and_vbdev(bdev[1], bdev[8]) == false); 419 420 CU_ASSERT(check_base_and_vbdev(bdev[2], bdev[4]) == false); 421 CU_ASSERT(check_base_and_vbdev(bdev[2], bdev[5]) == true); 422 CU_ASSERT(check_base_and_vbdev(bdev[2], bdev[6]) == true); 423 CU_ASSERT(check_base_and_vbdev(bdev[2], bdev[7]) == true); 424 CU_ASSERT(check_base_and_vbdev(bdev[2], bdev[8]) == false); 425 426 CU_ASSERT(check_base_and_vbdev(bdev[3], bdev[4]) == false); 427 CU_ASSERT(check_base_and_vbdev(bdev[3], bdev[5]) == false); 428 CU_ASSERT(check_base_and_vbdev(bdev[3], bdev[6]) == false); 429 CU_ASSERT(check_base_and_vbdev(bdev[3], bdev[7]) == true); 430 CU_ASSERT(check_base_and_vbdev(bdev[3], bdev[8]) == false); 431 432 /* Open bdev0 read-only. This should succeed. */ 433 rc = spdk_bdev_open(bdev[0], false, NULL, NULL, &desc[0]); 434 CU_ASSERT(rc == 0); 435 SPDK_CU_ASSERT_FATAL(desc[0] != NULL); 436 spdk_bdev_close(desc[0]); 437 438 /* 439 * Open bdev1 read/write. This should fail since bdev1 has been claimed 440 * by a vbdev module. 441 */ 442 rc = spdk_bdev_open(bdev[1], true, NULL, NULL, &desc[1]); 443 CU_ASSERT(rc == -EPERM); 444 445 /* 446 * Open bdev4 read/write. This should fail since bdev3 has been claimed 447 * by a vbdev module. 448 */ 449 rc = spdk_bdev_open(bdev[4], true, NULL, NULL, &desc[4]); 450 CU_ASSERT(rc == -EPERM); 451 452 /* Open bdev4 read-only. This should succeed. */ 453 rc = spdk_bdev_open(bdev[4], false, NULL, NULL, &desc[4]); 454 CU_ASSERT(rc == 0); 455 SPDK_CU_ASSERT_FATAL(desc[4] != NULL); 456 spdk_bdev_close(desc[4]); 457 458 /* 459 * Open bdev8 read/write. This should succeed since it is a leaf 460 * bdev. 461 */ 462 rc = spdk_bdev_open(bdev[8], true, NULL, NULL, &desc[8]); 463 CU_ASSERT(rc == 0); 464 SPDK_CU_ASSERT_FATAL(desc[8] != NULL); 465 spdk_bdev_close(desc[8]); 466 467 /* 468 * Open bdev5 read/write. This should fail since bdev4 has been claimed 469 * by a vbdev module. 470 */ 471 rc = spdk_bdev_open(bdev[5], true, NULL, NULL, &desc[5]); 472 CU_ASSERT(rc == -EPERM); 473 474 /* Open bdev4 read-only. This should succeed. */ 475 rc = spdk_bdev_open(bdev[5], false, NULL, NULL, &desc[5]); 476 CU_ASSERT(rc == 0); 477 SPDK_CU_ASSERT_FATAL(desc[5] != NULL); 478 spdk_bdev_close(desc[5]); 479 480 free_vbdev(bdev[8]); 481 482 free_vbdev(bdev[5]); 483 free_vbdev(bdev[6]); 484 free_vbdev(bdev[7]); 485 486 free_vbdev(bdev[4]); 487 488 free_bdev(bdev[0]); 489 free_bdev(bdev[1]); 490 free_bdev(bdev[2]); 491 free_bdev(bdev[3]); 492 } 493 494 static void 495 bytes_to_blocks_test(void) 496 { 497 struct spdk_bdev bdev; 498 uint64_t offset_blocks, num_blocks; 499 500 memset(&bdev, 0, sizeof(bdev)); 501 502 bdev.blocklen = 512; 503 504 /* All parameters valid */ 505 offset_blocks = 0; 506 num_blocks = 0; 507 CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 1024, &num_blocks) == 0); 508 CU_ASSERT(offset_blocks == 1); 509 CU_ASSERT(num_blocks == 2); 510 511 /* Offset not a block multiple */ 512 CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 3, &offset_blocks, 512, &num_blocks) != 0); 513 514 /* Length not a block multiple */ 515 CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 3, &num_blocks) != 0); 516 } 517 518 static void 519 num_blocks_test(void) 520 { 521 struct spdk_bdev bdev; 522 struct spdk_bdev_desc *desc = NULL; 523 int rc; 524 525 memset(&bdev, 0, sizeof(bdev)); 526 bdev.name = "num_blocks"; 527 bdev.fn_table = &fn_table; 528 bdev.module = &bdev_ut_if; 529 spdk_bdev_register(&bdev); 530 spdk_bdev_notify_blockcnt_change(&bdev, 50); 531 532 /* Growing block number */ 533 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 70) == 0); 534 /* Shrinking block number */ 535 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 30) == 0); 536 537 /* In case bdev opened */ 538 rc = spdk_bdev_open(&bdev, false, NULL, NULL, &desc); 539 CU_ASSERT(rc == 0); 540 SPDK_CU_ASSERT_FATAL(desc != NULL); 541 542 /* Growing block number */ 543 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 80) == 0); 544 /* Shrinking block number */ 545 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 20) != 0); 546 547 spdk_bdev_close(desc); 548 spdk_bdev_unregister(&bdev, NULL, NULL); 549 } 550 551 static void 552 io_valid_test(void) 553 { 554 struct spdk_bdev bdev; 555 556 memset(&bdev, 0, sizeof(bdev)); 557 558 bdev.blocklen = 512; 559 spdk_bdev_notify_blockcnt_change(&bdev, 100); 560 561 /* All parameters valid */ 562 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 1, 2) == true); 563 564 /* Last valid block */ 565 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 99, 1) == true); 566 567 /* Offset past end of bdev */ 568 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 100, 1) == false); 569 570 /* Offset + length past end of bdev */ 571 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 99, 2) == false); 572 573 /* Offset near end of uint64_t range (2^64 - 1) */ 574 CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 18446744073709551615ULL, 1) == false); 575 } 576 577 static void 578 alias_add_del_test(void) 579 { 580 struct spdk_bdev *bdev[2]; 581 int rc; 582 583 /* Creating and registering bdevs */ 584 bdev[0] = allocate_bdev("bdev0"); 585 SPDK_CU_ASSERT_FATAL(bdev[0] != 0); 586 587 bdev[1] = allocate_bdev("bdev1"); 588 SPDK_CU_ASSERT_FATAL(bdev[1] != 0); 589 590 /* 591 * Trying adding an alias identical to name. 592 * Alias is identical to name, so it can not be added to aliases list 593 */ 594 rc = spdk_bdev_alias_add(bdev[0], bdev[0]->name); 595 CU_ASSERT(rc == -EEXIST); 596 597 /* 598 * Trying to add empty alias, 599 * this one should fail 600 */ 601 rc = spdk_bdev_alias_add(bdev[0], NULL); 602 CU_ASSERT(rc == -EINVAL); 603 604 /* Trying adding same alias to two different registered bdevs */ 605 606 /* Alias is used first time, so this one should pass */ 607 rc = spdk_bdev_alias_add(bdev[0], "proper alias 0"); 608 CU_ASSERT(rc == 0); 609 610 /* Alias was added to another bdev, so this one should fail */ 611 rc = spdk_bdev_alias_add(bdev[1], "proper alias 0"); 612 CU_ASSERT(rc == -EEXIST); 613 614 /* Alias is used first time, so this one should pass */ 615 rc = spdk_bdev_alias_add(bdev[1], "proper alias 1"); 616 CU_ASSERT(rc == 0); 617 618 /* Trying removing an alias from registered bdevs */ 619 620 /* Alias is not on a bdev aliases list, so this one should fail */ 621 rc = spdk_bdev_alias_del(bdev[0], "not existing"); 622 CU_ASSERT(rc == -ENOENT); 623 624 /* Alias is present on a bdev aliases list, so this one should pass */ 625 rc = spdk_bdev_alias_del(bdev[0], "proper alias 0"); 626 CU_ASSERT(rc == 0); 627 628 /* Alias is present on a bdev aliases list, so this one should pass */ 629 rc = spdk_bdev_alias_del(bdev[1], "proper alias 1"); 630 CU_ASSERT(rc == 0); 631 632 /* Trying to remove name instead of alias, so this one should fail, name cannot be changed or removed */ 633 rc = spdk_bdev_alias_del(bdev[0], bdev[0]->name); 634 CU_ASSERT(rc != 0); 635 636 /* Unregister and free bdevs */ 637 spdk_bdev_unregister(bdev[0], NULL, NULL); 638 spdk_bdev_unregister(bdev[1], NULL, NULL); 639 640 free(bdev[0]); 641 free(bdev[1]); 642 } 643 644 static void 645 io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 646 { 647 spdk_bdev_free_io(bdev_io); 648 } 649 650 static void 651 bdev_init_cb(void *arg, int rc) 652 { 653 CU_ASSERT(rc == 0); 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 } 747 748 int 749 main(int argc, char **argv) 750 { 751 CU_pSuite suite = NULL; 752 unsigned int num_failures; 753 754 if (CU_initialize_registry() != CUE_SUCCESS) { 755 return CU_get_error(); 756 } 757 758 suite = CU_add_suite("bdev", null_init, null_clean); 759 if (suite == NULL) { 760 CU_cleanup_registry(); 761 return CU_get_error(); 762 } 763 764 if ( 765 CU_add_test(suite, "bytes_to_blocks_test", bytes_to_blocks_test) == NULL || 766 CU_add_test(suite, "num_blocks_test", num_blocks_test) == NULL || 767 CU_add_test(suite, "io_valid", io_valid_test) == NULL || 768 CU_add_test(suite, "open_write", open_write_test) == NULL || 769 CU_add_test(suite, "alias_add_del", alias_add_del_test) == NULL || 770 CU_add_test(suite, "get_device_stat", get_device_stat_test) == NULL || 771 CU_add_test(suite, "bdev_io_wait", bdev_io_wait_test) == NULL 772 ) { 773 CU_cleanup_registry(); 774 return CU_get_error(); 775 } 776 777 spdk_allocate_thread(_bdev_send_msg, NULL, NULL, NULL, "thread0"); 778 CU_basic_set_mode(CU_BRM_VERBOSE); 779 CU_basic_run_tests(); 780 num_failures = CU_get_number_of_failures(); 781 CU_cleanup_registry(); 782 spdk_free_thread(); 783 return num_failures; 784 } 785