xref: /spdk/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c (revision c7852cf98d4df6ce3e2b1f7660db634876c42e0e)
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 "bdev/lvol/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_blob_close(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 
107 	lvol_already_opened = true;
108 
109 	return 0;
110 }
111 
112 void
113 spdk_bdev_unregister(struct spdk_bdev *vbdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
114 {
115 	SPDK_CU_ASSERT_FATAL(vbdev != NULL);
116 	vbdev->fn_table->destruct(vbdev->ctxt);
117 }
118 
119 void
120 spdk_bdev_module_finish_done(void)
121 {
122 	return;
123 }
124 
125 uint64_t
126 spdk_bs_get_page_size(struct spdk_blob_store *bs)
127 {
128 	return SPDK_BS_PAGE_SIZE;
129 }
130 
131 static void
132 bdev_blob_destroy(struct spdk_bs_dev *bs_dev)
133 {
134 	CU_ASSERT(g_bs_dev != NULL);
135 	CU_ASSERT(bs_dev != NULL);
136 	CU_ASSERT(g_bs_dev == bs_dev);
137 	free(bs_dev);
138 	g_bs_dev = NULL;
139 	lvol_already_opened = false;
140 }
141 
142 struct spdk_bs_dev *
143 spdk_bdev_create_bs_dev(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx)
144 {
145 	struct spdk_bs_dev *bs_dev;
146 
147 	if (lvol_already_opened == true || bdev == NULL) {
148 		return NULL;
149 	}
150 
151 	bs_dev = calloc(1, sizeof(*bs_dev));
152 	SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
153 	bs_dev->destroy = bdev_blob_destroy;
154 
155 	CU_ASSERT(g_bs_dev == NULL);
156 	g_bs_dev = bs_dev;
157 	return bs_dev;
158 }
159 
160 void
161 spdk_lvs_opts_init(struct spdk_lvs_opts *opts)
162 {
163 }
164 
165 int
166 spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
167 	      spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
168 {
169 	struct spdk_lvol_store *lvs;
170 	int error = 0;
171 
172 	if (lvol_store_initialize_fail) {
173 		return -1;
174 	}
175 
176 	if (lvol_store_initialize_cb_fail) {
177 		bs_dev->destroy(bs_dev);
178 		lvs = NULL;
179 		error = -1;
180 	} else {
181 		lvs = calloc(1, sizeof(*lvs));
182 		SPDK_CU_ASSERT_FATAL(lvs != NULL);
183 		TAILQ_INIT(&lvs->lvols);
184 		lvs->bs_dev = bs_dev;
185 		error = 0;
186 	}
187 	cb_fn(cb_arg, lvs, error);
188 
189 	return 0;
190 }
191 
192 int
193 spdk_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg)
194 {
195 	struct spdk_lvol *lvol, *tmp;
196 
197 	TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
198 		TAILQ_REMOVE(&lvs->lvols, lvol, link);
199 		free(lvol->unique_id);
200 		free(lvol);
201 	}
202 	g_lvol_store = NULL;
203 	free(lvs);
204 
205 	g_bs_dev->destroy(g_bs_dev);
206 
207 	if (cb_fn != NULL) {
208 		cb_fn(cb_arg, 0);
209 	}
210 
211 	return 0;
212 }
213 
214 int
215 spdk_lvs_destroy(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn,
216 		 void *cb_arg)
217 {
218 	struct spdk_lvol *lvol, *tmp;
219 
220 	TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
221 		TAILQ_REMOVE(&lvs->lvols, lvol, link);
222 		free(lvol->unique_id);
223 		free(lvol);
224 	}
225 	g_lvol_store = NULL;
226 	free(lvs);
227 
228 	g_bs_dev->destroy(g_bs_dev);
229 
230 	if (cb_fn != NULL) {
231 		cb_fn(cb_arg, 0);
232 	}
233 
234 	return 0;
235 }
236 
237 int
238 spdk_lvol_resize(struct spdk_lvol *lvol, size_t sz,  spdk_lvol_op_complete cb_fn, void *cb_arg)
239 {
240 	cb_fn(cb_arg, 0);
241 
242 	return 0;
243 }
244 
245 int
246 spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size)
247 {
248 	bdev->blockcnt = size;
249 	return 0;
250 }
251 
252 uint64_t
253 spdk_bs_get_cluster_size(struct spdk_blob_store *bs)
254 {
255 	return g_cluster_size;
256 }
257 
258 struct spdk_bdev *
259 spdk_bdev_get_by_name(const char *bdev_name)
260 {
261 	if (!strcmp(g_base_bdev->name, bdev_name)) {
262 		return g_base_bdev;
263 	}
264 
265 	return NULL;
266 }
267 
268 void
269 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
270 {
271 	struct spdk_lvs_req *destruct_req;
272 	struct spdk_lvol *iter_lvol, *tmp;
273 	bool all_lvols_closed = true;
274 
275 	lvol->ref_count--;
276 
277 	TAILQ_FOREACH_SAFE(iter_lvol, &lvol->lvol_store->lvols, link, tmp) {
278 		if (iter_lvol->ref_count != 0) {
279 			all_lvols_closed = false;
280 		}
281 	}
282 
283 	destruct_req = lvol->lvol_store->destruct_req;
284 	if (destruct_req && all_lvols_closed == true) {
285 		if (!lvol->lvol_store->destruct) {
286 			spdk_lvs_unload(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg);
287 			free(destruct_req);
288 		}
289 	}
290 
291 	cb_fn(cb_arg, 0);
292 }
293 
294 void
295 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
296 {
297 	struct spdk_lvs_req *destruct_req;
298 
299 	SPDK_CU_ASSERT_FATAL(lvol == g_lvol);
300 
301 	if (lvol->ref_count != 0) {
302 		cb_fn(cb_arg, -ENODEV);
303 	}
304 
305 	TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link);
306 
307 	destruct_req = lvol->lvol_store->destruct_req;
308 	if (destruct_req && TAILQ_EMPTY(&lvol->lvol_store->lvols)) {
309 		if (!lvol->lvol_store->destruct) {
310 			spdk_lvs_unload(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg);
311 		} else {
312 			spdk_lvs_destroy(lvol->lvol_store, destruct_req->cb_fn, destruct_req->cb_arg);
313 			free(destruct_req);
314 		}
315 	}
316 	g_lvol = NULL;
317 	free(lvol->unique_id);
318 	free(lvol);
319 
320 	cb_fn(cb_arg, 0);
321 }
322 
323 void
324 spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
325 {
326 }
327 
328 struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol)
329 {
330 	CU_ASSERT(lvol == g_lvol);
331 	return g_ch;
332 }
333 
334 void
335 spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len)
336 {
337 	CU_ASSERT(cb == lvol_read);
338 }
339 
340 void
341 spdk_bs_io_read_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
342 		     void *payload, uint64_t offset, uint64_t length,
343 		     spdk_blob_op_complete cb_fn, void *cb_arg)
344 {
345 }
346 
347 void
348 spdk_bs_io_write_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
349 		      void *payload, uint64_t offset, uint64_t length,
350 		      spdk_blob_op_complete cb_fn, void *cb_arg)
351 {
352 }
353 
354 void
355 spdk_bs_io_unmap_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
356 		      uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg)
357 {
358 	CU_ASSERT(blob == NULL);
359 	CU_ASSERT(channel == g_ch);
360 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
361 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
362 }
363 
364 void
365 spdk_bs_io_write_zeroes_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
366 			     uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg)
367 {
368 	CU_ASSERT(blob == NULL);
369 	CU_ASSERT(channel == g_ch);
370 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
371 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
372 }
373 
374 void
375 spdk_bs_io_writev_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
376 		       struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
377 		       spdk_blob_op_complete cb_fn, void *cb_arg)
378 {
379 	CU_ASSERT(blob == NULL);
380 	CU_ASSERT(channel == g_ch);
381 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
382 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
383 }
384 
385 void
386 spdk_bs_io_readv_blob(struct spdk_blob *blob, struct spdk_io_channel *channel,
387 		      struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
388 		      spdk_blob_op_complete cb_fn, void *cb_arg)
389 {
390 	CU_ASSERT(blob == NULL);
391 	CU_ASSERT(channel == g_ch);
392 	CU_ASSERT(offset == g_io->u.bdev.offset_blocks);
393 	CU_ASSERT(length == g_io->u.bdev.num_blocks);
394 }
395 
396 void
397 spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module)
398 {
399 }
400 
401 int
402 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
403 {
404 	return 0;
405 }
406 
407 int
408 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
409 {
410 	return 0;
411 }
412 
413 int
414 spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
415 {
416 	return 0;
417 }
418 
419 int
420 spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
421 {
422 	return 0;
423 }
424 
425 int
426 spdk_json_write_object_end(struct spdk_json_write_ctx *w)
427 {
428 	return 0;
429 }
430 
431 const char *
432 spdk_bdev_get_name(const struct spdk_bdev *bdev)
433 {
434 	return "test";
435 }
436 
437 int
438 spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs, int base_bdev_count)
439 {
440 	g_registered_bdevs++;
441 	return 0;
442 }
443 
444 void
445 spdk_bdev_module_examine_done(struct spdk_bdev_module_if *module)
446 {
447 	g_examine_done = true;
448 }
449 
450 static struct spdk_lvol *
451 _lvol_create(struct spdk_lvol_store *lvs)
452 {
453 	struct spdk_lvol *lvol = calloc(1, sizeof(*lvol));
454 
455 	SPDK_CU_ASSERT_FATAL(lvol != NULL);
456 
457 	lvol->lvol_store = lvs;
458 	lvol->ref_count++;
459 	lvol->unique_id = spdk_sprintf_alloc("%s", "UNIT_TEST_UUID");
460 	SPDK_CU_ASSERT_FATAL(lvol->unique_id != NULL);
461 
462 	TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link);
463 
464 	return lvol;
465 }
466 
467 int
468 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
469 		 bool thin_provision, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
470 {
471 	struct spdk_lvol *lvol;
472 
473 	lvol = _lvol_create(lvs);
474 	cb_fn(cb_arg, lvol, 0);
475 
476 	return 0;
477 }
478 
479 static void
480 lvol_store_op_complete(void *cb_arg, int lvserrno)
481 {
482 	g_lvserrno = lvserrno;
483 	return;
484 }
485 
486 static void
487 lvol_store_op_with_handle_complete(void *cb_arg, struct spdk_lvol_store *lvs, int lvserrno)
488 {
489 	g_lvserrno = lvserrno;
490 	g_lvol_store = lvs;
491 	return;
492 }
493 
494 static void
495 vbdev_lvol_create_complete(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
496 {
497 	g_lvolerrno = lvolerrno;
498 	g_lvol = lvol;
499 }
500 
501 static void
502 vbdev_lvol_resize_complete(void *cb_arg, int lvolerrno)
503 {
504 	g_lvolerrno = lvolerrno;
505 }
506 
507 static void
508 ut_lvs_destroy(void)
509 {
510 	int rc = 0;
511 	int sz = 10;
512 	struct spdk_lvol_store *lvs;
513 
514 	/* Lvol store is succesfully created */
515 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
516 	CU_ASSERT(rc == 0);
517 	CU_ASSERT(g_lvserrno == 0);
518 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
519 	CU_ASSERT(g_bs_dev != NULL);
520 
521 	lvs = g_lvol_store;
522 	g_lvol_store = NULL;
523 
524 	uuid_generate_time(lvs->uuid);
525 
526 	/* Suuccessfully create lvol, which should be unloaded with lvs later */
527 	g_lvolerrno = -1;
528 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
529 	CU_ASSERT(rc == 0);
530 	CU_ASSERT(g_lvolerrno == 0);
531 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
532 
533 	/* Unload lvol store */
534 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
535 	CU_ASSERT(g_lvserrno == 0);
536 	CU_ASSERT(g_lvol_store == NULL);
537 }
538 
539 static void
540 ut_lvol_init(void)
541 {
542 	int sz = 10;
543 	int rc;
544 
545 	g_lvs = calloc(1, sizeof(*g_lvs));
546 	SPDK_CU_ASSERT_FATAL(g_lvs != NULL);
547 	TAILQ_INIT(&g_lvs->lvols);
548 	g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev));
549 	SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL);
550 	g_base_bdev = calloc(1, sizeof(*g_base_bdev));
551 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
552 
553 	g_lvs_bdev->lvs = g_lvs;
554 	g_lvs_bdev->bdev = g_base_bdev;
555 
556 	uuid_generate_time(g_lvs->uuid);
557 
558 	TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
559 
560 	/* Successful lvol create */
561 	g_lvolerrno = -1;
562 	rc = vbdev_lvol_create(g_lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
563 	SPDK_CU_ASSERT_FATAL(rc == 0);
564 	CU_ASSERT(g_lvol != NULL);
565 	CU_ASSERT(g_lvolerrno == 0);
566 
567 	/* Successful lvol destruct */
568 	vbdev_lvol_destruct(g_lvol);
569 	CU_ASSERT(g_lvol == NULL);
570 
571 	TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
572 
573 	free(g_lvs);
574 	free(g_lvs_bdev);
575 	free(g_base_bdev);
576 
577 
578 }
579 
580 static void
581 ut_lvol_hotremove(void)
582 {
583 	int rc = 0;
584 
585 	lvol_store_initialize_fail = false;
586 	lvol_store_initialize_cb_fail = false;
587 	lvol_already_opened = false;
588 	g_bs_dev = NULL;
589 
590 	/* Lvol store is succesfully created */
591 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
592 	CU_ASSERT(rc == 0);
593 	CU_ASSERT(g_lvserrno == 0);
594 	CU_ASSERT(g_lvol_store != NULL);
595 	CU_ASSERT(g_bs_dev != NULL);
596 
597 	/* Hot remove callback with NULL - stability check */
598 	vbdev_lvs_hotremove_cb(NULL);
599 
600 	/* Hot remove lvs on bdev removal */
601 	vbdev_lvs_hotremove_cb(&g_bdev);
602 
603 	CU_ASSERT(g_lvol_store == NULL);
604 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
605 
606 }
607 
608 static void
609 ut_lvol_examine(void)
610 {
611 	struct spdk_bdev *bdev;
612 
613 	lvol_already_opened = false;
614 	g_bs_dev = NULL;
615 	g_lvserrno = 0;
616 	g_examine_done = false;
617 
618 	/* Examine with NULL bdev */
619 	vbdev_lvs_examine(NULL);
620 	CU_ASSERT(g_bs_dev == NULL);
621 	CU_ASSERT(g_lvol_store == NULL);
622 	CU_ASSERT(g_examine_done == true);
623 
624 	/* Examine unsuccessfully - bdev already opened */
625 	g_bs_dev = NULL;
626 	g_examine_done = false;
627 	g_lvserrno = -1;
628 	lvol_already_opened = true;
629 	vbdev_lvs_examine(&g_bdev);
630 	CU_ASSERT(g_bs_dev == NULL);
631 	CU_ASSERT(g_lvol_store == NULL);
632 	CU_ASSERT(g_examine_done == true);
633 
634 	/* Examine unsuccessfully - fail on lvol store */
635 	g_bs_dev = NULL;
636 	g_examine_done = false;
637 	g_lvserrno = -1;
638 	lvol_already_opened = false;
639 	vbdev_lvs_examine(&g_bdev);
640 	CU_ASSERT(g_bs_dev != NULL);
641 	CU_ASSERT(g_lvol_store == NULL);
642 	CU_ASSERT(g_examine_done == true);
643 	CU_ASSERT(TAILQ_EMPTY(&g_spdk_lvol_pairs));
644 	free(g_bs_dev);
645 
646 	/* Examine unsuccesfully - fail on lvol load */
647 	g_bs_dev = NULL;
648 	g_lvserrno = 0;
649 	g_lvolerrno = -1;
650 	g_num_lvols = 1;
651 	g_examine_done = false;
652 	lvol_already_opened = false;
653 	g_registered_bdevs = 0;
654 	vbdev_lvs_examine(&g_bdev);
655 	CU_ASSERT(g_bs_dev != NULL);
656 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
657 	CU_ASSERT(g_examine_done == true);
658 	CU_ASSERT(g_registered_bdevs == 0);
659 	CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs));
660 	CU_ASSERT(TAILQ_EMPTY(&g_lvol_store->lvols));
661 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
662 	free(g_bs_dev);
663 
664 	/* Examine succesfully */
665 	g_bs_dev = NULL;
666 	g_lvserrno = 0;
667 	g_lvolerrno = 0;
668 	g_examine_done = false;
669 	g_registered_bdevs = 0;
670 	lvol_already_opened = false;
671 	vbdev_lvs_examine(&g_bdev);
672 	CU_ASSERT(g_bs_dev != NULL);
673 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
674 	CU_ASSERT(g_examine_done == true);
675 	CU_ASSERT(g_registered_bdevs != 0);
676 	CU_ASSERT(!TAILQ_EMPTY(&g_spdk_lvol_pairs));
677 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_lvol_store->lvols));
678 	TAILQ_FIRST(&g_lvol_store->lvols)->ref_count--;
679 	bdev = TAILQ_FIRST(&g_lvol_store->lvols)->bdev;
680 	vbdev_lvs_destruct(g_lvol_store, lvol_store_op_complete, NULL);
681 	free(bdev->name);
682 	free(bdev);
683 	free(g_bs_dev);
684 	free(g_lvol_store);
685 }
686 
687 static void
688 ut_lvol_resize(void)
689 {
690 	int sz = 10;
691 	int rc = 0;
692 
693 	g_lvs = calloc(1, sizeof(*g_lvs));
694 	SPDK_CU_ASSERT_FATAL(g_lvs != NULL);
695 
696 	TAILQ_INIT(&g_lvs->lvols);
697 
698 	g_lvs_bdev = calloc(1, sizeof(*g_lvs_bdev));
699 	SPDK_CU_ASSERT_FATAL(g_lvs_bdev != NULL);
700 	g_base_bdev = calloc(1, sizeof(*g_base_bdev));
701 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
702 	g_lvs_bdev->lvs = g_lvs;
703 	g_lvs_bdev->bdev = g_base_bdev;
704 
705 
706 	uuid_generate_time(g_lvs->uuid);
707 	g_base_bdev->blocklen = 4096;
708 	TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
709 
710 	/* Successful lvol create */
711 	g_lvolerrno = -1;
712 	rc = vbdev_lvol_create(g_lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
713 	CU_ASSERT(rc == 0);
714 	CU_ASSERT(g_lvolerrno == 0);
715 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
716 
717 	g_base_bdev->ctxt = g_lvol;
718 
719 	g_base_bdev->name = spdk_sprintf_alloc("%s", g_lvol->unique_id);
720 	SPDK_CU_ASSERT_FATAL(g_base_bdev->name != NULL);
721 
722 	/* Successful lvol resize */
723 	rc = vbdev_lvol_resize(g_lvol->unique_id, 20, vbdev_lvol_resize_complete, NULL);
724 	CU_ASSERT(rc == 0);
725 	CU_ASSERT(g_base_bdev->blockcnt == 20 * g_cluster_size / g_base_bdev->blocklen);
726 
727 	/* Resize with wrong bdev name */
728 	rc = vbdev_lvol_resize("wrong name", 20, vbdev_lvol_resize_complete, NULL);
729 	CU_ASSERT(rc != 0);
730 
731 	/* Resize with correct bdev name, but wrong lvol name */
732 	free(g_lvol->unique_id);
733 	g_lvol->unique_id = strdup("wrong name");
734 	SPDK_CU_ASSERT_FATAL(g_lvol->unique_id != NULL);
735 	rc = vbdev_lvol_resize(g_base_bdev->name, 20, vbdev_lvol_resize_complete, NULL);
736 	CU_ASSERT(rc != 0);
737 
738 	/* Successful lvol destruct */
739 	vbdev_lvol_destruct(g_lvol);
740 	CU_ASSERT(g_lvol == NULL);
741 
742 	TAILQ_REMOVE(&g_spdk_lvol_pairs, g_lvs_bdev, lvol_stores);
743 	free(g_lvs);
744 	free(g_lvs_bdev);
745 	free(g_base_bdev->name);
746 	free(g_base_bdev);
747 }
748 
749 static void
750 ut_lvs_unload(void)
751 {
752 	int rc = 0;
753 	int sz = 10;
754 	struct spdk_lvol_store *lvs;
755 
756 	/* Lvol store is succesfully created */
757 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
758 	CU_ASSERT(rc == 0);
759 	CU_ASSERT(g_lvserrno == 0);
760 	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
761 	CU_ASSERT(g_bs_dev != NULL);
762 
763 	lvs = g_lvol_store;
764 	g_lvol_store = NULL;
765 
766 	uuid_generate_time(lvs->uuid);
767 
768 	/* Suuccessfully create lvol, which should be destroyed with lvs later */
769 	g_lvolerrno = -1;
770 	rc = vbdev_lvol_create(lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
771 	CU_ASSERT(rc == 0);
772 	CU_ASSERT(g_lvolerrno == 0);
773 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
774 
775 	/* Unload lvol store */
776 	vbdev_lvs_unload(lvs, lvol_store_op_complete, NULL);
777 	CU_ASSERT(g_lvserrno == 0);
778 	CU_ASSERT(g_lvol_store == NULL);
779 	CU_ASSERT(g_lvol != NULL);
780 }
781 
782 static void
783 ut_lvs_init(void)
784 {
785 	int rc = 0;
786 	struct spdk_lvol_store *lvs;
787 	struct spdk_bs_dev *bs_dev_temp;
788 
789 	/* spdk_lvs_init() fails */
790 	lvol_store_initialize_fail = true;
791 
792 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
793 	CU_ASSERT(rc != 0);
794 	CU_ASSERT(g_lvserrno == 0);
795 	CU_ASSERT(g_lvol_store == NULL);
796 	CU_ASSERT(g_bs_dev == NULL);
797 
798 	lvol_store_initialize_fail = false;
799 
800 	/* spdk_lvs_init_cb() fails */
801 	lvol_store_initialize_cb_fail = true;
802 
803 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
804 	CU_ASSERT(rc == 0);
805 	CU_ASSERT(g_lvserrno != 0);
806 	CU_ASSERT(g_lvol_store == NULL);
807 	CU_ASSERT(g_bs_dev == NULL);
808 
809 	lvol_store_initialize_cb_fail = false;
810 
811 	/* Lvol store is succesfully created */
812 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
813 	CU_ASSERT(rc == 0);
814 	CU_ASSERT(g_lvserrno == 0);
815 	CU_ASSERT(g_lvol_store != NULL);
816 	CU_ASSERT(g_bs_dev != NULL);
817 
818 	lvs = g_lvol_store;
819 	g_lvol_store = NULL;
820 	bs_dev_temp = g_bs_dev;
821 	g_bs_dev = NULL;
822 
823 	/* Bdev with lvol store already claimed */
824 	rc = vbdev_lvs_create(&g_bdev, "lvs", 0, lvol_store_op_with_handle_complete, NULL);
825 	CU_ASSERT(rc != 0);
826 	CU_ASSERT(g_lvserrno == 0);
827 	CU_ASSERT(g_lvol_store == NULL);
828 	CU_ASSERT(g_bs_dev == NULL);
829 
830 	/* Destruct lvol store */
831 	g_bs_dev = bs_dev_temp;
832 
833 	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
834 	CU_ASSERT(g_lvserrno == 0);
835 	CU_ASSERT(g_lvol_store == NULL);
836 	CU_ASSERT(g_bs_dev == NULL);
837 	free(g_bs_dev);
838 
839 }
840 
841 static void
842 ut_vbdev_lvol_get_io_channel(void)
843 {
844 	struct spdk_io_channel *ch;
845 
846 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
847 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
848 
849 	ch = vbdev_lvol_get_io_channel(g_lvol);
850 	CU_ASSERT(ch == g_ch);
851 
852 	free(g_lvol);
853 
854 }
855 
856 static void
857 ut_vbdev_lvol_io_type_supported(void)
858 {
859 	struct spdk_lvol *lvol = g_lvol;
860 	bool ret;
861 	/* Supported types */
862 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_READ);
863 	CU_ASSERT(ret == true);
864 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
865 	CU_ASSERT(ret == true);
866 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
867 	CU_ASSERT(ret == true);
868 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_UNMAP);
869 	CU_ASSERT(ret == true);
870 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
871 	CU_ASSERT(ret == true);
872 
873 	/* Unsupported types */
874 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH);
875 	CU_ASSERT(ret == false);
876 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_ADMIN);
877 	CU_ASSERT(ret == false);
878 	ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_NVME_IO);
879 	CU_ASSERT(ret == false);
880 }
881 
882 static void
883 ut_lvol_op_comp(void)
884 {
885 	struct lvol_task task;
886 
887 	lvol_op_comp(&task, 1);
888 	CU_ASSERT(task.status == SPDK_BDEV_IO_STATUS_FAILED);
889 }
890 
891 static void
892 ut_lvol_read_write(void)
893 {
894 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task));
895 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
896 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
897 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
898 	g_lvol = calloc(1, sizeof(struct spdk_lvol));
899 	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
900 
901 	g_task = (struct lvol_task *)g_io->driver_ctx;
902 	g_io->bdev = g_base_bdev;
903 	g_io->bdev->ctxt = g_lvol;
904 	g_io->u.bdev.offset_blocks = 20;
905 	g_io->u.bdev.num_blocks = 20;
906 
907 	lvol_read(g_ch, g_io);
908 	CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS);
909 
910 	lvol_write(g_lvol, g_ch, g_io);
911 	CU_ASSERT(g_task->status == SPDK_BDEV_IO_STATUS_SUCCESS);
912 
913 	free(g_io);
914 	free(g_base_bdev);
915 	free(g_lvol);
916 }
917 
918 static void
919 ut_vbdev_lvol_submit_request(void)
920 {
921 	g_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct lvol_task));
922 	SPDK_CU_ASSERT_FATAL(g_io != NULL);
923 	g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
924 	SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
925 	g_task = (struct lvol_task *)g_io->driver_ctx;
926 
927 	g_io->bdev = g_base_bdev;
928 
929 	g_io->type = SPDK_BDEV_IO_TYPE_READ;
930 	vbdev_lvol_submit_request(g_ch, g_io);
931 
932 	free(g_io);
933 	free(g_base_bdev);
934 }
935 
936 int main(int argc, char **argv)
937 {
938 	CU_pSuite	suite = NULL;
939 	unsigned int	num_failures;
940 
941 	if (CU_initialize_registry() != CUE_SUCCESS) {
942 		return CU_get_error();
943 	}
944 
945 	suite = CU_add_suite("lvol", NULL, NULL);
946 	if (suite == NULL) {
947 		CU_cleanup_registry();
948 		return CU_get_error();
949 	}
950 
951 	if (
952 		CU_add_test(suite, "ut_lvs_init", ut_lvs_init) == NULL ||
953 		CU_add_test(suite, "ut_lvol_init", ut_lvol_init) == NULL ||
954 		CU_add_test(suite, "ut_lvs_destroy", ut_lvs_destroy) == NULL ||
955 		CU_add_test(suite, "ut_lvs_unload", ut_lvs_unload) == NULL ||
956 		CU_add_test(suite, "ut_lvol_resize", ut_lvol_resize) == NULL ||
957 		CU_add_test(suite, "lvol_hotremove", ut_lvol_hotremove) == NULL ||
958 		CU_add_test(suite, "ut_vbdev_lvol_get_io_channel", ut_vbdev_lvol_get_io_channel) == NULL ||
959 		CU_add_test(suite, "ut_vbdev_lvol_io_type_supported", ut_vbdev_lvol_io_type_supported) == NULL ||
960 		CU_add_test(suite, "ut_lvol_op_comp", ut_lvol_op_comp) == NULL ||
961 		CU_add_test(suite, "ut_lvol_read_write", ut_lvol_read_write) == NULL ||
962 		CU_add_test(suite, "ut_vbdev_lvol_submit_request", ut_vbdev_lvol_submit_request) == NULL ||
963 		CU_add_test(suite, "lvol_examine", ut_lvol_examine) == NULL
964 	) {
965 		CU_cleanup_registry();
966 		return CU_get_error();
967 	}
968 
969 	CU_basic_set_mode(CU_BRM_VERBOSE);
970 	CU_basic_run_tests();
971 	num_failures = CU_get_number_of_failures();
972 	CU_cleanup_registry();
973 	return num_failures;
974 }
975