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