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