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