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