xref: /spdk/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c (revision 5b250c0836979f4c87704fbc62a32c83e6f17298)
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_cunit.h"
8 #include "spdk/string.h"
9 
10 #include "common/lib/ut_multithread.c"
11 #include "bdev/lvol/vbdev_lvol.c"
12 
13 #include "unit/lib/json_mock.c"
14 
15 #define SPDK_BS_PAGE_SIZE 0x1000
16 
17 int g_lvolerrno;
18 int g_lvserrno;
19 int g_cluster_size;
20 int g_registered_bdevs;
21 int g_num_lvols = 0;
22 int g_lvol_open_enomem = -1;
23 struct spdk_lvol_store *g_lvs = NULL;
24 struct spdk_lvol *g_lvol = NULL;
25 struct lvol_store_bdev *g_lvs_bdev = NULL;
26 struct spdk_bdev *g_base_bdev = NULL;
27 struct spdk_bdev_io *g_io = NULL;
28 struct spdk_io_channel *g_ch = NULL;
29 
30 static struct spdk_bdev g_bdev = {};
31 static struct spdk_lvol_store *g_lvol_store = NULL;
32 bool lvol_store_initialize_fail = false;
33 bool lvol_store_initialize_cb_fail = false;
34 bool lvol_already_opened = false;
35 bool g_examine_done = false;
36 bool g_bdev_alias_already_exists = false;
37 bool g_lvs_with_name_already_exists = false;
38 bool g_ext_api_called;
39 bool g_bdev_is_missing = false;
40 
41 DEFINE_STUB_V(spdk_bdev_module_fini_start_done, (void));
42 DEFINE_STUB(spdk_bdev_get_memory_domains, int, (struct spdk_bdev *bdev,
43 		struct spdk_memory_domain **domains, int array_size), 0);
44 DEFINE_STUB(spdk_blob_get_esnap_id, int,
45 	    (struct spdk_blob *blob, const void **id, size_t *len), -ENOTSUP);
46 DEFINE_STUB(spdk_blob_is_esnap_clone, bool, (const struct spdk_blob *blob), false);
47 DEFINE_STUB(spdk_lvol_iter_immediate_clones, int,
48 	    (struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn, void *cb_arg), -ENOTSUP);
49 DEFINE_STUB(spdk_lvs_esnap_missing_add, int,
50 	    (struct spdk_lvol_store *lvs, struct spdk_lvol *lvol, const void *esnap_id,
51 	     uint32_t id_len), -ENOTSUP);
52 DEFINE_STUB(spdk_blob_is_degraded, bool, (const struct spdk_blob *blob), false);
53 
54 struct spdk_blob {
55 	uint64_t	id;
56 	char		name[32];
57 };
58 
59 struct spdk_blob_store {
60 	spdk_bs_esnap_dev_create esnap_bs_dev_create;
61 };
62 
63 const struct spdk_bdev_aliases_list *
64 spdk_bdev_get_aliases(const struct spdk_bdev *bdev)
65 {
66 	return &bdev->aliases;
67 }
68 
69 uint32_t
70 spdk_bdev_get_md_size(const struct spdk_bdev *bdev)
71 {
72 	return bdev->md_len;
73 }
74 
75 const struct spdk_uuid *
76 spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
77 {
78 	return &bdev->uuid;
79 }
80 
81 int
82 spdk_bdev_alias_add(struct spdk_bdev *bdev, const char *alias)
83 {
84 	struct spdk_bdev_alias *tmp;
85 
86 	CU_ASSERT(alias != NULL);
87 	CU_ASSERT(bdev != NULL);
88 	if (g_bdev_alias_already_exists) {
89 		return -EEXIST;
90 	}
91 
92 	tmp = calloc(1, sizeof(*tmp));
93 	SPDK_CU_ASSERT_FATAL(tmp != NULL);
94 
95 	tmp->alias.name = strdup(alias);
96 	SPDK_CU_ASSERT_FATAL(tmp->alias.name != NULL);
97 
98 	TAILQ_INSERT_TAIL(&bdev->aliases, tmp, tailq);
99 
100 	return 0;
101 }
102 
103 int
104 spdk_bdev_alias_del(struct spdk_bdev *bdev, const char *alias)
105 {
106 	struct spdk_bdev_alias *tmp;
107 
108 	CU_ASSERT(bdev != NULL);
109 
110 	TAILQ_FOREACH(tmp, &bdev->aliases, tailq) {
111 		SPDK_CU_ASSERT_FATAL(alias != NULL);
112 		if (strncmp(alias, tmp->alias.name, SPDK_LVOL_NAME_MAX) == 0) {
113 			TAILQ_REMOVE(&bdev->aliases, tmp, tailq);
114 			free(tmp->alias.name);
115 			free(tmp);
116 			return 0;
117 		}
118 	}
119 
120 	return -ENOENT;
121 }
122 
123 void
124 spdk_bdev_alias_del_all(struct spdk_bdev *bdev)
125 {
126 	struct spdk_bdev_alias *p, *tmp;
127 
128 	TAILQ_FOREACH_SAFE(p, &bdev->aliases, tailq, tmp) {
129 		TAILQ_REMOVE(&bdev->aliases, p, tailq);
130 		free(p->alias.name);
131 		free(p);
132 	}
133 }
134 
135 void
136 spdk_bdev_destruct_done(struct spdk_bdev *bdev, int bdeverrno)
137 {
138 	CU_ASSERT(bdeverrno == 0);
139 	SPDK_CU_ASSERT_FATAL(bdev->internal.unregister_cb != NULL);
140 	bdev->internal.unregister_cb(bdev->internal.unregister_ctx, bdeverrno);
141 }
142 
143 struct ut_bs_dev {
144 	struct spdk_bs_dev bs_dev;
145 	struct spdk_bdev *bdev;
146 };
147 
148 static void
149 ut_bs_dev_destroy(struct spdk_bs_dev *bs_dev)
150 {
151 	struct ut_bs_dev *ut_bs_dev = SPDK_CONTAINEROF(bs_dev, struct ut_bs_dev, bs_dev);
152 
153 	free(ut_bs_dev);
154 }
155 
156 int
157 spdk_bdev_create_bs_dev(const char *bdev_name, bool write,
158 			struct spdk_bdev_bs_dev_opts *opts, size_t opts_size,
159 			spdk_bdev_event_cb_t event_cb, void *event_ctx,
160 			struct spdk_bs_dev **bs_dev)
161 {
162 	struct spdk_bdev *bdev;
163 	struct ut_bs_dev *ut_bs_dev;
164 
165 	bdev = spdk_bdev_get_by_name(bdev_name);
166 	if (bdev == NULL) {
167 		return -ENODEV;
168 	}
169 
170 	ut_bs_dev = calloc(1, sizeof(*ut_bs_dev));
171 	SPDK_CU_ASSERT_FATAL(ut_bs_dev != NULL);
172 	ut_bs_dev->bs_dev.destroy = ut_bs_dev_destroy;
173 	ut_bs_dev->bdev = bdev;
174 	*bs_dev = &ut_bs_dev->bs_dev;
175 
176 	return 0;
177 }
178 
179 void
180 spdk_lvs_grow(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
181 {
182 	cb_fn(cb_arg, NULL, -EINVAL);
183 }
184 
185 void
186 spdk_lvs_rename(struct spdk_lvol_store *lvs, const char *new_name,
187 		spdk_lvs_op_complete cb_fn, void *cb_arg)
188 {
189 	if (g_lvs_with_name_already_exists) {
190 		g_lvolerrno = -EEXIST;
191 	} else {
192 		snprintf(lvs->name, sizeof(lvs->name), "%s", new_name);
193 		g_lvolerrno = 0;
194 	}
195 
196 	cb_fn(cb_arg, g_lvolerrno);
197 }
198 
199 void
200 spdk_lvol_rename(struct spdk_lvol *lvol, const char *new_name,
201 		 spdk_lvol_op_complete cb_fn, void *cb_arg)
202 {
203 	struct spdk_lvol *tmp;
204 
205 	if (strncmp(lvol->name, new_name, SPDK_LVOL_NAME_MAX) == 0) {
206 		cb_fn(cb_arg, 0);
207 		return;
208 	}
209 
210 	TAILQ_FOREACH(tmp, &lvol->lvol_store->lvols, link) {
211 		if (strncmp(tmp->name, new_name, SPDK_LVOL_NAME_MAX) == 0) {
212 			SPDK_ERRLOG("Lvol %s already exists in lvol store %s\n", new_name, lvol->lvol_store->name);
213 			cb_fn(cb_arg, -EEXIST);
214 			return;
215 		}
216 	}
217 
218 	snprintf(lvol->name, sizeof(lvol->name), "%s", new_name);
219 
220 	cb_fn(cb_arg, g_lvolerrno);
221 }
222 
223 void
224 spdk_lvol_open(struct spdk_lvol *lvol, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
225 {
226 	int lvolerrno;
227 
228 	if (g_lvol_open_enomem == lvol->lvol_store->lvols_opened) {
229 		lvolerrno = -ENOMEM;
230 		g_lvol_open_enomem = -1;
231 	} else {
232 		lvolerrno = g_lvolerrno;
233 	}
234 
235 	cb_fn(cb_arg, lvol, lvolerrno);
236 }
237 
238 uint64_t
239 spdk_blob_get_num_clusters(struct spdk_blob *b)
240 {
241 	return 0;
242 }
243 
244 /* Simulation of a blob with:
245  * - 1 io_unit per cluster
246  * - 20 data cluster
247  * - only last cluster allocated
248  */
249 uint64_t g_blob_allocated_io_unit_offset = 20;
250 
251 uint64_t
252 spdk_blob_get_next_allocated_io_unit(struct spdk_blob *blob, uint64_t offset)
253 {
254 	if (offset <= g_blob_allocated_io_unit_offset) {
255 		return g_blob_allocated_io_unit_offset;
256 	} else {
257 		return UINT64_MAX;
258 	}
259 }
260 
261 uint64_t
262 spdk_blob_get_next_unallocated_io_unit(struct spdk_blob *blob, uint64_t offset)
263 {
264 	if (offset < g_blob_allocated_io_unit_offset) {
265 		return offset;
266 	} else {
267 		return UINT64_MAX;
268 	}
269 }
270 
271 int
272 spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
273 		     size_t *count)
274 {
275 	*count = 0;
276 	return 0;
277 }
278 
279 spdk_blob_id
280 spdk_blob_get_parent_snapshot(struct spdk_blob_store *bs, spdk_blob_id blobid)
281 {
282 	return 0;
283 }
284 
285 bool g_blob_is_read_only = false;
286 
287 bool
288 spdk_blob_is_read_only(struct spdk_blob *blob)
289 {
290 	return g_blob_is_read_only;
291 }
292 
293 bool
294 spdk_blob_is_snapshot(struct spdk_blob *blob)
295 {
296 	return false;
297 }
298 
299 bool
300 spdk_blob_is_clone(struct spdk_blob *blob)
301 {
302 	return false;
303 }
304 
305 bool
306 spdk_blob_is_thin_provisioned(struct spdk_blob *blob)
307 {
308 	return false;
309 }
310 
311 static struct spdk_lvol *_lvol_create(struct spdk_lvol_store *lvs);
312 
313 int
314 spdk_lvol_create_esnap_clone(const void *esnap_id, uint32_t id_len, uint64_t size_bytes,
315 			     struct spdk_lvol_store *lvs, const char *clone_name,
316 			     spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
317 {
318 	struct spdk_lvol *lvol;
319 
320 	lvol = _lvol_create(lvs);
321 	snprintf(lvol->name, sizeof(lvol->name), "%s", clone_name);
322 
323 	cb_fn(cb_arg, lvol, 0);
324 	return 0;
325 }
326 
327 static void
328 lvs_load(struct spdk_bs_dev *dev, const struct spdk_lvs_opts *lvs_opts,
329 	 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
330 {
331 	struct spdk_lvol_store *lvs = NULL;
332 	int i;
333 	int lvserrno = g_lvserrno;
334 
335 	if (lvserrno != 0) {
336 		/* On error blobstore destroys bs_dev itself,
337 		 * by puttin back io channels.
338 		 * This operation is asynchronous, and completed
339 		 * after calling the callback for lvol. */
340 		cb_fn(cb_arg, g_lvol_store, lvserrno);
341 		dev->destroy(dev);
342 		return;
343 	}
344 
345 	lvs = calloc(1, sizeof(*lvs));
346 	SPDK_CU_ASSERT_FATAL(lvs != NULL);
347 	lvs->blobstore = calloc(1, sizeof(*lvs->blobstore));
348 	lvs->blobstore->esnap_bs_dev_create = lvs_opts->esnap_bs_dev_create;
349 	SPDK_CU_ASSERT_FATAL(lvs->blobstore != NULL);
350 	TAILQ_INIT(&lvs->lvols);
351 	TAILQ_INIT(&lvs->pending_lvols);
352 	TAILQ_INIT(&lvs->retry_open_lvols);
353 	spdk_uuid_generate(&lvs->uuid);
354 	lvs->bs_dev = dev;
355 	for (i = 0; i < g_num_lvols; i++) {
356 		_lvol_create(lvs);
357 		lvs->lvol_count++;
358 	}
359 
360 	cb_fn(cb_arg, lvs, lvserrno);
361 }
362 
363 void
364 spdk_lvs_load(struct spdk_bs_dev *dev,
365 	      spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
366 {
367 	lvs_load(dev, NULL, cb_fn, cb_arg);
368 }
369 
370 void
371 spdk_lvs_load_ext(struct spdk_bs_dev *bs_dev, const struct spdk_lvs_opts *lvs_opts,
372 		  spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
373 {
374 	lvs_load(bs_dev, lvs_opts, cb_fn, cb_arg);
375 }
376 
377 int
378 spdk_bs_bdev_claim(struct spdk_bs_dev *bs_dev, struct spdk_bdev_module *module)
379 {
380 	if (lvol_already_opened == true) {
381 		return -EPERM;
382 	}
383 
384 	lvol_already_opened = true;
385 
386 	return 0;
387 }
388 
389 static void
390 _spdk_bdev_unregister_cb(void *cb_arg, int rc)
391 {
392 	CU_ASSERT(rc == 0);
393 }
394 
395 void
396 spdk_bdev_unregister(struct spdk_bdev *vbdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
397 {
398 	int rc;
399 
400 	SPDK_CU_ASSERT_FATAL(vbdev != NULL);
401 	vbdev->internal.unregister_cb = cb_fn;
402 	vbdev->internal.unregister_ctx = cb_arg;
403 
404 	rc = vbdev->fn_table->destruct(vbdev->ctxt);
405 	CU_ASSERT(rc == 1);
406 }
407 
408 uint64_t
409 spdk_bs_get_page_size(struct spdk_blob_store *bs)
410 {
411 	return SPDK_BS_PAGE_SIZE;
412 }
413 
414 uint64_t
415 spdk_bs_get_io_unit_size(struct spdk_blob_store *bs)
416 {
417 	return SPDK_BS_PAGE_SIZE;
418 }
419 
420 static void
421 bdev_blob_destroy(struct spdk_bs_dev *bs_dev)
422 {
423 	CU_ASSERT(bs_dev != NULL);
424 	free(bs_dev);
425 	lvol_already_opened = false;
426 }
427 
428 static struct spdk_bdev *
429 bdev_blob_get_base_bdev(struct spdk_bs_dev *bs_dev)
430 {
431 	CU_ASSERT(bs_dev != NULL);
432 	return &g_bdev;
433 }
434 
435 int
436 spdk_bdev_create_bs_dev_ext(const char *bdev_name, spdk_bdev_event_cb_t event_cb,
437 			    void *event_ctx, struct spdk_bs_dev **_bs_dev)
438 {
439 	struct spdk_bs_dev *bs_dev;
440 
441 	if (lvol_already_opened == true) {
442 		return -EINVAL;
443 	}
444 
445 	bs_dev = calloc(1, sizeof(*bs_dev));
446 	SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
447 	bs_dev->blocklen = 4096;
448 	bs_dev->blockcnt = 128;
449 	bs_dev->destroy = bdev_blob_destroy;
450 	bs_dev->get_base_bdev = bdev_blob_get_base_bdev;
451 
452 	*_bs_dev = bs_dev;
453 
454 	return 0;
455 }
456 
457 void
458 spdk_lvs_opts_init(struct spdk_lvs_opts *opts)
459 {
460 	opts->cluster_sz = SPDK_LVS_OPTS_CLUSTER_SZ;
461 	opts->clear_method = LVS_CLEAR_WITH_UNMAP;
462 	opts->num_md_pages_per_cluster_ratio = 100;
463 	memset(opts->name, 0, sizeof(opts->name));
464 }
465 
466 int
467 spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
468 	      spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
469 {
470 	struct spdk_lvol_store *lvs;
471 	int error = 0;
472 
473 	if (lvol_store_initialize_fail) {
474 		return -1;
475 	}
476 
477 	if (lvol_store_initialize_cb_fail) {
478 		bs_dev->destroy(bs_dev);
479 		lvs = NULL;
480 		error = -1;
481 	} else {
482 		lvs = calloc(1, sizeof(*lvs));
483 		SPDK_CU_ASSERT_FATAL(lvs != NULL);
484 		TAILQ_INIT(&lvs->lvols);
485 		TAILQ_INIT(&lvs->pending_lvols);
486 		spdk_uuid_generate(&lvs->uuid);
487 		snprintf(lvs->name, sizeof(lvs->name), "%s", o->name);
488 		lvs->bs_dev = bs_dev;
489 		error = 0;
490 	}
491 	cb_fn(cb_arg, lvs, error);
492 
493 	return 0;
494 }
495 
496 int
497 spdk_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg)
498 {
499 	struct spdk_lvol *lvol, *tmp;
500 
501 	TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
502 		TAILQ_REMOVE(&lvs->lvols, lvol, link);
503 		free(lvol);
504 	}
505 	g_lvol_store = NULL;
506 
507 	lvs->bs_dev->destroy(lvs->bs_dev);
508 	free(lvs->blobstore);
509 	free(lvs);
510 
511 	if (cb_fn != NULL) {
512 		cb_fn(cb_arg, 0);
513 	}
514 
515 	return 0;
516 }
517 
518 int
519 spdk_lvs_destroy(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn,
520 		 void *cb_arg)
521 {
522 	struct spdk_lvol *lvol, *tmp;
523 	char *alias;
524 
525 	TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
526 		TAILQ_REMOVE(&lvs->lvols, lvol, link);
527 
528 		alias = spdk_sprintf_alloc("%s/%s", lvs->name, lvol->name);
529 		if (alias == NULL) {
530 			SPDK_ERRLOG("Cannot alloc memory for alias\n");
531 			return -1;
532 		}
533 		spdk_bdev_alias_del(lvol->bdev, alias);
534 
535 		free(alias);
536 		free(lvol);
537 	}
538 	g_lvol_store = NULL;
539 
540 	lvs->bs_dev->destroy(lvs->bs_dev);
541 	free(lvs->blobstore);
542 	free(lvs);
543 
544 	if (cb_fn != NULL) {
545 		cb_fn(cb_arg, 0);
546 	}
547 
548 	return 0;
549 }
550 
551 void
552 spdk_lvol_resize(struct spdk_lvol *lvol, size_t sz,  spdk_lvol_op_complete cb_fn, void *cb_arg)
553 {
554 	cb_fn(cb_arg, 0);
555 }
556 
557 void
558 spdk_lvol_set_read_only(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
559 {
560 	cb_fn(cb_arg, 0);
561 }
562 
563 int
564 spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size)
565 {
566 	bdev->blockcnt = size;
567 	return 0;
568 }
569 
570 uint64_t
571 spdk_bs_get_cluster_size(struct spdk_blob_store *bs)
572 {
573 	return g_cluster_size;
574 }
575 
576 struct spdk_bdev *
577 spdk_bdev_get_by_name(const char *bdev_name)
578 {
579 	struct spdk_uuid uuid;
580 	int rc;
581 
582 	if (g_base_bdev == NULL) {
583 		return NULL;
584 	}
585 
586 	if (!strcmp(g_base_bdev->name, bdev_name)) {
587 		return g_base_bdev;
588 	}
589 
590 	rc = spdk_uuid_parse(&uuid, bdev_name);
591 	if (rc == 0 && spdk_uuid_compare(&uuid, &g_base_bdev->uuid) == 0) {
592 		return g_base_bdev;
593 	}
594 
595 	return NULL;
596 }
597 
598 struct spdk_bdev_desc {
599 	struct spdk_bdev *bdev;
600 };
601 
602 int
603 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb,
604 		   void *event_ctx, struct spdk_bdev_desc **_desc)
605 {
606 	struct spdk_bdev_desc *desc;
607 	struct spdk_bdev *bdev;
608 
609 	bdev = spdk_bdev_get_by_name(bdev_name);
610 	if (bdev == NULL) {
611 		return -ENODEV;
612 	}
613 
614 	desc = calloc(1, sizeof(*desc));
615 	if (desc == NULL) {
616 		return -ENOMEM;
617 	}
618 
619 	desc->bdev = bdev;
620 	*_desc = desc;
621 	return 0;
622 }
623 
624 void
625 spdk_bdev_close(struct spdk_bdev_desc *desc)
626 {
627 	free(desc);
628 }
629 
630 struct spdk_bdev *
631 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
632 {
633 	return desc->bdev;
634 }
635 
636 void
637 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
638 {
639 	lvol->ref_count--;
640 
641 	SPDK_CU_ASSERT_FATAL(cb_fn != NULL);
642 	cb_fn(cb_arg, 0);
643 }
644 
645 bool
646 spdk_lvol_deletable(struct spdk_lvol *lvol)
647 {
648 	return true;
649 }
650 
651 void
652 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
653 {
654 	if (lvol->ref_count != 0) {
655 		cb_fn(cb_arg, -ENODEV);
656 	}
657 
658 	TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link);
659 
660 	SPDK_CU_ASSERT_FATAL(cb_fn != NULL);
661 	cb_fn(cb_arg, 0);
662 
663 	g_lvol = NULL;
664 	free(lvol);
665 }
666 
667 void
668 spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
669 {
670 	bdev_io->internal.status = status;
671 }
672 
673 struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol)
674 {
675 	CU_ASSERT(lvol == g_lvol);
676 	return g_ch;
677 }
678 
679 void
680 spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len)
681 {
682 	CU_ASSERT(cb == lvol_get_buf_cb);
683 }
684 
685 void
686 spdk_blob_io_read(struct spdk_blob *blob, struct spdk_io_channel *channel,
687 		  void *payload, uint64_t offset, uint64_t length,
688 		  spdk_blob_op_complete cb_fn, void *cb_arg)
689 {
690 	CU_ASSERT(blob == NULL);
691 	CU_ASSERT(channel == g_ch);
692 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
693 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
694 	cb_fn(cb_arg, 0);
695 }
696 
697 void
698 spdk_blob_io_write(struct spdk_blob *blob, struct spdk_io_channel *channel,
699 		   void *payload, uint64_t offset, uint64_t length,
700 		   spdk_blob_op_complete cb_fn, void *cb_arg)
701 {
702 	CU_ASSERT(blob == NULL);
703 	CU_ASSERT(channel == g_ch);
704 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
705 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
706 	cb_fn(cb_arg, 0);
707 }
708 
709 void
710 spdk_blob_io_unmap(struct spdk_blob *blob, struct spdk_io_channel *channel,
711 		   uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg)
712 {
713 	CU_ASSERT(blob == NULL);
714 	CU_ASSERT(channel == g_ch);
715 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
716 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
717 	cb_fn(cb_arg, 0);
718 }
719 
720 void
721 spdk_blob_io_write_zeroes(struct spdk_blob *blob, struct spdk_io_channel *channel,
722 			  uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg)
723 {
724 	CU_ASSERT(blob == NULL);
725 	CU_ASSERT(channel == g_ch);
726 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
727 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
728 	cb_fn(cb_arg, 0);
729 }
730 
731 void
732 spdk_blob_io_writev(struct spdk_blob *blob, struct spdk_io_channel *channel,
733 		    struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
734 		    spdk_blob_op_complete cb_fn, void *cb_arg)
735 {
736 	CU_ASSERT(blob == NULL);
737 	CU_ASSERT(channel == g_ch);
738 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
739 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
740 	cb_fn(cb_arg, 0);
741 }
742 
743 void
744 spdk_blob_io_writev_ext(struct spdk_blob *blob, struct spdk_io_channel *channel,
745 			struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
746 			spdk_blob_op_complete cb_fn, void *cb_arg,
747 			struct spdk_blob_ext_io_opts *io_opts)
748 {
749 	struct vbdev_lvol_io *lvol_io = (struct vbdev_lvol_io *)g_io->driver_ctx;
750 
751 	CU_ASSERT(blob == NULL);
752 	CU_ASSERT(channel == g_ch);
753 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
754 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
755 	CU_ASSERT(io_opts == &lvol_io->ext_io_opts);
756 	g_ext_api_called = true;
757 	cb_fn(cb_arg, 0);
758 }
759 
760 void
761 spdk_blob_io_readv(struct spdk_blob *blob, struct spdk_io_channel *channel,
762 		   struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
763 		   spdk_blob_op_complete cb_fn, void *cb_arg)
764 {
765 	CU_ASSERT(blob == NULL);
766 	CU_ASSERT(channel == g_ch);
767 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
768 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
769 	cb_fn(cb_arg, 0);
770 }
771 
772 void
773 spdk_blob_io_readv_ext(struct spdk_blob *blob, struct spdk_io_channel *channel,
774 		       struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
775 		       spdk_blob_op_complete cb_fn, void *cb_arg,
776 		       struct spdk_blob_ext_io_opts *io_opts)
777 {
778 	struct vbdev_lvol_io *lvol_io = (struct vbdev_lvol_io *)g_io->driver_ctx;
779 
780 	CU_ASSERT(blob == NULL);
781 	CU_ASSERT(channel == g_ch);
782 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
783 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
784 	CU_ASSERT(io_opts == &lvol_io->ext_io_opts);
785 	g_ext_api_called = true;
786 	cb_fn(cb_arg, 0);
787 }
788 
789 void
790 spdk_bdev_module_list_add(struct spdk_bdev_module *bdev_module)
791 {
792 }
793 
794 const char *
795 spdk_bdev_get_name(const struct spdk_bdev *bdev)
796 {
797 	return bdev->name;
798 }
799 
800 uint32_t
801 spdk_bdev_get_block_size(const struct spdk_bdev *bdev)
802 {
803 	return bdev->blocklen;
804 }
805 
806 uint64_t
807 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev)
808 {
809 	return bdev->blockcnt;
810 }
811 
812 int
813 spdk_bdev_register(struct spdk_bdev *vbdev)
814 {
815 	TAILQ_INIT(&vbdev->aliases);
816 
817 	g_registered_bdevs++;
818 	return 0;
819 }
820 
821 void
822 spdk_bdev_module_examine_done(struct spdk_bdev_module *module)
823 {
824 	SPDK_CU_ASSERT_FATAL(g_examine_done != true);
825 	g_examine_done = true;
826 }
827 
828 static struct spdk_lvol *
829 _lvol_create(struct spdk_lvol_store *lvs)
830 {
831 	struct spdk_lvol *lvol = calloc(1, sizeof(*lvol));
832 
833 	SPDK_CU_ASSERT_FATAL(lvol != NULL);
834 
835 	lvol->lvol_store = lvs;
836 	lvol->ref_count++;
837 	snprintf(lvol->unique_id, sizeof(lvol->unique_id), "%s", "UNIT_TEST_UUID");
838 
839 	TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link);
840 
841 	return lvol;
842 }
843 
844 int
845 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
846 		 bool thin_provision, enum lvol_clear_method clear_method, spdk_lvol_op_with_handle_complete cb_fn,
847 		 void *cb_arg)
848 {
849 	struct spdk_lvol *lvol;
850 
851 	lvol = _lvol_create(lvs);
852 	snprintf(lvol->name, sizeof(lvol->name), "%s", name);
853 	cb_fn(cb_arg, lvol, 0);
854 
855 	return 0;
856 }
857 
858 void
859 spdk_lvol_create_snapshot(struct spdk_lvol *lvol, const char *snapshot_name,
860 			  spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
861 {
862 	struct spdk_lvol *snap;
863 
864 	snap = _lvol_create(lvol->lvol_store);
865 	snprintf(snap->name, sizeof(snap->name), "%s", snapshot_name);
866 	cb_fn(cb_arg, snap, 0);
867 }
868 
869 void
870 spdk_lvol_create_clone(struct spdk_lvol *lvol, const char *clone_name,
871 		       spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
872 {
873 	struct spdk_lvol *clone;
874 
875 	clone = _lvol_create(lvol->lvol_store);
876 	snprintf(clone->name, sizeof(clone->name), "%s", clone_name);
877 	cb_fn(cb_arg, clone, 0);
878 }
879 
880 bool
881 spdk_lvs_notify_hotplug(const void *esnap_id, uint32_t id_len,
882 			spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
883 {
884 	struct spdk_uuid uuid = { 0 };
885 	char uuid_str[SPDK_UUID_STRING_LEN] = "bad";
886 
887 	CU_ASSERT(id_len == SPDK_UUID_STRING_LEN);
888 	CU_ASSERT(spdk_uuid_parse(&uuid, esnap_id) == 0);
889 	CU_ASSERT(spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &uuid) == 0);
890 	CU_ASSERT(strcmp(esnap_id, uuid_str) == 0);
891 
892 	return g_bdev_is_missing;
893 }
894 
895 static void
896 lvol_store_op_complete(void *cb_arg, int lvserrno)
897 {
898 	g_lvserrno = lvserrno;
899 	return;
900 }
901 
902 static void
903 lvol_store_op_with_handle_complete(void *cb_arg, struct spdk_lvol_store *lvs, int lvserrno)
904 {
905 	g_lvserrno = lvserrno;
906 	g_lvol_store = lvs;
907 	return;
908 }
909 
910 static void
911 vbdev_lvol_create_complete(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
912 {
913 	g_lvolerrno = lvolerrno;
914 	g_lvol = lvol;
915 }
916 
917 static void
918 vbdev_lvol_resize_complete(void *cb_arg, int lvolerrno)
919 {
920 	g_lvolerrno = lvolerrno;
921 }
922 
923 static void
924 vbdev_lvol_set_read_only_complete(void *cb_arg, int lvolerrno)
925 {
926 	g_lvolerrno = lvolerrno;
927 }
928 
929 static void
930 vbdev_lvol_rename_complete(void *cb_arg, int lvolerrno)
931 {
932 	g_lvolerrno = lvolerrno;
933 }
934 
935 static void
936 ut_lvs_destroy(void)
937 {
938 	int rc = 0;
939 	int sz = 10;
940 	struct spdk_lvol_store *lvs;
941 
942 	/* Lvol store is successfully created */
943 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
944 			      lvol_store_op_with_handle_complete, NULL);
945 	CU_ASSERT(rc == 0);
946 	CU_ASSERT(g_lvserrno == 0);
947 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
948 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
949 
950 	lvs = g_lvol_store;
951 	g_lvol_store = NULL;
952 
953 	spdk_uuid_generate(&lvs->uuid);
954 
955 	/* Successfully create lvol, which should be unloaded with lvs later */
956 	g_lvolerrno = -1;
957 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
958 			       NULL);
959 	CU_ASSERT(rc == 0);
960 	CU_ASSERT(g_lvolerrno == 0);
961 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
962 
963 	/* Unload lvol store */
964 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
965 	CU_ASSERT(g_lvserrno == 0);
966 	CU_ASSERT(g_lvol_store == NULL);
967 }
968 
969 static void
970 ut_lvol_init(void)
971 {
972 	struct spdk_lvol_store *lvs;
973 	int sz = 10;
974 	int rc;
975 
976 	/* Lvol store is successfully created */
977 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
978 			      lvol_store_op_with_handle_complete, NULL);
979 	CU_ASSERT(rc == 0);
980 	CU_ASSERT(g_lvserrno == 0);
981 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
982 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
983 	lvs = g_lvol_store;
984 
985 	/* Successful lvol create */
986 	g_lvolerrno = -1;
987 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
988 			       NULL);
989 	SPDK_CU_ASSERT_FATAL(rc == 0);
990 	CU_ASSERT(g_lvol != NULL);
991 	CU_ASSERT(g_lvolerrno == 0);
992 
993 	/* Successful lvol destroy */
994 	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
995 	CU_ASSERT(g_lvol == NULL);
996 
997 	/* Destroy lvol store */
998 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
999 	CU_ASSERT(g_lvserrno == 0);
1000 	CU_ASSERT(g_lvol_store == NULL);
1001 }
1002 
1003 static void
1004 ut_lvol_snapshot(void)
1005 {
1006 	struct spdk_lvol_store *lvs;
1007 	int sz = 10;
1008 	int rc;
1009 	struct spdk_lvol *lvol = NULL;
1010 
1011 	/* Lvol store is successfully created */
1012 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1013 			      lvol_store_op_with_handle_complete, NULL);
1014 	CU_ASSERT(rc == 0);
1015 	CU_ASSERT(g_lvserrno == 0);
1016 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1017 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1018 	lvs = g_lvol_store;
1019 
1020 	/* Successful lvol create */
1021 	g_lvolerrno = -1;
1022 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1023 			       NULL);
1024 	SPDK_CU_ASSERT_FATAL(rc == 0);
1025 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1026 	CU_ASSERT(g_lvolerrno == 0);
1027 
1028 	lvol = g_lvol;
1029 
1030 	/* Successful snap create */
1031 	vbdev_lvol_create_snapshot(lvol, "snap", vbdev_lvol_create_complete, NULL);
1032 	SPDK_CU_ASSERT_FATAL(rc == 0);
1033 	CU_ASSERT(g_lvol != NULL);
1034 	CU_ASSERT(g_lvolerrno == 0);
1035 
1036 	/* Successful lvol destroy */
1037 	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
1038 	CU_ASSERT(g_lvol == NULL);
1039 
1040 	/* Successful snap destroy */
1041 	g_lvol = lvol;
1042 	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
1043 	CU_ASSERT(g_lvol == NULL);
1044 
1045 	/* Destroy lvol store */
1046 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
1047 	CU_ASSERT(g_lvserrno == 0);
1048 	CU_ASSERT(g_lvol_store == NULL);
1049 }
1050 
1051 static void
1052 ut_lvol_clone(void)
1053 {
1054 	struct spdk_lvol_store *lvs;
1055 	int sz = 10;
1056 	int rc;
1057 	struct spdk_lvol *lvol = NULL;
1058 	struct spdk_lvol *snap = NULL;
1059 	struct spdk_lvol *clone = NULL;
1060 
1061 	/* Lvol store is successfully created */
1062 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1063 			      lvol_store_op_with_handle_complete, NULL);
1064 	CU_ASSERT(rc == 0);
1065 	CU_ASSERT(g_lvserrno == 0);
1066 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1067 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1068 	lvs = g_lvol_store;
1069 
1070 	/* Successful lvol create */
1071 	g_lvolerrno = -1;
1072 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1073 			       NULL);
1074 	SPDK_CU_ASSERT_FATAL(rc == 0);
1075 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1076 	CU_ASSERT(g_lvolerrno == 0);
1077 
1078 	lvol = g_lvol;
1079 
1080 	/* Successful snap create */
1081 	vbdev_lvol_create_snapshot(lvol, "snap", vbdev_lvol_create_complete, NULL);
1082 	SPDK_CU_ASSERT_FATAL(rc == 0);
1083 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1084 	CU_ASSERT(g_lvolerrno == 0);
1085 
1086 	snap = g_lvol;
1087 
1088 	/* Successful clone create */
1089 	vbdev_lvol_create_clone(snap, "clone", vbdev_lvol_create_complete, NULL);
1090 
1091 	SPDK_CU_ASSERT_FATAL(rc == 0);
1092 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1093 	CU_ASSERT(g_lvolerrno == 0);
1094 
1095 	clone = g_lvol;
1096 
1097 	/* Successful lvol destroy */
1098 	g_lvol = lvol;
1099 	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
1100 	CU_ASSERT(g_lvol == NULL);
1101 
1102 	/* Successful clone destroy */
1103 	g_lvol = clone;
1104 	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
1105 	CU_ASSERT(g_lvol == NULL);
1106 
1107 	/* Successful lvol destroy */
1108 	g_lvol = snap;
1109 	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
1110 	CU_ASSERT(g_lvol == NULL);
1111 
1112 	/* Destroy lvol store */
1113 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
1114 	CU_ASSERT(g_lvserrno == 0);
1115 	CU_ASSERT(g_lvol_store == NULL);
1116 }
1117 
1118 static void
1119 ut_lvol_hotremove(void)
1120 {
1121 	int rc = 0;
1122 
1123 	lvol_store_initialize_fail = false;
1124 	lvol_store_initialize_cb_fail = false;
1125 	lvol_already_opened = false;
1126 
1127 	/* Lvol store is successfully created */
1128 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1129 			      lvol_store_op_with_handle_complete, NULL);
1130 	CU_ASSERT(rc == 0);
1131 	CU_ASSERT(g_lvserrno == 0);
1132 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1133 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1134 
1135 	/* Hot remove callback with NULL - stability check */
1136 	vbdev_lvs_hotremove_cb(NULL);
1137 
1138 	/* Hot remove lvs on bdev removal */
1139 	vbdev_lvs_hotremove_cb(&g_bdev);
1140 
1141 	CU_ASSERT(g_lvol_store == NULL);
1142 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
1143 
1144 }
1145 
1146 static void
1147 ut_lvol_examine_config(void)
1148 {
1149 	/* No esnap clone needs the bdev. */
1150 	g_bdev_is_missing = false;
1151 	g_examine_done = false;
1152 	vbdev_lvs_examine_config(&g_bdev);
1153 	CU_ASSERT(g_examine_done);
1154 
1155 	g_bdev_is_missing = true;
1156 	g_examine_done = false;
1157 	vbdev_lvs_examine_config(&g_bdev);
1158 	CU_ASSERT(g_examine_done);
1159 
1160 	g_examine_done = false;
1161 }
1162 
1163 static void
1164 ut_lvs_examine_check(bool success)
1165 {
1166 	struct lvol_store_bdev *lvs_bdev;
1167 
1168 	/* Examine was finished regardless of result */
1169 	CU_ASSERT(g_examine_done == true);
1170 	g_examine_done = false;
1171 
1172 	if (success) {
1173 		SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_spdk_lvol_pairs));
1174 		lvs_bdev = TAILQ_FIRST(&g_spdk_lvol_pairs);
1175 		SPDK_CU_ASSERT_FATAL(lvs_bdev != NULL);
1176 		g_lvol_store = lvs_bdev->lvs;
1177 		SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1178 		SPDK_CU_ASSERT_FATAL(g_lvol_store->blobstore != NULL);
1179 		CU_ASSERT(g_lvol_store->blobstore->esnap_bs_dev_create != NULL);
1180 		CU_ASSERT(g_lvol_store->bs_dev != NULL);
1181 		CU_ASSERT(g_lvol_store->lvols_opened == spdk_min(g_num_lvols, g_registered_bdevs));
1182 	} else {
1183 		SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_spdk_lvol_pairs));
1184 		g_lvol_store = NULL;
1185 	}
1186 }
1187 
1188 static void
1189 ut_lvol_examine_disk(void)
1190 {
1191 	/* Examine unsuccessfully - bdev already opened */
1192 	g_lvserrno = -1;
1193 	lvol_already_opened = true;
1194 	vbdev_lvs_examine_disk(&g_bdev);
1195 	ut_lvs_examine_check(false);
1196 
1197 	/* Examine unsuccessfully - fail on lvol store */
1198 	g_lvserrno = -1;
1199 	lvol_already_opened = false;
1200 	vbdev_lvs_examine_disk(&g_bdev);
1201 	ut_lvs_examine_check(false);
1202 
1203 	/* Examine successfully
1204 	 * - one lvol fails to load
1205 	 * - lvs is loaded with no lvols present */
1206 	g_lvserrno = 0;
1207 	g_lvolerrno = -1;
1208 	g_num_lvols = 1;
1209 	lvol_already_opened = false;
1210 	g_registered_bdevs = 0;
1211 	vbdev_lvs_examine_disk(&g_bdev);
1212 	ut_lvs_examine_check(true);
1213 	CU_ASSERT(g_registered_bdevs == 0);
1214 	CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols));
1215 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
1216 	CU_ASSERT(g_lvserrno == 0);
1217 	CU_ASSERT(g_lvol_store == NULL);
1218 
1219 	/* Examine successfully */
1220 	g_lvserrno = 0;
1221 	g_lvolerrno = 0;
1222 	g_registered_bdevs = 0;
1223 	lvol_already_opened = false;
1224 	vbdev_lvs_examine_disk(&g_bdev);
1225 	ut_lvs_examine_check(true);
1226 	CU_ASSERT(g_registered_bdevs != 0);
1227 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols));
1228 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
1229 	CU_ASSERT(g_lvserrno == 0);
1230 
1231 	/* Examine multiple lvols successfully */
1232 	g_num_lvols = 4;
1233 	g_registered_bdevs = 0;
1234 	lvol_already_opened = false;
1235 	vbdev_lvs_examine_disk(&g_bdev);
1236 	ut_lvs_examine_check(true);
1237 	CU_ASSERT(g_registered_bdevs == g_num_lvols);
1238 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols));
1239 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
1240 	CU_ASSERT(g_lvserrno == 0);
1241 
1242 	/* Examine multiple lvols successfully - fail one with -ENOMEM on lvol open */
1243 	g_num_lvols = 4;
1244 	g_lvol_open_enomem = 2;
1245 	g_registered_bdevs = 0;
1246 	lvol_already_opened = false;
1247 	vbdev_lvs_examine_disk(&g_bdev);
1248 	ut_lvs_examine_check(true);
1249 	CU_ASSERT(g_registered_bdevs == g_num_lvols);
1250 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols));
1251 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
1252 	CU_ASSERT(g_lvserrno == 0);
1253 }
1254 
1255 static void
1256 ut_lvol_rename(void)
1257 {
1258 	struct spdk_lvol_store *lvs;
1259 	struct spdk_lvol *lvol;
1260 	struct spdk_lvol *lvol2;
1261 	int sz = 10;
1262 	int rc;
1263 
1264 	/* Lvol store is successfully created */
1265 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1266 			      lvol_store_op_with_handle_complete, NULL);
1267 	CU_ASSERT(rc == 0);
1268 	CU_ASSERT(g_lvserrno == 0);
1269 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1270 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1271 	lvs = g_lvol_store;
1272 
1273 	/* Successful lvols create */
1274 	g_lvolerrno = -1;
1275 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1276 			       NULL);
1277 	SPDK_CU_ASSERT_FATAL(rc == 0);
1278 	CU_ASSERT(g_lvol != NULL);
1279 	CU_ASSERT(g_lvolerrno == 0);
1280 	lvol = g_lvol;
1281 
1282 	g_lvolerrno = -1;
1283 	rc = vbdev_lvol_create(lvs, "lvol2", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1284 			       NULL);
1285 	SPDK_CU_ASSERT_FATAL(rc == 0);
1286 	CU_ASSERT(g_lvol != NULL);
1287 	CU_ASSERT(g_lvolerrno == 0);
1288 	lvol2 = g_lvol;
1289 
1290 	/* Successful rename lvol */
1291 	vbdev_lvol_rename(lvol, "new_lvol_name", vbdev_lvol_rename_complete, NULL);
1292 	SPDK_CU_ASSERT_FATAL(g_lvolerrno == 0);
1293 	CU_ASSERT_STRING_EQUAL(lvol->name, "new_lvol_name");
1294 
1295 	/* Renaming lvol with name already existing */
1296 	g_bdev_alias_already_exists = true;
1297 	vbdev_lvol_rename(lvol2, "new_lvol_name", vbdev_lvol_rename_complete, NULL);
1298 	g_bdev_alias_already_exists = false;
1299 	SPDK_CU_ASSERT_FATAL(g_lvolerrno != 0);
1300 	CU_ASSERT_STRING_NOT_EQUAL(lvol2->name, "new_lvol_name");
1301 
1302 	/* Renaming lvol with it's own name */
1303 	vbdev_lvol_rename(lvol, "new_lvol_name", vbdev_lvol_rename_complete, NULL);
1304 	SPDK_CU_ASSERT_FATAL(g_lvolerrno == 0);
1305 	CU_ASSERT_STRING_EQUAL(lvol->name, "new_lvol_name");
1306 
1307 	/* Successful lvols destroy */
1308 	vbdev_lvol_destroy(lvol, lvol_store_op_complete, NULL);
1309 	CU_ASSERT(g_lvol == NULL);
1310 
1311 	vbdev_lvol_destroy(lvol2, lvol_store_op_complete, NULL);
1312 	CU_ASSERT(g_lvol == NULL);
1313 
1314 	/* Destroy lvol store */
1315 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
1316 	CU_ASSERT(g_lvserrno == 0);
1317 	CU_ASSERT(g_lvol_store == NULL);
1318 }
1319 
1320 static void
1321 ut_bdev_finish(void)
1322 {
1323 	struct spdk_lvol_store *lvs;
1324 	struct spdk_lvol *lvol;
1325 	struct spdk_lvol *lvol2;
1326 	int sz = 10;
1327 	int rc;
1328 
1329 	/* Scenario 1
1330 	 * Test unload of lvs with no lvols during bdev finish. */
1331 
1332 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1333 			      lvol_store_op_with_handle_complete, NULL);
1334 	CU_ASSERT(rc == 0);
1335 	CU_ASSERT(g_lvserrno == 0);
1336 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1337 	lvs = g_lvol_store;
1338 
1339 	/* Start bdev finish */
1340 	vbdev_lvs_fini_start();
1341 	CU_ASSERT(g_shutdown_started == true);
1342 
1343 	/* During shutdown, lvs with no lvols should be unloaded */
1344 	CU_ASSERT(g_lvol_store == NULL);
1345 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
1346 
1347 	/* Revert module state back to normal */
1348 	g_shutdown_started = false;
1349 
1350 	/* Scenario 2
1351 	 * Test creating lvs with two lvols. Delete first lvol explicitly,
1352 	 * then start bdev finish. This should unload the remaining lvol and
1353 	 * lvol store. */
1354 
1355 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1356 			      lvol_store_op_with_handle_complete, NULL);
1357 	CU_ASSERT(rc == 0);
1358 	CU_ASSERT(g_lvserrno == 0);
1359 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1360 	lvs = g_lvol_store;
1361 
1362 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT,
1363 			       vbdev_lvol_create_complete, NULL);
1364 	SPDK_CU_ASSERT_FATAL(rc == 0);
1365 	CU_ASSERT(g_lvol != NULL);
1366 	CU_ASSERT(g_lvolerrno == 0);
1367 	lvol = g_lvol;
1368 
1369 	rc = vbdev_lvol_create(lvs, "lvol2", sz, false, LVOL_CLEAR_WITH_DEFAULT,
1370 			       vbdev_lvol_create_complete, NULL);
1371 	SPDK_CU_ASSERT_FATAL(rc == 0);
1372 	CU_ASSERT(g_lvol != NULL);
1373 	CU_ASSERT(g_lvolerrno == 0);
1374 	lvol2 = g_lvol;
1375 
1376 	/* Destroy explicitly first lvol */
1377 	vbdev_lvol_destroy(lvol, lvol_store_op_complete, NULL);
1378 	CU_ASSERT(g_lvol == NULL);
1379 	CU_ASSERT(g_lvolerrno == 0);
1380 
1381 	/* Start bdev finish and unregister remaining lvol */
1382 	vbdev_lvs_fini_start();
1383 	CU_ASSERT(g_shutdown_started == true);
1384 	spdk_bdev_unregister(lvol2->bdev, _spdk_bdev_unregister_cb, NULL);
1385 
1386 	/* During shutdown, removal of last lvol should unload lvs */
1387 	CU_ASSERT(g_lvol_store == NULL);
1388 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
1389 
1390 	/* Revert module state back to normal */
1391 	g_shutdown_started = false;
1392 }
1393 
1394 static void
1395 ut_lvol_resize(void)
1396 {
1397 	struct spdk_lvol_store *lvs;
1398 	struct spdk_lvol *lvol;
1399 	int sz = 10;
1400 	int rc = 0;
1401 
1402 	/* Lvol store is successfully created */
1403 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1404 			      lvol_store_op_with_handle_complete, NULL);
1405 	CU_ASSERT(rc == 0);
1406 	CU_ASSERT(g_lvserrno == 0);
1407 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1408 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1409 	lvs = g_lvol_store;
1410 
1411 	/* Successful lvol create */
1412 	g_lvolerrno = -1;
1413 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1414 			       NULL);
1415 	CU_ASSERT(rc == 0);
1416 	CU_ASSERT(g_lvolerrno == 0);
1417 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1418 	lvol = g_lvol;
1419 
1420 	/* Successful lvol resize */
1421 	g_lvolerrno = -1;
1422 	vbdev_lvol_resize(lvol, 20, vbdev_lvol_resize_complete, NULL);
1423 	CU_ASSERT(g_lvolerrno == 0);
1424 	CU_ASSERT(lvol->bdev->blockcnt == 20 * g_cluster_size / lvol->bdev->blocklen);
1425 
1426 	/* Resize with NULL lvol */
1427 	vbdev_lvol_resize(NULL, 20, vbdev_lvol_resize_complete, NULL);
1428 	CU_ASSERT(g_lvolerrno != 0);
1429 
1430 	/* Successful lvol destroy */
1431 	vbdev_lvol_destroy(lvol, lvol_store_op_complete, NULL);
1432 	CU_ASSERT(g_lvol == NULL);
1433 
1434 	/* Destroy lvol store */
1435 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
1436 	CU_ASSERT(g_lvserrno == 0);
1437 	CU_ASSERT(g_lvol_store == NULL);
1438 }
1439 
1440 static void
1441 ut_lvol_set_read_only(void)
1442 {
1443 	struct spdk_lvol_store *lvs;
1444 	struct spdk_lvol *lvol;
1445 	int sz = 10;
1446 	int rc = 0;
1447 
1448 	/* Lvol store is successfully created */
1449 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1450 			      lvol_store_op_with_handle_complete, NULL);
1451 	CU_ASSERT(rc == 0);
1452 	CU_ASSERT(g_lvserrno == 0);
1453 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1454 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1455 	lvs = g_lvol_store;
1456 
1457 	/* Successful lvol create */
1458 	g_lvolerrno = -1;
1459 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1460 			       NULL);
1461 	CU_ASSERT(rc == 0);
1462 	CU_ASSERT(g_lvolerrno == 0);
1463 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1464 	lvol = g_lvol;
1465 
1466 	/* Successful set lvol as read only */
1467 	g_lvolerrno = -1;
1468 	vbdev_lvol_set_read_only(lvol, vbdev_lvol_set_read_only_complete, NULL);
1469 	CU_ASSERT(g_lvolerrno == 0);
1470 
1471 	/* Successful lvol destroy */
1472 	vbdev_lvol_destroy(lvol, lvol_store_op_complete, NULL);
1473 	CU_ASSERT(g_lvol == NULL);
1474 
1475 	/* Destroy lvol store */
1476 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
1477 	CU_ASSERT(g_lvserrno == 0);
1478 	CU_ASSERT(g_lvol_store == NULL);
1479 }
1480 
1481 static void
1482 ut_lvs_unload(void)
1483 {
1484 	int rc = 0;
1485 	int sz = 10;
1486 	struct spdk_lvol_store *lvs;
1487 
1488 	/* Lvol store is successfully created */
1489 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1490 			      lvol_store_op_with_handle_complete, NULL);
1491 	CU_ASSERT(rc == 0);
1492 	CU_ASSERT(g_lvserrno == 0);
1493 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1494 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1495 
1496 	lvs = g_lvol_store;
1497 	g_lvol_store = NULL;
1498 
1499 	spdk_uuid_generate(&lvs->uuid);
1500 
1501 	/* Successfully create lvol, which should be destroyed with lvs later */
1502 	g_lvolerrno = -1;
1503 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1504 			       NULL);
1505 	CU_ASSERT(rc == 0);
1506 	CU_ASSERT(g_lvolerrno == 0);
1507 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1508 
1509 	/* Unload lvol store */
1510 	vbdev_lvs_unload(lvs, lvol_store_op_complete, NULL);
1511 	CU_ASSERT(g_lvserrno == 0);
1512 	CU_ASSERT(g_lvol_store == NULL);
1513 	CU_ASSERT(g_lvol != NULL);
1514 }
1515 
1516 static void
1517 ut_lvs_init(void)
1518 {
1519 	int rc = 0;
1520 	struct spdk_lvol_store *lvs;
1521 
1522 	/* spdk_lvs_init() fails */
1523 	lvol_store_initialize_fail = true;
1524 
1525 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1526 			      lvol_store_op_with_handle_complete, NULL);
1527 	CU_ASSERT(rc != 0);
1528 	CU_ASSERT(g_lvserrno == 0);
1529 	CU_ASSERT(g_lvol_store == NULL);
1530 
1531 	lvol_store_initialize_fail = false;
1532 
1533 	/* spdk_lvs_init_cb() fails */
1534 	lvol_store_initialize_cb_fail = true;
1535 
1536 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1537 			      lvol_store_op_with_handle_complete, NULL);
1538 	CU_ASSERT(rc == 0);
1539 	CU_ASSERT(g_lvserrno != 0);
1540 	CU_ASSERT(g_lvol_store == NULL);
1541 
1542 	lvol_store_initialize_cb_fail = false;
1543 
1544 	/* Lvol store is successfully created */
1545 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1546 			      lvol_store_op_with_handle_complete, NULL);
1547 	CU_ASSERT(rc == 0);
1548 	CU_ASSERT(g_lvserrno == 0);
1549 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1550 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1551 
1552 	lvs = g_lvol_store;
1553 	g_lvol_store = NULL;
1554 
1555 	/* Bdev with lvol store already claimed */
1556 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1557 			      lvol_store_op_with_handle_complete, NULL);
1558 	CU_ASSERT(rc != 0);
1559 	CU_ASSERT(g_lvserrno == 0);
1560 	CU_ASSERT(g_lvol_store == NULL);
1561 
1562 	/* Destruct lvol store */
1563 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
1564 	CU_ASSERT(g_lvserrno == 0);
1565 	CU_ASSERT(g_lvol_store == NULL);
1566 }
1567 
1568 static void
1569 ut_vbdev_lvol_get_io_channel(void)
1570 {
1571 	struct spdk_io_channel *ch;
1572 
1573 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
1574 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1575 
1576 	ch = vbdev_lvol_get_io_channel(g_lvol);
1577 	CU_ASSERT(ch == g_ch);
1578 
1579 	free(g_lvol);
1580 }
1581 
1582 static void
1583 ut_vbdev_lvol_io_type_supported(void)
1584 {
1585 	struct spdk_lvol *lvol;
1586 	bool ret;
1587 
1588 	lvol = calloc(1, sizeof(struct spdk_lvol));
1589 	SPDK_CU_ASSERT_FATAL(lvol != NULL);
1590 
1591 	g_blob_is_read_only = false;
1592 
1593 	/* Supported types */
1594 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ);
1595 	CU_ASSERT(ret == true);
1596 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
1597 	CU_ASSERT(ret == true);
1598 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
1599 	CU_ASSERT(ret == true);
1600 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP);
1601 	CU_ASSERT(ret == true);
1602 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
1603 	CU_ASSERT(ret == true);
1604 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_DATA);
1605 	CU_ASSERT(ret == true);
1606 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_HOLE);
1607 	CU_ASSERT(ret == true);
1608 
1609 	/* Unsupported types */
1610 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH);
1611 	CU_ASSERT(ret == false);
1612 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN);
1613 	CU_ASSERT(ret == false);
1614 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO);
1615 	CU_ASSERT(ret == false);
1616 
1617 	g_blob_is_read_only = true;
1618 
1619 	/* Supported types */
1620 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ);
1621 	CU_ASSERT(ret == true);
1622 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
1623 	CU_ASSERT(ret == true);
1624 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_DATA);
1625 	CU_ASSERT(ret == true);
1626 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_HOLE);
1627 	CU_ASSERT(ret == true);
1628 
1629 	/* Unsupported types */
1630 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
1631 	CU_ASSERT(ret == false);
1632 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP);
1633 	CU_ASSERT(ret == false);
1634 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
1635 	CU_ASSERT(ret == false);
1636 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH);
1637 	CU_ASSERT(ret == false);
1638 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN);
1639 	CU_ASSERT(ret == false);
1640 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO);
1641 	CU_ASSERT(ret == false);
1642 
1643 	free(lvol);
1644 }
1645 
1646 static void
1647 ut_lvol_read_write(void)
1648 {
1649 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + vbdev_lvs_get_ctx_size());
1650 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
1651 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
1652 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
1653 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
1654 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1655 
1656 	g_io->bdev = g_base_bdev;
1657 	g_io->bdev->ctxt = g_lvol;
1658 	g_io->u.bdev.offset_blocks = 20;
1659 	g_io->u.bdev.num_blocks = 20;
1660 
1661 	lvol_read(g_ch, g_io);
1662 	CU_ASSERT(g_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS);
1663 
1664 	lvol_write(g_lvol, g_ch, g_io);
1665 	CU_ASSERT(g_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS);
1666 
1667 	g_ext_api_called = false;
1668 	lvol_read(g_ch, g_io);
1669 	CU_ASSERT(g_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS);
1670 	CU_ASSERT(g_ext_api_called == true);
1671 	g_ext_api_called = false;
1672 
1673 	lvol_write(g_lvol, g_ch, g_io);
1674 	CU_ASSERT(g_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS);
1675 	CU_ASSERT(g_ext_api_called == true);
1676 	g_ext_api_called = false;
1677 
1678 	free(g_io);
1679 	free(g_base_bdev);
1680 	free(g_lvol);
1681 }
1682 
1683 static void
1684 ut_vbdev_lvol_submit_request(void)
1685 {
1686 	struct spdk_lvol request_lvol = {};
1687 	g_io = calloc(1, sizeof(struct spdk_bdev_io));
1688 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
1689 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
1690 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
1691 	g_io->bdev = g_base_bdev;
1692 
1693 	g_io->type = SPDK_BDEV_IO_TYPE_READ;
1694 	g_base_bdev->ctxt = &request_lvol;
1695 	vbdev_lvol_submit_request(g_ch, g_io);
1696 
1697 	free(g_io);
1698 	free(g_base_bdev);
1699 }
1700 
1701 static void
1702 ut_lvs_rename(void)
1703 {
1704 	int rc = 0;
1705 	int sz = 10;
1706 	struct spdk_lvol_store *lvs;
1707 
1708 	/* Lvol store is successfully created */
1709 	rc = vbdev_lvs_create("bdev", "old_lvs_name", 0, LVS_CLEAR_WITH_UNMAP, 0,
1710 			      lvol_store_op_with_handle_complete, NULL);
1711 	CU_ASSERT(rc == 0);
1712 	CU_ASSERT(g_lvserrno == 0);
1713 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1714 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1715 
1716 	lvs = g_lvol_store;
1717 	g_lvol_store = NULL;
1718 
1719 	g_base_bdev = calloc(1, sizeof(*g_base_bdev));
1720 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
1721 
1722 	/* Successfully create lvol, which should be destroyed with lvs later */
1723 	g_lvolerrno = -1;
1724 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, LVOL_CLEAR_WITH_DEFAULT, vbdev_lvol_create_complete,
1725 			       NULL);
1726 	CU_ASSERT(rc == 0);
1727 	CU_ASSERT(g_lvolerrno == 0);
1728 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1729 
1730 	/* Trying to rename lvs with lvols created */
1731 	vbdev_lvs_rename(lvs, "new_lvs_name", lvol_store_op_complete, NULL);
1732 	CU_ASSERT(g_lvserrno == 0);
1733 	CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name");
1734 	CU_ASSERT_STRING_EQUAL(TAILQ_FIRST(&g_lvol->bdev->aliases)->alias.name, "new_lvs_name/lvol");
1735 
1736 	/* Trying to rename lvs with name already used by another lvs */
1737 	/* This is a bdev_lvol test, so g_lvs_with_name_already_exists simulates
1738 	 * existing lvs with name 'another_new_lvs_name' and this name in fact is not compared */
1739 	g_lvs_with_name_already_exists = true;
1740 	vbdev_lvs_rename(lvs, "another_new_lvs_name", lvol_store_op_complete, NULL);
1741 	CU_ASSERT(g_lvserrno == -EEXIST);
1742 	CU_ASSERT_STRING_EQUAL(lvs->name, "new_lvs_name");
1743 	CU_ASSERT_STRING_EQUAL(TAILQ_FIRST(&g_lvol->bdev->aliases)->alias.name, "new_lvs_name/lvol");
1744 	g_lvs_with_name_already_exists = false;
1745 
1746 	/* Unload lvol store */
1747 	g_lvol_store = lvs;
1748 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
1749 	CU_ASSERT(g_lvserrno == 0);
1750 	CU_ASSERT(g_lvol_store == NULL);
1751 
1752 	free(g_base_bdev->name);
1753 	free(g_base_bdev);
1754 }
1755 
1756 static void
1757 ut_lvol_seek(void)
1758 {
1759 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + vbdev_lvs_get_ctx_size());
1760 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
1761 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
1762 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
1763 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
1764 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
1765 
1766 	g_io->bdev = g_base_bdev;
1767 	g_io->bdev->ctxt = g_lvol;
1768 
1769 	/* Data found */
1770 	g_io->u.bdev.offset_blocks = 10;
1771 	lvol_seek_data(g_lvol, g_io);
1772 	CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
1773 	CU_ASSERT(g_io->u.bdev.seek.offset == g_blob_allocated_io_unit_offset);
1774 
1775 	/* Data not found */
1776 	g_io->u.bdev.offset_blocks = 30;
1777 	lvol_seek_data(g_lvol, g_io);
1778 	CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
1779 	CU_ASSERT(g_io->u.bdev.seek.offset == UINT64_MAX);
1780 
1781 	/* Hole found */
1782 	g_io->u.bdev.offset_blocks = 10;
1783 	lvol_seek_hole(g_lvol, g_io);
1784 	CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
1785 	CU_ASSERT(g_io->u.bdev.seek.offset == 10);
1786 
1787 	/* Hole not found */
1788 	g_io->u.bdev.offset_blocks = 30;
1789 	lvol_seek_hole(g_lvol, g_io);
1790 	CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
1791 	CU_ASSERT(g_io->u.bdev.seek.offset == UINT64_MAX);
1792 
1793 	free(g_io);
1794 	free(g_base_bdev);
1795 	free(g_lvol);
1796 }
1797 
1798 static void
1799 ut_esnap_dev_create(void)
1800 {
1801 	struct spdk_lvol_store lvs = { 0 };
1802 	struct spdk_lvol lvol = { 0 };
1803 	struct spdk_blob blob = { 0 };
1804 	struct spdk_bdev bdev = { 0 };
1805 	const char uuid_str[SPDK_UUID_STRING_LEN] = "a27fd8fe-d4b9-431e-a044-271016228ce4";
1806 	char bad_uuid_str[SPDK_UUID_STRING_LEN] = "a27fd8fe-d4b9-431e-a044-271016228ce4";
1807 	char *unterminated;
1808 	size_t len;
1809 	struct spdk_bs_dev *bs_dev = NULL;
1810 	int rc;
1811 
1812 	bdev.name = "bdev0";
1813 	spdk_uuid_parse(&bdev.uuid, uuid_str);
1814 
1815 	/* NULL esnap_id */
1816 	rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, NULL, 0, &bs_dev);
1817 	CU_ASSERT(rc == -EINVAL);
1818 	CU_ASSERT(bs_dev == NULL);
1819 
1820 	/* Unterminated UUID: asan should catch reads past end of allocated buffer. */
1821 	len = strlen(uuid_str);
1822 	unterminated = calloc(1, len);
1823 	SPDK_CU_ASSERT_FATAL(unterminated != NULL);
1824 	memcpy(unterminated, uuid_str, len);
1825 	rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, unterminated, len, &bs_dev);
1826 	CU_ASSERT(rc == -EINVAL);
1827 	CU_ASSERT(bs_dev == NULL);
1828 
1829 	/* Invaid UUID but the right length is invalid */
1830 	bad_uuid_str[2] = 'z';
1831 	rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, bad_uuid_str, sizeof(uuid_str),
1832 					 &bs_dev);
1833 	CU_ASSERT(rc == -EINVAL);
1834 	CU_ASSERT(bs_dev == NULL);
1835 
1836 	/* Bdev not found */
1837 	g_base_bdev = NULL;
1838 	MOCK_SET(spdk_blob_is_degraded, true);
1839 	rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, uuid_str, sizeof(uuid_str), &bs_dev);
1840 	CU_ASSERT(rc == 0);
1841 	SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
1842 	CU_ASSERT(bs_dev->destroy == bs_dev_degraded_destroy);
1843 	bs_dev->destroy(bs_dev);
1844 
1845 	/* Cannot get a claim */
1846 	/* TODO: This suggests we need a way to wait for a claim to be available. */
1847 	g_base_bdev = &bdev;
1848 	lvol_already_opened = true;
1849 	MOCK_SET(spdk_blob_is_degraded, true);
1850 	rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, uuid_str, sizeof(uuid_str), &bs_dev);
1851 	CU_ASSERT(rc == 0);
1852 	SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
1853 	CU_ASSERT(bs_dev->destroy == bs_dev_degraded_destroy);
1854 	bs_dev->destroy(bs_dev);
1855 
1856 	/* Happy path */
1857 	lvol_already_opened = false;
1858 	MOCK_SET(spdk_blob_is_degraded, false);
1859 	rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, uuid_str, sizeof(uuid_str), &bs_dev);
1860 	CU_ASSERT(rc == 0);
1861 	SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
1862 	CU_ASSERT(bs_dev->destroy == ut_bs_dev_destroy);
1863 	bs_dev->destroy(bs_dev);
1864 
1865 	g_base_bdev = NULL;
1866 	lvol_already_opened = false;
1867 	free(unterminated);
1868 	MOCK_CLEAR(spdk_blob_is_degraded);
1869 }
1870 
1871 static void
1872 ut_lvol_esnap_clone_bad_args(void)
1873 {
1874 	struct spdk_bdev bdev = { 0 };
1875 	struct spdk_lvol_store *lvs;
1876 	const char *esnap_uuid = "255f4236-9427-42d0-a9d1-aa17f37dd8db";
1877 	const char *esnap_name = "esnap1";
1878 	int rc;
1879 
1880 	/* Lvol store is successfully created */
1881 	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
1882 			      lvol_store_op_with_handle_complete, NULL);
1883 	CU_ASSERT(rc == 0);
1884 	CU_ASSERT(g_lvserrno == 0);
1885 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
1886 	CU_ASSERT(g_lvol_store->bs_dev != NULL);
1887 	lvs = g_lvol_store;
1888 
1889 	rc = spdk_uuid_parse(&bdev.uuid, esnap_uuid);
1890 	CU_ASSERT(rc == 0);
1891 	bdev.name = strdup(esnap_name);
1892 	SPDK_CU_ASSERT_FATAL(bdev.name != NULL);
1893 	bdev.blocklen = 512;
1894 	bdev.blockcnt = 8192;
1895 
1896 	g_base_bdev = &bdev;
1897 
1898 	/* Error when lvs is NULL */
1899 	g_lvolerrno = 0xbad;
1900 	vbdev_lvol_create_bdev_clone(esnap_uuid, NULL, "clone1", vbdev_lvol_create_complete, NULL);
1901 	CU_ASSERT(g_lvolerrno == -EINVAL);
1902 
1903 	/* Error when the bdev does not exist */
1904 	g_base_bdev = NULL;
1905 	g_lvolerrno = 0xbad;
1906 	vbdev_lvol_create_bdev_clone(esnap_uuid, lvs, "clone1", vbdev_lvol_create_complete, NULL);
1907 	CU_ASSERT(g_lvolerrno == -ENODEV);
1908 
1909 	/* Success when creating by bdev UUID */
1910 	g_base_bdev = &bdev;
1911 	g_lvolerrno = 0xbad;
1912 	vbdev_lvol_create_bdev_clone(esnap_uuid, lvs, "clone1", vbdev_lvol_create_complete, NULL);
1913 	CU_ASSERT(g_lvolerrno == 0);
1914 
1915 	/* Success when creating by bdev name */
1916 	g_lvolerrno = 0xbad;
1917 	vbdev_lvol_create_bdev_clone(esnap_name, lvs, "clone2", vbdev_lvol_create_complete, NULL);
1918 	CU_ASSERT(g_lvolerrno == 0);
1919 
1920 	g_lvol_store = lvs;
1921 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
1922 	CU_ASSERT(g_lvserrno == 0);
1923 	CU_ASSERT(g_lvol_store == NULL);
1924 
1925 	free(bdev.name);
1926 	g_base_bdev = NULL;
1927 }
1928 
1929 int
1930 main(int argc, char **argv)
1931 {
1932 	CU_pSuite	suite = NULL;
1933 	unsigned int	num_failures;
1934 
1935 	CU_set_error_action(CUEA_ABORT);
1936 	CU_initialize_registry();
1937 
1938 	suite = CU_add_suite("lvol", NULL, NULL);
1939 
1940 	CU_ADD_TEST(suite, ut_lvs_init);
1941 	CU_ADD_TEST(suite, ut_lvol_init);
1942 	CU_ADD_TEST(suite, ut_lvol_snapshot);
1943 	CU_ADD_TEST(suite, ut_lvol_clone);
1944 	CU_ADD_TEST(suite, ut_lvs_destroy);
1945 	CU_ADD_TEST(suite, ut_lvs_unload);
1946 	CU_ADD_TEST(suite, ut_lvol_resize);
1947 	CU_ADD_TEST(suite, ut_lvol_set_read_only);
1948 	CU_ADD_TEST(suite, ut_lvol_hotremove);
1949 	CU_ADD_TEST(suite, ut_vbdev_lvol_get_io_channel);
1950 	CU_ADD_TEST(suite, ut_vbdev_lvol_io_type_supported);
1951 	CU_ADD_TEST(suite, ut_lvol_read_write);
1952 	CU_ADD_TEST(suite, ut_vbdev_lvol_submit_request);
1953 	CU_ADD_TEST(suite, ut_lvol_examine_config);
1954 	CU_ADD_TEST(suite, ut_lvol_examine_disk);
1955 	CU_ADD_TEST(suite, ut_lvol_rename);
1956 	CU_ADD_TEST(suite, ut_bdev_finish);
1957 	CU_ADD_TEST(suite, ut_lvs_rename);
1958 	CU_ADD_TEST(suite, ut_lvol_seek);
1959 	CU_ADD_TEST(suite, ut_esnap_dev_create);
1960 	CU_ADD_TEST(suite, ut_lvol_esnap_clone_bad_args);
1961 
1962 	allocate_threads(1);
1963 	set_thread(0);
1964 
1965 	CU_basic_set_mode(CU_BRM_VERBOSE);
1966 	CU_basic_run_tests();
1967 	num_failures = CU_get_number_of_failures();
1968 	CU_cleanup_registry();
1969 
1970 	free_threads();
1971 
1972 	return num_failures;
1973 }
1974