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_blob_close(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_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module) 391 { 392 } 393 394 int 395 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name) 396 { 397 return 0; 398 } 399 400 int 401 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val) 402 { 403 return 0; 404 } 405 406 int 407 spdk_json_write_object_begin(struct spdk_json_write_ctx *w) 408 { 409 return 0; 410 } 411 412 int 413 spdk_json_write_object_end(struct spdk_json_write_ctx *w) 414 { 415 return 0; 416 } 417 418 const char * 419 spdk_bdev_get_name(const struct spdk_bdev *bdev) 420 { 421 return "test"; 422 } 423 424 int 425 spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs, int base_bdev_count) 426 { 427 g_registered_bdevs++; 428 return 0; 429 } 430 431 void 432 spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module) 433 { 434 g_examine_done = true; 435 } 436 437 static struct spdk_lvol * 438 _lvol_create(struct spdk_lvol_store *lvs) 439 { 440 struct spdk_lvol *lvol = calloc(1, sizeof(*lvol)); 441 442 SPDK_CU_ASSERT_FATAL(lvol != NULL); 443 444 lvol->lvol_store = lvs; 445 lvol->ref_count++; 446 lvol->old_name = spdk_sprintf_alloc("%s", "UNIT_TEST_UUID"); 447 SPDK_CU_ASSERT_FATAL(lvol->old_name != NULL); 448 449 TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link); 450 451 return lvol; 452 } 453 454 int 455 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz, 456 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 457 { 458 struct spdk_lvol *lvol; 459 460 lvol = _lvol_create(lvs); 461 cb_fn(cb_arg, lvol, 0); 462 463 return 0; 464 } 465 466 static void 467 lvol_store_op_complete(void *cb_arg, int lvserrno) 468 { 469 g_lvserrno = lvserrno; 470 return; 471 } 472 473 static void 474 lvol_store_op_with_handle_complete(void *cb_arg, struct spdk_lvol_store *lvs, int lvserrno) 475 { 476 g_lvserrno = lvserrno; 477 g_lvol_store = lvs; 478 return; 479 } 480 481 static void 482 vbdev_lvol_create_complete(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 483 { 484 g_lvolerrno = lvolerrno; 485 g_lvol = lvol; 486 } 487 488 static void 489 vbdev_lvol_resize_complete(void *cb_arg, int lvolerrno) 490 { 491 g_lvolerrno = lvolerrno; 492 } 493 494 static void 495 ut_lvs_destroy(void) 496 { 497 int rc = 0; 498 int sz = 10; 499 struct spdk_lvol_store *lvs; 500 501 /* Lvol store is succesfully created */ 502 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 503 CU_ASSERT(rc == 0); 504 CU_ASSERT(g_lvserrno == 0); 505 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 506 CU_ASSERT(g_bs_dev != NULL); 507 508 lvs = g_lvol_store; 509 g_lvol_store = NULL; 510 511 uuid_generate_time(lvs->uuid); 512 513 /* Suuccessfully create lvol, which should be unloaded with lvs later */ 514 g_lvolerrno = -1; 515 rc = vbdev_lvol_create(lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 516 CU_ASSERT(rc == 0); 517 CU_ASSERT(g_lvolerrno == 0); 518 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 519 520 /* Unload lvol store */ 521 vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL); 522 CU_ASSERT(g_lvserrno == 0); 523 CU_ASSERT(g_lvol_store == NULL); 524 } 525 526 static void 527 ut_lvol_init(void) 528 { 529 int sz = 10; 530 int rc; 531 532 g_lvs = calloc(1, sizeof(*g_lvs)); 533 SPDK_CU_ASSERT_FATAL(g_lvs != NULL); 534 TAILQ_INIT(&g_lvs->lvols); 535 g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev)); 536 SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL); 537 g_base_bdev = calloc(1, sizeof(*g_base_bdev)); 538 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 539 540 g_lvs_bdev->lvs = g_lvs; 541 g_lvs_bdev->bdev = g_base_bdev; 542 543 uuid_generate_time(g_lvs->uuid); 544 545 TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 546 547 /* Successful lvol create */ 548 g_lvolerrno = -1; 549 rc = vbdev_lvol_create(g_lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 550 SPDK_CU_ASSERT_FATAL(rc == 0); 551 CU_ASSERT(g_lvol != NULL); 552 CU_ASSERT(g_lvolerrno == 0); 553 554 /* Successful lvol destruct */ 555 vbdev_lvol_destruct(g_lvol); 556 CU_ASSERT(g_lvol == NULL); 557 558 TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 559 560 free(g_lvs); 561 free(g_lvs_bdev); 562 free(g_base_bdev); 563 564 565 } 566 567 static void 568 ut_lvol_hotremove(void) 569 { 570 int rc = 0; 571 572 lvol_store_initialize_fail = false; 573 lvol_store_initialize_cb_fail = false; 574 lvol_already_opened = false; 575 g_bs_dev = NULL; 576 577 /* Lvol store is succesfully created */ 578 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 579 CU_ASSERT(rc == 0); 580 CU_ASSERT(g_lvserrno == 0); 581 CU_ASSERT(g_lvol_store != NULL); 582 CU_ASSERT(g_bs_dev != NULL); 583 584 /* Hot remove callback with NULL - stability check */ 585 vbdev_lvs_hotremove_cb(NULL); 586 587 /* Hot remove lvs on bdev removal */ 588 vbdev_lvs_hotremove_cb(&g_bdev); 589 590 CU_ASSERT(g_lvol_store == NULL); 591 CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs)); 592 593 } 594 595 static void 596 ut_lvol_examine(void) 597 { 598 struct spdk_bdev *bdev; 599 600 lvol_already_opened = false; 601 g_bs_dev = NULL; 602 g_lvserrno = 0; 603 g_examine_done = false; 604 605 /* Examine with NULL bdev */ 606 vbdev_lvs_examine(NULL); 607 CU_ASSERT(g_bs_dev == NULL); 608 CU_ASSERT(g_lvol_store == NULL); 609 CU_ASSERT(g_examine_done == true); 610 611 /* Examine unsuccessfully - bdev already opened */ 612 g_bs_dev = NULL; 613 g_examine_done = false; 614 g_lvserrno = -1; 615 lvol_already_opened = true; 616 vbdev_lvs_examine(&g_bdev); 617 CU_ASSERT(g_bs_dev == NULL); 618 CU_ASSERT(g_lvol_store == NULL); 619 CU_ASSERT(g_examine_done == true); 620 621 /* Examine unsuccessfully - fail on lvol store */ 622 g_bs_dev = NULL; 623 g_examine_done = false; 624 g_lvserrno = -1; 625 lvol_already_opened = false; 626 vbdev_lvs_examine(&g_bdev); 627 CU_ASSERT(g_bs_dev != NULL); 628 CU_ASSERT(g_lvol_store == NULL); 629 CU_ASSERT(g_examine_done == true); 630 CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs)); 631 free(g_bs_dev); 632 633 /* Examine unsuccesfully - fail on lvol load */ 634 g_bs_dev = NULL; 635 g_lvserrno = 0; 636 g_lvolerrno = -1; 637 g_num_lvols = 1; 638 g_examine_done = false; 639 lvol_already_opened = false; 640 g_registered_bdevs = 0; 641 vbdev_lvs_examine(&g_bdev); 642 CU_ASSERT(g_bs_dev != NULL); 643 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 644 CU_ASSERT(g_examine_done == true); 645 CU_ASSERT(g_registered_bdevs == 0); 646 CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs)); 647 CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols)); 648 vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); 649 free(g_bs_dev); 650 651 /* Examine succesfully */ 652 g_bs_dev = NULL; 653 g_lvserrno = 0; 654 g_lvolerrno = 0; 655 g_examine_done = false; 656 g_registered_bdevs = 0; 657 lvol_already_opened = false; 658 vbdev_lvs_examine(&g_bdev); 659 CU_ASSERT(g_bs_dev != NULL); 660 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 661 CU_ASSERT(g_examine_done == true); 662 CU_ASSERT(g_registered_bdevs != 0); 663 CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs)); 664 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols)); 665 TAILQ_FIRST(&g_lvol_store->lvols)->ref_count--; 666 bdev = TAILQ_FIRST(&g_lvol_store->lvols)->bdev; 667 vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); 668 free(bdev->name); 669 free(bdev); 670 free(g_bs_dev); 671 free(g_lvol_store); 672 } 673 674 static void 675 ut_lvol_resize(void) 676 { 677 int sz = 10; 678 int rc = 0; 679 680 g_lvs = calloc(1, sizeof(*g_lvs)); 681 SPDK_CU_ASSERT_FATAL(g_lvs != NULL); 682 683 TAILQ_INIT(&g_lvs->lvols); 684 685 g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev)); 686 SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL); 687 g_base_bdev = calloc(1, sizeof(*g_base_bdev)); 688 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 689 g_lvs_bdev->lvs = g_lvs; 690 g_lvs_bdev->bdev = g_base_bdev; 691 692 693 uuid_generate_time(g_lvs->uuid); 694 g_base_bdev->blocklen = 4096; 695 TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 696 697 /* Successful lvol create */ 698 g_lvolerrno = -1; 699 rc = vbdev_lvol_create(g_lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 700 CU_ASSERT(rc == 0); 701 CU_ASSERT(g_lvolerrno == 0); 702 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 703 704 g_base_bdev->ctxt = g_lvol; 705 706 g_base_bdev->name = spdk_sprintf_alloc("%s", g_lvol->old_name); 707 SPDK_CU_ASSERT_FATAL(g_base_bdev->name != NULL); 708 709 /* Successful lvol resize */ 710 rc = vbdev_lvol_resize(g_lvol->old_name, 20, vbdev_lvol_resize_complete, NULL); 711 CU_ASSERT(rc == 0); 712 CU_ASSERT(g_base_bdev->blockcnt == 20 * g_cluster_size / g_base_bdev->blocklen); 713 714 /* Resize with wrong bdev name */ 715 rc = vbdev_lvol_resize("wrong name", 20, vbdev_lvol_resize_complete, NULL); 716 CU_ASSERT(rc != 0); 717 718 /* Resize with correct bdev name, but wrong lvol name */ 719 free(g_lvol->old_name); 720 g_lvol->old_name = strdup("wrong name"); 721 SPDK_CU_ASSERT_FATAL(g_lvol->old_name != NULL); 722 rc = vbdev_lvol_resize(g_base_bdev->name, 20, vbdev_lvol_resize_complete, NULL); 723 CU_ASSERT(rc != 0); 724 725 /* Successful lvol destruct */ 726 vbdev_lvol_destruct(g_lvol); 727 CU_ASSERT(g_lvol == NULL); 728 729 TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 730 free(g_lvs); 731 free(g_lvs_bdev); 732 free(g_base_bdev->name); 733 free(g_base_bdev); 734 } 735 736 static void 737 ut_lvs_unload(void) 738 { 739 int rc = 0; 740 int sz = 10; 741 struct spdk_lvol_store *lvs; 742 743 /* Lvol store is succesfully created */ 744 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 745 CU_ASSERT(rc == 0); 746 CU_ASSERT(g_lvserrno == 0); 747 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 748 CU_ASSERT(g_bs_dev != NULL); 749 750 lvs = g_lvol_store; 751 g_lvol_store = NULL; 752 753 uuid_generate_time(lvs->uuid); 754 755 /* Suuccessfully create lvol, which should be destroyed with lvs later */ 756 g_lvolerrno = -1; 757 rc = vbdev_lvol_create(lvs, "lvol", sz, vbdev_lvol_create_complete, NULL); 758 CU_ASSERT(rc == 0); 759 CU_ASSERT(g_lvolerrno == 0); 760 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 761 762 /* Unload lvol store */ 763 vbdev_lvs_unload(lvs, lvol_store_op_complete, NULL); 764 CU_ASSERT(g_lvserrno == 0); 765 CU_ASSERT(g_lvol_store == NULL); 766 CU_ASSERT(g_lvol != NULL); 767 } 768 769 static void 770 ut_lvs_init(void) 771 { 772 int rc = 0; 773 struct spdk_lvol_store *lvs; 774 struct spdk_bs_dev *bs_dev_temp; 775 776 /* spdk_lvs_init() fails */ 777 lvol_store_initialize_fail = true; 778 779 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 780 CU_ASSERT(rc != 0); 781 CU_ASSERT(g_lvserrno == 0); 782 CU_ASSERT(g_lvol_store == NULL); 783 CU_ASSERT(g_bs_dev == NULL); 784 785 lvol_store_initialize_fail = false; 786 787 /* spdk_lvs_init_cb() fails */ 788 lvol_store_initialize_cb_fail = true; 789 790 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 791 CU_ASSERT(rc == 0); 792 CU_ASSERT(g_lvserrno != 0); 793 CU_ASSERT(g_lvol_store == NULL); 794 CU_ASSERT(g_bs_dev == NULL); 795 796 lvol_store_initialize_cb_fail = false; 797 798 /* Lvol store is succesfully created */ 799 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 800 CU_ASSERT(rc == 0); 801 CU_ASSERT(g_lvserrno == 0); 802 CU_ASSERT(g_lvol_store != NULL); 803 CU_ASSERT(g_bs_dev != NULL); 804 805 lvs = g_lvol_store; 806 g_lvol_store = NULL; 807 bs_dev_temp = g_bs_dev; 808 g_bs_dev = NULL; 809 810 /* Bdev with lvol store already claimed */ 811 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 812 CU_ASSERT(rc != 0); 813 CU_ASSERT(g_lvserrno == 0); 814 CU_ASSERT(g_lvol_store == NULL); 815 CU_ASSERT(g_bs_dev == NULL); 816 817 /* Destruct lvol store */ 818 g_bs_dev = bs_dev_temp; 819 820 vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL); 821 CU_ASSERT(g_lvserrno == 0); 822 CU_ASSERT(g_lvol_store == NULL); 823 CU_ASSERT(g_bs_dev == NULL); 824 free(g_bs_dev); 825 826 } 827 828 static void 829 ut_vbdev_lvol_get_io_channel(void) 830 { 831 struct spdk_io_channel *ch; 832 833 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 834 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 835 836 ch = vbdev_lvol_get_io_channel(g_lvol); 837 CU_ASSERT(ch == g_ch); 838 839 free(g_lvol); 840 841 } 842 843 static void 844 ut_vbdev_lvol_io_type_supported(void) 845 { 846 struct spdk_lvol *lvol = g_lvol; 847 bool ret; 848 /* Supported types */ 849 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ); 850 CU_ASSERT(ret == true); 851 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE); 852 CU_ASSERT(ret == true); 853 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET); 854 CU_ASSERT(ret == true); 855 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP); 856 CU_ASSERT(ret == true); 857 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES); 858 CU_ASSERT(ret == true); 859 860 /* Unsupported types */ 861 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH); 862 CU_ASSERT(ret == false); 863 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN); 864 CU_ASSERT(ret == false); 865 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO); 866 CU_ASSERT(ret == false); 867 } 868 869 static void 870 ut_lvol_op_comp(void) 871 { 872 struct lvol_task task; 873 874 lvol_op_comp(&task, 1); 875 CU_ASSERT(task.status == SPDK_BDEV_IO_STATUS_FAILED); 876 } 877 878 static void 879 ut_lvol_read_write(void) 880 { 881 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 882 SPDK_CU_ASSERT_FATAL(g_io != NULL); 883 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 884 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 885 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 886 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 887 888 g_task = (struct lvol_task *)g_io->driver_ctx; 889 g_io->bdev = g_base_bdev; 890 g_io->bdev->ctxt = g_lvol; 891 g_io->u.bdev.offset_blocks = 20; 892 g_io->u.bdev.num_blocks = 20; 893 894 lvol_read(g_ch, g_io); 895 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 896 897 lvol_write(g_lvol, g_ch, g_io); 898 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 899 900 free(g_io); 901 free(g_base_bdev); 902 free(g_lvol); 903 } 904 905 static void 906 ut_vbdev_lvol_submit_request(void) 907 { 908 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 909 SPDK_CU_ASSERT_FATAL(g_io != NULL); 910 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 911 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 912 g_task = (struct lvol_task *)g_io->driver_ctx; 913 914 g_io->bdev = g_base_bdev; 915 916 g_io->type = SPDK_BDEV_IO_TYPE_READ; 917 vbdev_lvol_submit_request(g_ch, g_io); 918 919 free(g_io); 920 free(g_base_bdev); 921 } 922 923 int main(int argc, char **argv) 924 { 925 CU_pSuite suite = NULL; 926 unsigned int num_failures; 927 928 if (CU_initialize_registry() != CUE_SUCCESS) { 929 return CU_get_error(); 930 } 931 932 suite = CU_add_suite("lvol", NULL, NULL); 933 if (suite == NULL) { 934 CU_cleanup_registry(); 935 return CU_get_error(); 936 } 937 938 if ( 939 CU_add_test(suite, "ut_lvs_init", ut_lvs_init) == NULL || 940 CU_add_test(suite, "ut_lvol_init", ut_lvol_init) == NULL || 941 CU_add_test(suite, "ut_lvs_destroy", ut_lvs_destroy) == NULL || 942 CU_add_test(suite, "ut_lvs_unload", ut_lvs_unload) == NULL || 943 CU_add_test(suite, "ut_lvol_resize", ut_lvol_resize) == NULL || 944 CU_add_test(suite, "lvol_hotremove", ut_lvol_hotremove) == NULL || 945 CU_add_test(suite, "ut_vbdev_lvol_get_io_channel", ut_vbdev_lvol_get_io_channel) == NULL || 946 CU_add_test(suite, "ut_vbdev_lvol_io_type_supported", ut_vbdev_lvol_io_type_supported) == NULL || 947 CU_add_test(suite, "ut_lvol_op_comp", ut_lvol_op_comp) == NULL || 948 CU_add_test(suite, "ut_lvol_read_write", ut_lvol_read_write) == NULL || 949 CU_add_test(suite, "ut_vbdev_lvol_submit_request", ut_vbdev_lvol_submit_request) == NULL || 950 CU_add_test(suite, "lvol_examine", ut_lvol_examine) == NULL 951 ) { 952 CU_cleanup_registry(); 953 return CU_get_error(); 954 } 955 956 CU_basic_set_mode(CU_BRM_VERBOSE); 957 CU_basic_run_tests(); 958 num_failures = CU_get_number_of_failures(); 959 CU_cleanup_registry(); 960 return num_failures; 961 } 962