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