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 #include "spdk/string.h" 36 37 #include "vbdev_lvol.c" 38 39 #define SPDK_BS_PAGE_SIZE 0x1000 40 41 int g_lvolerrno; 42 int g_lvserrno; 43 int g_cluster_size; 44 int g_registered_bdevs; 45 int g_num_lvols = 0; 46 struct spdk_lvol_store *g_lvs = NULL; 47 struct spdk_lvol *g_lvol = NULL; 48 struct lvol_store_bdev *g_lvs_bdev = NULL; 49 struct spdk_bdev *g_base_bdev = NULL; 50 struct spdk_bdev_io *g_io = NULL; 51 struct spdk_io_channel *g_ch = NULL; 52 struct lvol_task *g_task = NULL; 53 54 static struct spdk_bdev g_bdev = {}; 55 static struct spdk_bs_dev *g_bs_dev = NULL; 56 static struct spdk_lvol_store *g_lvol_store = NULL; 57 bool lvol_store_initialize_fail = false; 58 bool lvol_store_initialize_cb_fail = false; 59 bool lvol_already_opened = false; 60 bool g_examine_done = false; 61 62 void 63 spdk_bdev_unregister_done(struct spdk_bdev *bdev, int bdeverrno) 64 { 65 } 66 67 void 68 spdk_lvol_open(struct spdk_lvol *lvol, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 69 { 70 cb_fn(cb_arg, lvol, g_lvolerrno); 71 } 72 73 void 74 spdk_bs_md_close_blob(struct spdk_blob **b, spdk_blob_op_complete cb_fn, void *cb_arg) 75 { 76 } 77 78 static struct spdk_lvol *_lvol_create(struct spdk_lvol_store *lvs); 79 80 void 81 spdk_lvs_load(struct spdk_bs_dev *dev, 82 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 83 { 84 struct spdk_lvol_store *lvs; 85 int i; 86 87 if (g_lvserrno == 0) { 88 lvs = calloc(1, sizeof(*lvs)); 89 SPDK_CU_ASSERT_FATAL(lvs != NULL); 90 TAILQ_INIT(&lvs->lvols); 91 g_lvol_store = lvs; 92 for (i = 0; i < g_num_lvols; i++) { 93 _lvol_create(lvs); 94 } 95 } 96 97 cb_fn(cb_arg, g_lvol_store, g_lvserrno); 98 } 99 100 int 101 spdk_bs_bdev_claim(struct spdk_bs_dev *bs_dev, struct spdk_bdev_module_if *module) 102 { 103 if (lvol_already_opened == true) { 104 return -1; 105 } 106 107 lvol_already_opened = true; 108 109 return 0; 110 } 111 112 void 113 spdk_vbdev_unregister(struct spdk_bdev *vbdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg) 114 { 115 SPDK_CU_ASSERT_FATAL(vbdev != NULL); 116 vbdev->fn_table->destruct(vbdev->ctxt); 117 } 118 119 void 120 spdk_bdev_module_finish_done(void) 121 { 122 return; 123 } 124 125 uint64_t 126 spdk_bs_get_page_size(struct spdk_blob_store *bs) 127 { 128 return SPDK_BS_PAGE_SIZE; 129 } 130 131 static void 132 bdev_blob_destroy(struct spdk_bs_dev *bs_dev) 133 { 134 CU_ASSERT(g_bs_dev != NULL); 135 CU_ASSERT(bs_dev != NULL); 136 CU_ASSERT(g_bs_dev == bs_dev); 137 free(bs_dev); 138 g_bs_dev = NULL; 139 lvol_already_opened = false; 140 } 141 142 struct spdk_bs_dev * 143 spdk_bdev_create_bs_dev(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx) 144 { 145 struct spdk_bs_dev *bs_dev; 146 147 if (lvol_already_opened == true || bdev == NULL) { 148 return NULL; 149 } 150 151 bs_dev = calloc(1, sizeof(*bs_dev)); 152 SPDK_CU_ASSERT_FATAL(bs_dev != NULL); 153 bs_dev->destroy = bdev_blob_destroy; 154 155 CU_ASSERT(g_bs_dev == NULL); 156 g_bs_dev = bs_dev; 157 return bs_dev; 158 } 159 160 void 161 spdk_lvs_opts_init(struct spdk_lvs_opts *opts) 162 { 163 } 164 165 int 166 spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o, 167 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 168 { 169 struct spdk_lvol_store *lvs; 170 int error = 0; 171 172 if (lvol_store_initialize_fail) { 173 return -1; 174 } 175 176 if (lvol_store_initialize_cb_fail) { 177 bs_dev->destroy(bs_dev); 178 lvs = NULL; 179 error = -1; 180 } else { 181 lvs = calloc(1, sizeof(*lvs)); 182 SPDK_CU_ASSERT_FATAL(lvs != NULL); 183 TAILQ_INIT(&lvs->lvols); 184 lvs->bs_dev = bs_dev; 185 error = 0; 186 } 187 cb_fn(cb_arg, lvs, error); 188 189 return 0; 190 } 191 192 int 193 spdk_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg) 194 { 195 struct spdk_lvol *lvol, *tmp; 196 197 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 198 TAILQ_REMOVE(&lvs->lvols, lvol, link); 199 free(lvol->old_name); 200 free(lvol); 201 } 202 g_lvol_store = NULL; 203 free(lvs); 204 205 g_bs_dev->destroy(g_bs_dev); 206 207 if (cb_fn != NULL) { 208 cb_fn(cb_arg, 0); 209 } 210 211 return 0; 212 } 213 214 int 215 spdk_lvs_destroy(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, 216 void *cb_arg) 217 { 218 struct spdk_lvol *lvol, *tmp; 219 220 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 221 TAILQ_REMOVE(&lvs->lvols, lvol, link); 222 free(lvol->old_name); 223 free(lvol); 224 } 225 g_lvol_store = NULL; 226 free(lvs); 227 228 g_bs_dev->destroy(g_bs_dev); 229 230 if (cb_fn != NULL) { 231 cb_fn(cb_arg, 0); 232 } 233 234 return 0; 235 } 236 237 int 238 spdk_lvol_resize(struct spdk_lvol *lvol, size_t sz, spdk_lvol_op_complete cb_fn, void *cb_arg) 239 { 240 cb_fn(cb_arg, 0); 241 242 return 0; 243 } 244 245 uint64_t 246 spdk_bs_get_cluster_size(struct spdk_blob_store *bs) 247 { 248 return g_cluster_size; 249 } 250 251 struct spdk_bdev * 252 spdk_bdev_get_by_name(const char *bdev_name) 253 { 254 if (!strcmp(g_base_bdev->name, bdev_name)) { 255 return g_base_bdev; 256 } 257 258 return NULL; 259 } 260 261 void 262 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 263 { 264 struct spdk_lvs_req *destruct_req; 265 struct spdk_lvol *iter_lvol, *tmp; 266 bool all_lvols_closed = true; 267 268 lvol->ref_count--; 269 270 TAILQ_FOREACH_SAFE(iter_lvol, &lvol->lvol_store->lvols, link, tmp) { 271 if (iter_lvol->ref_count != 0) { 272 all_lvols_closed = false; 273 } 274 } 275 276 destruct_req = lvol->lvol_store->destruct_req; 277 if (destruct_req && all_lvols_closed == true) { 278 if (!lvol->lvol_store->destruct) { 279 spdk_lvs_unload(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg); 280 free(destruct_req); 281 } 282 } 283 284 cb_fn(cb_arg, 0); 285 } 286 287 void 288 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 289 { 290 struct spdk_lvs_req *destruct_req; 291 292 SPDK_CU_ASSERT_FATAL(lvol == g_lvol); 293 294 if (lvol->ref_count != 0) { 295 cb_fn(cb_arg, -ENODEV); 296 } 297 298 TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link); 299 300 destruct_req = lvol->lvol_store->destruct_req; 301 if (destruct_req && TAILQ_EMPTY(&lvol->lvol_store->lvols)) { 302 if (!lvol->lvol_store->destruct) { 303 spdk_lvs_unload(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg); 304 } else { 305 spdk_lvs_destroy(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg); 306 free(destruct_req); 307 } 308 } 309 g_lvol = NULL; 310 free(lvol->old_name); 311 free(lvol); 312 313 cb_fn(cb_arg, 0); 314 } 315 316 void 317 spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status) 318 { 319 } 320 321 struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol) 322 { 323 CU_ASSERT(lvol == g_lvol); 324 return g_ch; 325 } 326 327 void 328 spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len) 329 { 330 CU_ASSERT(cb == lvol_read); 331 } 332 333 void 334 spdk_bs_io_read_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 335 void *payload, uint64_t offset, uint64_t length, 336 spdk_blob_op_complete cb_fn, void *cb_arg) 337 { 338 } 339 340 void 341 spdk_bs_io_write_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 342 void *payload, uint64_t offset, uint64_t length, 343 spdk_blob_op_complete cb_fn, void *cb_arg) 344 { 345 } 346 347 void 348 spdk_bs_io_unmap_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 349 uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg) 350 { 351 CU_ASSERT(blob == NULL); 352 CU_ASSERT(channel == g_ch); 353 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 354 CU_ASSERT(length == g_io->u.bdev.num_blocks); 355 } 356 357 void 358 spdk_bs_io_write_zeroes_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 359 uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg) 360 { 361 CU_ASSERT(blob == NULL); 362 CU_ASSERT(channel == g_ch); 363 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 364 CU_ASSERT(length == g_io->u.bdev.num_blocks); 365 } 366 367 void 368 spdk_bs_io_writev_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 369 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length, 370 spdk_blob_op_complete cb_fn, void *cb_arg) 371 { 372 CU_ASSERT(blob == NULL); 373 CU_ASSERT(channel == g_ch); 374 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 375 CU_ASSERT(length == g_io->u.bdev.num_blocks); 376 } 377 378 void 379 spdk_bs_io_readv_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 380 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length, 381 spdk_blob_op_complete cb_fn, void *cb_arg) 382 { 383 CU_ASSERT(blob == NULL); 384 CU_ASSERT(channel == g_ch); 385 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 386 CU_ASSERT(length == g_io->u.bdev.num_blocks); 387 } 388 389 void 390 spdk_bs_io_flush_channel(struct spdk_io_channel *channel, spdk_blob_op_complete cb_fn, void *cb_arg) 391 { 392 } 393 394 void 395 spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module) 396 { 397 } 398 399 int 400 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name) 401 { 402 return 0; 403 } 404 405 int 406 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val) 407 { 408 return 0; 409 } 410 411 int 412 spdk_json_write_object_begin(struct spdk_json_write_ctx *w) 413 { 414 return 0; 415 } 416 417 int 418 spdk_json_write_object_end(struct spdk_json_write_ctx *w) 419 { 420 return 0; 421 } 422 423 const char * 424 spdk_bdev_get_name(const struct spdk_bdev *bdev) 425 { 426 return "test"; 427 } 428 429 int 430 spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs, int base_bdev_count) 431 { 432 g_registered_bdevs++; 433 return 0; 434 } 435 436 void 437 spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module) 438 { 439 g_examine_done = true; 440 } 441 442 static struct spdk_lvol * 443 _lvol_create(struct spdk_lvol_store *lvs) 444 { 445 struct spdk_lvol *lvol = calloc(1, sizeof(*lvol)); 446 447 SPDK_CU_ASSERT_FATAL(lvol != NULL); 448 449 lvol->lvol_store = lvs; 450 lvol->ref_count++; 451 lvol->old_name = spdk_sprintf_alloc("%s", "UNIT_TEST_UUID"); 452 SPDK_CU_ASSERT_FATAL(lvol->old_name != NULL); 453 454 TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link); 455 456 return lvol; 457 } 458 459 int 460 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz, 461 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 462 { 463 struct spdk_lvol *lvol; 464 465 lvol = _lvol_create(lvs); 466 cb_fn(cb_arg, lvol, 0); 467 468 return 0; 469 } 470 471 static void 472 lvol_store_op_complete(void *cb_arg, int lvserrno) 473 { 474 g_lvserrno = lvserrno; 475 return; 476 } 477 478 static void 479 lvol_store_op_with_handle_complete(void *cb_arg, struct spdk_lvol_store *lvs, int lvserrno) 480 { 481 g_lvserrno = lvserrno; 482 g_lvol_store = lvs; 483 return; 484 } 485 486 static void 487 vbdev_lvol_create_complete(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 488 { 489 g_lvolerrno = lvolerrno; 490 g_lvol = lvol; 491 } 492 493 static void 494 vbdev_lvol_resize_complete(void *cb_arg, int lvolerrno) 495 { 496 g_lvolerrno = lvolerrno; 497 } 498 499 static void 500 ut_lvs_destroy(void) 501 { 502 int rc = 0; 503 int sz = 10; 504 struct spdk_lvol_store *lvs; 505 506 /* Lvol store is succesfully created */ 507 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 508 CU_ASSERT(rc == 0); 509 CU_ASSERT(g_lvserrno == 0); 510 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 511 CU_ASSERT(g_bs_dev != NULL); 512 513 lvs = g_lvol_store; 514 g_lvol_store = NULL; 515 516 uuid_generate_time(lvs->uuid); 517 518 /* Suuccessfully create lvol, which should be unloaded with lvs later */ 519 g_lvolerrno = -1; 520 rc = vbdev_lvol_create(lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 521 CU_ASSERT(rc == 0); 522 CU_ASSERT(g_lvolerrno == 0); 523 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 524 525 /* Unload lvol store */ 526 vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL); 527 CU_ASSERT(g_lvserrno == 0); 528 CU_ASSERT(g_lvol_store == NULL); 529 } 530 531 static void 532 ut_lvol_init(void) 533 { 534 int sz = 10; 535 int rc; 536 537 g_lvs = calloc(1, sizeof(*g_lvs)); 538 SPDK_CU_ASSERT_FATAL(g_lvs != NULL); 539 TAILQ_INIT(&g_lvs->lvols); 540 g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev)); 541 SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL); 542 g_base_bdev = calloc(1, sizeof(*g_base_bdev)); 543 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 544 545 g_lvs_bdev->lvs = g_lvs; 546 g_lvs_bdev->bdev = g_base_bdev; 547 548 uuid_generate_time(g_lvs->uuid); 549 550 TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 551 552 /* Successful lvol create */ 553 g_lvolerrno = -1; 554 rc = vbdev_lvol_create(g_lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 555 SPDK_CU_ASSERT_FATAL(rc == 0); 556 CU_ASSERT(g_lvol != NULL); 557 CU_ASSERT(g_lvolerrno == 0); 558 559 /* Successful lvol destruct */ 560 vbdev_lvol_destruct(g_lvol); 561 CU_ASSERT(g_lvol == NULL); 562 563 TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 564 565 free(g_lvs); 566 free(g_lvs_bdev); 567 free(g_base_bdev); 568 569 570 } 571 572 static void 573 ut_lvol_hotremove(void) 574 { 575 int rc = 0; 576 577 lvol_store_initialize_fail = false; 578 lvol_store_initialize_cb_fail = false; 579 lvol_already_opened = false; 580 g_bs_dev = NULL; 581 582 /* Lvol store is succesfully created */ 583 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 584 CU_ASSERT(rc == 0); 585 CU_ASSERT(g_lvserrno == 0); 586 CU_ASSERT(g_lvol_store != NULL); 587 CU_ASSERT(g_bs_dev != NULL); 588 589 /* Hot remove callback with NULL - stability check */ 590 vbdev_lvs_hotremove_cb(NULL); 591 592 /* Hot remove lvs on bdev removal */ 593 vbdev_lvs_hotremove_cb(&g_bdev); 594 595 CU_ASSERT(g_lvol_store == NULL); 596 CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs)); 597 598 } 599 600 static void 601 ut_lvol_examine(void) 602 { 603 struct spdk_bdev *bdev; 604 605 lvol_already_opened = false; 606 g_bs_dev = NULL; 607 g_lvserrno = 0; 608 g_examine_done = false; 609 610 /* Examine with NULL bdev */ 611 vbdev_lvs_examine(NULL); 612 CU_ASSERT(g_bs_dev == NULL); 613 CU_ASSERT(g_lvol_store == NULL); 614 CU_ASSERT(g_examine_done == true); 615 616 /* Examine unsuccessfully - bdev already opened */ 617 g_bs_dev = NULL; 618 g_examine_done = false; 619 g_lvserrno = -1; 620 lvol_already_opened = true; 621 vbdev_lvs_examine(&g_bdev); 622 CU_ASSERT(g_bs_dev == NULL); 623 CU_ASSERT(g_lvol_store == NULL); 624 CU_ASSERT(g_examine_done == true); 625 626 /* Examine unsuccessfully - fail on lvol store */ 627 g_bs_dev = NULL; 628 g_examine_done = false; 629 g_lvserrno = -1; 630 lvol_already_opened = false; 631 vbdev_lvs_examine(&g_bdev); 632 CU_ASSERT(g_bs_dev != NULL); 633 CU_ASSERT(g_lvol_store == NULL); 634 CU_ASSERT(g_examine_done == true); 635 CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs)); 636 free(g_bs_dev); 637 638 /* Examine unsuccesfully - fail on lvol load */ 639 g_bs_dev = NULL; 640 g_lvserrno = 0; 641 g_lvolerrno = -1; 642 g_num_lvols = 1; 643 g_examine_done = false; 644 lvol_already_opened = false; 645 g_registered_bdevs = 0; 646 vbdev_lvs_examine(&g_bdev); 647 CU_ASSERT(g_bs_dev != NULL); 648 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 649 CU_ASSERT(g_examine_done == true); 650 CU_ASSERT(g_registered_bdevs == 0); 651 CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs)); 652 CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols)); 653 vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); 654 free(g_bs_dev); 655 656 /* Examine succesfully */ 657 g_bs_dev = NULL; 658 g_lvserrno = 0; 659 g_lvolerrno = 0; 660 g_examine_done = false; 661 g_registered_bdevs = 0; 662 lvol_already_opened = false; 663 vbdev_lvs_examine(&g_bdev); 664 CU_ASSERT(g_bs_dev != NULL); 665 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 666 CU_ASSERT(g_examine_done == true); 667 CU_ASSERT(g_registered_bdevs != 0); 668 CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs)); 669 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols)); 670 TAILQ_FIRST(&g_lvol_store->lvols)->ref_count--; 671 bdev = TAILQ_FIRST(&g_lvol_store->lvols)->bdev; 672 vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); 673 free(bdev->name); 674 free(bdev); 675 free(g_bs_dev); 676 free(g_lvol_store); 677 } 678 679 static void 680 ut_lvol_resize(void) 681 { 682 int sz = 10; 683 int rc = 0; 684 685 g_lvs = calloc(1, sizeof(*g_lvs)); 686 SPDK_CU_ASSERT_FATAL(g_lvs != NULL); 687 688 TAILQ_INIT(&g_lvs->lvols); 689 690 g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev)); 691 SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL); 692 g_base_bdev = calloc(1, sizeof(*g_base_bdev)); 693 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 694 g_lvs_bdev->lvs = g_lvs; 695 g_lvs_bdev->bdev = g_base_bdev; 696 697 698 uuid_generate_time(g_lvs->uuid); 699 g_base_bdev->blocklen = 4096; 700 TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 701 702 /* Successful lvol create */ 703 g_lvolerrno = -1; 704 rc = vbdev_lvol_create(g_lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 705 CU_ASSERT(rc == 0); 706 CU_ASSERT(g_lvolerrno == 0); 707 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 708 709 g_base_bdev->ctxt = g_lvol; 710 711 g_base_bdev->name = spdk_sprintf_alloc("%s", g_lvol->old_name); 712 SPDK_CU_ASSERT_FATAL(g_base_bdev->name != NULL); 713 714 /* Successful lvol resize */ 715 rc = vbdev_lvol_resize(g_lvol->old_name, 20, vbdev_lvol_resize_complete, NULL); 716 CU_ASSERT(rc == 0); 717 CU_ASSERT(g_base_bdev->blockcnt == 20 * g_cluster_size / g_base_bdev->blocklen); 718 719 /* Resize with wrong bdev name */ 720 rc = vbdev_lvol_resize("wrong name", 20, vbdev_lvol_resize_complete, NULL); 721 CU_ASSERT(rc != 0); 722 723 /* Resize with correct bdev name, but wrong lvol name */ 724 free(g_lvol->old_name); 725 g_lvol->old_name = strdup("wrong name"); 726 SPDK_CU_ASSERT_FATAL(g_lvol->old_name != NULL); 727 rc = vbdev_lvol_resize(g_base_bdev->name, 20, vbdev_lvol_resize_complete, NULL); 728 CU_ASSERT(rc != 0); 729 730 /* Successful lvol destruct */ 731 vbdev_lvol_destruct(g_lvol); 732 CU_ASSERT(g_lvol == NULL); 733 734 TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 735 free(g_lvs); 736 free(g_lvs_bdev); 737 free(g_base_bdev->name); 738 free(g_base_bdev); 739 } 740 741 static void 742 ut_lvs_unload(void) 743 { 744 int rc = 0; 745 int sz = 10; 746 struct spdk_lvol_store *lvs; 747 748 /* Lvol store is succesfully created */ 749 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 750 CU_ASSERT(rc == 0); 751 CU_ASSERT(g_lvserrno == 0); 752 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 753 CU_ASSERT(g_bs_dev != NULL); 754 755 lvs = g_lvol_store; 756 g_lvol_store = NULL; 757 758 uuid_generate_time(lvs->uuid); 759 760 /* Suuccessfully create lvol, which should be destroyed with lvs later */ 761 g_lvolerrno = -1; 762 rc = vbdev_lvol_create(lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 763 CU_ASSERT(rc == 0); 764 CU_ASSERT(g_lvolerrno == 0); 765 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 766 767 /* Unload lvol store */ 768 vbdev_lvs_unload(lvs, lvol_store_op_complete, NULL); 769 CU_ASSERT(g_lvserrno == 0); 770 CU_ASSERT(g_lvol_store == NULL); 771 CU_ASSERT(g_lvol != NULL); 772 } 773 774 static void 775 ut_lvs_init(void) 776 { 777 int rc = 0; 778 struct spdk_lvol_store *lvs; 779 struct spdk_bs_dev *bs_dev_temp; 780 781 /* spdk_lvs_init() fails */ 782 lvol_store_initialize_fail = true; 783 784 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 785 CU_ASSERT(rc != 0); 786 CU_ASSERT(g_lvserrno == 0); 787 CU_ASSERT(g_lvol_store == NULL); 788 CU_ASSERT(g_bs_dev == NULL); 789 790 lvol_store_initialize_fail = false; 791 792 /* spdk_lvs_init_cb() fails */ 793 lvol_store_initialize_cb_fail = true; 794 795 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 796 CU_ASSERT(rc == 0); 797 CU_ASSERT(g_lvserrno != 0); 798 CU_ASSERT(g_lvol_store == NULL); 799 CU_ASSERT(g_bs_dev == NULL); 800 801 lvol_store_initialize_cb_fail = false; 802 803 /* Lvol store is succesfully created */ 804 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 805 CU_ASSERT(rc == 0); 806 CU_ASSERT(g_lvserrno == 0); 807 CU_ASSERT(g_lvol_store != NULL); 808 CU_ASSERT(g_bs_dev != NULL); 809 810 lvs = g_lvol_store; 811 g_lvol_store = NULL; 812 bs_dev_temp = g_bs_dev; 813 g_bs_dev = NULL; 814 815 /* Bdev with lvol store already claimed */ 816 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 817 CU_ASSERT(rc != 0); 818 CU_ASSERT(g_lvserrno == 0); 819 CU_ASSERT(g_lvol_store == NULL); 820 CU_ASSERT(g_bs_dev == NULL); 821 822 /* Destruct lvol store */ 823 g_bs_dev = bs_dev_temp; 824 825 vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL); 826 CU_ASSERT(g_lvserrno == 0); 827 CU_ASSERT(g_lvol_store == NULL); 828 CU_ASSERT(g_bs_dev == NULL); 829 free(g_bs_dev); 830 831 } 832 833 static void 834 ut_vbdev_lvol_get_io_channel(void) 835 { 836 struct spdk_io_channel *ch; 837 838 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 839 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 840 841 ch = vbdev_lvol_get_io_channel(g_lvol); 842 CU_ASSERT(ch == g_ch); 843 844 free(g_lvol); 845 846 } 847 848 static void 849 ut_vbdev_lvol_io_type_supported(void) 850 { 851 struct spdk_lvol *lvol = g_lvol; 852 bool ret; 853 /* Supported types */ 854 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ); 855 CU_ASSERT(ret == true); 856 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE); 857 CU_ASSERT(ret == true); 858 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH); 859 CU_ASSERT(ret == true); 860 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET); 861 CU_ASSERT(ret == true); 862 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP); 863 CU_ASSERT(ret == true); 864 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES); 865 CU_ASSERT(ret == true); 866 867 /* Unsupported types */ 868 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN); 869 CU_ASSERT(ret == false); 870 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO); 871 CU_ASSERT(ret == false); 872 } 873 874 static void 875 ut_lvol_op_comp(void) 876 { 877 struct lvol_task task; 878 879 lvol_op_comp(&task, 1); 880 CU_ASSERT(task.status == SPDK_BDEV_IO_STATUS_FAILED); 881 } 882 883 static void 884 ut_lvol_flush(void) 885 { 886 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 887 SPDK_CU_ASSERT_FATAL(g_io != NULL); 888 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 889 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 890 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 891 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 892 893 g_task = (struct lvol_task *)g_io->driver_ctx; 894 g_io->bdev = g_base_bdev; 895 g_io->bdev->ctxt = g_lvol; 896 897 /* Successful flush to lvol */ 898 lvol_flush(g_ch, g_io); 899 900 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 901 902 free(g_io); 903 free(g_base_bdev); 904 free(g_lvol); 905 } 906 907 static void 908 ut_lvol_read_write(void) 909 { 910 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 911 SPDK_CU_ASSERT_FATAL(g_io != NULL); 912 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 913 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 914 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 915 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 916 917 g_task = (struct lvol_task *)g_io->driver_ctx; 918 g_io->bdev = g_base_bdev; 919 g_io->bdev->ctxt = g_lvol; 920 g_io->u.bdev.offset_blocks = 20; 921 g_io->u.bdev.num_blocks = 20; 922 923 lvol_read(g_ch, g_io); 924 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 925 926 lvol_write(g_lvol, g_ch, g_io); 927 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 928 929 free(g_io); 930 free(g_base_bdev); 931 free(g_lvol); 932 } 933 934 static void 935 ut_vbdev_lvol_submit_request(void) 936 { 937 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 938 SPDK_CU_ASSERT_FATAL(g_io != NULL); 939 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 940 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 941 g_task = (struct lvol_task *)g_io->driver_ctx; 942 943 g_io->bdev = g_base_bdev; 944 945 g_io->type = SPDK_BDEV_IO_TYPE_READ; 946 vbdev_lvol_submit_request(g_ch, g_io); 947 948 free(g_io); 949 free(g_base_bdev); 950 } 951 952 int main(int argc, char **argv) 953 { 954 CU_pSuite suite = NULL; 955 unsigned int num_failures; 956 957 if (CU_initialize_registry() != CUE_SUCCESS) { 958 return CU_get_error(); 959 } 960 961 suite = CU_add_suite("lvol", NULL, NULL); 962 if (suite == NULL) { 963 CU_cleanup_registry(); 964 return CU_get_error(); 965 } 966 967 if ( 968 CU_add_test(suite, "ut_lvs_init", ut_lvs_init) == NULL || 969 CU_add_test(suite, "ut_lvol_init", ut_lvol_init) == NULL || 970 CU_add_test(suite, "ut_lvs_destroy", ut_lvs_destroy) == NULL || 971 CU_add_test(suite, "ut_lvs_unload", ut_lvs_unload) == NULL || 972 CU_add_test(suite, "ut_lvol_resize", ut_lvol_resize) == NULL || 973 CU_add_test(suite, "lvol_hotremove", ut_lvol_hotremove) == NULL || 974 CU_add_test(suite, "ut_vbdev_lvol_get_io_channel", ut_vbdev_lvol_get_io_channel) == NULL || 975 CU_add_test(suite, "ut_vbdev_lvol_io_type_supported", ut_vbdev_lvol_io_type_supported) == NULL || 976 CU_add_test(suite, "ut_lvol_op_comp", ut_lvol_op_comp) == NULL || 977 CU_add_test(suite, "ut_lvol_flush", ut_lvol_flush) == NULL || 978 CU_add_test(suite, "ut_lvol_read_write", ut_lvol_read_write) == NULL || 979 CU_add_test(suite, "ut_vbdev_lvol_submit_request", ut_vbdev_lvol_submit_request) == NULL || 980 CU_add_test(suite, "lvol_examine", ut_lvol_examine) == NULL 981 ) { 982 CU_cleanup_registry(); 983 return CU_get_error(); 984 } 985 986 CU_basic_set_mode(CU_BRM_VERBOSE); 987 CU_basic_run_tests(); 988 num_failures = CU_get_number_of_failures(); 989 CU_cleanup_registry(); 990 return num_failures; 991 } 992