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_unmap_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 344 uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg) 345 { 346 CU_ASSERT(blob == NULL); 347 CU_ASSERT(channel == g_ch); 348 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 349 CU_ASSERT(length == g_io->u.bdev.num_blocks); 350 } 351 352 void 353 spdk_bs_io_write_zeroes_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 354 uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg) 355 { 356 CU_ASSERT(blob == NULL); 357 CU_ASSERT(channel == g_ch); 358 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 359 CU_ASSERT(length == g_io->u.bdev.num_blocks); 360 } 361 362 void 363 spdk_bs_io_writev_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 364 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length, 365 spdk_blob_op_complete cb_fn, void *cb_arg) 366 { 367 CU_ASSERT(blob == NULL); 368 CU_ASSERT(channel == g_ch); 369 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 370 CU_ASSERT(length == g_io->u.bdev.num_blocks); 371 } 372 373 void 374 spdk_bs_io_readv_blob(struct spdk_blob *blob, struct spdk_io_channel *channel, 375 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length, 376 spdk_blob_op_complete cb_fn, void *cb_arg) 377 { 378 CU_ASSERT(blob == NULL); 379 CU_ASSERT(channel == g_ch); 380 CU_ASSERT(offset == g_io->u.bdev.offset_blocks); 381 CU_ASSERT(length == g_io->u.bdev.num_blocks); 382 } 383 384 void 385 spdk_bs_io_flush_channel(struct spdk_io_channel *channel, spdk_blob_op_complete cb_fn, void *cb_arg) 386 { 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->uuid, "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 uuid_t wrong_uuid; 530 int sz = 10; 531 int rc; 532 533 g_lvs = calloc(1, sizeof(*g_lvs)); 534 SPDK_CU_ASSERT_FATAL(g_lvs != NULL); 535 TAILQ_INIT(&g_lvs->lvols); 536 g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev)); 537 SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL); 538 g_base_bdev = calloc(1, sizeof(*g_base_bdev)); 539 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 540 541 g_lvs_bdev->lvs = g_lvs; 542 g_lvs_bdev->bdev = g_base_bdev; 543 544 uuid_generate_time(g_lvs->uuid); 545 uuid_generate_time(wrong_uuid); 546 547 /* Incorrect uuid set */ 548 g_lvolerrno = 0; 549 rc = vbdev_lvol_create(wrong_uuid, "lvol", sz, vbdev_lvol_create_complete, NULL); 550 CU_ASSERT(rc == -ENODEV); 551 552 TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 553 554 /* Successful lvol create */ 555 g_lvolerrno = -1; 556 rc = vbdev_lvol_create(g_lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL); 557 SPDK_CU_ASSERT_FATAL(rc == 0); 558 CU_ASSERT(g_lvol != NULL); 559 CU_ASSERT(g_lvolerrno == 0); 560 561 /* Successful lvol destruct */ 562 vbdev_lvol_destruct(g_lvol); 563 CU_ASSERT(g_lvol == NULL); 564 565 TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 566 567 free(g_lvs); 568 free(g_lvs_bdev); 569 free(g_base_bdev); 570 571 572 } 573 574 static void 575 ut_lvol_hotremove(void) 576 { 577 int rc = 0; 578 579 lvol_store_initialize_fail = false; 580 lvol_store_initialize_cb_fail = false; 581 lvol_already_opened = false; 582 g_bs_dev = NULL; 583 584 /* Lvol store is succesfully created */ 585 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 586 CU_ASSERT(rc == 0); 587 CU_ASSERT(g_lvserrno == 0); 588 CU_ASSERT(g_lvol_store != NULL); 589 CU_ASSERT(g_bs_dev != NULL); 590 591 /* Hot remove callback with NULL - stability check */ 592 vbdev_lvs_hotremove_cb(NULL); 593 594 /* Hot remove lvs on bdev removal */ 595 vbdev_lvs_hotremove_cb(&g_bdev); 596 597 CU_ASSERT(g_lvol_store == NULL); 598 CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs)); 599 600 } 601 602 static void 603 ut_lvol_examine(void) 604 { 605 struct spdk_bdev *bdev; 606 607 lvol_already_opened = false; 608 g_bs_dev = NULL; 609 g_lvserrno = 0; 610 g_examine_done = false; 611 612 /* Examine with NULL bdev */ 613 vbdev_lvs_examine(NULL); 614 CU_ASSERT(g_bs_dev == NULL); 615 CU_ASSERT(g_lvol_store == NULL); 616 CU_ASSERT(g_examine_done == true); 617 618 /* Examine unsuccessfully - bdev already opened */ 619 g_bs_dev = NULL; 620 g_examine_done = false; 621 g_lvserrno = -1; 622 lvol_already_opened = true; 623 vbdev_lvs_examine(&g_bdev); 624 CU_ASSERT(g_bs_dev == NULL); 625 CU_ASSERT(g_lvol_store == NULL); 626 CU_ASSERT(g_examine_done == true); 627 628 /* Examine unsuccessfully - fail on lvol store */ 629 g_bs_dev = NULL; 630 g_examine_done = false; 631 g_lvserrno = -1; 632 lvol_already_opened = false; 633 vbdev_lvs_examine(&g_bdev); 634 CU_ASSERT(g_bs_dev != NULL); 635 CU_ASSERT(g_lvol_store == NULL); 636 CU_ASSERT(g_examine_done == true); 637 CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs)); 638 free(g_bs_dev); 639 640 /* Examine unsuccesfully - fail on lvol load */ 641 g_bs_dev = NULL; 642 g_lvserrno = 0; 643 g_lvolerrno = -1; 644 g_num_lvols = 1; 645 g_examine_done = false; 646 lvol_already_opened = false; 647 g_registered_bdevs = 0; 648 vbdev_lvs_examine(&g_bdev); 649 CU_ASSERT(g_bs_dev != NULL); 650 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 651 CU_ASSERT(g_examine_done == true); 652 CU_ASSERT(g_registered_bdevs == 0); 653 CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs)); 654 CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols)); 655 vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); 656 free(g_bs_dev); 657 658 /* Examine succesfully */ 659 g_bs_dev = NULL; 660 g_lvserrno = 0; 661 g_lvolerrno = 0; 662 g_examine_done = false; 663 g_registered_bdevs = 0; 664 lvol_already_opened = false; 665 vbdev_lvs_examine(&g_bdev); 666 CU_ASSERT(g_bs_dev != NULL); 667 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 668 CU_ASSERT(g_examine_done == true); 669 CU_ASSERT(g_registered_bdevs != 0); 670 CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs)); 671 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols)); 672 TAILQ_FIRST(&g_lvol_store->lvols)->ref_count--; 673 bdev = TAILQ_FIRST(&g_lvol_store->lvols)->bdev; 674 vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL); 675 free(bdev->name); 676 free(bdev); 677 free(g_bs_dev); 678 free(g_lvol_store); 679 } 680 681 static void 682 ut_lvol_resize(void) 683 { 684 int sz = 10; 685 int rc = 0; 686 687 g_lvs = calloc(1, sizeof(*g_lvs)); 688 SPDK_CU_ASSERT_FATAL(g_lvs != NULL); 689 690 TAILQ_INIT(&g_lvs->lvols); 691 692 g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev)); 693 SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL); 694 g_base_bdev = calloc(1, sizeof(*g_base_bdev)); 695 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 696 g_lvs_bdev->lvs = g_lvs; 697 g_lvs_bdev->bdev = g_base_bdev; 698 699 700 uuid_generate_time(g_lvs->uuid); 701 g_base_bdev->blocklen = 4096; 702 TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 703 704 /* Successful lvol create */ 705 g_lvolerrno = -1; 706 rc = vbdev_lvol_create(g_lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL); 707 CU_ASSERT(rc == 0); 708 CU_ASSERT(g_lvolerrno == 0); 709 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 710 711 g_base_bdev->ctxt = g_lvol; 712 713 g_base_bdev->name = spdk_sprintf_alloc("%s", g_lvol->old_name); 714 SPDK_CU_ASSERT_FATAL(g_base_bdev->name != NULL); 715 716 /* Successful lvol resize */ 717 rc = vbdev_lvol_resize(g_lvol->old_name, 20, vbdev_lvol_resize_complete, NULL); 718 CU_ASSERT(rc == 0); 719 CU_ASSERT(g_base_bdev->blockcnt == 20 * g_cluster_size / g_base_bdev->blocklen); 720 721 /* Resize with wrong bdev name */ 722 rc = vbdev_lvol_resize("wrong name", 20, vbdev_lvol_resize_complete, NULL); 723 CU_ASSERT(rc != 0); 724 725 /* Resize with correct bdev name, but wrong lvol name */ 726 free(g_lvol->old_name); 727 g_lvol->old_name = strdup("wrong name"); 728 SPDK_CU_ASSERT_FATAL(g_lvol->old_name != NULL); 729 rc = vbdev_lvol_resize(g_base_bdev->name, 20, vbdev_lvol_resize_complete, NULL); 730 CU_ASSERT(rc != 0); 731 732 /* Successful lvol destruct */ 733 vbdev_lvol_destruct(g_lvol); 734 CU_ASSERT(g_lvol == NULL); 735 736 TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores); 737 free(g_lvs); 738 free(g_lvs_bdev); 739 free(g_base_bdev->name); 740 free(g_base_bdev); 741 } 742 743 static void 744 ut_lvs_unload(void) 745 { 746 int rc = 0; 747 int sz = 10; 748 struct spdk_lvol_store *lvs; 749 750 /* Lvol store is succesfully created */ 751 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 752 CU_ASSERT(rc == 0); 753 CU_ASSERT(g_lvserrno == 0); 754 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 755 CU_ASSERT(g_bs_dev != NULL); 756 757 lvs = g_lvol_store; 758 g_lvol_store = NULL; 759 760 uuid_generate_time(lvs->uuid); 761 762 /* Suuccessfully create lvol, which should be destroyed with lvs later */ 763 g_lvolerrno = -1; 764 rc = vbdev_lvol_create(lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL); 765 CU_ASSERT(rc == 0); 766 CU_ASSERT(g_lvolerrno == 0); 767 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 768 769 /* Unload lvol store */ 770 vbdev_lvs_unload(lvs, lvol_store_op_complete, NULL); 771 CU_ASSERT(g_lvserrno == 0); 772 CU_ASSERT(g_lvol_store == NULL); 773 CU_ASSERT(g_lvol != NULL); 774 } 775 776 static void 777 ut_lvs_init(void) 778 { 779 int rc = 0; 780 struct spdk_lvol_store *lvs; 781 struct spdk_bs_dev *bs_dev_temp; 782 783 /* spdk_lvs_init() fails */ 784 lvol_store_initialize_fail = true; 785 786 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 787 CU_ASSERT(rc != 0); 788 CU_ASSERT(g_lvserrno == 0); 789 CU_ASSERT(g_lvol_store == NULL); 790 CU_ASSERT(g_bs_dev == NULL); 791 792 lvol_store_initialize_fail = false; 793 794 /* spdk_lvs_init_cb() fails */ 795 lvol_store_initialize_cb_fail = true; 796 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 lvol_store_initialize_cb_fail = false; 804 805 /* Lvol store is succesfully created */ 806 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 807 CU_ASSERT(rc == 0); 808 CU_ASSERT(g_lvserrno == 0); 809 CU_ASSERT(g_lvol_store != NULL); 810 CU_ASSERT(g_bs_dev != NULL); 811 812 lvs = g_lvol_store; 813 g_lvol_store = NULL; 814 bs_dev_temp = g_bs_dev; 815 g_bs_dev = NULL; 816 817 /* Bdev with lvol store already claimed */ 818 rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL); 819 CU_ASSERT(rc != 0); 820 CU_ASSERT(g_lvserrno == 0); 821 CU_ASSERT(g_lvol_store == NULL); 822 CU_ASSERT(g_bs_dev == NULL); 823 824 /* Destruct lvol store */ 825 g_bs_dev = bs_dev_temp; 826 827 vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL); 828 CU_ASSERT(g_lvserrno == 0); 829 CU_ASSERT(g_lvol_store == NULL); 830 CU_ASSERT(g_bs_dev == NULL); 831 free(g_bs_dev); 832 833 } 834 835 static void 836 ut_vbdev_lvol_get_io_channel(void) 837 { 838 struct spdk_io_channel *ch; 839 840 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 841 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 842 843 ch = vbdev_lvol_get_io_channel(g_lvol); 844 CU_ASSERT(ch == g_ch); 845 846 free(g_lvol); 847 848 } 849 850 static void 851 ut_vbdev_lvol_io_type_supported(void) 852 { 853 struct spdk_lvol *lvol = g_lvol; 854 bool ret; 855 /* Supported types */ 856 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ); 857 CU_ASSERT(ret == true); 858 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE); 859 CU_ASSERT(ret == true); 860 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH); 861 CU_ASSERT(ret == true); 862 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET); 863 CU_ASSERT(ret == true); 864 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP); 865 CU_ASSERT(ret == true); 866 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES); 867 CU_ASSERT(ret == true); 868 869 /* Unsupported types */ 870 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN); 871 CU_ASSERT(ret == false); 872 ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO); 873 CU_ASSERT(ret == false); 874 } 875 876 static void 877 ut_lvol_op_comp(void) 878 { 879 struct lvol_task task; 880 881 lvol_op_comp(&task, 1); 882 CU_ASSERT(task.status == SPDK_BDEV_IO_STATUS_FAILED); 883 } 884 885 static void 886 ut_lvol_flush(void) 887 { 888 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 889 SPDK_CU_ASSERT_FATAL(g_io != NULL); 890 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 891 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 892 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 893 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 894 895 g_task = (struct lvol_task *)g_io->driver_ctx; 896 g_io->bdev = g_base_bdev; 897 g_io->bdev->ctxt = g_lvol; 898 899 /* Successful flush to lvol */ 900 lvol_flush(g_ch, g_io); 901 902 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 903 904 free(g_io); 905 free(g_base_bdev); 906 free(g_lvol); 907 } 908 909 static void 910 ut_lvol_read_write(void) 911 { 912 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 913 SPDK_CU_ASSERT_FATAL(g_io != NULL); 914 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 915 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 916 g_lvol = calloc(1, sizeof(struct spdk_lvol)); 917 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 918 919 g_task = (struct lvol_task *)g_io->driver_ctx; 920 g_io->bdev = g_base_bdev; 921 g_io->bdev->ctxt = g_lvol; 922 g_io->u.bdev.offset_blocks = 20; 923 g_io->u.bdev.num_blocks = 20; 924 925 lvol_read(g_ch, g_io); 926 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 927 928 lvol_write(g_lvol, g_ch, g_io); 929 CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS); 930 931 free(g_io); 932 free(g_base_bdev); 933 free(g_lvol); 934 } 935 936 static void 937 ut_vbdev_lvol_submit_request(void) 938 { 939 g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task)); 940 SPDK_CU_ASSERT_FATAL(g_io != NULL); 941 g_base_bdev = calloc(1, sizeof(struct spdk_bdev)); 942 SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL); 943 g_task = (struct lvol_task *)g_io->driver_ctx; 944 945 g_io->bdev = g_base_bdev; 946 947 g_io->type = SPDK_BDEV_IO_TYPE_READ; 948 vbdev_lvol_submit_request(g_ch, g_io); 949 950 free(g_io); 951 free(g_base_bdev); 952 } 953 954 int main(int argc, char **argv) 955 { 956 CU_pSuite suite = NULL; 957 unsigned int num_failures; 958 959 if (CU_initialize_registry() != CUE_SUCCESS) { 960 return CU_get_error(); 961 } 962 963 suite = CU_add_suite("lvol", NULL, NULL); 964 if (suite == NULL) { 965 CU_cleanup_registry(); 966 return CU_get_error(); 967 } 968 969 if ( 970 CU_add_test(suite, "ut_lvs_init", ut_lvs_init) == NULL || 971 CU_add_test(suite, "ut_lvol_init", ut_lvol_init) == NULL || 972 CU_add_test(suite, "ut_lvs_destroy", ut_lvs_destroy) == NULL || 973 CU_add_test(suite, "ut_lvs_unload", ut_lvs_unload) == NULL || 974 CU_add_test(suite, "ut_lvol_resize", ut_lvol_resize) == NULL || 975 CU_add_test(suite, "lvol_hotremove", ut_lvol_hotremove) == NULL || 976 CU_add_test(suite, "ut_vbdev_lvol_get_io_channel", ut_vbdev_lvol_get_io_channel) == NULL || 977 CU_add_test(suite, "ut_vbdev_lvol_io_type_supported", ut_vbdev_lvol_io_type_supported) == NULL || 978 CU_add_test(suite, "ut_lvol_op_comp", ut_lvol_op_comp) == NULL || 979 CU_add_test(suite, "ut_lvol_flush", ut_lvol_flush) == NULL || 980 CU_add_test(suite, "ut_lvol_read_write", ut_lvol_read_write) == NULL || 981 CU_add_test(suite, "ut_vbdev_lvol_submit_request", ut_vbdev_lvol_submit_request) == NULL || 982 CU_add_test(suite, "lvol_examine", ut_lvol_examine) == NULL 983 ) { 984 CU_cleanup_registry(); 985 return CU_get_error(); 986 } 987 988 CU_basic_set_mode(CU_BRM_VERBOSE); 989 CU_basic_run_tests(); 990 num_failures = CU_get_number_of_failures(); 991 CU_cleanup_registry(); 992 return num_failures; 993 } 994