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