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