1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 Intel Corporation. 3 * All rights reserved. 4 * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 */ 6 7 #include "spdk_internal/cunit.h" 8 #include "spdk/blob.h" 9 #include "spdk/util.h" 10 11 #include "spdk/bdev_module.h" 12 #include "thread/thread_internal.h" 13 14 #include "common/lib/ut_multithread.c" 15 #include "lvol/lvol.c" 16 17 #define DEV_BUFFER_SIZE (64 * 1024 * 1024) 18 #define DEV_BUFFER_BLOCKLEN (4096) 19 #define DEV_BUFFER_BLOCKCNT (DEV_BUFFER_SIZE / DEV_BUFFER_BLOCKLEN) 20 #define BS_CLUSTER_SIZE (1024 * 1024) 21 #define BS_FREE_CLUSTERS (DEV_BUFFER_SIZE / BS_CLUSTER_SIZE) 22 #define BS_PAGE_SIZE (4096) 23 24 #define SPDK_BLOB_OPTS_CLUSTER_SZ (1024 * 1024) 25 #define SPDK_BLOB_OPTS_NUM_MD_PAGES UINT32_MAX 26 #define SPDK_BLOB_OPTS_MAX_MD_OPS 32 27 #define SPDK_BLOB_OPTS_MAX_CHANNEL_OPS 512 28 29 #define SPDK_BLOB_THIN_PROV (1ULL << 0) 30 31 32 DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), NULL); 33 DEFINE_STUB(spdk_bdev_get_by_name, struct spdk_bdev *, (const char *name), NULL); 34 DEFINE_STUB(spdk_bdev_create_bs_dev_ro, int, 35 (const char *bdev_name, spdk_bdev_event_cb_t event_cb, void *event_ctx, 36 struct spdk_bs_dev **bs_dev), -ENOTSUP); 37 DEFINE_STUB(spdk_blob_is_esnap_clone, bool, (const struct spdk_blob *blob), false); 38 DEFINE_STUB(spdk_blob_is_degraded, bool, (const struct spdk_blob *blob), false); 39 DEFINE_STUB_V(spdk_bs_grow_live, 40 (struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_arg)); 41 42 43 const char *uuid = "828d9766-ae50-11e7-bd8d-001e67edf350"; 44 45 struct spdk_blob { 46 spdk_blob_id id; 47 uint32_t ref; 48 struct spdk_blob_store *bs; 49 int close_status; 50 int open_status; 51 int load_status; 52 TAILQ_ENTRY(spdk_blob) link; 53 char uuid[SPDK_UUID_STRING_LEN]; 54 char name[SPDK_LVS_NAME_MAX]; 55 bool thin_provisioned; 56 struct spdk_bs_dev *back_bs_dev; 57 uint64_t num_clusters; 58 }; 59 60 int g_lvserrno; 61 int g_close_super_status; 62 int g_resize_rc; 63 int g_inflate_rc; 64 int g_remove_rc; 65 bool g_lvs_rename_blob_open_error = false; 66 bool g_blob_read_only = false; 67 bool g_blob_is_snapshot = false; 68 struct spdk_lvol_store *g_lvol_store; 69 struct spdk_lvol *g_lvol; 70 spdk_blob_id g_blobid = 1; 71 struct spdk_io_channel *g_io_channel; 72 struct lvol_ut_bs_dev g_esnap_dev; 73 74 struct spdk_blob_store { 75 struct spdk_bs_opts bs_opts; 76 spdk_blob_id super_blobid; 77 TAILQ_HEAD(, spdk_blob) blobs; 78 int get_super_status; 79 spdk_bs_esnap_dev_create esnap_bs_dev_create; 80 }; 81 82 struct lvol_ut_bs_dev { 83 struct spdk_bs_dev bs_dev; 84 int init_status; 85 int load_status; 86 struct spdk_blob_store *bs; 87 }; 88 89 struct ut_cb_res { 90 void *data; 91 int err; 92 }; 93 94 void 95 spdk_bs_inflate_blob(struct spdk_blob_store *bs, struct spdk_io_channel *channel, 96 spdk_blob_id blobid, spdk_blob_op_complete cb_fn, void *cb_arg) 97 { 98 cb_fn(cb_arg, g_inflate_rc); 99 } 100 101 void 102 spdk_bs_blob_decouple_parent(struct spdk_blob_store *bs, struct spdk_io_channel *channel, 103 spdk_blob_id blobid, spdk_blob_op_complete cb_fn, void *cb_arg) 104 { 105 cb_fn(cb_arg, g_inflate_rc); 106 } 107 108 void 109 spdk_bs_iter_next(struct spdk_blob_store *bs, struct spdk_blob *b, 110 spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) 111 { 112 struct spdk_blob *next; 113 int _errno = 0; 114 115 next = TAILQ_NEXT(b, link); 116 if (next == NULL) { 117 _errno = -ENOENT; 118 } else if (next->load_status != 0) { 119 _errno = next->load_status; 120 } 121 122 cb_fn(cb_arg, next, _errno); 123 } 124 125 void 126 spdk_bs_iter_first(struct spdk_blob_store *bs, 127 spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) 128 { 129 struct spdk_blob *first; 130 int _errno = 0; 131 132 first = TAILQ_FIRST(&bs->blobs); 133 if (first == NULL) { 134 _errno = -ENOENT; 135 } else if (first->load_status != 0) { 136 _errno = first->load_status; 137 } 138 139 cb_fn(cb_arg, first, _errno); 140 } 141 142 uint64_t 143 spdk_blob_get_num_clusters(struct spdk_blob *blob) 144 { 145 return blob->num_clusters; 146 } 147 148 void 149 spdk_bs_get_super(struct spdk_blob_store *bs, 150 spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 151 { 152 if (bs->get_super_status != 0) { 153 cb_fn(cb_arg, 0, bs->get_super_status); 154 } else { 155 cb_fn(cb_arg, bs->super_blobid, 0); 156 } 157 } 158 159 void 160 spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid, 161 spdk_bs_op_complete cb_fn, void *cb_arg) 162 { 163 bs->super_blobid = blobid; 164 cb_fn(cb_arg, 0); 165 } 166 167 void 168 spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts, 169 spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) 170 { 171 struct lvol_ut_bs_dev *ut_dev = SPDK_CONTAINEROF(dev, struct lvol_ut_bs_dev, bs_dev); 172 struct spdk_blob_store *bs = NULL; 173 174 if (ut_dev->load_status == 0) { 175 bs = ut_dev->bs; 176 } 177 178 cb_fn(cb_arg, bs, ut_dev->load_status); 179 } 180 181 void 182 spdk_bs_grow(struct spdk_bs_dev *dev, struct spdk_bs_opts *o, 183 spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) 184 { 185 cb_fn(cb_arg, NULL, -EINVAL); 186 } 187 188 struct spdk_io_channel *spdk_bs_alloc_io_channel(struct spdk_blob_store *bs) 189 { 190 if (g_io_channel == NULL) { 191 g_io_channel = calloc(1, sizeof(struct spdk_io_channel)); 192 SPDK_CU_ASSERT_FATAL(g_io_channel != NULL); 193 } 194 g_io_channel->ref++; 195 return g_io_channel; 196 } 197 198 void 199 spdk_bs_free_io_channel(struct spdk_io_channel *channel) 200 { 201 g_io_channel->ref--; 202 if (g_io_channel->ref == 0) { 203 free(g_io_channel); 204 g_io_channel = NULL; 205 } 206 return; 207 } 208 209 int 210 spdk_blob_set_xattr(struct spdk_blob *blob, const char *name, const void *value, 211 uint16_t value_len) 212 { 213 if (!strcmp(name, "uuid")) { 214 CU_ASSERT(value_len == SPDK_UUID_STRING_LEN); 215 memcpy(blob->uuid, value, SPDK_UUID_STRING_LEN); 216 } else if (!strcmp(name, "name")) { 217 CU_ASSERT(value_len <= SPDK_LVS_NAME_MAX); 218 memcpy(blob->name, value, value_len); 219 } 220 221 return 0; 222 } 223 224 int 225 spdk_blob_get_xattr_value(struct spdk_blob *blob, const char *name, 226 const void **value, size_t *value_len) 227 { 228 if (!strcmp(name, "uuid") && strnlen(blob->uuid, SPDK_UUID_STRING_LEN) != 0) { 229 CU_ASSERT(strnlen(blob->uuid, SPDK_UUID_STRING_LEN) == (SPDK_UUID_STRING_LEN - 1)); 230 *value = blob->uuid; 231 *value_len = SPDK_UUID_STRING_LEN; 232 return 0; 233 } else if (!strcmp(name, "name") && strnlen(blob->name, SPDK_LVS_NAME_MAX) != 0) { 234 *value = blob->name; 235 *value_len = strnlen(blob->name, SPDK_LVS_NAME_MAX) + 1; 236 return 0; 237 } 238 239 return -ENOENT; 240 } 241 242 void 243 spdk_blob_set_esnap_bs_dev(struct spdk_blob *blob, struct spdk_bs_dev *back_bs_dev, 244 spdk_blob_op_complete cb_fn, void *cb_arg) 245 { 246 blob->back_bs_dev = back_bs_dev; 247 cb_fn(cb_arg, 0); 248 } 249 250 bool 251 spdk_blob_is_thin_provisioned(struct spdk_blob *blob) 252 { 253 return blob->thin_provisioned; 254 } 255 256 int 257 spdk_bs_blob_shallow_copy(struct spdk_blob_store *bs, struct spdk_io_channel *channel, 258 spdk_blob_id blobid, struct spdk_bs_dev *ext_dev, 259 spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg, 260 spdk_blob_op_complete cb_fn, void *cb_arg) 261 { 262 cb_fn(cb_arg, 0); 263 return 0; 264 } 265 266 bool 267 spdk_blob_is_snapshot(struct spdk_blob *blob) 268 { 269 return g_blob_is_snapshot; 270 } 271 272 void 273 spdk_bs_blob_set_parent(struct spdk_blob_store *bs, spdk_blob_id blob_id, 274 spdk_blob_id snapshot_id, spdk_blob_op_complete cb_fn, void *cb_arg) 275 { 276 cb_fn(cb_arg, 0); 277 } 278 279 DEFINE_STUB(spdk_bs_get_page_size, uint64_t, (struct spdk_blob_store *bs), BS_PAGE_SIZE); 280 281 int 282 spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) 283 { 284 bdev->blockcnt = size; 285 return 0; 286 } 287 288 const struct spdk_uuid * 289 spdk_bdev_get_uuid(const struct spdk_bdev *bdev) 290 { 291 return &bdev->uuid; 292 } 293 294 uint64_t 295 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) 296 { 297 return bdev->blockcnt; 298 } 299 300 uint32_t 301 spdk_bdev_get_block_size(const struct spdk_bdev *bdev) 302 { 303 return bdev->blocklen; 304 } 305 306 static void 307 init_dev(struct lvol_ut_bs_dev *dev) 308 { 309 memset(dev, 0, sizeof(*dev)); 310 dev->bs_dev.blockcnt = DEV_BUFFER_BLOCKCNT; 311 dev->bs_dev.blocklen = DEV_BUFFER_BLOCKLEN; 312 } 313 314 static void 315 free_dev(struct lvol_ut_bs_dev *dev) 316 { 317 struct spdk_blob_store *bs = dev->bs; 318 struct spdk_blob *blob, *tmp; 319 320 if (bs == NULL) { 321 return; 322 } 323 324 TAILQ_FOREACH_SAFE(blob, &bs->blobs, link, tmp) { 325 TAILQ_REMOVE(&bs->blobs, blob, link); 326 free(blob); 327 } 328 329 free(bs); 330 dev->bs = NULL; 331 } 332 333 static void 334 init_bdev(struct spdk_bdev *bdev, char *name, size_t size) 335 { 336 memset(bdev, 0, sizeof(*bdev)); 337 bdev->name = name; 338 spdk_uuid_generate(&bdev->uuid); 339 bdev->blocklen = BS_PAGE_SIZE; 340 bdev->phys_blocklen = BS_PAGE_SIZE; 341 bdev->blockcnt = size / BS_PAGE_SIZE; 342 } 343 344 void 345 spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o, 346 spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) 347 { 348 struct lvol_ut_bs_dev *ut_dev = SPDK_CONTAINEROF(dev, struct lvol_ut_bs_dev, bs_dev); 349 struct spdk_blob_store *bs; 350 351 bs = calloc(1, sizeof(*bs)); 352 SPDK_CU_ASSERT_FATAL(bs != NULL); 353 354 TAILQ_INIT(&bs->blobs); 355 356 ut_dev->bs = bs; 357 bs->esnap_bs_dev_create = o->esnap_bs_dev_create; 358 359 memcpy(&bs->bs_opts, o, sizeof(struct spdk_bs_opts)); 360 361 cb_fn(cb_arg, bs, 0); 362 } 363 364 void 365 spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_arg) 366 { 367 cb_fn(cb_arg, 0); 368 } 369 370 void 371 spdk_bs_destroy(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, 372 void *cb_arg) 373 { 374 free(bs); 375 376 cb_fn(cb_arg, 0); 377 } 378 379 void 380 spdk_bs_delete_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, 381 spdk_blob_op_complete cb_fn, void *cb_arg) 382 { 383 struct spdk_blob *blob; 384 385 TAILQ_FOREACH(blob, &bs->blobs, link) { 386 if (blob->id == blobid) { 387 TAILQ_REMOVE(&bs->blobs, blob, link); 388 free(blob); 389 break; 390 } 391 } 392 393 cb_fn(cb_arg, g_remove_rc); 394 } 395 396 spdk_blob_id 397 spdk_blob_get_id(struct spdk_blob *blob) 398 { 399 return blob->id; 400 } 401 402 void 403 spdk_bs_opts_init(struct spdk_bs_opts *opts, size_t opts_size) 404 { 405 memset(opts, 0, sizeof(*opts)); 406 opts->opts_size = opts_size; 407 opts->cluster_sz = SPDK_BLOB_OPTS_CLUSTER_SZ; 408 opts->num_md_pages = SPDK_BLOB_OPTS_NUM_MD_PAGES; 409 opts->max_md_ops = SPDK_BLOB_OPTS_MAX_MD_OPS; 410 opts->max_channel_ops = SPDK_BLOB_OPTS_MAX_CHANNEL_OPS; 411 } 412 413 DEFINE_STUB(spdk_bs_get_cluster_size, uint64_t, (struct spdk_blob_store *bs), BS_CLUSTER_SIZE); 414 415 void 416 spdk_blob_close(struct spdk_blob *b, spdk_blob_op_complete cb_fn, void *cb_arg) 417 { 418 b->ref--; 419 420 cb_fn(cb_arg, b->close_status); 421 } 422 423 void 424 spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_fn, void *cb_arg) 425 { 426 if (g_resize_rc != 0) { 427 return cb_fn(cb_arg, g_resize_rc); 428 } else if (sz > DEV_BUFFER_SIZE / BS_CLUSTER_SIZE) { 429 return cb_fn(cb_arg, -ENOMEM); 430 } 431 cb_fn(cb_arg, 0); 432 } 433 434 DEFINE_STUB(spdk_blob_set_read_only, int, (struct spdk_blob *blob), 0); 435 436 void 437 spdk_blob_sync_md(struct spdk_blob *blob, spdk_blob_op_complete cb_fn, void *cb_arg) 438 { 439 cb_fn(cb_arg, 0); 440 } 441 442 void 443 spdk_bs_open_blob_ext(struct spdk_blob_store *bs, spdk_blob_id blobid, 444 struct spdk_blob_open_opts *opts, spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) 445 { 446 spdk_bs_open_blob(bs, blobid, cb_fn, cb_arg); 447 } 448 449 void 450 spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, 451 spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) 452 { 453 struct spdk_blob *blob; 454 455 if (!g_lvs_rename_blob_open_error) { 456 TAILQ_FOREACH(blob, &bs->blobs, link) { 457 if (blob->id == blobid) { 458 blob->ref++; 459 cb_fn(cb_arg, blob, blob->open_status); 460 return; 461 } 462 } 463 } 464 465 cb_fn(cb_arg, NULL, -ENOENT); 466 } 467 468 DEFINE_STUB(spdk_bs_free_cluster_count, uint64_t, (struct spdk_blob_store *bs), BS_FREE_CLUSTERS); 469 470 void 471 spdk_blob_opts_init(struct spdk_blob_opts *opts, size_t opts_size) 472 { 473 opts->opts_size = opts_size; 474 opts->num_clusters = 0; 475 opts->thin_provision = false; 476 opts->xattrs.count = 0; 477 opts->xattrs.names = NULL; 478 opts->xattrs.ctx = NULL; 479 opts->xattrs.get_value = NULL; 480 } 481 482 void 483 spdk_blob_open_opts_init(struct spdk_blob_open_opts *opts, size_t opts_size) 484 { 485 opts->opts_size = opts_size; 486 opts->clear_method = BLOB_CLEAR_WITH_DEFAULT; 487 } 488 489 bool 490 spdk_blob_is_read_only(struct spdk_blob *blob) 491 { 492 return g_blob_read_only; 493 } 494 495 void 496 spdk_bs_create_blob(struct spdk_blob_store *bs, 497 spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 498 { 499 spdk_bs_create_blob_ext(bs, NULL, cb_fn, cb_arg); 500 } 501 502 void 503 spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_opts *opts, 504 spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 505 { 506 struct spdk_blob *b; 507 508 if (opts && opts->num_clusters > DEV_BUFFER_SIZE / BS_CLUSTER_SIZE) { 509 cb_fn(cb_arg, 0, -1); 510 return; 511 } 512 513 b = calloc(1, sizeof(*b)); 514 SPDK_CU_ASSERT_FATAL(b != NULL); 515 516 b->id = g_blobid++; 517 if (opts != NULL && opts->thin_provision) { 518 b->thin_provisioned = true; 519 } 520 b->bs = bs; 521 522 if (opts != NULL) { 523 b->num_clusters = opts->num_clusters; 524 } else { 525 b->num_clusters = 1; 526 } 527 528 TAILQ_INSERT_TAIL(&bs->blobs, b, link); 529 cb_fn(cb_arg, b->id, 0); 530 } 531 532 void 533 spdk_bs_create_snapshot(struct spdk_blob_store *bs, spdk_blob_id blobid, 534 const struct spdk_blob_xattr_opts *snapshot_xattrs, 535 spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 536 { 537 spdk_bs_create_blob_ext(bs, NULL, cb_fn, cb_arg); 538 } 539 540 void 541 spdk_bs_create_clone(struct spdk_blob_store *bs, spdk_blob_id blobid, 542 const struct spdk_blob_xattr_opts *clone_xattrs, 543 spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 544 { 545 spdk_bs_create_blob_ext(bs, NULL, cb_fn, cb_arg); 546 } 547 548 static int g_spdk_blob_get_esnap_id_errno; 549 static bool g_spdk_blob_get_esnap_id_called; 550 static void *g_spdk_blob_get_esnap_id; 551 static size_t g_spdk_blob_get_esnap_id_len; 552 int 553 spdk_blob_get_esnap_id(struct spdk_blob *blob, const void **id, size_t *len) 554 { 555 g_spdk_blob_get_esnap_id_called = true; 556 if (g_spdk_blob_get_esnap_id_errno == 0) { 557 *id = g_spdk_blob_get_esnap_id; 558 *len = g_spdk_blob_get_esnap_id_len; 559 } 560 return g_spdk_blob_get_esnap_id_errno; 561 } 562 563 static spdk_blob_id g_spdk_blob_get_clones_snap_id = 0xbad; 564 static size_t g_spdk_blob_get_clones_count; 565 static spdk_blob_id *g_spdk_blob_get_clones_ids; 566 int 567 spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blob_id, spdk_blob_id *ids, 568 size_t *count) 569 { 570 if (blob_id != g_spdk_blob_get_clones_snap_id) { 571 *count = 0; 572 return 0; 573 } 574 if (ids == NULL || *count < g_spdk_blob_get_clones_count) { 575 *count = g_spdk_blob_get_clones_count; 576 return -ENOMEM; 577 } 578 memcpy(ids, g_spdk_blob_get_clones_ids, g_spdk_blob_get_clones_count * sizeof(*ids)); 579 return 0; 580 } 581 582 static void 583 lvol_store_op_with_handle_complete(void *cb_arg, struct spdk_lvol_store *lvol_store, int lvserrno) 584 { 585 g_lvol_store = lvol_store; 586 g_lvserrno = lvserrno; 587 if (cb_arg != NULL) { 588 struct ut_cb_res *res = cb_arg; 589 590 res->data = lvol_store; 591 res->err = lvserrno; 592 } 593 } 594 595 static void 596 lvol_op_with_handle_complete(void *cb_arg, struct spdk_lvol *lvol, int lvserrno) 597 { 598 g_lvol = lvol; 599 g_lvserrno = lvserrno; 600 if (cb_arg != NULL) { 601 struct ut_cb_res *res = cb_arg; 602 603 res->data = lvol; 604 res->err = lvserrno; 605 } 606 } 607 608 static void 609 op_complete(void *cb_arg, int lvserrno) 610 { 611 g_lvserrno = lvserrno; 612 if (cb_arg != NULL) { 613 struct ut_cb_res *res = cb_arg; 614 615 res->err = lvserrno; 616 } 617 } 618 619 static struct ut_cb_res * 620 ut_cb_res_clear(struct ut_cb_res *res) 621 { 622 memset(res, 0, sizeof(*res)); 623 res->data = (void *)(uintptr_t)(-1); 624 res->err = 0xbad; 625 return res; 626 } 627 628 static bool 629 ut_cb_res_untouched(const struct ut_cb_res *res) 630 { 631 struct ut_cb_res pristine; 632 633 ut_cb_res_clear(&pristine); 634 return !memcmp(&pristine, res, sizeof(pristine)); 635 } 636 637 struct count_clones_ctx { 638 struct spdk_lvol *stop_on_lvol; 639 int stop_errno; 640 int count; 641 }; 642 643 static int 644 count_clones(void *_ctx, struct spdk_lvol *lvol) 645 { 646 struct count_clones_ctx *ctx = _ctx; 647 648 if (ctx->stop_on_lvol == lvol) { 649 return ctx->stop_errno; 650 } 651 ctx->count++; 652 return 0; 653 } 654 655 static void 656 lvs_init_unload_success(void) 657 { 658 struct lvol_ut_bs_dev dev; 659 struct spdk_lvs_opts opts; 660 int rc = 0; 661 662 init_dev(&dev); 663 664 spdk_lvs_opts_init(&opts); 665 snprintf(opts.name, sizeof(opts.name), "lvs"); 666 667 g_lvserrno = -1; 668 669 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 670 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 671 CU_ASSERT(rc == 0); 672 CU_ASSERT(g_lvserrno == 0); 673 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 674 CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores)); 675 676 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 677 lvol_op_with_handle_complete, NULL); 678 CU_ASSERT(g_lvserrno == 0); 679 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 680 681 /* Lvol store has an open lvol, this unload should fail. */ 682 g_lvserrno = -1; 683 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 684 CU_ASSERT(rc == -EBUSY); 685 CU_ASSERT(g_lvserrno == -EBUSY); 686 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 687 CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores)); 688 689 /* Lvol has to be closed (or destroyed) before unloading lvol store. */ 690 spdk_lvol_close(g_lvol, op_complete, NULL); 691 CU_ASSERT(g_lvserrno == 0); 692 693 g_lvserrno = -1; 694 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 695 CU_ASSERT(rc == 0); 696 CU_ASSERT(g_lvserrno == 0); 697 g_lvol_store = NULL; 698 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 699 700 free_dev(&dev); 701 } 702 703 static void 704 lvs_init_destroy_success(void) 705 { 706 struct lvol_ut_bs_dev dev; 707 struct spdk_lvs_opts opts; 708 int rc = 0; 709 710 init_dev(&dev); 711 712 spdk_lvs_opts_init(&opts); 713 snprintf(opts.name, sizeof(opts.name), "lvs"); 714 715 g_lvserrno = -1; 716 717 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 718 CU_ASSERT(rc == 0); 719 CU_ASSERT(g_lvserrno == 0); 720 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 721 722 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 723 lvol_op_with_handle_complete, NULL); 724 CU_ASSERT(g_lvserrno == 0); 725 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 726 727 /* Lvol store contains one lvol, this destroy should fail. */ 728 g_lvserrno = -1; 729 rc = spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 730 CU_ASSERT(rc == -EBUSY); 731 CU_ASSERT(g_lvserrno == -EBUSY); 732 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 733 734 spdk_lvol_close(g_lvol, op_complete, NULL); 735 CU_ASSERT(g_lvserrno == 0); 736 737 spdk_lvol_destroy(g_lvol, op_complete, NULL); 738 739 g_lvserrno = -1; 740 rc = spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 741 CU_ASSERT(rc == 0); 742 CU_ASSERT(g_lvserrno == 0); 743 g_lvol_store = NULL; 744 } 745 746 static void 747 lvs_init_opts_success(void) 748 { 749 struct lvol_ut_bs_dev dev; 750 struct spdk_lvs_opts opts; 751 int rc = 0; 752 753 init_dev(&dev); 754 755 g_lvserrno = -1; 756 757 spdk_lvs_opts_init(&opts); 758 snprintf(opts.name, sizeof(opts.name), "lvs"); 759 opts.cluster_sz = 8192; 760 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 761 CU_ASSERT(rc == 0); 762 CU_ASSERT(g_lvserrno == 0); 763 CU_ASSERT(dev.bs->bs_opts.cluster_sz == opts.cluster_sz); 764 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 765 766 g_lvserrno = -1; 767 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 768 CU_ASSERT(rc == 0); 769 CU_ASSERT(g_lvserrno == 0); 770 g_lvol_store = NULL; 771 772 free_dev(&dev); 773 } 774 775 static void 776 lvs_unload_lvs_is_null_fail(void) 777 { 778 int rc = 0; 779 780 g_lvserrno = -1; 781 rc = spdk_lvs_unload(NULL, op_complete, NULL); 782 CU_ASSERT(rc == -ENODEV); 783 CU_ASSERT(g_lvserrno == -1); 784 } 785 786 static void 787 lvs_names(void) 788 { 789 struct lvol_ut_bs_dev dev_x, dev_y, dev_x2; 790 struct spdk_lvs_opts opts_none, opts_x, opts_y, opts_full; 791 struct spdk_lvol_store *lvs_x, *lvs_y, *lvs_x2; 792 int rc = 0; 793 794 init_dev(&dev_x); 795 init_dev(&dev_y); 796 init_dev(&dev_x2); 797 798 spdk_lvs_opts_init(&opts_none); 799 spdk_lvs_opts_init(&opts_x); 800 opts_x.name[0] = 'x'; 801 spdk_lvs_opts_init(&opts_y); 802 opts_y.name[0] = 'y'; 803 spdk_lvs_opts_init(&opts_full); 804 memset(opts_full.name, 'a', sizeof(opts_full.name)); 805 806 /* Test that opts with no name fails spdk_lvs_init(). */ 807 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 808 rc = spdk_lvs_init(&dev_x.bs_dev, &opts_none, lvol_store_op_with_handle_complete, NULL); 809 CU_ASSERT(rc != 0); 810 CU_ASSERT(g_lvol_store == NULL); 811 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 812 813 /* Test that opts with no null terminator for name fails spdk_lvs_init(). */ 814 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 815 rc = spdk_lvs_init(&dev_x.bs_dev, &opts_full, lvol_store_op_with_handle_complete, NULL); 816 CU_ASSERT(rc != 0); 817 CU_ASSERT(g_lvol_store == NULL); 818 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 819 820 /* Test that we can create an lvolstore with name 'x'. */ 821 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 822 g_lvol_store = NULL; 823 rc = spdk_lvs_init(&dev_x.bs_dev, &opts_x, lvol_store_op_with_handle_complete, NULL); 824 CU_ASSERT(rc == 0); 825 CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores)); 826 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 827 lvs_x = g_lvol_store; 828 829 /* Test that we can create an lvolstore with name 'y'. */ 830 g_lvol_store = NULL; 831 rc = spdk_lvs_init(&dev_y.bs_dev, &opts_y, lvol_store_op_with_handle_complete, NULL); 832 CU_ASSERT(rc == 0); 833 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 834 lvs_y = g_lvol_store; 835 836 /* Test that we cannot create another lvolstore with name 'x'. */ 837 rc = spdk_lvs_init(&dev_x2.bs_dev, &opts_x, lvol_store_op_with_handle_complete, NULL); 838 CU_ASSERT(rc == -EEXIST); 839 840 /* Now destroy lvolstore 'x' and then confirm we can create a new lvolstore with name 'x'. */ 841 g_lvserrno = -1; 842 rc = spdk_lvs_destroy(lvs_x, op_complete, NULL); 843 CU_ASSERT(rc == 0); 844 CU_ASSERT(g_lvserrno == 0); 845 g_lvol_store = NULL; 846 rc = spdk_lvs_init(&dev_x.bs_dev, &opts_x, lvol_store_op_with_handle_complete, NULL); 847 CU_ASSERT(rc == 0); 848 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 849 lvs_x = g_lvol_store; 850 851 /* 852 * Unload lvolstore 'x'. Then we should be able to create another lvolstore with name 'x'. 853 */ 854 g_lvserrno = -1; 855 rc = spdk_lvs_unload(lvs_x, op_complete, NULL); 856 CU_ASSERT(rc == 0); 857 CU_ASSERT(g_lvserrno == 0); 858 g_lvol_store = NULL; 859 rc = spdk_lvs_init(&dev_x2.bs_dev, &opts_x, lvol_store_op_with_handle_complete, NULL); 860 CU_ASSERT(rc == 0); 861 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 862 lvs_x2 = g_lvol_store; 863 864 /* Confirm that we cannot load the first lvolstore 'x'. */ 865 g_lvserrno = 0; 866 spdk_lvs_load(&dev_x.bs_dev, lvol_store_op_with_handle_complete, NULL); 867 CU_ASSERT(g_lvserrno != 0); 868 869 /* Destroy the second lvolstore 'x'. Then we should be able to load the first lvolstore 'x'. */ 870 g_lvserrno = -1; 871 rc = spdk_lvs_destroy(lvs_x2, op_complete, NULL); 872 CU_ASSERT(rc == 0); 873 CU_ASSERT(g_lvserrno == 0); 874 g_lvserrno = -1; 875 spdk_lvs_load(&dev_x.bs_dev, lvol_store_op_with_handle_complete, NULL); 876 CU_ASSERT(g_lvserrno == 0); 877 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 878 lvs_x = g_lvol_store; 879 880 g_lvserrno = -1; 881 rc = spdk_lvs_destroy(lvs_x, op_complete, NULL); 882 CU_ASSERT(rc == 0); 883 CU_ASSERT(g_lvserrno == 0); 884 885 g_lvserrno = -1; 886 rc = spdk_lvs_destroy(lvs_y, op_complete, NULL); 887 CU_ASSERT(rc == 0); 888 CU_ASSERT(g_lvserrno == 0); 889 } 890 891 static void 892 lvol_create_destroy_success(void) 893 { 894 struct lvol_ut_bs_dev dev; 895 struct spdk_lvs_opts opts; 896 int rc = 0; 897 898 init_dev(&dev); 899 900 spdk_lvs_opts_init(&opts); 901 snprintf(opts.name, sizeof(opts.name), "lvs"); 902 903 g_lvserrno = -1; 904 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 905 CU_ASSERT(rc == 0); 906 CU_ASSERT(g_lvserrno == 0); 907 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 908 909 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 910 lvol_op_with_handle_complete, NULL); 911 CU_ASSERT(g_lvserrno == 0); 912 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 913 914 spdk_lvol_close(g_lvol, op_complete, NULL); 915 CU_ASSERT(g_lvserrno == 0); 916 spdk_lvol_destroy(g_lvol, op_complete, NULL); 917 CU_ASSERT(g_lvserrno == 0); 918 919 g_lvserrno = -1; 920 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 921 CU_ASSERT(rc == 0); 922 CU_ASSERT(g_lvserrno == 0); 923 g_lvol_store = NULL; 924 925 free_dev(&dev); 926 } 927 928 static void 929 lvol_create_fail(void) 930 { 931 struct lvol_ut_bs_dev dev; 932 struct spdk_lvs_opts opts; 933 int rc = 0; 934 935 init_dev(&dev); 936 937 spdk_lvs_opts_init(&opts); 938 snprintf(opts.name, sizeof(opts.name), "lvs"); 939 940 g_lvol_store = NULL; 941 g_lvserrno = 0; 942 rc = spdk_lvs_init(NULL, &opts, lvol_store_op_with_handle_complete, NULL); 943 CU_ASSERT(rc != 0); 944 CU_ASSERT(g_lvol_store == NULL); 945 946 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 947 CU_ASSERT(rc == 0); 948 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 949 950 g_lvol = NULL; 951 rc = spdk_lvol_create(NULL, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 952 lvol_op_with_handle_complete, NULL); 953 CU_ASSERT(rc != 0); 954 CU_ASSERT(g_lvol == NULL); 955 956 g_lvol = NULL; 957 rc = spdk_lvol_create(g_lvol_store, "lvol", DEV_BUFFER_SIZE + 1, false, LVOL_CLEAR_WITH_DEFAULT, 958 lvol_op_with_handle_complete, NULL); 959 CU_ASSERT(rc == 0); 960 CU_ASSERT(g_lvserrno != 0); 961 CU_ASSERT(g_lvol == NULL); 962 963 g_lvserrno = -1; 964 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 965 CU_ASSERT(rc == 0); 966 CU_ASSERT(g_lvserrno == 0); 967 g_lvol_store = NULL; 968 969 free_dev(&dev); 970 } 971 972 static void 973 lvol_destroy_fail(void) 974 { 975 struct lvol_ut_bs_dev dev; 976 struct spdk_lvs_opts opts; 977 int rc = 0; 978 979 init_dev(&dev); 980 981 spdk_lvs_opts_init(&opts); 982 snprintf(opts.name, sizeof(opts.name), "lvs"); 983 984 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 985 CU_ASSERT(rc == 0); 986 CU_ASSERT(g_lvserrno == 0); 987 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 988 989 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 990 lvol_op_with_handle_complete, NULL); 991 CU_ASSERT(g_lvserrno == 0); 992 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 993 994 spdk_lvol_close(g_lvol, op_complete, NULL); 995 CU_ASSERT(g_lvserrno == 0); 996 spdk_lvol_destroy(g_lvol, op_complete, NULL); 997 CU_ASSERT(g_lvserrno == 0); 998 999 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 1000 lvol_op_with_handle_complete, NULL); 1001 CU_ASSERT(g_lvserrno == 0); 1002 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1003 1004 spdk_lvol_close(g_lvol, op_complete, NULL); 1005 CU_ASSERT(g_lvserrno == 0); 1006 1007 g_remove_rc = -1; 1008 spdk_lvol_destroy(g_lvol, op_complete, NULL); 1009 CU_ASSERT(g_lvserrno != 0); 1010 CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols)); 1011 g_remove_rc = 0; 1012 1013 g_lvserrno = -1; 1014 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1015 CU_ASSERT(rc == 0); 1016 CU_ASSERT(g_lvserrno == 0); 1017 g_lvol_store = NULL; 1018 1019 free_dev(&dev); 1020 } 1021 1022 static void 1023 lvol_close(void) 1024 { 1025 struct lvol_ut_bs_dev dev; 1026 struct spdk_lvol *lvol; 1027 struct spdk_lvol_store *lvs; 1028 struct spdk_lvs_opts opts; 1029 struct ut_cb_res cb_res; 1030 1031 int rc = 0; 1032 1033 init_dev(&dev); 1034 1035 spdk_lvs_opts_init(&opts); 1036 snprintf(opts.name, sizeof(opts.name), "lvs"); 1037 1038 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, 1039 ut_cb_res_clear(&cb_res)); 1040 CU_ASSERT(rc == 0); 1041 CU_ASSERT(cb_res.err == 0); 1042 SPDK_CU_ASSERT_FATAL(cb_res.data != NULL); 1043 lvs = cb_res.data; 1044 1045 spdk_lvol_create(lvs, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 1046 lvol_op_with_handle_complete, ut_cb_res_clear(&cb_res)); 1047 CU_ASSERT(cb_res.err == 0); 1048 SPDK_CU_ASSERT_FATAL(cb_res.data != NULL); 1049 lvol = cb_res.data; 1050 CU_ASSERT(lvol->action_in_progress == false); 1051 1052 /* Fail - lvol does not exist */ 1053 spdk_lvol_close(NULL, op_complete, ut_cb_res_clear(&cb_res)); 1054 CU_ASSERT(cb_res.err == -ENODEV); 1055 CU_ASSERT(lvol->action_in_progress == false); 1056 1057 /* Fail - lvol not open */ 1058 lvol->ref_count = 0; 1059 spdk_lvol_close(lvol, op_complete, ut_cb_res_clear(&cb_res)); 1060 CU_ASSERT(cb_res.err == -EINVAL); 1061 CU_ASSERT(lvol->action_in_progress == false); 1062 lvol->ref_count = 1; 1063 1064 /* Fail - blob close fails */ 1065 lvol->blob->close_status = -1; 1066 spdk_lvol_close(lvol, op_complete, ut_cb_res_clear(&cb_res)); 1067 CU_ASSERT(cb_res.err == -1); 1068 CU_ASSERT(lvol->action_in_progress == false); 1069 lvol->blob->close_status = 0; 1070 1071 /* Success */ 1072 spdk_lvol_close(lvol, op_complete, ut_cb_res_clear(&cb_res)); 1073 CU_ASSERT(cb_res.err == 0); 1074 1075 rc = spdk_lvs_unload(lvs, op_complete, ut_cb_res_clear(&cb_res)); 1076 CU_ASSERT(rc == 0); 1077 CU_ASSERT(cb_res.err == 0); 1078 1079 free_dev(&dev); 1080 } 1081 1082 static void 1083 lvol_resize(void) 1084 { 1085 struct lvol_ut_bs_dev dev; 1086 struct spdk_lvs_opts opts; 1087 int rc = 0; 1088 1089 init_dev(&dev); 1090 1091 spdk_lvs_opts_init(&opts); 1092 snprintf(opts.name, sizeof(opts.name), "lvs"); 1093 1094 g_resize_rc = 0; 1095 g_lvserrno = -1; 1096 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1097 CU_ASSERT(rc == 0); 1098 CU_ASSERT(g_lvserrno == 0); 1099 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1100 1101 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 1102 lvol_op_with_handle_complete, NULL); 1103 CU_ASSERT(g_lvserrno == 0); 1104 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1105 1106 /* Resize to same size */ 1107 spdk_lvol_resize(g_lvol, 10, op_complete, NULL); 1108 CU_ASSERT(g_lvserrno == 0); 1109 1110 /* Resize to smaller size */ 1111 spdk_lvol_resize(g_lvol, 5, op_complete, NULL); 1112 CU_ASSERT(g_lvserrno == 0); 1113 1114 /* Resize to bigger size */ 1115 spdk_lvol_resize(g_lvol, 15, op_complete, NULL); 1116 CU_ASSERT(g_lvserrno == 0); 1117 1118 /* Resize to size = 0 */ 1119 spdk_lvol_resize(g_lvol, 0, op_complete, NULL); 1120 CU_ASSERT(g_lvserrno == 0); 1121 1122 /* Resize to bigger size than available */ 1123 g_lvserrno = 0; 1124 spdk_lvol_resize(g_lvol, 0xFFFFFFFF, op_complete, NULL); 1125 CU_ASSERT(g_lvserrno != 0); 1126 1127 /* Fail resize */ 1128 g_resize_rc = -1; 1129 g_lvserrno = 0; 1130 spdk_lvol_resize(g_lvol, 10, op_complete, NULL); 1131 CU_ASSERT(g_lvserrno != 0); 1132 g_resize_rc = 0; 1133 1134 g_resize_rc = 0; 1135 spdk_lvol_close(g_lvol, op_complete, NULL); 1136 CU_ASSERT(g_lvserrno == 0); 1137 spdk_lvol_destroy(g_lvol, op_complete, NULL); 1138 CU_ASSERT(g_lvserrno == 0); 1139 1140 g_lvserrno = -1; 1141 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1142 CU_ASSERT(rc == 0); 1143 CU_ASSERT(g_lvserrno == 0); 1144 g_lvol_store = NULL; 1145 1146 free_dev(&dev); 1147 } 1148 1149 static void 1150 lvol_set_read_only(void) 1151 { 1152 struct lvol_ut_bs_dev dev; 1153 struct spdk_lvs_opts opts; 1154 int rc = 0; 1155 struct spdk_lvol *lvol, *clone; 1156 1157 init_dev(&dev); 1158 1159 spdk_lvs_opts_init(&opts); 1160 snprintf(opts.name, sizeof(opts.name), "lvs"); 1161 1162 g_lvserrno = -1; 1163 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1164 CU_ASSERT(rc == 0); 1165 CU_ASSERT(g_lvserrno == 0); 1166 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1167 1168 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 1169 lvol_op_with_handle_complete, NULL); 1170 CU_ASSERT(g_lvserrno == 0); 1171 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1172 lvol = g_lvol; 1173 1174 /* Set lvol as read only */ 1175 spdk_lvol_set_read_only(lvol, op_complete, NULL); 1176 CU_ASSERT(g_lvserrno == 0); 1177 1178 /* Create lvol clone from read only lvol */ 1179 spdk_lvol_create_clone(lvol, "clone", lvol_op_with_handle_complete, NULL); 1180 CU_ASSERT(g_lvserrno == 0); 1181 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1182 CU_ASSERT_STRING_EQUAL(g_lvol->name, "clone"); 1183 clone = g_lvol; 1184 1185 spdk_lvol_close(lvol, op_complete, NULL); 1186 CU_ASSERT(g_lvserrno == 0); 1187 spdk_lvol_close(clone, op_complete, NULL); 1188 CU_ASSERT(g_lvserrno == 0); 1189 1190 g_lvserrno = -1; 1191 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1192 CU_ASSERT(rc == 0); 1193 CU_ASSERT(g_lvserrno == 0); 1194 g_lvol_store = NULL; 1195 1196 free_dev(&dev); 1197 } 1198 1199 static void 1200 null_cb(void *ctx, struct spdk_blob_store *bs, int bserrno) 1201 { 1202 SPDK_CU_ASSERT_FATAL(bs != NULL); 1203 } 1204 1205 static void 1206 test_lvs_load(void) 1207 { 1208 int rc = -1; 1209 struct lvol_ut_bs_dev dev; 1210 struct spdk_lvs_with_handle_req *req; 1211 struct spdk_bs_opts bs_opts = {}; 1212 struct spdk_blob *super_blob; 1213 struct spdk_lvs_opts opts = {}; 1214 1215 req = calloc(1, sizeof(*req)); 1216 SPDK_CU_ASSERT_FATAL(req != NULL); 1217 1218 init_dev(&dev); 1219 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 1220 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "LVOLSTORE"); 1221 spdk_bs_init(&dev.bs_dev, &bs_opts, null_cb, NULL); 1222 SPDK_CU_ASSERT_FATAL(dev.bs != NULL); 1223 1224 /* Fail on bs load */ 1225 dev.load_status = -1; 1226 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1227 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1228 CU_ASSERT(g_lvserrno != 0); 1229 CU_ASSERT(g_lvol_store == NULL); 1230 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1231 1232 /* Fail on getting super blob */ 1233 dev.load_status = 0; 1234 dev.bs->get_super_status = -1; 1235 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1236 CU_ASSERT(g_lvserrno == -ENODEV); 1237 CU_ASSERT(g_lvol_store == NULL); 1238 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1239 1240 /* Fail on opening super blob */ 1241 g_lvserrno = 0; 1242 super_blob = calloc(1, sizeof(*super_blob)); 1243 super_blob->id = 0x100; 1244 super_blob->open_status = -1; 1245 TAILQ_INSERT_TAIL(&dev.bs->blobs, super_blob, link); 1246 dev.bs->super_blobid = 0x100; 1247 dev.bs->get_super_status = 0; 1248 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1249 CU_ASSERT(g_lvserrno == -ENODEV); 1250 CU_ASSERT(g_lvol_store == NULL); 1251 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1252 1253 /* Fail on getting uuid */ 1254 g_lvserrno = 0; 1255 super_blob->open_status = 0; 1256 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1257 CU_ASSERT(g_lvserrno == -EINVAL); 1258 CU_ASSERT(g_lvol_store == NULL); 1259 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1260 1261 /* Fail on getting name */ 1262 g_lvserrno = 0; 1263 spdk_blob_set_xattr(super_blob, "uuid", uuid, SPDK_UUID_STRING_LEN); 1264 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1265 CU_ASSERT(g_lvserrno == -EINVAL); 1266 CU_ASSERT(g_lvol_store == NULL); 1267 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1268 1269 /* Fail on closing super blob */ 1270 g_lvserrno = 0; 1271 spdk_blob_set_xattr(super_blob, "name", "lvs", strlen("lvs") + 1); 1272 super_blob->close_status = -1; 1273 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1274 CU_ASSERT(g_lvserrno == -ENODEV); 1275 CU_ASSERT(g_lvol_store == NULL); 1276 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1277 1278 /* Fail on invalid options */ 1279 g_lvserrno = -1; 1280 spdk_lvs_opts_init(&opts); 1281 opts.opts_size = 0; /* Invalid length */ 1282 spdk_lvs_load_ext(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1283 CU_ASSERT(g_lvserrno == -EINVAL); 1284 CU_ASSERT(g_lvol_store == NULL); 1285 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1286 1287 /* Load successfully */ 1288 g_lvserrno = 0; 1289 super_blob->close_status = 0; 1290 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1291 CU_ASSERT(g_lvserrno == 0); 1292 CU_ASSERT(g_lvol_store != NULL); 1293 CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores)); 1294 1295 g_lvserrno = -1; 1296 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1297 CU_ASSERT(rc == 0); 1298 CU_ASSERT(g_lvserrno == 0); 1299 CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 1300 1301 free(req); 1302 free_dev(&dev); 1303 } 1304 1305 static void 1306 lvols_load(void) 1307 { 1308 int rc = -1; 1309 struct lvol_ut_bs_dev dev; 1310 struct spdk_lvs_with_handle_req *req; 1311 struct spdk_bs_opts bs_opts; 1312 struct spdk_blob *super_blob, *blob1, *blob2, *blob3; 1313 1314 req = calloc(1, sizeof(*req)); 1315 SPDK_CU_ASSERT_FATAL(req != NULL); 1316 1317 init_dev(&dev); 1318 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 1319 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "LVOLSTORE"); 1320 spdk_bs_init(&dev.bs_dev, &bs_opts, null_cb, NULL); 1321 super_blob = calloc(1, sizeof(*super_blob)); 1322 SPDK_CU_ASSERT_FATAL(super_blob != NULL); 1323 super_blob->id = 0x100; 1324 spdk_blob_set_xattr(super_blob, "uuid", uuid, SPDK_UUID_STRING_LEN); 1325 spdk_blob_set_xattr(super_blob, "name", "lvs", strlen("lvs") + 1); 1326 TAILQ_INSERT_TAIL(&dev.bs->blobs, super_blob, link); 1327 dev.bs->super_blobid = 0x100; 1328 1329 /* 1330 * Create 3 blobs, write different char values to the last char in the UUID 1331 * to make sure they are unique. 1332 */ 1333 blob1 = calloc(1, sizeof(*blob1)); 1334 SPDK_CU_ASSERT_FATAL(blob1 != NULL); 1335 blob1->id = 0x1; 1336 spdk_blob_set_xattr(blob1, "uuid", uuid, SPDK_UUID_STRING_LEN); 1337 spdk_blob_set_xattr(blob1, "name", "lvol1", strlen("lvol1") + 1); 1338 blob1->uuid[SPDK_UUID_STRING_LEN - 2] = '1'; 1339 1340 blob2 = calloc(1, sizeof(*blob2)); 1341 SPDK_CU_ASSERT_FATAL(blob2 != NULL); 1342 blob2->id = 0x2; 1343 spdk_blob_set_xattr(blob2, "uuid", uuid, SPDK_UUID_STRING_LEN); 1344 spdk_blob_set_xattr(blob2, "name", "lvol2", strlen("lvol2") + 1); 1345 blob2->uuid[SPDK_UUID_STRING_LEN - 2] = '2'; 1346 1347 blob3 = calloc(1, sizeof(*blob3)); 1348 SPDK_CU_ASSERT_FATAL(blob3 != NULL); 1349 blob3->id = 0x3; 1350 spdk_blob_set_xattr(blob3, "uuid", uuid, SPDK_UUID_STRING_LEN); 1351 spdk_blob_set_xattr(blob3, "name", "lvol3", strlen("lvol3") + 1); 1352 blob3->uuid[SPDK_UUID_STRING_LEN - 2] = '3'; 1353 1354 /* Load lvs with 0 blobs */ 1355 g_lvserrno = 0; 1356 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1357 CU_ASSERT(g_lvserrno == 0); 1358 CU_ASSERT(g_lvol_store != NULL); 1359 CU_ASSERT(g_lvserrno == 0); 1360 1361 g_lvserrno = -1; 1362 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1363 CU_ASSERT(rc == 0); 1364 CU_ASSERT(g_lvserrno == 0); 1365 1366 TAILQ_INSERT_TAIL(&dev.bs->blobs, blob1, link); 1367 TAILQ_INSERT_TAIL(&dev.bs->blobs, blob2, link); 1368 TAILQ_INSERT_TAIL(&dev.bs->blobs, blob3, link); 1369 1370 /* Load lvs again with 3 blobs, but fail on 1st one */ 1371 g_lvol_store = NULL; 1372 g_lvserrno = 0; 1373 blob1->load_status = -1; 1374 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1375 CU_ASSERT(g_lvserrno != 0); 1376 CU_ASSERT(g_lvol_store == NULL); 1377 1378 /* Load lvs again with 3 blobs, but fail on 3rd one */ 1379 g_lvol_store = NULL; 1380 g_lvserrno = 0; 1381 blob1->load_status = 0; 1382 blob2->load_status = 0; 1383 blob3->load_status = -1; 1384 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1385 CU_ASSERT(g_lvserrno != 0); 1386 CU_ASSERT(g_lvol_store == NULL); 1387 1388 /* Load lvs again with 3 blobs, with success */ 1389 g_lvol_store = NULL; 1390 g_lvserrno = 0; 1391 blob1->load_status = 0; 1392 blob2->load_status = 0; 1393 blob3->load_status = 0; 1394 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1395 CU_ASSERT(g_lvserrno == 0); 1396 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1397 CU_ASSERT(!TAILQ_EMPTY(&g_lvol_store->lvols)); 1398 1399 g_lvserrno = -1; 1400 /* rc = */ spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1401 /* 1402 * Disable these two asserts for now. lvolstore should allow unload as long 1403 * as the lvols were not opened - but this is coming a future patch. 1404 */ 1405 /* CU_ASSERT(rc == 0); */ 1406 /* CU_ASSERT(g_lvserrno == 0); */ 1407 1408 free(req); 1409 free_dev(&dev); 1410 } 1411 1412 static void 1413 lvol_open(void) 1414 { 1415 struct lvol_ut_bs_dev dev; 1416 struct spdk_lvs_with_handle_req *req; 1417 struct spdk_bs_opts bs_opts; 1418 struct spdk_blob *super_blob, *blob1, *blob2, *blob3; 1419 struct spdk_lvol *lvol, *tmp; 1420 1421 req = calloc(1, sizeof(*req)); 1422 SPDK_CU_ASSERT_FATAL(req != NULL); 1423 1424 init_dev(&dev); 1425 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 1426 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "LVOLSTORE"); 1427 spdk_bs_init(&dev.bs_dev, &bs_opts, null_cb, NULL); 1428 super_blob = calloc(1, sizeof(*super_blob)); 1429 SPDK_CU_ASSERT_FATAL(super_blob != NULL); 1430 super_blob->id = 0x100; 1431 spdk_blob_set_xattr(super_blob, "uuid", uuid, SPDK_UUID_STRING_LEN); 1432 spdk_blob_set_xattr(super_blob, "name", "lvs", strlen("lvs") + 1); 1433 TAILQ_INSERT_TAIL(&dev.bs->blobs, super_blob, link); 1434 dev.bs->super_blobid = 0x100; 1435 1436 /* 1437 * Create 3 blobs, write different char values to the last char in the UUID 1438 * to make sure they are unique. 1439 */ 1440 blob1 = calloc(1, sizeof(*blob1)); 1441 SPDK_CU_ASSERT_FATAL(blob1 != NULL); 1442 blob1->id = 0x1; 1443 spdk_blob_set_xattr(blob1, "uuid", uuid, SPDK_UUID_STRING_LEN); 1444 spdk_blob_set_xattr(blob1, "name", "lvol1", strlen("lvol1") + 1); 1445 blob1->uuid[SPDK_UUID_STRING_LEN - 2] = '1'; 1446 1447 blob2 = calloc(1, sizeof(*blob2)); 1448 SPDK_CU_ASSERT_FATAL(blob2 != NULL); 1449 blob2->id = 0x2; 1450 spdk_blob_set_xattr(blob2, "uuid", uuid, SPDK_UUID_STRING_LEN); 1451 spdk_blob_set_xattr(blob2, "name", "lvol2", strlen("lvol2") + 1); 1452 blob2->uuid[SPDK_UUID_STRING_LEN - 2] = '2'; 1453 1454 blob3 = calloc(1, sizeof(*blob3)); 1455 SPDK_CU_ASSERT_FATAL(blob3 != NULL); 1456 blob3->id = 0x2; 1457 spdk_blob_set_xattr(blob3, "uuid", uuid, SPDK_UUID_STRING_LEN); 1458 spdk_blob_set_xattr(blob3, "name", "lvol3", strlen("lvol3") + 1); 1459 blob3->uuid[SPDK_UUID_STRING_LEN - 2] = '3'; 1460 1461 TAILQ_INSERT_TAIL(&dev.bs->blobs, blob1, link); 1462 TAILQ_INSERT_TAIL(&dev.bs->blobs, blob2, link); 1463 TAILQ_INSERT_TAIL(&dev.bs->blobs, blob3, link); 1464 1465 /* Load lvs with 3 blobs */ 1466 g_lvol_store = NULL; 1467 g_lvserrno = 0; 1468 spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); 1469 CU_ASSERT(g_lvserrno == 0); 1470 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1471 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_stores)); 1472 1473 blob1->open_status = -1; 1474 blob2->open_status = -1; 1475 blob3->open_status = -1; 1476 1477 /* Fail opening all lvols */ 1478 TAILQ_FOREACH_SAFE(lvol, &g_lvol_store->lvols, link, tmp) { 1479 spdk_lvol_open(lvol, lvol_op_with_handle_complete, NULL); 1480 CU_ASSERT(g_lvserrno != 0); 1481 } 1482 1483 blob1->open_status = 0; 1484 blob2->open_status = 0; 1485 blob3->open_status = 0; 1486 1487 /* Open all lvols */ 1488 TAILQ_FOREACH_SAFE(lvol, &g_lvol_store->lvols, link, tmp) { 1489 spdk_lvol_open(lvol, lvol_op_with_handle_complete, NULL); 1490 CU_ASSERT(g_lvserrno == 0); 1491 } 1492 1493 /* Close all lvols */ 1494 TAILQ_FOREACH_SAFE(lvol, &g_lvol_store->lvols, link, tmp) { 1495 spdk_lvol_close(lvol, op_complete, NULL); 1496 CU_ASSERT(g_lvserrno == 0); 1497 } 1498 1499 g_lvserrno = -1; 1500 spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 1501 1502 free(req); 1503 free(blob1); 1504 free(blob2); 1505 free(blob3); 1506 } 1507 1508 static void 1509 lvol_snapshot(void) 1510 { 1511 struct lvol_ut_bs_dev dev; 1512 struct spdk_lvol *lvol; 1513 struct spdk_lvs_opts opts; 1514 int rc = 0; 1515 1516 init_dev(&dev); 1517 1518 spdk_lvs_opts_init(&opts); 1519 snprintf(opts.name, sizeof(opts.name), "lvs"); 1520 1521 g_lvserrno = -1; 1522 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1523 CU_ASSERT(rc == 0); 1524 CU_ASSERT(g_lvserrno == 0); 1525 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1526 1527 spdk_lvol_create(g_lvol_store, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 1528 lvol_op_with_handle_complete, NULL); 1529 CU_ASSERT(g_lvserrno == 0); 1530 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1531 1532 lvol = g_lvol; 1533 1534 spdk_lvol_create_snapshot(lvol, "snap", lvol_op_with_handle_complete, NULL); 1535 CU_ASSERT(g_lvserrno == 0); 1536 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1537 CU_ASSERT_STRING_EQUAL(g_lvol->name, "snap"); 1538 1539 /* Lvol has to be closed (or destroyed) before unloading lvol store. */ 1540 spdk_lvol_close(g_lvol, op_complete, NULL); 1541 CU_ASSERT(g_lvserrno == 0); 1542 g_lvserrno = -1; 1543 1544 spdk_lvol_close(lvol, op_complete, NULL); 1545 CU_ASSERT(g_lvserrno == 0); 1546 g_lvserrno = -1; 1547 1548 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1549 CU_ASSERT(rc == 0); 1550 CU_ASSERT(g_lvserrno == 0); 1551 g_lvol_store = NULL; 1552 1553 free_dev(&dev); 1554 } 1555 1556 static void 1557 lvol_snapshot_fail(void) 1558 { 1559 struct lvol_ut_bs_dev dev; 1560 struct spdk_lvol *lvol, *snap; 1561 struct spdk_lvs_opts opts; 1562 int rc = 0; 1563 1564 init_dev(&dev); 1565 1566 spdk_lvs_opts_init(&opts); 1567 snprintf(opts.name, sizeof(opts.name), "lvs"); 1568 1569 g_lvserrno = -1; 1570 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1571 CU_ASSERT(rc == 0); 1572 CU_ASSERT(g_lvserrno == 0); 1573 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1574 1575 spdk_lvol_create(g_lvol_store, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 1576 lvol_op_with_handle_complete, NULL); 1577 CU_ASSERT(g_lvserrno == 0); 1578 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1579 1580 lvol = g_lvol; 1581 1582 spdk_lvol_create_snapshot(NULL, "snap", lvol_op_with_handle_complete, NULL); 1583 CU_ASSERT(g_lvserrno < 0); 1584 SPDK_CU_ASSERT_FATAL(g_lvol == NULL); 1585 1586 spdk_lvol_create_snapshot(lvol, "", lvol_op_with_handle_complete, NULL); 1587 CU_ASSERT(g_lvserrno < 0); 1588 SPDK_CU_ASSERT_FATAL(g_lvol == NULL); 1589 1590 spdk_lvol_create_snapshot(lvol, NULL, lvol_op_with_handle_complete, NULL); 1591 CU_ASSERT(g_lvserrno < 0); 1592 SPDK_CU_ASSERT_FATAL(g_lvol == NULL); 1593 1594 spdk_lvol_create_snapshot(lvol, "snap", lvol_op_with_handle_complete, NULL); 1595 CU_ASSERT(g_lvserrno == 0); 1596 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1597 CU_ASSERT_STRING_EQUAL(g_lvol->name, "snap"); 1598 1599 snap = g_lvol; 1600 1601 spdk_lvol_create_snapshot(lvol, "snap", lvol_op_with_handle_complete, NULL); 1602 CU_ASSERT(g_lvserrno < 0); 1603 1604 spdk_lvol_close(lvol, op_complete, NULL); 1605 CU_ASSERT(g_lvserrno == 0); 1606 g_lvserrno = -1; 1607 1608 spdk_lvol_close(snap, op_complete, NULL); 1609 CU_ASSERT(g_lvserrno == 0); 1610 g_lvserrno = -1; 1611 1612 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1613 CU_ASSERT(rc == 0); 1614 CU_ASSERT(g_lvserrno == 0); 1615 g_lvol_store = NULL; 1616 1617 free_dev(&dev); 1618 } 1619 1620 static void 1621 lvol_clone(void) 1622 { 1623 struct lvol_ut_bs_dev dev; 1624 struct spdk_lvol *lvol; 1625 struct spdk_lvol *snap; 1626 struct spdk_lvs_opts opts; 1627 int rc = 0; 1628 1629 init_dev(&dev); 1630 1631 spdk_lvs_opts_init(&opts); 1632 snprintf(opts.name, sizeof(opts.name), "lvs"); 1633 1634 g_lvserrno = -1; 1635 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1636 CU_ASSERT(rc == 0); 1637 CU_ASSERT(g_lvserrno == 0); 1638 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1639 1640 spdk_lvol_create(g_lvol_store, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 1641 lvol_op_with_handle_complete, NULL); 1642 CU_ASSERT(g_lvserrno == 0); 1643 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1644 1645 lvol = g_lvol; 1646 1647 spdk_lvol_create_snapshot(lvol, "snap", lvol_op_with_handle_complete, NULL); 1648 CU_ASSERT(g_lvserrno == 0); 1649 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1650 CU_ASSERT_STRING_EQUAL(g_lvol->name, "snap"); 1651 1652 snap = g_lvol; 1653 1654 spdk_lvol_create_clone(snap, "clone", lvol_op_with_handle_complete, NULL); 1655 CU_ASSERT(g_lvserrno == 0); 1656 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1657 CU_ASSERT_STRING_EQUAL(g_lvol->name, "clone"); 1658 1659 /* Lvol has to be closed (or destroyed) before unloading lvol store. */ 1660 spdk_lvol_close(g_lvol, op_complete, NULL); 1661 CU_ASSERT(g_lvserrno == 0); 1662 g_lvserrno = -1; 1663 1664 spdk_lvol_close(snap, op_complete, NULL); 1665 CU_ASSERT(g_lvserrno == 0); 1666 g_lvserrno = -1; 1667 1668 spdk_lvol_close(lvol, op_complete, NULL); 1669 CU_ASSERT(g_lvserrno == 0); 1670 g_lvserrno = -1; 1671 1672 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1673 CU_ASSERT(rc == 0); 1674 CU_ASSERT(g_lvserrno == 0); 1675 g_lvol_store = NULL; 1676 1677 free_dev(&dev); 1678 } 1679 1680 static void 1681 lvol_clone_fail(void) 1682 { 1683 struct lvol_ut_bs_dev dev; 1684 struct spdk_lvol *lvol; 1685 struct spdk_lvol *snap; 1686 struct spdk_lvol *clone; 1687 struct spdk_lvs_opts opts; 1688 int rc = 0; 1689 1690 init_dev(&dev); 1691 1692 spdk_lvs_opts_init(&opts); 1693 snprintf(opts.name, sizeof(opts.name), "lvs"); 1694 1695 g_lvserrno = -1; 1696 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1697 CU_ASSERT(rc == 0); 1698 CU_ASSERT(g_lvserrno == 0); 1699 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1700 1701 spdk_lvol_create(g_lvol_store, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 1702 lvol_op_with_handle_complete, NULL); 1703 CU_ASSERT(g_lvserrno == 0); 1704 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1705 1706 lvol = g_lvol; 1707 1708 spdk_lvol_create_snapshot(lvol, "snap", lvol_op_with_handle_complete, NULL); 1709 CU_ASSERT(g_lvserrno == 0); 1710 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1711 CU_ASSERT_STRING_EQUAL(g_lvol->name, "snap"); 1712 1713 snap = g_lvol; 1714 1715 spdk_lvol_create_clone(NULL, "clone", lvol_op_with_handle_complete, NULL); 1716 CU_ASSERT(g_lvserrno < 0); 1717 1718 spdk_lvol_create_clone(snap, "", lvol_op_with_handle_complete, NULL); 1719 CU_ASSERT(g_lvserrno < 0); 1720 1721 spdk_lvol_create_clone(snap, NULL, lvol_op_with_handle_complete, NULL); 1722 CU_ASSERT(g_lvserrno < 0); 1723 1724 spdk_lvol_create_clone(snap, "clone", lvol_op_with_handle_complete, NULL); 1725 CU_ASSERT(g_lvserrno == 0); 1726 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1727 CU_ASSERT_STRING_EQUAL(g_lvol->name, "clone"); 1728 1729 clone = g_lvol; 1730 1731 spdk_lvol_create_clone(snap, "clone", lvol_op_with_handle_complete, NULL); 1732 CU_ASSERT(g_lvserrno < 0); 1733 1734 /* Lvol has to be closed (or destroyed) before unloading lvol store. */ 1735 spdk_lvol_close(clone, op_complete, NULL); 1736 CU_ASSERT(g_lvserrno == 0); 1737 g_lvserrno = -1; 1738 1739 spdk_lvol_close(snap, op_complete, NULL); 1740 CU_ASSERT(g_lvserrno == 0); 1741 g_lvserrno = -1; 1742 1743 spdk_lvol_close(lvol, op_complete, NULL); 1744 CU_ASSERT(g_lvserrno == 0); 1745 g_lvserrno = -1; 1746 1747 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1748 CU_ASSERT(rc == 0); 1749 CU_ASSERT(g_lvserrno == 0); 1750 g_lvol_store = NULL; 1751 1752 free_dev(&dev); 1753 } 1754 1755 static void 1756 lvol_iter_clones(void) 1757 { 1758 struct lvol_ut_bs_dev dev; 1759 struct spdk_lvol *lvol, *snap, *clone; 1760 struct spdk_lvs_opts opts; 1761 struct count_clones_ctx ctx = { 0 }; 1762 spdk_blob_id mock_clones[2]; 1763 int rc = 0; 1764 1765 init_dev(&dev); 1766 1767 spdk_lvs_opts_init(&opts); 1768 snprintf(opts.name, sizeof(opts.name), "lvs"); 1769 1770 g_spdk_blob_get_clones_ids = mock_clones; 1771 1772 g_lvserrno = -1; 1773 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1774 CU_ASSERT(rc == 0); 1775 CU_ASSERT(g_lvserrno == 0); 1776 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1777 1778 /* Create a volume */ 1779 spdk_lvol_create(g_lvol_store, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 1780 lvol_op_with_handle_complete, NULL); 1781 CU_ASSERT(g_lvserrno == 0); 1782 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1783 lvol = g_lvol; 1784 1785 /* Create a snapshot of the volume */ 1786 spdk_lvol_create_snapshot(lvol, "snap", lvol_op_with_handle_complete, NULL); 1787 CU_ASSERT(g_lvserrno == 0); 1788 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1789 CU_ASSERT_STRING_EQUAL(g_lvol->name, "snap"); 1790 snap = g_lvol; 1791 1792 g_spdk_blob_get_clones_snap_id = snap->blob_id; 1793 g_spdk_blob_get_clones_count = 1; 1794 mock_clones[0] = lvol->blob_id; 1795 1796 /* The snapshot turned the lvol into a clone, so the snapshot now has one clone. */ 1797 memset(&ctx, 0, sizeof(ctx)); 1798 rc = spdk_lvol_iter_immediate_clones(snap, count_clones, &ctx); 1799 CU_ASSERT(rc == 0); 1800 CU_ASSERT(ctx.count == 1); 1801 1802 /* The snapshotted volume still has no clones. */ 1803 memset(&ctx, 0, sizeof(ctx)); 1804 rc = spdk_lvol_iter_immediate_clones(lvol, count_clones, &ctx); 1805 CU_ASSERT(rc == 0); 1806 CU_ASSERT(ctx.count == 0); 1807 1808 /* Iteration can be stopped and the return value is propagated. */ 1809 memset(&ctx, 0, sizeof(ctx)); 1810 ctx.stop_on_lvol = lvol; 1811 ctx.stop_errno = 42; 1812 rc = spdk_lvol_iter_immediate_clones(snap, count_clones, &ctx); 1813 CU_ASSERT(rc == 42); 1814 CU_ASSERT(ctx.count == 0); 1815 1816 /* Create a clone of the snapshot */ 1817 spdk_lvol_create_clone(snap, "clone", lvol_op_with_handle_complete, NULL); 1818 CU_ASSERT(g_lvserrno == 0); 1819 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1820 CU_ASSERT_STRING_EQUAL(g_lvol->name, "clone"); 1821 clone = g_lvol; 1822 1823 g_spdk_blob_get_clones_count = 2; 1824 mock_clones[1] = clone->blob_id; 1825 1826 /* The snapshot now has two clones */ 1827 memset(&ctx, 0, sizeof(ctx)); 1828 rc = spdk_lvol_iter_immediate_clones(snap, count_clones, &ctx); 1829 CU_ASSERT(rc == 0); 1830 CU_ASSERT(ctx.count == 2); 1831 1832 /* Cleanup */ 1833 g_spdk_blob_get_clones_snap_id = 0xbad; 1834 g_spdk_blob_get_clones_count = 0; 1835 g_spdk_blob_get_clones_ids = NULL; 1836 1837 spdk_lvol_close(snap, op_complete, NULL); 1838 CU_ASSERT(g_lvserrno == 0); 1839 1840 g_lvserrno = -1; 1841 spdk_lvol_close(clone, op_complete, NULL); 1842 CU_ASSERT(g_lvserrno == 0); 1843 1844 g_lvserrno = -1; 1845 spdk_lvol_close(lvol, op_complete, NULL); 1846 CU_ASSERT(g_lvserrno == 0); 1847 1848 g_lvserrno = -1; 1849 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 1850 CU_ASSERT(rc == 0); 1851 CU_ASSERT(g_lvserrno == 0); 1852 g_lvol_store = NULL; 1853 g_lvol = NULL; 1854 1855 free_dev(&dev); 1856 } 1857 1858 static void 1859 lvol_names(void) 1860 { 1861 struct lvol_ut_bs_dev dev; 1862 struct spdk_lvs_opts opts; 1863 struct spdk_lvol_store *lvs; 1864 struct spdk_lvol *lvol, *lvol2; 1865 char fullname[SPDK_LVOL_NAME_MAX]; 1866 int rc = 0; 1867 1868 init_dev(&dev); 1869 1870 spdk_lvs_opts_init(&opts); 1871 snprintf(opts.name, sizeof(opts.name), "lvs"); 1872 1873 g_lvserrno = -1; 1874 g_lvol_store = NULL; 1875 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1876 CU_ASSERT(rc == 0); 1877 CU_ASSERT(g_lvserrno == 0); 1878 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1879 lvs = g_lvol_store; 1880 1881 rc = spdk_lvol_create(lvs, NULL, 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1882 NULL); 1883 CU_ASSERT(rc == -EINVAL); 1884 1885 rc = spdk_lvol_create(lvs, "", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1886 NULL); 1887 CU_ASSERT(rc == -EINVAL); 1888 1889 memset(fullname, 'x', sizeof(fullname)); 1890 rc = spdk_lvol_create(lvs, fullname, 1, false, LVOL_CLEAR_WITH_DEFAULT, 1891 lvol_op_with_handle_complete, NULL); 1892 CU_ASSERT(rc == -EINVAL); 1893 1894 g_lvserrno = -1; 1895 rc = spdk_lvol_create(lvs, "lvol", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1896 NULL); 1897 CU_ASSERT(rc == 0); 1898 CU_ASSERT(g_lvserrno == 0); 1899 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1900 lvol = g_lvol; 1901 1902 rc = spdk_lvol_create(lvs, "lvol", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1903 NULL); 1904 CU_ASSERT(rc == -EEXIST); 1905 1906 g_lvserrno = -1; 1907 rc = spdk_lvol_create(lvs, "lvol2", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1908 NULL); 1909 CU_ASSERT(rc == 0); 1910 CU_ASSERT(g_lvserrno == 0); 1911 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1912 lvol2 = g_lvol; 1913 1914 spdk_lvol_close(lvol, op_complete, NULL); 1915 spdk_lvol_destroy(lvol, op_complete, NULL); 1916 1917 g_lvserrno = -1; 1918 g_lvol = NULL; 1919 rc = spdk_lvol_create(lvs, "lvol", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1920 NULL); 1921 CU_ASSERT(rc == 0); 1922 CU_ASSERT(g_lvserrno == 0); 1923 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1924 lvol = g_lvol; 1925 1926 spdk_lvol_close(lvol, op_complete, NULL); 1927 spdk_lvol_destroy(lvol, op_complete, NULL); 1928 1929 spdk_lvol_close(lvol2, op_complete, NULL); 1930 spdk_lvol_destroy(lvol2, op_complete, NULL); 1931 1932 /* Simulate creating two lvols with same name simultaneously. */ 1933 lvol = calloc(1, sizeof(*lvol)); 1934 SPDK_CU_ASSERT_FATAL(lvol != NULL); 1935 snprintf(lvol->name, sizeof(lvol->name), "tmp_name"); 1936 TAILQ_INSERT_TAIL(&lvs->pending_lvols, lvol, link); 1937 rc = spdk_lvol_create(lvs, "tmp_name", 1, false, LVOL_CLEAR_WITH_DEFAULT, 1938 lvol_op_with_handle_complete, NULL); 1939 CU_ASSERT(rc == -EEXIST); 1940 1941 /* Remove name from temporary list and try again. */ 1942 TAILQ_REMOVE(&lvs->pending_lvols, lvol, link); 1943 free(lvol); 1944 1945 rc = spdk_lvol_create(lvs, "tmp_name", 1, false, LVOL_CLEAR_WITH_DEFAULT, 1946 lvol_op_with_handle_complete, NULL); 1947 CU_ASSERT(rc == 0); 1948 CU_ASSERT(g_lvserrno == 0); 1949 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1950 lvol = g_lvol; 1951 1952 spdk_lvol_close(lvol, op_complete, NULL); 1953 spdk_lvol_destroy(lvol, op_complete, NULL); 1954 1955 g_lvserrno = -1; 1956 rc = spdk_lvs_destroy(lvs, op_complete, NULL); 1957 CU_ASSERT(rc == 0); 1958 CU_ASSERT(g_lvserrno == 0); 1959 g_lvol_store = NULL; 1960 } 1961 1962 static void 1963 lvol_rename(void) 1964 { 1965 struct lvol_ut_bs_dev dev; 1966 struct spdk_lvs_opts opts; 1967 struct spdk_lvol_store *lvs; 1968 struct spdk_lvol *lvol, *lvol2; 1969 int rc = 0; 1970 1971 init_dev(&dev); 1972 1973 spdk_lvs_opts_init(&opts); 1974 snprintf(opts.name, sizeof(opts.name), "lvs"); 1975 1976 g_lvserrno = -1; 1977 g_lvol_store = NULL; 1978 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 1979 CU_ASSERT(rc == 0); 1980 CU_ASSERT(g_lvserrno == 0); 1981 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 1982 lvs = g_lvol_store; 1983 1984 /* Trying to create new lvol */ 1985 g_lvserrno = -1; 1986 rc = spdk_lvol_create(lvs, "lvol", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1987 NULL); 1988 CU_ASSERT(rc == 0); 1989 CU_ASSERT(g_lvserrno == 0); 1990 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 1991 lvol = g_lvol; 1992 1993 /* Trying to create second lvol with existing lvol name */ 1994 g_lvserrno = -1; 1995 g_lvol = NULL; 1996 rc = spdk_lvol_create(lvs, "lvol", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 1997 NULL); 1998 CU_ASSERT(rc == -EEXIST); 1999 CU_ASSERT(g_lvserrno == -1); 2000 SPDK_CU_ASSERT_FATAL(g_lvol == NULL); 2001 2002 /* Trying to create second lvol with non existing name */ 2003 g_lvserrno = -1; 2004 rc = spdk_lvol_create(lvs, "lvol2", 1, false, LVOL_CLEAR_WITH_DEFAULT, lvol_op_with_handle_complete, 2005 NULL); 2006 CU_ASSERT(rc == 0); 2007 CU_ASSERT(g_lvserrno == 0); 2008 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2009 lvol2 = g_lvol; 2010 2011 /* Trying to rename lvol with not existing name */ 2012 spdk_lvol_rename(lvol, "lvol_new", op_complete, NULL); 2013 CU_ASSERT(g_lvserrno == 0); 2014 CU_ASSERT_STRING_EQUAL(lvol->name, "lvol_new"); 2015 2016 /* Trying to rename lvol with other lvol name */ 2017 spdk_lvol_rename(lvol2, "lvol_new", op_complete, NULL); 2018 CU_ASSERT(g_lvserrno == -EEXIST); 2019 CU_ASSERT_STRING_NOT_EQUAL(lvol2->name, "lvol_new"); 2020 2021 spdk_lvol_close(lvol, op_complete, NULL); 2022 spdk_lvol_destroy(lvol, op_complete, NULL); 2023 2024 spdk_lvol_close(lvol2, op_complete, NULL); 2025 spdk_lvol_destroy(lvol2, op_complete, NULL); 2026 2027 g_lvserrno = -1; 2028 rc = spdk_lvs_destroy(lvs, op_complete, NULL); 2029 CU_ASSERT(rc == 0); 2030 CU_ASSERT(g_lvserrno == 0); 2031 g_lvol_store = NULL; 2032 } 2033 2034 static void 2035 lvs_rename(void) 2036 { 2037 struct lvol_ut_bs_dev dev; 2038 struct spdk_lvs_opts opts; 2039 struct spdk_lvol_store *lvs, *lvs2; 2040 int rc = 0; 2041 2042 init_dev(&dev); 2043 2044 spdk_lvs_opts_init(&opts); 2045 snprintf(opts.name, sizeof(opts.name), "lvs"); 2046 g_lvserrno = -1; 2047 g_lvol_store = NULL; 2048 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2049 CU_ASSERT(rc == 0); 2050 CU_ASSERT(g_lvserrno == 0); 2051 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2052 lvs = g_lvol_store; 2053 2054 spdk_lvs_opts_init(&opts); 2055 snprintf(opts.name, sizeof(opts.name), "unimportant_lvs_name"); 2056 g_lvserrno = -1; 2057 g_lvol_store = NULL; 2058 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2059 CU_ASSERT(rc == 0); 2060 CU_ASSERT(g_lvserrno == 0); 2061 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2062 lvs2 = g_lvol_store; 2063 2064 /* Trying to rename lvs with new name */ 2065 spdk_lvs_rename(lvs, "new_lvs_name", op_complete, NULL); 2066 CU_ASSERT(g_lvserrno == 0); 2067 CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); 2068 2069 /* Trying to rename lvs with name lvs already has */ 2070 spdk_lvs_rename(lvs, "new_lvs_name", op_complete, NULL); 2071 CU_ASSERT(g_lvserrno == 0); 2072 CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); 2073 2074 /* Trying to rename lvs with name already existing */ 2075 spdk_lvs_rename(lvs2, "new_lvs_name", op_complete, NULL); 2076 CU_ASSERT(g_lvserrno == -EEXIST); 2077 CU_ASSERT_STRING_EQUAL(lvs2->name, "unimportant_lvs_name"); 2078 2079 /* Trying to rename lvs with another rename process started with the same name */ 2080 /* Simulate renaming process in progress */ 2081 snprintf(lvs2->new_name, sizeof(lvs2->new_name), "another_new_lvs_name"); 2082 CU_ASSERT_STRING_EQUAL(lvs2->new_name, "another_new_lvs_name"); 2083 /* Start second process */ 2084 spdk_lvs_rename(lvs, "another_new_lvs_name", op_complete, NULL); 2085 CU_ASSERT(g_lvserrno == -EEXIST); 2086 CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); 2087 /* reverting lvs2 new name to proper value */ 2088 snprintf(lvs2->new_name, sizeof(lvs2->new_name), "unimportant_lvs_name"); 2089 CU_ASSERT_STRING_EQUAL(lvs2->new_name, "unimportant_lvs_name"); 2090 2091 /* Simulate error while lvs rename */ 2092 g_lvs_rename_blob_open_error = true; 2093 spdk_lvs_rename(lvs, "complete_new_lvs_name", op_complete, NULL); 2094 CU_ASSERT(g_lvserrno != 0); 2095 CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name"); 2096 CU_ASSERT_STRING_EQUAL(lvs->new_name, "new_lvs_name"); 2097 g_lvs_rename_blob_open_error = false; 2098 2099 g_lvserrno = -1; 2100 rc = spdk_lvs_destroy(lvs, op_complete, NULL); 2101 CU_ASSERT(rc == 0); 2102 CU_ASSERT(g_lvserrno == 0); 2103 g_lvol_store = NULL; 2104 2105 g_lvserrno = -1; 2106 rc = spdk_lvs_destroy(lvs2, op_complete, NULL); 2107 CU_ASSERT(rc == 0); 2108 CU_ASSERT(g_lvserrno == 0); 2109 g_lvol_store = NULL; 2110 } 2111 static void 2112 lvol_refcnt(void) 2113 { 2114 struct lvol_ut_bs_dev dev; 2115 struct spdk_lvs_opts opts; 2116 struct spdk_lvol *lvol; 2117 int rc = 0; 2118 2119 init_dev(&dev); 2120 2121 spdk_lvs_opts_init(&opts); 2122 snprintf(opts.name, sizeof(opts.name), "lvs"); 2123 2124 g_lvserrno = -1; 2125 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2126 CU_ASSERT(rc == 0); 2127 CU_ASSERT(g_lvserrno == 0); 2128 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2129 2130 2131 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 2132 lvol_op_with_handle_complete, NULL); 2133 2134 CU_ASSERT(g_lvserrno == 0); 2135 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2136 CU_ASSERT(g_lvol->ref_count == 1); 2137 2138 lvol = g_lvol; 2139 spdk_lvol_open(g_lvol, lvol_op_with_handle_complete, NULL); 2140 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2141 CU_ASSERT(lvol->ref_count == 2); 2142 2143 /* Trying to destroy lvol while its open should fail */ 2144 spdk_lvol_destroy(lvol, op_complete, NULL); 2145 CU_ASSERT(g_lvserrno != 0); 2146 2147 spdk_lvol_close(lvol, op_complete, NULL); 2148 CU_ASSERT(lvol->ref_count == 1); 2149 CU_ASSERT(g_lvserrno == 0); 2150 2151 spdk_lvol_close(lvol, op_complete, NULL); 2152 CU_ASSERT(lvol->ref_count == 0); 2153 CU_ASSERT(g_lvserrno == 0); 2154 2155 /* Try to close already closed lvol */ 2156 spdk_lvol_close(lvol, op_complete, NULL); 2157 CU_ASSERT(lvol->ref_count == 0); 2158 CU_ASSERT(g_lvserrno != 0); 2159 2160 g_lvserrno = -1; 2161 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2162 CU_ASSERT(rc == 0); 2163 CU_ASSERT(g_lvserrno == 0); 2164 g_lvol_store = NULL; 2165 2166 CU_ASSERT(rc == 0); 2167 CU_ASSERT(g_lvserrno == 0); 2168 g_lvol_store = NULL; 2169 2170 free_dev(&dev); 2171 } 2172 2173 static void 2174 lvol_create_thin_provisioned(void) 2175 { 2176 struct lvol_ut_bs_dev dev; 2177 struct spdk_lvs_opts opts; 2178 int rc = 0; 2179 2180 init_dev(&dev); 2181 2182 spdk_lvs_opts_init(&opts); 2183 snprintf(opts.name, sizeof(opts.name), "lvs"); 2184 2185 g_lvserrno = -1; 2186 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2187 CU_ASSERT(rc == 0); 2188 CU_ASSERT(g_lvserrno == 0); 2189 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2190 2191 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 2192 lvol_op_with_handle_complete, NULL); 2193 CU_ASSERT(g_lvserrno == 0); 2194 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2195 2196 CU_ASSERT(g_lvol->blob->thin_provisioned == false); 2197 2198 spdk_lvol_close(g_lvol, op_complete, NULL); 2199 CU_ASSERT(g_lvserrno == 0); 2200 spdk_lvol_destroy(g_lvol, op_complete, NULL); 2201 CU_ASSERT(g_lvserrno == 0); 2202 2203 spdk_lvol_create(g_lvol_store, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 2204 lvol_op_with_handle_complete, NULL); 2205 CU_ASSERT(g_lvserrno == 0); 2206 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2207 2208 CU_ASSERT(g_lvol->blob->thin_provisioned == true); 2209 2210 spdk_lvol_close(g_lvol, op_complete, NULL); 2211 CU_ASSERT(g_lvserrno == 0); 2212 spdk_lvol_destroy(g_lvol, op_complete, NULL); 2213 CU_ASSERT(g_lvserrno == 0); 2214 2215 g_lvserrno = -1; 2216 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2217 CU_ASSERT(rc == 0); 2218 CU_ASSERT(g_lvserrno == 0); 2219 g_lvol_store = NULL; 2220 2221 free_dev(&dev); 2222 } 2223 2224 static void 2225 lvol_inflate(void) 2226 { 2227 struct lvol_ut_bs_dev dev; 2228 struct spdk_lvs_opts opts; 2229 int rc = 0; 2230 2231 init_dev(&dev); 2232 2233 spdk_lvs_opts_init(&opts); 2234 snprintf(opts.name, sizeof(opts.name), "lvs"); 2235 2236 g_lvserrno = -1; 2237 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2238 CU_ASSERT(rc == 0); 2239 CU_ASSERT(g_lvserrno == 0); 2240 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2241 2242 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 2243 lvol_op_with_handle_complete, NULL); 2244 CU_ASSERT(g_lvserrno == 0); 2245 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2246 2247 g_inflate_rc = -1; 2248 spdk_lvol_inflate(g_lvol, op_complete, NULL); 2249 CU_ASSERT(g_lvserrno != 0); 2250 2251 g_inflate_rc = 0; 2252 spdk_lvol_inflate(g_lvol, op_complete, NULL); 2253 CU_ASSERT(g_lvserrno == 0); 2254 2255 spdk_lvol_close(g_lvol, op_complete, NULL); 2256 CU_ASSERT(g_lvserrno == 0); 2257 spdk_lvol_destroy(g_lvol, op_complete, NULL); 2258 CU_ASSERT(g_lvserrno == 0); 2259 2260 g_lvserrno = -1; 2261 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2262 CU_ASSERT(rc == 0); 2263 CU_ASSERT(g_lvserrno == 0); 2264 g_lvol_store = NULL; 2265 2266 free_dev(&dev); 2267 2268 /* Make sure that all references to the io_channel was closed after 2269 * inflate call 2270 */ 2271 CU_ASSERT(g_io_channel == NULL); 2272 } 2273 2274 static void 2275 lvol_decouple_parent(void) 2276 { 2277 struct lvol_ut_bs_dev dev; 2278 struct spdk_lvs_opts opts; 2279 int rc = 0; 2280 2281 init_dev(&dev); 2282 2283 spdk_lvs_opts_init(&opts); 2284 snprintf(opts.name, sizeof(opts.name), "lvs"); 2285 2286 g_lvserrno = -1; 2287 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2288 CU_ASSERT(rc == 0); 2289 CU_ASSERT(g_lvserrno == 0); 2290 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2291 2292 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 2293 lvol_op_with_handle_complete, NULL); 2294 CU_ASSERT(g_lvserrno == 0); 2295 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2296 2297 g_inflate_rc = -1; 2298 spdk_lvol_decouple_parent(g_lvol, op_complete, NULL); 2299 CU_ASSERT(g_lvserrno != 0); 2300 2301 g_inflate_rc = 0; 2302 spdk_lvol_decouple_parent(g_lvol, op_complete, NULL); 2303 CU_ASSERT(g_lvserrno == 0); 2304 2305 spdk_lvol_close(g_lvol, op_complete, NULL); 2306 CU_ASSERT(g_lvserrno == 0); 2307 spdk_lvol_destroy(g_lvol, op_complete, NULL); 2308 CU_ASSERT(g_lvserrno == 0); 2309 2310 g_lvserrno = -1; 2311 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2312 CU_ASSERT(rc == 0); 2313 CU_ASSERT(g_lvserrno == 0); 2314 g_lvol_store = NULL; 2315 2316 free_dev(&dev); 2317 2318 /* Make sure that all references to the io_channel was closed after 2319 * inflate call 2320 */ 2321 CU_ASSERT(g_io_channel == NULL); 2322 } 2323 2324 static void 2325 lvol_get_xattr(void) 2326 { 2327 struct lvol_ut_bs_dev dev; 2328 struct spdk_lvs_opts opts; 2329 int rc = 0; 2330 struct spdk_lvol *lvol; 2331 const char *value = NULL; 2332 size_t value_len = 0; 2333 2334 init_dev(&dev); 2335 2336 spdk_lvs_opts_init(&opts); 2337 snprintf(opts.name, sizeof(opts.name), "lvs"); 2338 2339 g_lvserrno = -1; 2340 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2341 CU_ASSERT(rc == 0); 2342 CU_ASSERT(g_lvserrno == 0); 2343 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2344 2345 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 2346 lvol_op_with_handle_complete, NULL); 2347 CU_ASSERT(g_lvserrno == 0); 2348 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2349 lvol = g_lvol; 2350 2351 /* Should be able to look up name */ 2352 lvol_get_xattr_value(lvol, "name", (const void **)&value, &value_len); 2353 CU_ASSERT(value != NULL && strcmp(value, "lvol") == 0); 2354 CU_ASSERT(value_len != 0); 2355 2356 /* Looking up something that doesn't exist should indicate non-existence */ 2357 lvol_get_xattr_value(lvol, "mumble", (const void **)&value, &value_len); 2358 CU_ASSERT(value == NULL); 2359 CU_ASSERT(value_len == 0); 2360 2361 /* Clean up */ 2362 spdk_lvol_close(lvol, op_complete, NULL); 2363 CU_ASSERT(g_lvserrno == 0); 2364 spdk_lvol_destroy(lvol, op_complete, NULL); 2365 CU_ASSERT(g_lvserrno == 0); 2366 2367 g_lvserrno = -1; 2368 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2369 CU_ASSERT(rc == 0); 2370 CU_ASSERT(g_lvserrno == 0); 2371 g_lvol_store = NULL; 2372 2373 free_dev(&dev); 2374 } 2375 2376 struct spdk_bs_dev *g_esnap_bs_dev; 2377 int g_esnap_bs_dev_errno = -ENOTSUP; 2378 2379 static int 2380 ut_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, 2381 const void *esnap_id, uint32_t id_len, 2382 struct spdk_bs_dev **_bs_dev) 2383 { 2384 *_bs_dev = g_esnap_bs_dev; 2385 return g_esnap_bs_dev_errno; 2386 } 2387 2388 static void 2389 lvol_esnap_reload(void) 2390 { 2391 struct lvol_ut_bs_dev dev; 2392 struct spdk_lvs_with_handle_req *req; 2393 struct spdk_lvs_opts opts; 2394 int rc; 2395 2396 g_esnap_bs_dev = NULL; 2397 g_esnap_bs_dev_errno = -ENOTSUP; 2398 2399 req = calloc(1, sizeof(*req)); 2400 SPDK_CU_ASSERT_FATAL(req != NULL); 2401 2402 init_dev(&dev); 2403 2404 /* Create an lvstore with external snapshot support */ 2405 spdk_lvs_opts_init(&opts); 2406 snprintf(opts.name, sizeof(opts.name), "lvs"); 2407 opts.esnap_bs_dev_create = ut_esnap_bs_dev_create; 2408 g_lvserrno = -1; 2409 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2410 CU_ASSERT(rc == 0); 2411 CU_ASSERT(g_lvserrno == 0); 2412 CU_ASSERT(dev.bs->esnap_bs_dev_create == ut_esnap_bs_dev_create); 2413 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2414 2415 /* Unload the lvstore */ 2416 g_lvserrno = -1; 2417 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2418 CU_ASSERT(rc == 0); 2419 CU_ASSERT(g_lvserrno == 0); 2420 g_lvol_store = NULL; 2421 2422 /* Load the lvstore with external snapshot support */ 2423 g_lvserrno = -1; 2424 spdk_lvs_opts_init(&opts); 2425 opts.esnap_bs_dev_create = ut_esnap_bs_dev_create; 2426 spdk_lvs_load_ext(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2427 CU_ASSERT(g_lvserrno == 0); 2428 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2429 CU_ASSERT(dev.bs->esnap_bs_dev_create == ut_esnap_bs_dev_create); 2430 2431 g_lvserrno = -1; 2432 rc = spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 2433 CU_ASSERT(rc == 0); 2434 CU_ASSERT(g_lvserrno == 0); 2435 g_lvol_store = NULL; 2436 2437 free(req); 2438 } 2439 2440 static void 2441 lvol_esnap_create_bad_args(void) 2442 { 2443 struct lvol_ut_bs_dev dev; 2444 struct spdk_bdev esnap_bdev; 2445 struct spdk_lvs_opts opts; 2446 char long_name[SPDK_LVOL_NAME_MAX + 1]; 2447 int rc; 2448 struct ut_cb_res lvres1, lvres2; 2449 struct spdk_lvol *lvol; 2450 char uuid_str[SPDK_UUID_STRING_LEN]; 2451 uint64_t block_sz, cluster_sz; 2452 2453 init_dev(&dev); 2454 block_sz = dev.bs_dev.blocklen; 2455 2456 spdk_lvs_opts_init(&opts); 2457 cluster_sz = opts.cluster_sz; 2458 snprintf(opts.name, sizeof(opts.name), "lvs"); 2459 opts.esnap_bs_dev_create = ut_esnap_bs_dev_create; 2460 g_lvserrno = -1; 2461 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2462 CU_ASSERT(rc == 0); 2463 CU_ASSERT(g_lvserrno == 0); 2464 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2465 2466 init_bdev(&esnap_bdev, "bdev1", BS_CLUSTER_SIZE); 2467 CU_ASSERT(spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &esnap_bdev.uuid) == 0); 2468 MOCK_SET(spdk_bdev_get_by_name, &esnap_bdev); 2469 2470 /* error with lvs == NULL */ 2471 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, NULL, "clone1", 2472 lvol_op_with_handle_complete, NULL); 2473 CU_ASSERT(rc == -EINVAL); 2474 2475 /* error with clone name that is too short */ 2476 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, g_lvol_store, "", 2477 lvol_op_with_handle_complete, NULL); 2478 CU_ASSERT(rc == -EINVAL); 2479 2480 /* error with clone name that is too long */ 2481 memset(long_name, 'a', sizeof(long_name)); 2482 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, g_lvol_store, 2483 long_name, lvol_op_with_handle_complete, NULL); 2484 CU_ASSERT(rc == -EINVAL); 2485 2486 /* error with size that is not a multiple of an integer multiple of cluster_sz */ 2487 CU_ASSERT(((cluster_sz + block_sz) % cluster_sz) != 0); 2488 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz + block_sz, 2489 g_lvol_store, "clone1", 2490 lvol_op_with_handle_complete, NULL); 2491 CU_ASSERT(rc == -EINVAL); 2492 2493 /* error when an lvol with that name already exists */ 2494 spdk_lvol_create(g_lvol_store, "lvol", 10, false, LVOL_CLEAR_WITH_DEFAULT, 2495 lvol_op_with_handle_complete, NULL); 2496 CU_ASSERT(g_lvserrno == 0); 2497 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2498 lvol = g_lvol; 2499 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, g_lvol_store, 2500 "lvol", lvol_op_with_handle_complete, NULL); 2501 CU_ASSERT(rc == -EEXIST); 2502 spdk_lvol_close(lvol, op_complete, ut_cb_res_clear(&lvres1)); 2503 spdk_lvol_destroy(lvol, op_complete, ut_cb_res_clear(&lvres2)); 2504 poll_threads(); 2505 CU_ASSERT(lvres1.err == 0); 2506 CU_ASSERT(lvres2.err == 0); 2507 g_lvol = NULL; 2508 2509 /* error when two clones created at the same time with the same name */ 2510 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, g_lvol_store, 2511 "clone1", lvol_op_with_handle_complete, 2512 ut_cb_res_clear(&lvres1)); 2513 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, g_lvol_store, 2514 "clone1", lvol_op_with_handle_complete, 2515 ut_cb_res_clear(&lvres2)); 2516 CU_ASSERT(rc == -EEXIST); 2517 poll_threads(); 2518 CU_ASSERT(g_lvol != NULL); 2519 CU_ASSERT(lvres1.err == 0); 2520 CU_ASSERT(lvres2.err == 0xbad); 2521 CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->pending_lvols)); 2522 spdk_lvol_close(g_lvol, op_complete, ut_cb_res_clear(&lvres1)); 2523 spdk_lvol_destroy(g_lvol, op_complete, ut_cb_res_clear(&lvres2)); 2524 poll_threads(); 2525 CU_ASSERT(lvres1.err == 0); 2526 CU_ASSERT(lvres2.err == 0); 2527 g_lvol = NULL; 2528 2529 g_lvserrno = -1; 2530 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 2531 CU_ASSERT(rc == 0); 2532 CU_ASSERT(g_lvserrno == 0); 2533 g_lvol_store = NULL; 2534 2535 free_dev(&dev); 2536 } 2537 2538 static void 2539 lvol_esnap_create_delete(void) 2540 { 2541 struct lvol_ut_bs_dev dev; 2542 struct spdk_bdev esnap_bdev; 2543 struct spdk_lvs_opts opts; 2544 char uuid_str[SPDK_UUID_STRING_LEN]; 2545 int rc; 2546 uint64_t cluster_sz; 2547 2548 init_dev(&dev); 2549 init_dev(&g_esnap_dev); 2550 2551 spdk_lvs_opts_init(&opts); 2552 cluster_sz = opts.cluster_sz; 2553 snprintf(opts.name, sizeof(opts.name), "lvs"); 2554 opts.esnap_bs_dev_create = ut_esnap_bs_dev_create; 2555 g_lvserrno = -1; 2556 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2557 CU_ASSERT(rc == 0); 2558 CU_ASSERT(g_lvserrno == 0); 2559 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2560 2561 g_lvserrno = 0xbad; 2562 init_bdev(&esnap_bdev, "bdev1", BS_CLUSTER_SIZE); 2563 CU_ASSERT(spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &esnap_bdev.uuid) == 0); 2564 MOCK_SET(spdk_bdev_get_by_name, &esnap_bdev); 2565 rc = spdk_lvol_create_esnap_clone(uuid_str, strlen(uuid_str), cluster_sz, g_lvol_store, 2566 "clone1", lvol_op_with_handle_complete, NULL); 2567 CU_ASSERT(rc == 0); 2568 poll_threads(); 2569 CU_ASSERT(g_lvserrno == 0); 2570 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 2571 MOCK_CLEAR(spdk_bdev_get_by_name); 2572 2573 g_lvserrno = 0xbad; 2574 spdk_lvol_close(g_lvol, op_complete, NULL); 2575 CU_ASSERT(g_lvserrno == 0); 2576 g_lvserrno = 0xbad; 2577 spdk_lvol_destroy(g_lvol, op_complete, NULL); 2578 CU_ASSERT(g_lvserrno == 0); 2579 g_lvol = NULL; 2580 2581 g_lvserrno = -1; 2582 rc = spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 2583 CU_ASSERT(rc == 0); 2584 CU_ASSERT(g_lvserrno == 0); 2585 g_lvol_store = NULL; 2586 } 2587 2588 static void 2589 lvol_esnap_load_esnaps(void) 2590 { 2591 struct spdk_blob blob = { .id = 42 }; 2592 struct spdk_lvol_store *lvs; 2593 struct spdk_lvol *lvol; 2594 struct spdk_bs_dev *bs_dev = NULL; 2595 struct spdk_bs_dev esnap_bs_dev = { 0 }; 2596 int rc; 2597 uint64_t esnap_id = 42; 2598 2599 lvs = lvs_alloc(); 2600 SPDK_CU_ASSERT_FATAL(lvs != NULL); 2601 lvs->esnap_bs_dev_create = ut_esnap_bs_dev_create; 2602 lvol = lvol_alloc(lvs, __func__, true, LVOL_CLEAR_WITH_DEFAULT); 2603 SPDK_CU_ASSERT_FATAL(lvol != NULL); 2604 2605 /* Handle missing bs_ctx and blob_ctx gracefully */ 2606 rc = lvs_esnap_bs_dev_create(NULL, NULL, &blob, &esnap_id, sizeof(esnap_id), &bs_dev); 2607 CU_ASSERT(rc == -EINVAL); 2608 2609 /* Do not try to load external snapshot when load_esnaps is false */ 2610 g_spdk_blob_get_esnap_id_called = false; 2611 bs_dev = NULL; 2612 rc = lvs_esnap_bs_dev_create(lvs, lvol, &blob, &esnap_id, sizeof(esnap_id), &bs_dev); 2613 CU_ASSERT(rc == 0); 2614 CU_ASSERT(bs_dev == NULL); 2615 CU_ASSERT(!g_spdk_blob_get_esnap_id_called); 2616 2617 /* Same, with only lvs */ 2618 bs_dev = NULL; 2619 rc = lvs_esnap_bs_dev_create(lvs, NULL, &blob, &esnap_id, sizeof(esnap_id), &bs_dev); 2620 CU_ASSERT(rc == 0); 2621 CU_ASSERT(bs_dev == NULL); 2622 CU_ASSERT(!g_spdk_blob_get_esnap_id_called); 2623 2624 /* Same, with only lvol */ 2625 bs_dev = NULL; 2626 rc = lvs_esnap_bs_dev_create(NULL, lvol, &blob, &esnap_id, sizeof(esnap_id), &bs_dev); 2627 CU_ASSERT(rc == 0); 2628 CU_ASSERT(bs_dev == NULL); 2629 CU_ASSERT(!g_spdk_blob_get_esnap_id_called); 2630 2631 /* Happy path */ 2632 g_esnap_bs_dev = &esnap_bs_dev; 2633 g_esnap_bs_dev_errno = 0; 2634 2635 lvs->load_esnaps = true; 2636 ut_spdk_bdev_create_bs_dev_ro = 0; 2637 g_spdk_blob_get_esnap_id_errno = 0; 2638 bs_dev = NULL; 2639 rc = lvs_esnap_bs_dev_create(lvs, lvol, &blob, &esnap_id, sizeof(esnap_id), &bs_dev); 2640 CU_ASSERT(rc == 0); 2641 2642 /* Clean up */ 2643 lvol_free(lvol); 2644 lvs_free(lvs); 2645 g_esnap_bs_dev = NULL; 2646 g_esnap_bs_dev_errno = -ENOTSUP; 2647 } 2648 2649 struct ut_degraded_dev { 2650 struct spdk_bs_dev bs_dev; 2651 struct spdk_lvol *lvol; 2652 }; 2653 2654 static void 2655 ut_destroy_degraded(struct spdk_bs_dev *ddev) 2656 { 2657 free(ddev); 2658 } 2659 2660 static int 2661 ut_create_degraded(struct spdk_lvol_store *lvs, struct spdk_lvol *lvol, 2662 struct spdk_blob *blob, const char *name, struct spdk_bs_dev **bs_dev) 2663 { 2664 struct ut_degraded_dev *ddev; 2665 2666 ddev = calloc(1, sizeof(*ddev)); 2667 SPDK_CU_ASSERT_FATAL(ddev != NULL); 2668 2669 ddev->lvol = lvol; 2670 ddev->bs_dev.destroy = ut_destroy_degraded; 2671 ddev->bs_dev.blockcnt = UINT64_MAX / 512; 2672 ddev->bs_dev.blocklen = 512; 2673 *bs_dev = &ddev->bs_dev; 2674 return 0; 2675 } 2676 2677 static void 2678 lvol_esnap_missing(void) 2679 { 2680 struct lvol_ut_bs_dev dev; 2681 struct spdk_lvs_opts opts; 2682 struct spdk_blob blob = { .id = 42 }; 2683 struct ut_cb_res cb_res; 2684 struct spdk_lvol_store *lvs; 2685 struct spdk_lvol *lvol1, *lvol2; 2686 struct spdk_bs_dev *bs_dev; 2687 struct spdk_bdev esnap_bdev; 2688 struct spdk_lvs_degraded_lvol_set *degraded_set; 2689 const char *name1 = "lvol1"; 2690 const char *name2 = "lvol2"; 2691 char uuid_str[SPDK_UUID_STRING_LEN]; 2692 uint64_t cluster_sz; 2693 int rc; 2694 2695 /* Create an lvstore */ 2696 init_dev(&dev); 2697 spdk_lvs_opts_init(&opts); 2698 cluster_sz = opts.cluster_sz; 2699 snprintf(opts.name, sizeof(opts.name), "lvs"); 2700 g_lvserrno = -1; 2701 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2702 CU_ASSERT(rc == 0); 2703 CU_ASSERT(g_lvserrno == 0); 2704 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2705 lvs = g_lvol_store; 2706 lvs->load_esnaps = true; 2707 2708 /* Pre-populate the lvstore with a degraded device */ 2709 lvol1 = lvol_alloc(lvs, name1, true, LVOL_CLEAR_WITH_DEFAULT); 2710 SPDK_CU_ASSERT_FATAL(lvol1 != NULL); 2711 lvol1->blob_id = blob.id; 2712 TAILQ_REMOVE(&lvs->pending_lvols, lvol1, link); 2713 TAILQ_INSERT_TAIL(&lvs->lvols, lvol1, link); 2714 rc = ut_create_degraded(lvs, lvol1, &blob, name1, &bs_dev); 2715 CU_ASSERT(rc == 0); 2716 SPDK_CU_ASSERT_FATAL(bs_dev != NULL); 2717 2718 /* A clone with a missing external snapshot prevents a conflicting clone's creation */ 2719 init_bdev(&esnap_bdev, "bdev1", BS_CLUSTER_SIZE); 2720 CU_ASSERT(spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &esnap_bdev.uuid) == 0); 2721 MOCK_SET(spdk_bdev_get_by_name, &esnap_bdev); 2722 rc = spdk_lvol_create_esnap_clone(uuid_str, sizeof(uuid_str), cluster_sz, g_lvol_store, 2723 name1, lvol_op_with_handle_complete, 2724 ut_cb_res_clear(&cb_res)); 2725 CU_ASSERT(rc == -EEXIST); 2726 CU_ASSERT(ut_cb_res_untouched(&cb_res)); 2727 MOCK_CLEAR(spdk_bdev_get_by_name); 2728 2729 /* A clone with a missing external snapshot prevents a conflicting lvol's creation */ 2730 rc = spdk_lvol_create(lvs, name1, 10, false, LVOL_CLEAR_WITH_DEFAULT, 2731 lvol_op_with_handle_complete, ut_cb_res_clear(&cb_res)); 2732 CU_ASSERT(rc == -EEXIST); 2733 CU_ASSERT(ut_cb_res_untouched(&cb_res)); 2734 2735 /* Using a unique lvol name allows the clone to be created. */ 2736 MOCK_SET(spdk_bdev_get_by_name, &esnap_bdev); 2737 MOCK_SET(spdk_blob_is_esnap_clone, true); 2738 rc = spdk_lvol_create_esnap_clone(uuid_str, sizeof(uuid_str), cluster_sz, g_lvol_store, 2739 name2, lvol_op_with_handle_complete, 2740 ut_cb_res_clear(&cb_res)); 2741 SPDK_CU_ASSERT_FATAL(rc == 0); 2742 CU_ASSERT(cb_res.err == 0); 2743 SPDK_CU_ASSERT_FATAL(cb_res.data != NULL); 2744 lvol2 = cb_res.data; 2745 CU_ASSERT(lvol2->degraded_set == NULL); 2746 spdk_lvol_close(lvol2, op_complete, ut_cb_res_clear(&cb_res)); 2747 CU_ASSERT(cb_res.err == 0); 2748 spdk_lvol_destroy(lvol2, op_complete, ut_cb_res_clear(&cb_res)); 2749 CU_ASSERT(cb_res.err == 0); 2750 MOCK_CLEAR(spdk_blob_is_esnap_clone); 2751 MOCK_CLEAR(spdk_bdev_get_by_name); 2752 2753 /* Destroying the esnap clone removes it from the degraded_set esnaps tree. */ 2754 spdk_lvol_destroy(lvol1, op_complete, ut_cb_res_clear(&cb_res)); 2755 CU_ASSERT(cb_res.err == 0); 2756 CU_ASSERT(RB_EMPTY(&lvs->degraded_lvol_sets_tree)); 2757 bs_dev->destroy(bs_dev); 2758 2759 /* Create a missing device again */ 2760 lvol1 = lvol_alloc(lvs, name1, true, LVOL_CLEAR_WITH_DEFAULT); 2761 SPDK_CU_ASSERT_FATAL(lvol1 != NULL); 2762 lvol1->blob_id = blob.id; 2763 TAILQ_REMOVE(&lvs->pending_lvols, lvol1, link); 2764 TAILQ_INSERT_TAIL(&lvs->lvols, lvol1, link); 2765 rc = ut_create_degraded(lvs, lvol1, &blob, name1, &bs_dev); 2766 CU_ASSERT(rc == 0); 2767 SPDK_CU_ASSERT_FATAL(bs_dev != NULL); 2768 lvol1->blob = &blob; 2769 rc = spdk_lvs_esnap_missing_add(lvs, lvol1, esnap_bdev.name, strlen(esnap_bdev.name) + 1); 2770 CU_ASSERT(rc == 0); 2771 lvol1->ref_count = 1; 2772 2773 /* 2774 * Creating a snapshot of lvol1 makes lvol1 a clone of the new snapshot. What was a clone of 2775 * the external snapshot is now a clone of the snapshot. The snapshot is a clone of the 2776 * external snapshot. Now the snapshot is degraded_set its external snapshot. 2777 */ 2778 degraded_set = lvol1->degraded_set; 2779 CU_ASSERT(degraded_set != NULL); 2780 spdk_lvol_create_snapshot(lvol1, name2, lvol_op_with_handle_complete, 2781 ut_cb_res_clear(&cb_res)); 2782 CU_ASSERT(cb_res.err == 0); 2783 SPDK_CU_ASSERT_FATAL(cb_res.data != NULL); 2784 lvol2 = cb_res.data; 2785 CU_ASSERT(lvol1->degraded_set == NULL); 2786 CU_ASSERT(lvol2->degraded_set == degraded_set); 2787 2788 /* 2789 * Removing the snapshot (lvol2) makes the first lvol (lvol1) back into a clone of an 2790 * external snapshot. 2791 */ 2792 MOCK_SET(spdk_blob_is_esnap_clone, true); 2793 g_spdk_blob_get_clones_snap_id = lvol2->blob_id; 2794 g_spdk_blob_get_clones_ids = &lvol1->blob_id; 2795 g_spdk_blob_get_clones_count = 1; 2796 spdk_lvol_close(lvol2, op_complete, ut_cb_res_clear(&cb_res)); 2797 CU_ASSERT(cb_res.err == 0); 2798 spdk_lvol_destroy(lvol2, op_complete, ut_cb_res_clear(&cb_res)); 2799 CU_ASSERT(cb_res.err == 0); 2800 CU_ASSERT(lvol1->degraded_set == degraded_set); 2801 g_spdk_blob_get_clones_snap_id = 0xbad; 2802 g_spdk_blob_get_clones_ids = NULL; 2803 g_spdk_blob_get_clones_count = 0; 2804 2805 /* Clean up */ 2806 spdk_lvol_close(lvol1, op_complete, ut_cb_res_clear(&cb_res)); 2807 CU_ASSERT(cb_res.err == 0); 2808 spdk_lvol_destroy(lvol1, op_complete, ut_cb_res_clear(&cb_res)); 2809 CU_ASSERT(cb_res.err == 0); 2810 bs_dev->destroy(bs_dev); 2811 rc = spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 2812 CU_ASSERT(rc == 0); 2813 MOCK_CLEAR(spdk_blob_is_esnap_clone); 2814 } 2815 2816 struct hotplug_lvol { 2817 /* 2818 * These fields must be set before calling lvol_esnap_hotplug_scenario(). 2819 */ 2820 char *lvol_name; 2821 char *esnap_id; 2822 /* How many times hotplug is expected to be called, likely 1. */ 2823 int expect_hp_count; 2824 /* If not 0, return this during hotplug without registering esnap_dev. */ 2825 int hotplug_retval; 2826 /* If true, call spdk_lvs_esnap_missing_add(), return 0, NULL bs_dev */ 2827 bool register_missing; 2828 2829 /* 2830 * These fields set are set by lvol_esnap_hotplug_scenario(). 2831 */ 2832 struct spdk_lvol *lvol; 2833 int id_len; 2834 int hp_count; 2835 bool created; 2836 }; 2837 2838 struct missing_esnap { 2839 char *esnap_id; 2840 struct spdk_bs_dev *esnap_dev; 2841 int expect_missing_lvol_count_after_create; 2842 int expect_missing_lvol_count_after_hotplug; 2843 }; 2844 2845 /* Arrays. Terminate with a zeroed struct. */ 2846 struct hotplug_lvol *g_hotplug_lvols; 2847 struct missing_esnap *g_missing_esnap; 2848 2849 static int 2850 missing_get_lvol_count(struct spdk_lvol_store *lvs, char *esnap_id) 2851 { 2852 struct spdk_lvs_degraded_lvol_set find = { 0 }; 2853 struct spdk_lvs_degraded_lvol_set *found; 2854 struct spdk_lvol *lvol; 2855 int count = 0; 2856 2857 find.esnap_id = esnap_id; 2858 find.id_len = strlen(esnap_id) + 1; 2859 2860 found = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 2861 if (found == NULL) { 2862 return 0; 2863 } 2864 TAILQ_FOREACH(lvol, &found->lvols, degraded_link) { 2865 count++; 2866 } 2867 return count; 2868 } 2869 2870 static struct missing_esnap * 2871 get_missing_esnap(struct missing_esnap *missing_esnap, const char *esnap_id) 2872 { 2873 for (; missing_esnap->esnap_id != NULL; missing_esnap++) { 2874 if (strcmp(missing_esnap->esnap_id, esnap_id) == 0) { 2875 return missing_esnap; 2876 } 2877 } 2878 return NULL; 2879 } 2880 2881 static int 2882 ut_esnap_hotplug_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, 2883 const void *esnap_id, uint32_t id_len, struct spdk_bs_dev **bs_dev) 2884 { 2885 struct spdk_lvol_store *lvs = bs_ctx; 2886 struct spdk_lvol *lvol = blob_ctx; 2887 struct hotplug_lvol *hp_lvol; 2888 struct missing_esnap *missing_esnap; 2889 int rc; 2890 2891 CU_ASSERT(lvs != NULL); 2892 CU_ASSERT(lvol != NULL); 2893 2894 for (hp_lvol = g_hotplug_lvols; hp_lvol->lvol != NULL; hp_lvol++) { 2895 if (hp_lvol->lvol->blob == lvol->blob) { 2896 break; 2897 } 2898 } 2899 if (hp_lvol->lvol == NULL) { 2900 return -EINVAL; 2901 } 2902 2903 if (!hp_lvol->created) { 2904 hp_lvol->created = true; 2905 rc = spdk_lvs_esnap_missing_add(lvs, lvol, hp_lvol->esnap_id, hp_lvol->id_len); 2906 CU_ASSERT(rc == 0); 2907 *bs_dev = NULL; 2908 return 0; 2909 } 2910 2911 hp_lvol->hp_count++; 2912 2913 if (hp_lvol->hotplug_retval != 0) { 2914 return hp_lvol->hotplug_retval; 2915 } 2916 2917 missing_esnap = get_missing_esnap(g_missing_esnap, esnap_id); 2918 if (missing_esnap == NULL) { 2919 return -ENODEV; 2920 } 2921 2922 if (hp_lvol->register_missing) { 2923 rc = spdk_lvs_esnap_missing_add(hp_lvol->lvol->lvol_store, hp_lvol->lvol, 2924 hp_lvol->esnap_id, hp_lvol->id_len); 2925 CU_ASSERT(rc == 0); 2926 *bs_dev = NULL; 2927 return 0; 2928 } 2929 2930 *bs_dev = missing_esnap->esnap_dev; 2931 return 0; 2932 } 2933 2934 /* 2935 * Creates an lvolstore with the specified esnap clone lvols. They are all initially missing their 2936 * external snapshots, similar to what would happen if an lvolstore's device is examined before the 2937 * devices that act as external snapshots. After the lvols are loaded, the blobstore is notified of 2938 * each missing esnap (degraded_set). 2939 * 2940 * @param hotplug_lvols An array of esnap clone lvols to create. The array is terminated by zeroed 2941 * element. 2942 * @parm degraded_lvol_sets_tree An array of external snapshots that will be hotplugged. The array is 2943 * terminated by a zeroed element. 2944 * @desc Unused, but is very helpful when displaying stack traces in a debugger. 2945 */ 2946 static bool 2947 lvol_esnap_hotplug_scenario(struct hotplug_lvol *hotplug_lvols, 2948 struct missing_esnap *degraded_lvol_sets_tree, 2949 char *desc) 2950 { 2951 struct lvol_ut_bs_dev dev; 2952 struct spdk_lvs_opts opts; 2953 struct spdk_lvol_store *lvs; 2954 struct spdk_lvs_degraded_lvol_set *degraded_set; 2955 struct hotplug_lvol *hp_lvol; 2956 struct missing_esnap *m_esnap; 2957 int count; 2958 int rc; 2959 uint32_t num_failures = CU_get_number_of_failures(); 2960 2961 g_hotplug_lvols = hotplug_lvols; 2962 g_missing_esnap = degraded_lvol_sets_tree; 2963 2964 /* Create the lvstore */ 2965 init_dev(&dev); 2966 spdk_lvs_opts_init(&opts); 2967 snprintf(opts.name, sizeof(opts.name), "lvs"); 2968 g_lvserrno = -1; 2969 rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 2970 CU_ASSERT(rc == 0); 2971 CU_ASSERT(g_lvserrno == 0); 2972 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 2973 lvs = g_lvol_store; 2974 lvs->esnap_bs_dev_create = ut_esnap_hotplug_dev_create; 2975 2976 /* Create the lvols */ 2977 for (hp_lvol = hotplug_lvols; hp_lvol->lvol_name != NULL; hp_lvol++) { 2978 if (hp_lvol->id_len == 0) { 2979 hp_lvol->id_len = strlen(hp_lvol->esnap_id) + 1; 2980 } 2981 2982 g_lvserrno = 0xbad; 2983 rc = spdk_lvol_create_esnap_clone(hp_lvol->esnap_id, hp_lvol->id_len, 2984 opts.cluster_sz, lvs, hp_lvol->lvol_name, 2985 lvol_op_with_handle_complete, NULL); 2986 CU_ASSERT(rc == 0); 2987 poll_threads(); 2988 CU_ASSERT(g_lvserrno == 0); 2989 CU_ASSERT(g_lvol != NULL); 2990 if (g_lvol == NULL) { 2991 break; 2992 } 2993 hp_lvol->lvol = g_lvol; 2994 /* This is normally triggered by the blobstore in blob_load_esnap(), but that part 2995 * of blobstore is not mocked by lvol_ut. Later commits will further exercise 2996 * hotplug with a functional blobstore. See test/lvol/esnap/esnap.c and 2997 * test/lvol/external_snapshot.sh in later commits. 2998 */ 2999 rc = ut_esnap_hotplug_dev_create(lvs, hp_lvol->lvol, hp_lvol->lvol->blob, 3000 hp_lvol->esnap_id, hp_lvol->id_len, 3001 &hp_lvol->lvol->blob->back_bs_dev); 3002 CU_ASSERT(rc == 0); 3003 } 3004 3005 /* Verify lvol count in lvs->degraded_lvol_sets_tree tree. */ 3006 for (m_esnap = degraded_lvol_sets_tree; m_esnap->esnap_id != NULL; m_esnap++) { 3007 count = missing_get_lvol_count(lvs, m_esnap->esnap_id); 3008 CU_ASSERT(m_esnap->expect_missing_lvol_count_after_create == count); 3009 } 3010 3011 /* Verify lvs->degraded_lvol_sets_tree tree has nothing extra */ 3012 RB_FOREACH(degraded_set, degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree) { 3013 m_esnap = get_missing_esnap(degraded_lvol_sets_tree, degraded_set->esnap_id); 3014 CU_ASSERT(m_esnap != NULL); 3015 if (m_esnap != NULL) { 3016 count = missing_get_lvol_count(lvs, m_esnap->esnap_id); 3017 CU_ASSERT(m_esnap->expect_missing_lvol_count_after_create == count); 3018 } 3019 } 3020 3021 /* Perform hotplug */ 3022 for (m_esnap = degraded_lvol_sets_tree; m_esnap->esnap_id != NULL; m_esnap++) { 3023 spdk_lvs_notify_hotplug(m_esnap->esnap_id, strlen(m_esnap->esnap_id) + 1, 3024 lvol_op_with_handle_complete, NULL); 3025 } 3026 3027 /* Verify lvol->degraded_set and back_bs_dev */ 3028 for (hp_lvol = hotplug_lvols; hp_lvol->lvol != NULL; hp_lvol++) { 3029 if (hp_lvol->register_missing || hp_lvol->hotplug_retval != 0) { 3030 CU_ASSERT(hp_lvol->lvol->degraded_set != NULL); 3031 CU_ASSERT(hp_lvol->lvol->blob->back_bs_dev == NULL); 3032 } else { 3033 CU_ASSERT(hp_lvol->lvol->degraded_set == NULL); 3034 m_esnap = get_missing_esnap(degraded_lvol_sets_tree, hp_lvol->esnap_id); 3035 CU_ASSERT(m_esnap != NULL); 3036 if (m_esnap != NULL) { 3037 CU_ASSERT(hp_lvol->lvol->blob->back_bs_dev == m_esnap->esnap_dev); 3038 } 3039 } 3040 } 3041 3042 /* Verify hotplug count on lvols */ 3043 for (hp_lvol = hotplug_lvols; hp_lvol->lvol != NULL; hp_lvol++) { 3044 CU_ASSERT(hp_lvol->hp_count == 1); 3045 } 3046 3047 /* Verify lvol count in lvs->degraded_lvol_sets_tree tree. */ 3048 for (m_esnap = degraded_lvol_sets_tree; m_esnap->esnap_id != NULL; m_esnap++) { 3049 count = missing_get_lvol_count(lvs, m_esnap->esnap_id); 3050 CU_ASSERT(m_esnap->expect_missing_lvol_count_after_hotplug == count); 3051 } 3052 3053 /* Verify lvs->degraded_lvol_sets_tree tree has nothing extra */ 3054 RB_FOREACH(degraded_set, degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree) { 3055 m_esnap = get_missing_esnap(degraded_lvol_sets_tree, degraded_set->esnap_id); 3056 CU_ASSERT(m_esnap != NULL); 3057 if (m_esnap != NULL) { 3058 count = missing_get_lvol_count(lvs, m_esnap->esnap_id); 3059 CU_ASSERT(m_esnap->expect_missing_lvol_count_after_hotplug == count); 3060 } 3061 } 3062 3063 /* Clean up */ 3064 for (hp_lvol = hotplug_lvols; hp_lvol->lvol != NULL; hp_lvol++) { 3065 g_lvserrno = 0xbad; 3066 spdk_lvol_close(hp_lvol->lvol, op_complete, NULL); 3067 CU_ASSERT(g_lvserrno == 0); 3068 g_lvserrno = 0xbad; 3069 spdk_lvol_destroy(hp_lvol->lvol, op_complete, NULL); 3070 CU_ASSERT(g_lvserrno == 0); 3071 } 3072 g_lvserrno = 0xabad; 3073 rc = spdk_lvs_destroy(g_lvol_store, op_complete, NULL); 3074 poll_threads(); 3075 CU_ASSERT(rc == 0); 3076 CU_ASSERT(g_lvserrno == 0); 3077 g_lvol = NULL; 3078 g_lvol_store = NULL; 3079 3080 return num_failures == CU_get_number_of_failures(); 3081 } 3082 3083 static void 3084 lvol_esnap_hotplug(void) 3085 { 3086 struct spdk_bs_dev bs_dev = { 0 }; 3087 struct spdk_bs_dev bs_dev2 = { 0 }; 3088 uint64_t i; 3089 bool ok; 3090 #define HOTPLUG_LVOL(_lvol_name, _esnap_id, _hotplug_retval, _register_missing) { \ 3091 .lvol_name = _lvol_name, \ 3092 .esnap_id = _esnap_id, \ 3093 .hotplug_retval = _hotplug_retval, \ 3094 .register_missing = _register_missing, \ 3095 } 3096 #define MISSING_ESNAP(_esnap_id, _esnap_dev, _after_create, _after_hotplug) { \ 3097 .esnap_id = _esnap_id, \ 3098 .esnap_dev = _esnap_dev, \ 3099 .expect_missing_lvol_count_after_create = _after_create, \ 3100 .expect_missing_lvol_count_after_hotplug = _after_hotplug, \ 3101 } 3102 struct { 3103 char *desc; 3104 struct hotplug_lvol h[4]; 3105 struct missing_esnap m[3]; 3106 } scenario[] = { 3107 { 3108 "one missing, happy path", 3109 { HOTPLUG_LVOL("lvol1", "esnap1", 0, false) }, 3110 { MISSING_ESNAP("esnap1", &bs_dev, 1, 0) } 3111 }, 3112 { 3113 "one missing, cb registers degraded_set", 3114 { HOTPLUG_LVOL("lvol1", "esnap1", 0, true) }, 3115 { MISSING_ESNAP("esnap1", &bs_dev, 1, 1) } 3116 }, 3117 { 3118 "one missing, cb retuns -ENOMEM", 3119 { HOTPLUG_LVOL("lvol1", "esnap1", -ENOMEM, true) }, 3120 { MISSING_ESNAP("esnap1", &bs_dev, 1, 1) } 3121 }, 3122 { 3123 "two missing with same esnap, happy path", 3124 { 3125 HOTPLUG_LVOL("lvol1", "esnap1", 0, false), 3126 HOTPLUG_LVOL("lvol2", "esnap1", 0, false) 3127 }, 3128 { MISSING_ESNAP("esnap1", &bs_dev, 2, 0) } 3129 }, 3130 { 3131 "two missing with same esnap, first -ENOMEM", 3132 { 3133 HOTPLUG_LVOL("lvol1", "esnap1", -ENOMEM, false), 3134 HOTPLUG_LVOL("lvol2", "esnap1", 0, false) 3135 }, 3136 { MISSING_ESNAP("esnap1", &bs_dev, 2, 1) } 3137 }, 3138 { 3139 "two missing with same esnap, second -ENOMEM", 3140 { 3141 HOTPLUG_LVOL("lvol1", "esnap1", 0, false), 3142 HOTPLUG_LVOL("lvol2", "esnap1", -ENOMEM, false) 3143 }, 3144 { MISSING_ESNAP("esnap1", &bs_dev, 2, 1) } 3145 }, 3146 { 3147 "two missing with different esnaps, happy path", 3148 { 3149 HOTPLUG_LVOL("lvol1", "esnap1", 0, false), 3150 HOTPLUG_LVOL("lvol2", "esnap2", 0, false) 3151 }, 3152 { 3153 MISSING_ESNAP("esnap1", &bs_dev, 1, 0), 3154 MISSING_ESNAP("esnap2", &bs_dev2, 1, 0) 3155 } 3156 }, 3157 { 3158 "two missing with different esnaps, first still missing", 3159 { 3160 HOTPLUG_LVOL("lvol1", "esnap1", 0, true), 3161 HOTPLUG_LVOL("lvol2", "esnap2", 0, false) 3162 }, 3163 { 3164 MISSING_ESNAP("esnap1", &bs_dev, 1, 1), 3165 MISSING_ESNAP("esnap2", &bs_dev2, 1, 0) 3166 } 3167 }, 3168 { 3169 "three missing with same esnap, happy path", 3170 { 3171 HOTPLUG_LVOL("lvol1", "esnap1", 0, false), 3172 HOTPLUG_LVOL("lvol2", "esnap1", 0, false), 3173 HOTPLUG_LVOL("lvol3", "esnap1", 0, false) 3174 }, 3175 { MISSING_ESNAP("esnap1", &bs_dev, 3, 0) } 3176 }, 3177 { 3178 "three missing with same esnap, first still missing", 3179 { 3180 HOTPLUG_LVOL("lvol1", "esnap1", 0, true), 3181 HOTPLUG_LVOL("lvol2", "esnap1", 0, false), 3182 HOTPLUG_LVOL("lvol3", "esnap1", 0, false) 3183 }, 3184 { MISSING_ESNAP("esnap1", &bs_dev, 3, 1) } 3185 }, 3186 { 3187 "three missing with same esnap, first two still missing", 3188 { 3189 HOTPLUG_LVOL("lvol1", "esnap1", 0, true), 3190 HOTPLUG_LVOL("lvol2", "esnap1", 0, true), 3191 HOTPLUG_LVOL("lvol3", "esnap1", 0, false) 3192 }, 3193 { MISSING_ESNAP("esnap1", &bs_dev, 3, 2) } 3194 }, 3195 { 3196 "three missing with same esnap, middle still missing", 3197 { 3198 HOTPLUG_LVOL("lvol1", "esnap1", 0, false), 3199 HOTPLUG_LVOL("lvol2", "esnap1", 0, true), 3200 HOTPLUG_LVOL("lvol3", "esnap1", 0, false) 3201 }, 3202 { MISSING_ESNAP("esnap1", &bs_dev, 3, 1) } 3203 }, 3204 { 3205 "three missing with same esnap, last still missing", 3206 { 3207 HOTPLUG_LVOL("lvol1", "esnap1", 0, false), 3208 HOTPLUG_LVOL("lvol2", "esnap1", 0, false), 3209 HOTPLUG_LVOL("lvol3", "esnap1", 0, true) 3210 }, 3211 { MISSING_ESNAP("esnap1", &bs_dev, 3, 1) } 3212 }, 3213 }; 3214 #undef HOTPLUG_LVOL 3215 #undef MISSING_ESNAP 3216 3217 printf("\n"); 3218 for (i = 0; i < SPDK_COUNTOF(scenario); i++) { 3219 ok = lvol_esnap_hotplug_scenario(scenario[i].h, scenario[i].m, scenario[i].desc); 3220 /* Add markers in the output to help correlate failures to scenarios. */ 3221 CU_ASSERT(ok); 3222 printf("\t%s scenario %" PRIu64 ": %s - %s\n", __func__, i, 3223 ok ? "PASS" : "FAIL", scenario[i].desc); 3224 } 3225 } 3226 3227 static void 3228 lvol_get_by(void) 3229 { 3230 struct lvol_ut_bs_dev dev1, dev2; 3231 struct spdk_lvol_store *lvs1, *lvs2; 3232 struct spdk_lvol *lvol1, *lvol2, *lvol3; 3233 struct spdk_lvs_opts opts; 3234 int rc = 0; 3235 struct spdk_uuid uuid; 3236 3237 init_dev(&dev1); 3238 3239 spdk_lvs_opts_init(&opts); 3240 snprintf(opts.name, sizeof(opts.name), "lvs"); 3241 3242 g_lvserrno = -1; 3243 rc = spdk_lvs_init(&dev1.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 3244 CU_ASSERT(rc == 0); 3245 CU_ASSERT(g_lvserrno == 0); 3246 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 3247 lvs1 = g_lvol_store; 3248 3249 /* Create lvol name "lvol" */ 3250 spdk_lvol_create(lvs1, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 3251 lvol_op_with_handle_complete, NULL); 3252 CU_ASSERT(g_lvserrno == 0); 3253 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3254 lvol1 = g_lvol; 3255 3256 /* Should be able to look up lvol1 by its name and UUID */ 3257 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1); 3258 /* Be sure a pointer comparison isn't used. */ 3259 memcpy(&uuid, &lvol1->uuid, sizeof(uuid)); 3260 CU_ASSERT(spdk_lvol_get_by_uuid(&uuid) == lvol1); 3261 3262 /* Shorter and longer values for lvol_name must not match. */ 3263 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvoll") == NULL); 3264 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvo") == NULL); 3265 3266 /* Shorter and longer values for lvs_name must not match. */ 3267 CU_ASSERT(spdk_lvol_get_by_names("lvss", "lvol") == NULL); 3268 CU_ASSERT(spdk_lvol_get_by_names("lv", "lvol") == NULL); 3269 3270 /* Create lvol name "lvol2" */ 3271 spdk_lvol_create(lvs1, "lvol2", 10, true, LVOL_CLEAR_WITH_DEFAULT, 3272 lvol_op_with_handle_complete, NULL); 3273 CU_ASSERT(g_lvserrno == 0); 3274 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3275 lvol2 = g_lvol; 3276 3277 /* When there are multiple lvols, the right one is found */ 3278 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1); 3279 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol2") == lvol2); 3280 3281 /* Create a second lvolstore */ 3282 init_dev(&dev2); 3283 snprintf(opts.name, sizeof(opts.name), "lvs2"); 3284 g_lvserrno = -1; 3285 rc = spdk_lvs_init(&dev2.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 3286 CU_ASSERT(rc == 0); 3287 CU_ASSERT(g_lvserrno == 0); 3288 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 3289 lvs2 = g_lvol_store; 3290 3291 /* Lookups that worked with one lvstore still work */ 3292 memcpy(&uuid, &lvol1->uuid, sizeof(uuid)); 3293 CU_ASSERT(spdk_lvol_get_by_uuid(&uuid) == lvol1); 3294 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1); 3295 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol2") == lvol2); 3296 3297 /* Add an lvol name "lvol" in the second lvstore */ 3298 spdk_lvol_create(lvs2, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT, 3299 lvol_op_with_handle_complete, NULL); 3300 CU_ASSERT(g_lvserrno == 0); 3301 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3302 lvol3 = g_lvol; 3303 3304 /* Lookups by name find the lvols in the right lvstores */ 3305 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1); 3306 CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol2") == lvol2); 3307 CU_ASSERT(spdk_lvol_get_by_names("lvs2", "lvol") == lvol3); 3308 3309 /* Clean up */ 3310 g_lvserrno = -1; 3311 spdk_lvol_close(lvol1, op_complete, NULL); 3312 CU_ASSERT(g_lvserrno == 0); 3313 3314 g_lvserrno = -1; 3315 spdk_lvol_close(lvol2, op_complete, NULL); 3316 CU_ASSERT(g_lvserrno == 0); 3317 3318 g_lvserrno = -1; 3319 spdk_lvol_close(lvol3, op_complete, NULL); 3320 CU_ASSERT(g_lvserrno == 0); 3321 3322 g_lvserrno = -1; 3323 rc = spdk_lvs_unload(lvs1, op_complete, NULL); 3324 CU_ASSERT(rc == 0); 3325 CU_ASSERT(g_lvserrno == 0); 3326 3327 g_lvserrno = -1; 3328 rc = spdk_lvs_unload(lvs2, op_complete, NULL); 3329 CU_ASSERT(rc == 0); 3330 CU_ASSERT(g_lvserrno == 0); 3331 3332 g_lvol_store = NULL; 3333 g_lvol = NULL; 3334 3335 free_dev(&dev1); 3336 free_dev(&dev2); 3337 } 3338 3339 static void 3340 lvol_shallow_copy(void) 3341 { 3342 struct lvol_ut_bs_dev bs_dev; 3343 struct spdk_lvs_opts opts; 3344 struct spdk_bs_dev ext_dev; 3345 int rc = 0; 3346 3347 init_dev(&bs_dev); 3348 3349 ext_dev.blocklen = DEV_BUFFER_BLOCKLEN; 3350 ext_dev.blockcnt = BS_CLUSTER_SIZE / DEV_BUFFER_BLOCKLEN; 3351 3352 spdk_lvs_opts_init(&opts); 3353 snprintf(opts.name, sizeof(opts.name), "lvs"); 3354 3355 g_lvserrno = -1; 3356 rc = spdk_lvs_init(&bs_dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 3357 CU_ASSERT(rc == 0); 3358 CU_ASSERT(g_lvserrno == 0); 3359 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 3360 3361 spdk_lvol_create(g_lvol_store, "lvol", BS_CLUSTER_SIZE, false, LVOL_CLEAR_WITH_DEFAULT, 3362 lvol_op_with_handle_complete, NULL); 3363 CU_ASSERT(g_lvserrno == 0); 3364 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3365 3366 /* Successful shallow copy */ 3367 g_blob_read_only = true; 3368 rc = spdk_lvol_shallow_copy(g_lvol, &ext_dev, NULL, NULL, op_complete, NULL); 3369 CU_ASSERT(rc == 0); 3370 CU_ASSERT(g_lvserrno == 0); 3371 3372 /* Shallow copy with null lvol */ 3373 rc = spdk_lvol_shallow_copy(NULL, &ext_dev, NULL, NULL, op_complete, NULL); 3374 CU_ASSERT(rc == -EINVAL); 3375 3376 /* Shallow copy with null ext_dev */ 3377 rc = spdk_lvol_shallow_copy(g_lvol, NULL, NULL, NULL, op_complete, NULL); 3378 CU_ASSERT(rc == -EINVAL); 3379 3380 spdk_lvol_close(g_lvol, op_complete, NULL); 3381 CU_ASSERT(g_lvserrno == 0); 3382 spdk_lvol_destroy(g_lvol, op_complete, NULL); 3383 CU_ASSERT(g_lvserrno == 0); 3384 3385 g_lvserrno = -1; 3386 rc = spdk_lvs_unload(g_lvol_store, op_complete, NULL); 3387 CU_ASSERT(rc == 0); 3388 CU_ASSERT(g_lvserrno == 0); 3389 g_lvol_store = NULL; 3390 3391 free_dev(&bs_dev); 3392 3393 /* Make sure that all references to the io_channel was closed after 3394 * shallow copy call 3395 */ 3396 CU_ASSERT(g_io_channel == NULL); 3397 } 3398 3399 static void 3400 lvol_set_parent(void) 3401 { 3402 struct lvol_ut_bs_dev bs1_dev; 3403 struct spdk_lvol_store *lvol_store1; 3404 struct spdk_lvol *lvol1, *lvol2, *snapshot1; 3405 struct spdk_lvs_opts opts; 3406 uint64_t cluster_sz = BS_CLUSTER_SIZE; 3407 int rc = 0; 3408 3409 init_dev(&bs1_dev); 3410 3411 /* Create lvol store 1 */ 3412 spdk_lvs_opts_init(&opts); 3413 snprintf(opts.name, sizeof(opts.name), "lvs1"); 3414 3415 g_lvserrno = -1; 3416 rc = spdk_lvs_init(&bs1_dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); 3417 CU_ASSERT(rc == 0); 3418 CU_ASSERT(g_lvserrno == 0); 3419 SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 3420 3421 lvol_store1 = g_lvol_store; 3422 3423 /* Create lvol1 */ 3424 spdk_lvol_create(lvol_store1, "lvol1", cluster_sz, true, LVOL_CLEAR_WITH_DEFAULT, 3425 lvol_op_with_handle_complete, NULL); 3426 CU_ASSERT(g_lvserrno == 0); 3427 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3428 3429 lvol1 = g_lvol; 3430 3431 /* Create lvol2 with same size of lvol1 */ 3432 spdk_lvol_create(lvol_store1, "lvol2", cluster_sz, true, LVOL_CLEAR_WITH_DEFAULT, 3433 lvol_op_with_handle_complete, NULL); 3434 CU_ASSERT(g_lvserrno == 0); 3435 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3436 3437 lvol2 = g_lvol; 3438 3439 /* Create a snapshot of lvol2 */ 3440 spdk_lvol_create_snapshot(lvol2, "snap1", lvol_op_with_handle_complete, NULL); 3441 CU_ASSERT(g_lvserrno == 0); 3442 SPDK_CU_ASSERT_FATAL(g_lvol != NULL); 3443 CU_ASSERT_STRING_EQUAL(g_lvol->name, "snap1"); 3444 3445 snapshot1 = g_lvol; 3446 3447 /* Set parent with a NULL lvol */ 3448 g_lvserrno = 0; 3449 spdk_lvol_set_parent(NULL, snapshot1, op_complete, NULL); 3450 CU_ASSERT(g_lvserrno == -EINVAL); 3451 3452 /* Set parent with a NULL parent snapshot */ 3453 g_lvserrno = 0; 3454 spdk_lvol_set_parent(lvol1, NULL, op_complete, NULL); 3455 CU_ASSERT(g_lvserrno == -EINVAL); 3456 3457 /* Set parent successful */ 3458 g_blob_is_snapshot = true; 3459 g_lvserrno = -1; 3460 spdk_lvol_set_parent(lvol1, snapshot1, op_complete, NULL); 3461 CU_ASSERT(g_lvserrno == 0); 3462 3463 /* Clean up */ 3464 spdk_lvol_close(lvol1, op_complete, NULL); 3465 CU_ASSERT(g_lvserrno == 0); 3466 spdk_lvol_destroy(lvol1, op_complete, NULL); 3467 CU_ASSERT(g_lvserrno == 0); 3468 3469 spdk_lvol_close(lvol2, op_complete, NULL); 3470 CU_ASSERT(g_lvserrno == 0); 3471 spdk_lvol_destroy(lvol2, op_complete, NULL); 3472 CU_ASSERT(g_lvserrno == 0); 3473 3474 spdk_lvol_close(snapshot1, op_complete, NULL); 3475 CU_ASSERT(g_lvserrno == 0); 3476 spdk_lvol_destroy(snapshot1, op_complete, NULL); 3477 CU_ASSERT(g_lvserrno == 0); 3478 3479 g_lvserrno = -1; 3480 rc = spdk_lvs_destroy(lvol_store1, op_complete, NULL); 3481 CU_ASSERT(rc == 0); 3482 CU_ASSERT(g_lvserrno == 0); 3483 lvol_store1 = NULL; 3484 } 3485 3486 int 3487 main(int argc, char **argv) 3488 { 3489 CU_pSuite suite = NULL; 3490 unsigned int num_failures; 3491 3492 CU_initialize_registry(); 3493 3494 suite = CU_add_suite("lvol", NULL, NULL); 3495 3496 CU_ADD_TEST(suite, lvs_init_unload_success); 3497 CU_ADD_TEST(suite, lvs_init_destroy_success); 3498 CU_ADD_TEST(suite, lvs_init_opts_success); 3499 CU_ADD_TEST(suite, lvs_unload_lvs_is_null_fail); 3500 CU_ADD_TEST(suite, lvs_names); 3501 CU_ADD_TEST(suite, lvol_create_destroy_success); 3502 CU_ADD_TEST(suite, lvol_create_fail); 3503 CU_ADD_TEST(suite, lvol_destroy_fail); 3504 CU_ADD_TEST(suite, lvol_close); 3505 CU_ADD_TEST(suite, lvol_resize); 3506 CU_ADD_TEST(suite, lvol_set_read_only); 3507 CU_ADD_TEST(suite, test_lvs_load); 3508 CU_ADD_TEST(suite, lvols_load); 3509 CU_ADD_TEST(suite, lvol_open); 3510 CU_ADD_TEST(suite, lvol_snapshot); 3511 CU_ADD_TEST(suite, lvol_snapshot_fail); 3512 CU_ADD_TEST(suite, lvol_clone); 3513 CU_ADD_TEST(suite, lvol_clone_fail); 3514 CU_ADD_TEST(suite, lvol_iter_clones); 3515 CU_ADD_TEST(suite, lvol_refcnt); 3516 CU_ADD_TEST(suite, lvol_names); 3517 CU_ADD_TEST(suite, lvol_create_thin_provisioned); 3518 CU_ADD_TEST(suite, lvol_rename); 3519 CU_ADD_TEST(suite, lvs_rename); 3520 CU_ADD_TEST(suite, lvol_inflate); 3521 CU_ADD_TEST(suite, lvol_decouple_parent); 3522 CU_ADD_TEST(suite, lvol_get_xattr); 3523 CU_ADD_TEST(suite, lvol_esnap_reload); 3524 CU_ADD_TEST(suite, lvol_esnap_create_bad_args); 3525 CU_ADD_TEST(suite, lvol_esnap_create_delete); 3526 CU_ADD_TEST(suite, lvol_esnap_load_esnaps); 3527 CU_ADD_TEST(suite, lvol_esnap_missing); 3528 CU_ADD_TEST(suite, lvol_esnap_hotplug); 3529 CU_ADD_TEST(suite, lvol_get_by); 3530 CU_ADD_TEST(suite, lvol_shallow_copy); 3531 CU_ADD_TEST(suite, lvol_set_parent); 3532 3533 allocate_threads(1); 3534 set_thread(0); 3535 3536 num_failures = spdk_ut_run_tests(argc, argv, NULL); 3537 CU_cleanup_registry(); 3538 3539 free_threads(); 3540 3541 return num_failures; 3542 } 3543