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