xref: /spdk/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c (revision 161a3002750e4acd9e9da110b1dc70c0730e37e8)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk_cunit.h"
35 #include "spdk/string.h"
36 
37 #include "vbdev_lvol.c"
38 
39 #define SPDK_BS_PAGE_SIZE 0x1000
40 
41 int g_lvolerrno;
42 int g_lvserrno;
43 int g_cluster_size;
44 int g_registered_bdevs;
45 int g_num_lvols = 0;
46 struct spdk_lvol_store *g_lvs = NULL;
47 struct spdk_lvol *g_lvol = NULL;
48 struct lvol_store_bdev *g_lvs_bdev = NULL;
49 struct spdk_bdev *g_base_bdev = NULL;
50 struct spdk_bdev_io *g_io = NULL;
51 struct spdk_io_channel *g_ch = NULL;
52 struct lvol_task *g_task = NULL;
53 
54 static struct spdk_bdev g_bdev = {};
55 static struct spdk_bs_dev *g_bs_dev = NULL;
56 static struct spdk_lvol_store *g_lvol_store = NULL;
57 bool lvol_store_initialize_fail = false;
58 bool lvol_store_initialize_cb_fail = false;
59 bool lvol_already_opened = false;
60 bool g_examine_done = false;
61 
62 void
63 spdk_bdev_unregister_done(struct spdk_bdev *bdev, int bdeverrno)
64 {
65 }
66 
67 void
68 spdk_lvol_open(struct spdk_lvol *lvol, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
69 {
70 	cb_fn(cb_arg, lvol, g_lvolerrno);
71 }
72 
73 void
74 spdk_bs_md_close_blob(struct spdk_blob **b, spdk_blob_op_complete cb_fn, void *cb_arg)
75 {
76 }
77 
78 static struct spdk_lvol *_lvol_create(struct spdk_lvol_store *lvs);
79 
80 void
81 spdk_lvs_load(struct spdk_bs_dev *dev,
82 	      spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
83 {
84 	struct spdk_lvol_store *lvs;
85 	int i;
86 
87 	if (g_lvserrno == 0) {
88 		lvs = calloc(1, sizeof(*lvs));
89 		SPDK_CU_ASSERT_FATAL(lvs != NULL);
90 		TAILQ_INIT(&lvs->lvols);
91 		g_lvol_store = lvs;
92 		for (i = 0; i < g_num_lvols; i++) {
93 			_lvol_create(lvs);
94 		}
95 	}
96 
97 	cb_fn(cb_arg, g_lvol_store, g_lvserrno);
98 }
99 
100 int
101 spdk_bs_bdev_claim(struct spdk_bs_dev *bs_dev, struct spdk_bdev_module_if *module)
102 {
103 	if (lvol_already_opened == true)
104 		return -1;
105 
106 	lvol_already_opened = true;
107 
108 	return 0;
109 }
110 
111 void
112 spdk_vbdev_unregister(struct spdk_bdev *vbdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
113 {
114 	SPDK_CU_ASSERT_FATAL(vbdev != NULL);
115 	vbdev->fn_table->destruct(vbdev->ctxt);
116 }
117 
118 void
119 spdk_bdev_module_finish_done(void)
120 {
121 	return;
122 }
123 
124 uint64_t
125 spdk_bs_get_page_size(struct spdk_blob_store *bs)
126 {
127 	return SPDK_BS_PAGE_SIZE;
128 }
129 
130 static void
131 bdev_blob_destroy(struct spdk_bs_dev *bs_dev)
132 {
133 	CU_ASSERT(g_bs_dev != NULL);
134 	CU_ASSERT(bs_dev != NULL);
135 	CU_ASSERT(g_bs_dev == bs_dev);
136 	free(bs_dev);
137 	g_bs_dev = NULL;
138 	lvol_already_opened = false;
139 }
140 
141 struct spdk_bs_dev *
142 spdk_bdev_create_bs_dev(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx)
143 {
144 	struct spdk_bs_dev *bs_dev;
145 
146 	if (lvol_already_opened == true || bdev == NULL)
147 		return NULL;
148 
149 	bs_dev = calloc(1, sizeof(*bs_dev));
150 	SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
151 	bs_dev->destroy = bdev_blob_destroy;
152 
153 	CU_ASSERT(g_bs_dev == NULL);
154 	g_bs_dev = bs_dev;
155 	return bs_dev;
156 }
157 
158 void
159 spdk_lvs_opts_init(struct spdk_lvs_opts *opts)
160 {
161 }
162 
163 int
164 spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
165 	      spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
166 {
167 	struct spdk_lvol_store *lvs;
168 	int error = 0;
169 
170 	if (lvol_store_initialize_fail)
171 		return -1;
172 
173 	if (lvol_store_initialize_cb_fail) {
174 		bs_dev->destroy(bs_dev);
175 		lvs = NULL;
176 		error = -1;
177 	} else {
178 		lvs = calloc(1, sizeof(*lvs));
179 		SPDK_CU_ASSERT_FATAL(lvs != NULL);
180 		TAILQ_INIT(&lvs->lvols);
181 		lvs->bs_dev = bs_dev;
182 		error = 0;
183 	}
184 	cb_fn(cb_arg, lvs, error);
185 
186 	return 0;
187 }
188 
189 int
190 spdk_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg)
191 {
192 	struct spdk_lvol *lvol, *tmp;
193 
194 	TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
195 		TAILQ_REMOVE(&lvs->lvols, lvol, link);
196 		free(lvol->old_name);
197 		free(lvol);
198 	}
199 	g_lvol_store = NULL;
200 	free(lvs);
201 
202 	g_bs_dev->destroy(g_bs_dev);
203 
204 	if (cb_fn != NULL)
205 		cb_fn(cb_arg, 0);
206 
207 	return 0;
208 }
209 
210 int
211 spdk_lvs_destroy(struct spdk_lvol_store *lvs,  bool unmap_device, spdk_lvs_op_complete cb_fn,
212 		 void *cb_arg)
213 {
214 	struct spdk_lvol *lvol, *tmp;
215 
216 	TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
217 		TAILQ_REMOVE(&lvs->lvols, lvol, link);
218 		free(lvol->old_name);
219 		free(lvol);
220 	}
221 	g_lvol_store = NULL;
222 	free(lvs);
223 
224 	g_bs_dev->destroy(g_bs_dev);
225 
226 	if (cb_fn != NULL)
227 		cb_fn(cb_arg, 0);
228 
229 	return 0;
230 }
231 
232 int
233 spdk_lvol_resize(struct spdk_lvol *lvol, size_t sz,  spdk_lvol_op_complete cb_fn, void *cb_arg)
234 {
235 	cb_fn(cb_arg, 0);
236 
237 	return 0;
238 }
239 
240 uint64_t
241 spdk_bs_get_cluster_size(struct spdk_blob_store *bs)
242 {
243 	return g_cluster_size;
244 }
245 
246 struct spdk_bdev *
247 spdk_bdev_get_by_name(const char *bdev_name)
248 {
249 	if (!strcmp(g_base_bdev->name, bdev_name)) {
250 		return g_base_bdev;
251 	}
252 
253 	return NULL;
254 }
255 
256 void
257 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
258 {
259 	struct spdk_lvs_req *destruct_req;
260 	struct spdk_lvol *iter_lvol, *tmp;
261 	bool all_lvols_closed = true;
262 
263 	lvol->ref_count--;
264 
265 	TAILQ_FOREACH_SAFE(iter_lvol, &lvol->lvol_store->lvols, link, tmp) {
266 		if (iter_lvol->ref_count != 0) {
267 			all_lvols_closed = false;
268 		}
269 	}
270 
271 	destruct_req = lvol->lvol_store->destruct_req;
272 	if (destruct_req && all_lvols_closed == true) {
273 		if (!lvol->lvol_store->destruct) {
274 			spdk_lvs_unload(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg);
275 			free(destruct_req);
276 		}
277 	}
278 
279 	cb_fn(cb_arg, 0);
280 }
281 
282 void
283 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
284 {
285 	struct spdk_lvs_req *destruct_req;
286 
287 	SPDK_CU_ASSERT_FATAL(lvol == g_lvol);
288 
289 	if (lvol->ref_count != 0) {
290 		cb_fn(cb_arg, -ENODEV);
291 	}
292 
293 	TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link);
294 
295 	destruct_req = lvol->lvol_store->destruct_req;
296 	if (destruct_req && TAILQ_EMPTY(&lvol->lvol_store->lvols)) {
297 		if (!lvol->lvol_store->destruct) {
298 			spdk_lvs_unload(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg);
299 		} else {
300 			spdk_lvs_destroy(lvol->lvol_store, false, destruct_req->cb_fn, destruct_req->cb_arg);
301 			free(destruct_req);
302 		}
303 	}
304 	g_lvol = NULL;
305 	free(lvol->old_name);
306 	free(lvol);
307 
308 	cb_fn(cb_arg, 0);
309 }
310 
311 void
312 spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
313 {
314 }
315 
316 struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol)
317 {
318 	CU_ASSERT(lvol == g_lvol);
319 	return g_ch;
320 }
321 
322 void
323 spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len)
324 {
325 	CU_ASSERT(cb == lvol_read);
326 }
327 
328 void
329 spdk_bs_io_read_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
330 		     void *payload, uint64_t offset, uint64_t length,
331 		     spdk_blob_op_complete cb_fn, void *cb_arg)
332 {
333 }
334 
335 void
336 spdk_bs_io_write_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
337 		      void *payload, uint64_t offset, uint64_t length,
338 		      spdk_blob_op_complete cb_fn, void *cb_arg)
339 {
340 }
341 
342 void
343 spdk_bs_io_unmap_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
344 		      uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg)
345 {
346 	CU_ASSERT(blob == NULL);
347 	CU_ASSERT(channel == g_ch);
348 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
349 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
350 }
351 
352 void
353 spdk_bs_io_write_zeroes_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
354 			     uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg)
355 {
356 	CU_ASSERT(blob == NULL);
357 	CU_ASSERT(channel == g_ch);
358 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
359 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
360 }
361 
362 void
363 spdk_bs_io_writev_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
364 		       struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
365 		       spdk_blob_op_complete cb_fn, void *cb_arg)
366 {
367 	CU_ASSERT(blob == NULL);
368 	CU_ASSERT(channel == g_ch);
369 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
370 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
371 }
372 
373 void
374 spdk_bs_io_readv_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
375 		      struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
376 		      spdk_blob_op_complete cb_fn, void *cb_arg)
377 {
378 	CU_ASSERT(blob == NULL);
379 	CU_ASSERT(channel == g_ch);
380 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
381 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
382 }
383 
384 void
385 spdk_bs_io_flush_channel(struct spdk_io_channel *channel, spdk_blob_op_complete cb_fn, void *cb_arg)
386 {
387 }
388 
389 void
390 spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module)
391 {
392 }
393 
394 int
395 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
396 {
397 	return 0;
398 }
399 
400 int
401 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
402 {
403 	return 0;
404 }
405 
406 int
407 spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
408 {
409 	return 0;
410 }
411 
412 int
413 spdk_json_write_object_end(struct spdk_json_write_ctx *w)
414 {
415 	return 0;
416 }
417 
418 const char *
419 spdk_bdev_get_name(const struct spdk_bdev *bdev)
420 {
421 	return "test";
422 }
423 
424 int
425 spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs, int base_bdev_count)
426 {
427 	g_registered_bdevs++;
428 	return 0;
429 }
430 
431 void
432 spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module)
433 {
434 	g_examine_done = true;
435 }
436 
437 static struct spdk_lvol *
438 _lvol_create(struct spdk_lvol_store *lvs)
439 {
440 	struct spdk_lvol *lvol = calloc(1, sizeof(*lvol));
441 
442 	SPDK_CU_ASSERT_FATAL(lvol != NULL);
443 
444 	lvol->lvol_store = lvs;
445 	lvol->ref_count++;
446 	lvol->old_name = spdk_sprintf_alloc("%s", "UNIT_TEST_UUID");
447 	SPDK_CU_ASSERT_FATAL(lvol->old_name != NULL);
448 
449 	TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link);
450 
451 	return lvol;
452 }
453 
454 int
455 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
456 		 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
457 {
458 	struct spdk_lvol *lvol;
459 
460 	lvol = _lvol_create(lvs);
461 	cb_fn(cb_arg, lvol, 0);
462 
463 	return 0;
464 }
465 
466 static void
467 lvol_store_op_complete(void *cb_arg, int lvserrno)
468 {
469 	g_lvserrno = lvserrno;
470 	return;
471 }
472 
473 static void
474 lvol_store_op_with_handle_complete(void *cb_arg, struct spdk_lvol_store *lvs, int lvserrno)
475 {
476 	g_lvserrno = lvserrno;
477 	g_lvol_store = lvs;
478 	return;
479 }
480 
481 static void
482 vbdev_lvol_create_complete(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
483 {
484 	g_lvolerrno = lvolerrno;
485 	g_lvol = lvol;
486 }
487 
488 static void
489 vbdev_lvol_resize_complete(void *cb_arg, int lvolerrno)
490 {
491 	g_lvolerrno = lvolerrno;
492 }
493 
494 static void
495 ut_lvs_destroy(void)
496 {
497 	int rc = 0;
498 	int sz = 10;
499 	struct spdk_lvol_store *lvs;
500 
501 	/* Lvol store is succesfully created */
502 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
503 	CU_ASSERT(rc == 0);
504 	CU_ASSERT(g_lvserrno == 0);
505 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
506 	CU_ASSERT(g_bs_dev != NULL);
507 
508 	lvs = g_lvol_store;
509 	g_lvol_store = NULL;
510 
511 	uuid_generate_time(lvs->uuid);
512 
513 	/* Suuccessfully create lvol, which should be unloaded with lvs later */
514 	g_lvolerrno = -1;
515 	rc = vbdev_lvol_create(lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL);
516 	CU_ASSERT(rc == 0);
517 	CU_ASSERT(g_lvolerrno == 0);
518 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
519 
520 	/* Unload lvol store */
521 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
522 	CU_ASSERT(g_lvserrno == 0);
523 	CU_ASSERT(g_lvol_store == NULL);
524 }
525 
526 static void
527 ut_lvol_init(void)
528 {
529 	uuid_t wrong_uuid;
530 	int sz = 10;
531 	int rc;
532 
533 	g_lvs = calloc(1, sizeof(*g_lvs));
534 	SPDK_CU_ASSERT_FATAL(g_lvs != NULL);
535 	TAILQ_INIT(&g_lvs->lvols);
536 	g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev));
537 	SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL);
538 	g_base_bdev = calloc(1, sizeof(*g_base_bdev));
539 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
540 
541 	g_lvs_bdev->lvs = g_lvs;
542 	g_lvs_bdev->bdev = g_base_bdev;
543 
544 	uuid_generate_time(g_lvs->uuid);
545 	uuid_generate_time(wrong_uuid);
546 
547 	/* Incorrect uuid set */
548 	g_lvolerrno = 0;
549 	rc = vbdev_lvol_create(wrong_uuid, "lvol", sz, vbdev_lvol_create_complete, NULL);
550 	CU_ASSERT(rc == -ENODEV);
551 
552 	TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
553 
554 	/* Successful lvol create */
555 	g_lvolerrno = -1;
556 	rc = vbdev_lvol_create(g_lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL);
557 	SPDK_CU_ASSERT_FATAL(rc == 0);
558 	CU_ASSERT(g_lvol != NULL);
559 	CU_ASSERT(g_lvolerrno == 0);
560 
561 	/* Successful lvol destruct */
562 	vbdev_lvol_destruct(g_lvol);
563 	CU_ASSERT(g_lvol == NULL);
564 
565 	TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
566 
567 	free(g_lvs);
568 	free(g_lvs_bdev);
569 	free(g_base_bdev);
570 
571 
572 }
573 
574 static void
575 ut_lvol_hotremove(void)
576 {
577 	int rc = 0;
578 
579 	lvol_store_initialize_fail = false;
580 	lvol_store_initialize_cb_fail = false;
581 	lvol_already_opened = false;
582 	g_bs_dev = NULL;
583 
584 	/* Lvol store is succesfully created */
585 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
586 	CU_ASSERT(rc == 0);
587 	CU_ASSERT(g_lvserrno == 0);
588 	CU_ASSERT(g_lvol_store != NULL);
589 	CU_ASSERT(g_bs_dev != NULL);
590 
591 	/* Hot remove callback with NULL - stability check */
592 	vbdev_lvs_hotremove_cb(NULL);
593 
594 	/* Hot remove lvs on bdev removal */
595 	vbdev_lvs_hotremove_cb(&g_bdev);
596 
597 	CU_ASSERT(g_lvol_store == NULL);
598 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
599 
600 }
601 
602 static void
603 ut_lvol_examine(void)
604 {
605 	struct spdk_bdev *bdev;
606 
607 	lvol_already_opened = false;
608 	g_bs_dev = NULL;
609 	g_lvserrno = 0;
610 	g_examine_done = false;
611 
612 	/* Examine with NULL bdev */
613 	vbdev_lvs_examine(NULL);
614 	CU_ASSERT(g_bs_dev == NULL);
615 	CU_ASSERT(g_lvol_store == NULL);
616 	CU_ASSERT(g_examine_done == true);
617 
618 	/* Examine unsuccessfully - bdev already opened */
619 	g_bs_dev = NULL;
620 	g_examine_done = false;
621 	g_lvserrno = -1;
622 	lvol_already_opened = true;
623 	vbdev_lvs_examine(&g_bdev);
624 	CU_ASSERT(g_bs_dev == NULL);
625 	CU_ASSERT(g_lvol_store == NULL);
626 	CU_ASSERT(g_examine_done == true);
627 
628 	/* Examine unsuccessfully - fail on lvol store */
629 	g_bs_dev = NULL;
630 	g_examine_done = false;
631 	g_lvserrno = -1;
632 	lvol_already_opened = false;
633 	vbdev_lvs_examine(&g_bdev);
634 	CU_ASSERT(g_bs_dev != NULL);
635 	CU_ASSERT(g_lvol_store == NULL);
636 	CU_ASSERT(g_examine_done == true);
637 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
638 	free(g_bs_dev);
639 
640 	/* Examine unsuccesfully - fail on lvol load */
641 	g_bs_dev = NULL;
642 	g_lvserrno = 0;
643 	g_lvolerrno = -1;
644 	g_num_lvols = 1;
645 	g_examine_done = false;
646 	lvol_already_opened = false;
647 	g_registered_bdevs = 0;
648 	vbdev_lvs_examine(&g_bdev);
649 	CU_ASSERT(g_bs_dev != NULL);
650 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
651 	CU_ASSERT(g_examine_done == true);
652 	CU_ASSERT(g_registered_bdevs == 0);
653 	CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs));
654 	CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols));
655 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
656 	free(g_bs_dev);
657 
658 	/* Examine succesfully */
659 	g_bs_dev = NULL;
660 	g_lvserrno = 0;
661 	g_lvolerrno = 0;
662 	g_examine_done = false;
663 	g_registered_bdevs = 0;
664 	lvol_already_opened = false;
665 	vbdev_lvs_examine(&g_bdev);
666 	CU_ASSERT(g_bs_dev != NULL);
667 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
668 	CU_ASSERT(g_examine_done == true);
669 	CU_ASSERT(g_registered_bdevs != 0);
670 	CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs));
671 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols));
672 	TAILQ_FIRST(&g_lvol_store->lvols)->ref_count--;
673 	bdev = TAILQ_FIRST(&g_lvol_store->lvols)->bdev;
674 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
675 	free(bdev->name);
676 	free(bdev);
677 	free(g_bs_dev);
678 	free(g_lvol_store);
679 }
680 
681 static void
682 ut_lvol_resize(void)
683 {
684 	int sz = 10;
685 	int rc = 0;
686 
687 	g_lvs = calloc(1, sizeof(*g_lvs));
688 	SPDK_CU_ASSERT_FATAL(g_lvs != NULL);
689 
690 	TAILQ_INIT(&g_lvs->lvols);
691 
692 	g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev));
693 	SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL);
694 	g_base_bdev = calloc(1, sizeof(*g_base_bdev));
695 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
696 	g_lvs_bdev->lvs = g_lvs;
697 	g_lvs_bdev->bdev = g_base_bdev;
698 
699 
700 	uuid_generate_time(g_lvs->uuid);
701 	g_base_bdev->blocklen = 4096;
702 	TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
703 
704 	/* Successful lvol create */
705 	g_lvolerrno = -1;
706 	rc = vbdev_lvol_create(g_lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL);
707 	CU_ASSERT(rc == 0);
708 	CU_ASSERT(g_lvolerrno == 0);
709 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
710 
711 	g_base_bdev->ctxt = g_lvol;
712 
713 	g_base_bdev->name = spdk_sprintf_alloc("%s", g_lvol->old_name);
714 	SPDK_CU_ASSERT_FATAL(g_base_bdev->name != NULL);
715 
716 	/* Successful lvol resize */
717 	rc = vbdev_lvol_resize(g_lvol->old_name, 20, vbdev_lvol_resize_complete, NULL);
718 	CU_ASSERT(rc == 0);
719 	CU_ASSERT(g_base_bdev->blockcnt == 20 * g_cluster_size / g_base_bdev->blocklen);
720 
721 	/* Resize with wrong bdev name */
722 	rc = vbdev_lvol_resize("wrong name", 20, vbdev_lvol_resize_complete, NULL);
723 	CU_ASSERT(rc != 0);
724 
725 	/* Resize with correct bdev name, but wrong lvol name */
726 	free(g_lvol->old_name);
727 	g_lvol->old_name = strdup("wrong name");
728 	SPDK_CU_ASSERT_FATAL(g_lvol->old_name != NULL);
729 	rc = vbdev_lvol_resize(g_base_bdev->name, 20, vbdev_lvol_resize_complete, NULL);
730 	CU_ASSERT(rc != 0);
731 
732 	/* Successful lvol destruct */
733 	vbdev_lvol_destruct(g_lvol);
734 	CU_ASSERT(g_lvol == NULL);
735 
736 	TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
737 	free(g_lvs);
738 	free(g_lvs_bdev);
739 	free(g_base_bdev->name);
740 	free(g_base_bdev);
741 }
742 
743 static void
744 ut_lvs_unload(void)
745 {
746 	int rc = 0;
747 	int sz = 10;
748 	struct spdk_lvol_store *lvs;
749 
750 	/* Lvol store is succesfully created */
751 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
752 	CU_ASSERT(rc == 0);
753 	CU_ASSERT(g_lvserrno == 0);
754 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
755 	CU_ASSERT(g_bs_dev != NULL);
756 
757 	lvs = g_lvol_store;
758 	g_lvol_store = NULL;
759 
760 	uuid_generate_time(lvs->uuid);
761 
762 	/* Suuccessfully create lvol, which should be destroyed with lvs later */
763 	g_lvolerrno = -1;
764 	rc = vbdev_lvol_create(lvs->uuid, "lvol", sz, vbdev_lvol_create_complete, NULL);
765 	CU_ASSERT(rc == 0);
766 	CU_ASSERT(g_lvolerrno == 0);
767 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
768 
769 	/* Unload lvol store */
770 	vbdev_lvs_unload(lvs, lvol_store_op_complete, NULL);
771 	CU_ASSERT(g_lvserrno == 0);
772 	CU_ASSERT(g_lvol_store == NULL);
773 	CU_ASSERT(g_lvol != NULL);
774 }
775 
776 static void
777 ut_lvs_init(void)
778 {
779 	int rc = 0;
780 	struct spdk_lvol_store *lvs;
781 	struct spdk_bs_dev *bs_dev_temp;
782 
783 	/* spdk_lvs_init() fails */
784 	lvol_store_initialize_fail = true;
785 
786 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
787 	CU_ASSERT(rc != 0);
788 	CU_ASSERT(g_lvserrno == 0);
789 	CU_ASSERT(g_lvol_store == NULL);
790 	CU_ASSERT(g_bs_dev == NULL);
791 
792 	lvol_store_initialize_fail = false;
793 
794 	/* spdk_lvs_init_cb() fails */
795 	lvol_store_initialize_cb_fail = true;
796 
797 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
798 	CU_ASSERT(rc == 0);
799 	CU_ASSERT(g_lvserrno != 0);
800 	CU_ASSERT(g_lvol_store == NULL);
801 	CU_ASSERT(g_bs_dev == NULL);
802 
803 	lvol_store_initialize_cb_fail = false;
804 
805 	/* Lvol store is succesfully created */
806 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
807 	CU_ASSERT(rc == 0);
808 	CU_ASSERT(g_lvserrno == 0);
809 	CU_ASSERT(g_lvol_store != NULL);
810 	CU_ASSERT(g_bs_dev != NULL);
811 
812 	lvs = g_lvol_store;
813 	g_lvol_store = NULL;
814 	bs_dev_temp = g_bs_dev;
815 	g_bs_dev = NULL;
816 
817 	/* Bdev with lvol store already claimed */
818 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
819 	CU_ASSERT(rc != 0);
820 	CU_ASSERT(g_lvserrno == 0);
821 	CU_ASSERT(g_lvol_store == NULL);
822 	CU_ASSERT(g_bs_dev == NULL);
823 
824 	/* Destruct lvol store */
825 	g_bs_dev = bs_dev_temp;
826 
827 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
828 	CU_ASSERT(g_lvserrno == 0);
829 	CU_ASSERT(g_lvol_store == NULL);
830 	CU_ASSERT(g_bs_dev == NULL);
831 	free(g_bs_dev);
832 
833 }
834 
835 static void
836 ut_vbdev_lvol_get_io_channel(void)
837 {
838 	struct spdk_io_channel *ch;
839 
840 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
841 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
842 
843 	ch = vbdev_lvol_get_io_channel(g_lvol);
844 	CU_ASSERT(ch == g_ch);
845 
846 	free(g_lvol);
847 
848 }
849 
850 static void
851 ut_vbdev_lvol_io_type_supported(void)
852 {
853 	struct spdk_lvol *lvol = g_lvol;
854 	bool ret;
855 	/* Supported types */
856 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ);
857 	CU_ASSERT(ret == true);
858 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
859 	CU_ASSERT(ret == true);
860 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH);
861 	CU_ASSERT(ret == true);
862 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
863 	CU_ASSERT(ret == true);
864 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP);
865 	CU_ASSERT(ret == true);
866 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
867 	CU_ASSERT(ret == true);
868 
869 	/* Unsupported types */
870 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN);
871 	CU_ASSERT(ret == false);
872 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO);
873 	CU_ASSERT(ret == false);
874 }
875 
876 static void
877 ut_lvol_op_comp(void)
878 {
879 	struct lvol_task task;
880 
881 	lvol_op_comp(&task, 1);
882 	CU_ASSERT(task.status == SPDK_BDEV_IO_STATUS_FAILED);
883 }
884 
885 static void
886 ut_lvol_flush(void)
887 {
888 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task));
889 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
890 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
891 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
892 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
893 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
894 
895 	g_task = (struct lvol_task *)g_io->driver_ctx;
896 	g_io->bdev = g_base_bdev;
897 	g_io->bdev->ctxt = g_lvol;
898 
899 	/* Successful flush to lvol */
900 	lvol_flush(g_ch, g_io);
901 
902 	CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS);
903 
904 	free(g_io);
905 	free(g_base_bdev);
906 	free(g_lvol);
907 }
908 
909 static void
910 ut_lvol_read_write(void)
911 {
912 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task));
913 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
914 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
915 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
916 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
917 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
918 
919 	g_task = (struct lvol_task *)g_io->driver_ctx;
920 	g_io->bdev = g_base_bdev;
921 	g_io->bdev->ctxt = g_lvol;
922 	g_io->u.bdev.offset_blocks = 20;
923 	g_io->u.bdev.num_blocks = 20;
924 
925 	lvol_read(g_ch, g_io);
926 	CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS);
927 
928 	lvol_write(g_lvol, g_ch, g_io);
929 	CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS);
930 
931 	free(g_io);
932 	free(g_base_bdev);
933 	free(g_lvol);
934 }
935 
936 static void
937 ut_vbdev_lvol_submit_request(void)
938 {
939 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task));
940 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
941 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
942 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
943 	g_task = (struct lvol_task *)g_io->driver_ctx;
944 
945 	g_io->bdev = g_base_bdev;
946 
947 	g_io->type = SPDK_BDEV_IO_TYPE_READ;
948 	vbdev_lvol_submit_request(g_ch, g_io);
949 
950 	free(g_io);
951 	free(g_base_bdev);
952 }
953 
954 int main(int argc, char **argv)
955 {
956 	CU_pSuite	suite = NULL;
957 	unsigned int	num_failures;
958 
959 	if (CU_initialize_registry() != CUE_SUCCESS) {
960 		return CU_get_error();
961 	}
962 
963 	suite = CU_add_suite("lvol", NULL, NULL);
964 	if (suite == NULL) {
965 		CU_cleanup_registry();
966 		return CU_get_error();
967 	}
968 
969 	if (
970 		CU_add_test(suite, "ut_lvs_init", ut_lvs_init) == NULL ||
971 		CU_add_test(suite, "ut_lvol_init", ut_lvol_init) == NULL ||
972 		CU_add_test(suite, "ut_lvs_destroy", ut_lvs_destroy) == NULL ||
973 		CU_add_test(suite, "ut_lvs_unload", ut_lvs_unload) == NULL ||
974 		CU_add_test(suite, "ut_lvol_resize", ut_lvol_resize) == NULL ||
975 		CU_add_test(suite, "lvol_hotremove", ut_lvol_hotremove) == NULL ||
976 		CU_add_test(suite, "ut_vbdev_lvol_get_io_channel", ut_vbdev_lvol_get_io_channel) == NULL ||
977 		CU_add_test(suite, "ut_vbdev_lvol_io_type_supported", ut_vbdev_lvol_io_type_supported) == NULL ||
978 		CU_add_test(suite, "ut_lvol_op_comp", ut_lvol_op_comp) == NULL ||
979 		CU_add_test(suite, "ut_lvol_flush", ut_lvol_flush) == NULL ||
980 		CU_add_test(suite, "ut_lvol_read_write", ut_lvol_read_write) == NULL ||
981 		CU_add_test(suite, "ut_vbdev_lvol_submit_request", ut_vbdev_lvol_submit_request) == NULL ||
982 		CU_add_test(suite, "lvol_examine", ut_lvol_examine) == NULL
983 	) {
984 		CU_cleanup_registry();
985 		return CU_get_error();
986 	}
987 
988 	CU_basic_set_mode(CU_BRM_VERBOSE);
989 	CU_basic_run_tests();
990 	num_failures = CU_get_number_of_failures();
991 	CU_cleanup_registry();
992 	return num_failures;
993 }
994