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