Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2018 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : : #include "spdk_internal/cunit.h"
9 : : #include "spdk/env.h"
10 : : #include "spdk_internal/mock.h"
11 : : #include "thread/thread_internal.h"
12 : : #include "bdev/raid/bdev_raid.c"
13 : : #include "bdev/raid/bdev_raid_rpc.c"
14 : : #include "bdev/raid/raid0.c"
15 : : #include "common/lib/ut_multithread.c"
16 : :
17 : : #define MAX_BASE_DRIVES 32
18 : : #define MAX_RAIDS 2
19 : : #define INVALID_IO_SUBMIT 0xFFFF
20 : : #define MAX_TEST_IO_RANGE (3 * 3 * 3 * (MAX_BASE_DRIVES + 5))
21 : : #define BLOCK_CNT (1024ul * 1024ul * 1024ul * 1024ul)
22 : :
23 : : struct spdk_bdev_channel {
24 : : struct spdk_io_channel *channel;
25 : : };
26 : :
27 : : struct spdk_bdev_desc {
28 : : struct spdk_bdev *bdev;
29 : : };
30 : :
31 : : /* Data structure to capture the output of IO for verification */
32 : : struct io_output {
33 : : struct spdk_bdev_desc *desc;
34 : : struct spdk_io_channel *ch;
35 : : uint64_t offset_blocks;
36 : : uint64_t num_blocks;
37 : : spdk_bdev_io_completion_cb cb;
38 : : void *cb_arg;
39 : : enum spdk_bdev_io_type iotype;
40 : : };
41 : :
42 : : struct raid_io_ranges {
43 : : uint64_t lba;
44 : : uint64_t nblocks;
45 : : };
46 : :
47 : : /* Globals */
48 : : int g_bdev_io_submit_status;
49 : : struct io_output *g_io_output = NULL;
50 : : uint32_t g_io_output_index;
51 : : uint32_t g_io_comp_status;
52 : : bool g_child_io_status_flag;
53 : : void *g_rpc_req;
54 : : uint32_t g_rpc_req_size;
55 : : TAILQ_HEAD(bdev, spdk_bdev);
56 : : struct bdev g_bdev_list;
57 : : TAILQ_HEAD(waitq, spdk_bdev_io_wait_entry);
58 : : struct waitq g_io_waitq;
59 : : uint32_t g_block_len;
60 : : uint32_t g_strip_size;
61 : : uint32_t g_max_io_size;
62 : : uint8_t g_max_base_drives;
63 : : uint8_t g_max_raids;
64 : : uint8_t g_ignore_io_output;
65 : : uint8_t g_rpc_err;
66 : : char *g_get_raids_output[MAX_RAIDS];
67 : : uint32_t g_get_raids_count;
68 : : uint8_t g_json_decode_obj_err;
69 : : uint8_t g_json_decode_obj_create;
70 : : uint8_t g_config_level_create = 0;
71 : : uint8_t g_test_multi_raids;
72 : : struct raid_io_ranges g_io_ranges[MAX_TEST_IO_RANGE];
73 : : uint32_t g_io_range_idx;
74 : : uint64_t g_lba_offset;
75 : : uint64_t g_bdev_ch_io_device;
76 : : bool g_bdev_io_defer_completion;
77 : : TAILQ_HEAD(, spdk_bdev_io) g_deferred_ios = TAILQ_HEAD_INITIALIZER(g_deferred_ios);
78 : :
79 : 0 : DEFINE_STUB_V(spdk_bdev_module_examine_done, (struct spdk_bdev_module *module));
80 : 6 : DEFINE_STUB_V(spdk_bdev_module_list_add, (struct spdk_bdev_module *bdev_module));
81 [ + + ]: 576 : DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev,
82 : : enum spdk_bdev_io_type io_type), true);
83 : 4032 : DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
84 : 0 : DEFINE_STUB(spdk_bdev_flush_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
85 : : uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
86 : : void *cb_arg), 0);
87 : 0 : DEFINE_STUB(spdk_conf_next_section, struct spdk_conf_section *, (struct spdk_conf_section *sp),
88 : : NULL);
89 : 36 : DEFINE_STUB_V(spdk_rpc_register_method, (const char *method, spdk_rpc_method_handler func,
90 : : uint32_t state_mask));
91 : 0 : DEFINE_STUB_V(spdk_rpc_register_alias_deprecated, (const char *method, const char *alias));
92 : 30 : DEFINE_STUB_V(spdk_jsonrpc_end_result, (struct spdk_jsonrpc_request *request,
93 : : struct spdk_json_write_ctx *w));
94 : 234 : DEFINE_STUB_V(spdk_jsonrpc_send_bool_response, (struct spdk_jsonrpc_request *request,
95 : : bool value));
96 : 0 : DEFINE_STUB(spdk_json_decode_string, int, (const struct spdk_json_val *val, void *out), 0);
97 : 0 : DEFINE_STUB(spdk_json_decode_uint32, int, (const struct spdk_json_val *val, void *out), 0);
98 : 0 : DEFINE_STUB(spdk_json_decode_uuid, int, (const struct spdk_json_val *val, void *out), 0);
99 : 0 : DEFINE_STUB(spdk_json_decode_array, int, (const struct spdk_json_val *values,
100 : : spdk_json_decode_fn decode_func,
101 : : void *out, size_t max_size, size_t *out_size, size_t stride), 0);
102 : 0 : DEFINE_STUB(spdk_json_decode_bool, int, (const struct spdk_json_val *val, void *out), 0);
103 : 1386 : DEFINE_STUB(spdk_json_write_name, int, (struct spdk_json_write_ctx *w, const char *name), 0);
104 : 1380 : DEFINE_STUB(spdk_json_write_object_begin, int, (struct spdk_json_write_ctx *w), 0);
105 : 6 : DEFINE_STUB(spdk_json_write_named_object_begin, int, (struct spdk_json_write_ctx *w,
106 : : const char *name), 0);
107 : 1344 : DEFINE_STUB(spdk_json_write_string, int, (struct spdk_json_write_ctx *w, const char *val), 0);
108 : 1386 : DEFINE_STUB(spdk_json_write_object_end, int, (struct spdk_json_write_ctx *w), 0);
109 : 72 : DEFINE_STUB(spdk_json_write_array_begin, int, (struct spdk_json_write_ctx *w), 0);
110 : 72 : DEFINE_STUB(spdk_json_write_array_end, int, (struct spdk_json_write_ctx *w), 0);
111 : 0 : DEFINE_STUB(spdk_json_write_named_array_begin, int, (struct spdk_json_write_ctx *w,
112 : : const char *name), 0);
113 : 0 : DEFINE_STUB(spdk_json_write_bool, int, (struct spdk_json_write_ctx *w, bool val), 0);
114 : 0 : DEFINE_STUB(spdk_json_write_null, int, (struct spdk_json_write_ctx *w), 0);
115 : 2688 : DEFINE_STUB(spdk_json_write_named_uint64, int, (struct spdk_json_write_ctx *w, const char *name,
116 : : uint64_t val), 0);
117 : 36 : DEFINE_STUB(spdk_strerror, const char *, (int errnum), NULL);
118 : 0 : DEFINE_STUB(spdk_bdev_queue_io_wait, int, (struct spdk_bdev *bdev, struct spdk_io_channel *ch,
119 : : struct spdk_bdev_io_wait_entry *entry), 0);
120 : 0 : DEFINE_STUB(spdk_bdev_get_memory_domains, int, (struct spdk_bdev *bdev,
121 : : struct spdk_memory_domain **domains, int array_size), 0);
122 : 0 : DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test_bdev");
123 : 4020 : DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, (const struct spdk_bdev *bdev), 0);
124 [ + + ]: 4020 : DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), false);
125 [ + + ]: 96 : DEFINE_STUB(spdk_bdev_is_md_separate, bool, (const struct spdk_bdev *bdev), false);
126 : 4020 : DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev),
127 : : SPDK_DIF_DISABLE);
128 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false);
129 : 0 : DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0);
130 : 6 : DEFINE_STUB_V(raid_bdev_init_superblock, (struct raid_bdev *raid_bdev));
131 : :
132 : : int
133 : 4020 : raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
134 : : raid_bdev_load_sb_cb cb, void *cb_ctx)
135 : : {
136 [ - + + - ]: 4020 : cb(NULL, -EINVAL, cb_ctx);
137 : :
138 : 4020 : return 0;
139 : : }
140 : :
141 : : void
142 : 6 : raid_bdev_write_superblock(struct raid_bdev *raid_bdev, raid_bdev_write_sb_cb cb, void *cb_ctx)
143 : : {
144 [ - + + - ]: 6 : cb(0, raid_bdev, cb_ctx);
145 : 6 : }
146 : :
147 : : const struct spdk_uuid *
148 : 4032 : spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
149 : : {
150 [ + - ]: 4032 : return &bdev->uuid;
151 : : }
152 : :
153 : : struct spdk_io_channel *
154 : 5940 : spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
155 : : {
156 : 5940 : return spdk_get_io_channel(&g_bdev_ch_io_device);
157 : : }
158 : :
159 : : static void
160 : 6 : set_test_opts(void)
161 : : {
162 : :
163 : 6 : g_max_base_drives = MAX_BASE_DRIVES;
164 : 6 : g_max_raids = MAX_RAIDS;
165 : 6 : g_block_len = 4096;
166 : 6 : g_strip_size = 64;
167 : 6 : g_max_io_size = 1024;
168 : :
169 [ - + ]: 6 : printf("Test Options\n");
170 [ - + ]: 6 : printf("blocklen = %u, strip_size = %u, max_io_size = %u, g_max_base_drives = %u, "
171 : : "g_max_raids = %u\n",
172 : 1 : g_block_len, g_strip_size, g_max_io_size, g_max_base_drives, g_max_raids);
173 : 6 : }
174 : :
175 : : /* Set globals before every test run */
176 : : static void
177 : 96 : set_globals(void)
178 : : {
179 : 16 : uint32_t max_splits;
180 : :
181 : 96 : g_bdev_io_submit_status = 0;
182 [ - + ]: 96 : if (g_max_io_size < g_strip_size) {
183 : 0 : max_splits = 2;
184 : 0 : } else {
185 [ + + ]: 96 : max_splits = (g_max_io_size / g_strip_size) + 1;
186 : : }
187 [ + + ]: 96 : if (max_splits < g_max_base_drives) {
188 : 96 : max_splits = g_max_base_drives;
189 : 16 : }
190 : :
191 : 96 : g_io_output = calloc(max_splits, sizeof(struct io_output));
192 [ + + # # ]: 96 : SPDK_CU_ASSERT_FATAL(g_io_output != NULL);
193 : 96 : g_io_output_index = 0;
194 [ + + ]: 96 : memset(g_get_raids_output, 0, sizeof(g_get_raids_output));
195 : 96 : g_get_raids_count = 0;
196 : 96 : g_io_comp_status = 0;
197 : 96 : g_ignore_io_output = 0;
198 : 96 : g_config_level_create = 0;
199 : 96 : g_rpc_err = 0;
200 : 96 : g_test_multi_raids = 0;
201 : 96 : g_child_io_status_flag = true;
202 [ + - ]: 96 : TAILQ_INIT(&g_bdev_list);
203 [ + - ]: 96 : TAILQ_INIT(&g_io_waitq);
204 : 96 : g_rpc_req = NULL;
205 : 96 : g_rpc_req_size = 0;
206 : 96 : g_json_decode_obj_err = 0;
207 : 96 : g_json_decode_obj_create = 0;
208 : 96 : g_lba_offset = 0;
209 : 96 : g_bdev_io_defer_completion = false;
210 : 96 : }
211 : :
212 : : static void
213 : 96 : base_bdevs_cleanup(void)
214 : : {
215 : 16 : struct spdk_bdev *bdev;
216 : 16 : struct spdk_bdev *bdev_next;
217 : :
218 [ + + ]: 96 : if (!TAILQ_EMPTY(&g_bdev_list)) {
219 [ + + + - : 3936 : TAILQ_FOREACH_SAFE(bdev, &g_bdev_list, internal.link, bdev_next) {
+ - + - +
- + + ]
220 [ + - + - ]: 3840 : free(bdev->name);
221 [ + + + - : 3840 : TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
+ - + - +
+ + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ]
222 : 3840 : free(bdev);
223 : 640 : }
224 : 16 : }
225 : 96 : }
226 : :
227 : : static void
228 : 6 : check_and_remove_raid_bdev(struct raid_bdev *raid_bdev)
229 : : {
230 : 1 : struct raid_base_bdev_info *base_info;
231 : :
232 [ + + # # ]: 6 : assert(raid_bdev != NULL);
233 [ + + + - : 6 : assert(raid_bdev->base_bdev_info != NULL);
+ - # # ]
234 : :
235 [ + + + - : 198 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
+ - + - +
- + - + -
+ + + - ]
236 [ + + + - : 192 : if (base_info->desc) {
+ + ]
237 : 186 : raid_bdev_free_base_bdev_resource(base_info);
238 : 31 : }
239 : 32 : }
240 [ + + + - : 6 : assert(raid_bdev->num_base_bdevs_discovered == 0);
+ - # # ]
241 : 6 : raid_bdev_cleanup_and_free(raid_bdev);
242 : 6 : }
243 : :
244 : : /* Reset globals */
245 : : static void
246 : 96 : reset_globals(void)
247 : : {
248 [ + - ]: 96 : if (g_io_output) {
249 : 96 : free(g_io_output);
250 : 96 : g_io_output = NULL;
251 : 16 : }
252 : 96 : g_rpc_req = NULL;
253 : 96 : g_rpc_req_size = 0;
254 : 96 : }
255 : :
256 : : void
257 : 18 : spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb,
258 : : uint64_t len)
259 : : {
260 [ - + + - : 18 : cb(bdev_io->internal.ch->channel, bdev_io, true);
+ - + - +
- + - +
- ]
261 : 18 : }
262 : :
263 : : /* Store the IO completion status in global variable to verify by various tests */
264 : : void
265 : 5862 : spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
266 : : {
267 : 5862 : g_io_comp_status = ((status == SPDK_BDEV_IO_STATUS_SUCCESS) ? true : false);
268 : 5862 : }
269 : :
270 : : static void
271 : 106512 : set_io_output(struct io_output *output,
272 : : struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
273 : : uint64_t offset_blocks, uint64_t num_blocks,
274 : : spdk_bdev_io_completion_cb cb, void *cb_arg,
275 : : enum spdk_bdev_io_type iotype)
276 : : {
277 [ + - + - ]: 106512 : output->desc = desc;
278 [ + - + - ]: 106512 : output->ch = ch;
279 [ + - + - ]: 106512 : output->offset_blocks = offset_blocks;
280 [ + - + - ]: 106512 : output->num_blocks = num_blocks;
281 [ + - + - ]: 106512 : output->cb = cb;
282 [ + - + - ]: 106512 : output->cb_arg = cb_arg;
283 [ + - + - ]: 106512 : output->iotype = iotype;
284 : 106512 : }
285 : :
286 : : static void
287 : 106512 : child_io_complete(struct spdk_bdev_io *child_io, spdk_bdev_io_completion_cb cb, void *cb_arg)
288 : : {
289 [ + + + + ]: 106512 : if (g_bdev_io_defer_completion) {
290 [ + - + - : 60 : child_io->internal.cb = cb;
+ - ]
291 [ + - + - : 60 : child_io->internal.caller_ctx = cb_arg;
+ - ]
292 [ + - + - : 60 : TAILQ_INSERT_TAIL(&g_deferred_ios, child_io, internal.link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
293 : 10 : } else {
294 [ - + + - : 106452 : cb(child_io, g_child_io_status_flag, cb_arg);
+ - ]
295 : : }
296 : 106512 : }
297 : :
298 : : static void
299 : 60 : complete_deferred_ios(void)
300 : : {
301 : 10 : struct spdk_bdev_io *child_io, *tmp;
302 : :
303 [ + + + - : 120 : TAILQ_FOREACH_SAFE(child_io, &g_deferred_ios, internal.link, tmp) {
+ - + - +
- + + ]
304 [ + + + - : 60 : TAILQ_REMOVE(&g_deferred_ios, child_io, internal.link);
+ - + - -
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
- + - + -
+ - + - +
+ - + - +
- + - + -
+ - + - +
- + - ]
305 [ + + + - : 60 : child_io->internal.cb(child_io, g_child_io_status_flag, child_io->internal.caller_ctx);
+ - - + +
- + - + -
+ - + - ]
306 : 10 : }
307 : 60 : }
308 : :
309 : : /* It will cache the split IOs for verification */
310 : : int
311 : 84 : spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
312 : : struct iovec *iov, int iovcnt,
313 : : uint64_t offset_blocks, uint64_t num_blocks,
314 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
315 : : {
316 [ + - ]: 84 : struct io_output *output = &g_io_output[g_io_output_index];
317 : 14 : struct spdk_bdev_io *child_io;
318 : :
319 [ - + ]: 84 : if (g_ignore_io_output) {
320 : 0 : return 0;
321 : : }
322 : :
323 [ - + ]: 84 : if (g_max_io_size < g_strip_size) {
324 [ # # # # ]: 0 : SPDK_CU_ASSERT_FATAL(g_io_output_index < 2);
325 : 0 : } else {
326 [ + + + + : 84 : SPDK_CU_ASSERT_FATAL(g_io_output_index < (g_max_io_size / g_strip_size) + 1);
# # ]
327 : : }
328 [ + + ]: 84 : if (g_bdev_io_submit_status == 0) {
329 : 84 : set_io_output(output, desc, ch, offset_blocks, num_blocks, cb, cb_arg,
330 : : SPDK_BDEV_IO_TYPE_WRITE);
331 : 84 : g_io_output_index++;
332 : :
333 : 84 : child_io = calloc(1, sizeof(struct spdk_bdev_io));
334 [ + + # # ]: 84 : SPDK_CU_ASSERT_FATAL(child_io != NULL);
335 : 84 : child_io_complete(child_io, cb, cb_arg);
336 : 14 : }
337 : :
338 : 84 : return g_bdev_io_submit_status;
339 : 14 : }
340 : :
341 : : int
342 : 84 : spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
343 : : struct iovec *iov, int iovcnt,
344 : : uint64_t offset_blocks, uint64_t num_blocks,
345 : : spdk_bdev_io_completion_cb cb, void *cb_arg,
346 : : struct spdk_bdev_ext_io_opts *opts)
347 : : {
348 : 84 : return spdk_bdev_writev_blocks(desc, ch, iov, iovcnt, offset_blocks, num_blocks, cb, cb_arg);
349 : : }
350 : :
351 : : int
352 : 0 : spdk_bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
353 : : struct iovec *iov, int iovcnt, void *md,
354 : : uint64_t offset_blocks, uint64_t num_blocks,
355 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
356 : : {
357 : 0 : return spdk_bdev_writev_blocks(desc, ch, iov, iovcnt, offset_blocks, num_blocks, cb, cb_arg);
358 : : }
359 : :
360 : : int
361 : 192 : spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
362 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
363 : : {
364 [ + - ]: 192 : struct io_output *output = &g_io_output[g_io_output_index];
365 : 32 : struct spdk_bdev_io *child_io;
366 : :
367 [ - + ]: 192 : if (g_ignore_io_output) {
368 : 0 : return 0;
369 : : }
370 : :
371 [ + + ]: 192 : if (g_bdev_io_submit_status == 0) {
372 : 192 : set_io_output(output, desc, ch, 0, 0, cb, cb_arg, SPDK_BDEV_IO_TYPE_RESET);
373 : 192 : g_io_output_index++;
374 : :
375 : 192 : child_io = calloc(1, sizeof(struct spdk_bdev_io));
376 [ + + # # ]: 192 : SPDK_CU_ASSERT_FATAL(child_io != NULL);
377 : 192 : child_io_complete(child_io, cb, cb_arg);
378 : 32 : }
379 : :
380 : 192 : return g_bdev_io_submit_status;
381 : 32 : }
382 : :
383 : : int
384 : 106218 : spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
385 : : uint64_t offset_blocks, uint64_t num_blocks,
386 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
387 : : {
388 [ + - ]: 106218 : struct io_output *output = &g_io_output[g_io_output_index];
389 : 17703 : struct spdk_bdev_io *child_io;
390 : :
391 [ - + ]: 106218 : if (g_ignore_io_output) {
392 : 0 : return 0;
393 : : }
394 : :
395 [ + + ]: 106218 : if (g_bdev_io_submit_status == 0) {
396 : 106218 : set_io_output(output, desc, ch, offset_blocks, num_blocks, cb, cb_arg,
397 : : SPDK_BDEV_IO_TYPE_UNMAP);
398 : 106218 : g_io_output_index++;
399 : :
400 : 106218 : child_io = calloc(1, sizeof(struct spdk_bdev_io));
401 [ + + # # ]: 106218 : SPDK_CU_ASSERT_FATAL(child_io != NULL);
402 : 106218 : child_io_complete(child_io, cb, cb_arg);
403 : 17703 : }
404 : :
405 : 106218 : return g_bdev_io_submit_status;
406 : 17703 : }
407 : :
408 : : void
409 : 114 : spdk_bdev_destruct_done(struct spdk_bdev *bdev, int bdeverrno)
410 : : {
411 : 114 : CU_ASSERT(bdeverrno == 0);
412 [ + + + - : 114 : SPDK_CU_ASSERT_FATAL(bdev->internal.unregister_cb != NULL);
+ - + - #
# ]
413 [ + - + - : 114 : bdev->internal.unregister_cb(bdev->internal.unregister_ctx, bdeverrno);
+ - - + +
- + - + -
+ - ]
414 : 114 : }
415 : :
416 : : int
417 : 114 : spdk_bdev_register(struct spdk_bdev *bdev)
418 : : {
419 [ + - + - : 114 : TAILQ_INSERT_TAIL(&g_bdev_list, bdev, internal.link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
420 : 114 : return 0;
421 : : }
422 : :
423 : : void
424 : 114 : spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
425 : : {
426 : 19 : int ret;
427 : :
428 [ + + + - : 114 : SPDK_CU_ASSERT_FATAL(spdk_bdev_get_by_name(bdev->name) == bdev);
+ - # # ]
429 [ + + + - : 114 : TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
+ - + - +
+ + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ]
430 : :
431 [ + - + - : 114 : bdev->internal.unregister_cb = cb_fn;
+ - ]
432 [ + - + - : 114 : bdev->internal.unregister_ctx = cb_arg;
+ - ]
433 : :
434 [ + - + - : 114 : ret = bdev->fn_table->destruct(bdev->ctxt);
+ - + - -
+ + - + -
+ - ]
435 : 114 : CU_ASSERT(ret == 1);
436 : :
437 : 114 : poll_threads();
438 : 114 : }
439 : :
440 : : int
441 : 4152 : spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb,
442 : : void *event_ctx, struct spdk_bdev_desc **_desc)
443 : : {
444 : 692 : struct spdk_bdev *bdev;
445 : :
446 : 4152 : bdev = spdk_bdev_get_by_name(bdev_name);
447 [ + + ]: 4152 : if (bdev == NULL) {
448 : 6 : return -ENODEV;
449 : : }
450 : :
451 [ + - ]: 4146 : *_desc = (void *)bdev;
452 : 4146 : return 0;
453 : 692 : }
454 : :
455 : : struct spdk_bdev *
456 : 12084 : spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
457 : : {
458 : 12084 : return (void *)desc;
459 : : }
460 : :
461 : : int
462 : 168 : spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
463 : : {
464 [ + + ]: 168 : if (!g_test_multi_raids) {
465 : 24 : struct rpc_bdev_raid_create *req = g_rpc_req;
466 [ + + + + : 24 : if (strcmp(name, "strip_size_kb") == 0) {
+ + ]
467 [ + - + - ]: 6 : CU_ASSERT(req->strip_size_kb == val);
468 [ + + + + : 19 : } else if (strcmp(name, "blocklen_shift") == 0) {
+ - ]
469 : 0 : CU_ASSERT(spdk_u32log2(g_block_len) == val);
470 [ + + + + : 18 : } else if (strcmp(name, "num_base_bdevs") == 0) {
+ + ]
471 [ + - + - : 6 : CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
+ - ]
472 [ + + + + : 13 : } else if (strcmp(name, "state") == 0) {
+ - ]
473 : 0 : CU_ASSERT(val == RAID_BDEV_STATE_ONLINE);
474 [ + + + + : 12 : } else if (strcmp(name, "destruct_called") == 0) {
+ - ]
475 : 0 : CU_ASSERT(val == 0);
476 [ + + + + : 12 : } else if (strcmp(name, "num_base_bdevs_discovered") == 0) {
+ + ]
477 [ + - + - : 6 : CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
+ - ]
478 : 1 : }
479 : 4 : }
480 : 168 : return 0;
481 : : }
482 : :
483 : : int
484 : 1542 : spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
485 : : {
486 [ + + ]: 1542 : if (g_test_multi_raids) {
487 [ + + + + : 1332 : if (strcmp(name, "name") == 0) {
+ + ]
488 [ + + + - : 36 : g_get_raids_output[g_get_raids_count] = strdup(val);
+ - + - ]
489 [ + + + - : 36 : SPDK_CU_ASSERT_FATAL(g_get_raids_output[g_get_raids_count] != NULL);
+ - + - #
# ]
490 : 36 : g_get_raids_count++;
491 : 6 : }
492 : 222 : } else {
493 : 210 : struct rpc_bdev_raid_create *req = g_rpc_req;
494 [ + + + + : 210 : if (strcmp(name, "raid_level") == 0) {
+ + ]
495 [ + + + + : 6 : CU_ASSERT(strcmp(val, raid_bdev_level_to_str(req->level)) == 0);
+ - + - ]
496 : 1 : }
497 : 35 : }
498 : 1542 : return 0;
499 : : }
500 : :
501 : : int
502 : 1386 : spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
503 : : {
504 [ + + ]: 1386 : if (!g_test_multi_raids) {
505 : 198 : struct rpc_bdev_raid_create *req = g_rpc_req;
506 [ + + + + : 198 : if (strcmp(name, "superblock") == 0) {
+ + ]
507 [ + + + - : 6 : CU_ASSERT(val == req->superblock_enabled);
+ - + - ]
508 : 1 : }
509 : 33 : }
510 : 1386 : return 0;
511 : : }
512 : :
513 : : void
514 : 106512 : spdk_bdev_free_io(struct spdk_bdev_io *bdev_io)
515 : : {
516 [ + - ]: 106512 : if (bdev_io) {
517 : 106512 : free(bdev_io);
518 : 17752 : }
519 : 106512 : }
520 : :
521 : : /* It will cache split IOs for verification */
522 : : int
523 : 18 : spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
524 : : struct iovec *iov, int iovcnt,
525 : : uint64_t offset_blocks, uint64_t num_blocks,
526 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
527 : : {
528 [ + - ]: 18 : struct io_output *output = &g_io_output[g_io_output_index];
529 : 3 : struct spdk_bdev_io *child_io;
530 : :
531 [ - + ]: 18 : if (g_ignore_io_output) {
532 : 0 : return 0;
533 : : }
534 : :
535 [ + + + + : 18 : SPDK_CU_ASSERT_FATAL(g_io_output_index <= (g_max_io_size / g_strip_size) + 1);
# # ]
536 [ + + ]: 18 : if (g_bdev_io_submit_status == 0) {
537 : 18 : set_io_output(output, desc, ch, offset_blocks, num_blocks, cb, cb_arg,
538 : : SPDK_BDEV_IO_TYPE_READ);
539 : 18 : g_io_output_index++;
540 : :
541 : 18 : child_io = calloc(1, sizeof(struct spdk_bdev_io));
542 [ + + # # ]: 18 : SPDK_CU_ASSERT_FATAL(child_io != NULL);
543 : 18 : child_io_complete(child_io, cb, cb_arg);
544 : 3 : }
545 : :
546 : 18 : return g_bdev_io_submit_status;
547 : 3 : }
548 : :
549 : : int
550 : 18 : spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
551 : : struct iovec *iov, int iovcnt,
552 : : uint64_t offset_blocks, uint64_t num_blocks,
553 : : spdk_bdev_io_completion_cb cb, void *cb_arg,
554 : : struct spdk_bdev_ext_io_opts *opts)
555 : : {
556 : 18 : return spdk_bdev_readv_blocks(desc, ch, iov, iovcnt, offset_blocks, num_blocks, cb, cb_arg);
557 : : }
558 : :
559 : : int
560 : 0 : spdk_bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
561 : : struct iovec *iov, int iovcnt, void *md,
562 : : uint64_t offset_blocks, uint64_t num_blocks,
563 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
564 : : {
565 : 0 : return spdk_bdev_readv_blocks(desc, ch, iov, iovcnt, offset_blocks, num_blocks, cb, cb_arg);
566 : : }
567 : :
568 : :
569 : : void
570 : 4020 : spdk_bdev_module_release_bdev(struct spdk_bdev *bdev)
571 : : {
572 [ + - + - : 4020 : CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE);
+ - ]
573 [ + - + - : 4020 : CU_ASSERT(bdev->internal.claim.v1.module != NULL);
+ - + - +
- ]
574 [ + - + - : 4020 : bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE;
+ - ]
575 [ + - + - : 4020 : bdev->internal.claim.v1.module = NULL;
+ - + - +
- ]
576 : 4020 : }
577 : :
578 : : int
579 : 4032 : spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
580 : : struct spdk_bdev_module *module)
581 : : {
582 [ + + + - : 4032 : if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) {
+ - + + ]
583 [ + - + - : 12 : CU_ASSERT(bdev->internal.claim.v1.module != NULL);
+ - + - +
- ]
584 : 12 : return -1;
585 : : }
586 [ + - + - : 4020 : CU_ASSERT(bdev->internal.claim.v1.module == NULL);
+ - + - +
- ]
587 [ + - + - : 4020 : bdev->internal.claim_type = SPDK_BDEV_CLAIM_EXCL_WRITE;
+ - ]
588 [ + - + - : 4020 : bdev->internal.claim.v1.module = module;
+ - + - +
- ]
589 : 4020 : return 0;
590 : 672 : }
591 : :
592 : : int
593 : 324 : spdk_json_decode_object(const struct spdk_json_val *values,
594 : : const struct spdk_json_object_decoder *decoders, size_t num_decoders,
595 : : void *out)
596 : : {
597 : 54 : struct rpc_bdev_raid_create *req, *_out;
598 : 54 : size_t i;
599 : :
600 [ + + ]: 324 : if (g_json_decode_obj_err) {
601 : 18 : return -1;
602 [ + + ]: 306 : } else if (g_json_decode_obj_create) {
603 : 150 : req = g_rpc_req;
604 : 150 : _out = out;
605 : :
606 [ + + + - : 150 : _out->name = strdup(req->name);
+ - + - +
- ]
607 [ + + + - : 150 : SPDK_CU_ASSERT_FATAL(_out->name != NULL);
+ - # # ]
608 [ + - + - : 150 : _out->strip_size_kb = req->strip_size_kb;
+ - + - ]
609 [ + - + - : 150 : _out->level = req->level;
+ - + - ]
610 [ + + + - : 150 : _out->superblock_enabled = req->superblock_enabled;
+ - + - +
- ]
611 [ + - + - : 150 : _out->base_bdevs.num_base_bdevs = req->base_bdevs.num_base_bdevs;
+ - + - +
- + - ]
612 [ + + + - : 4950 : for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) {
+ - + + ]
613 [ + + + - : 4800 : _out->base_bdevs.base_bdevs[i] = strdup(req->base_bdevs.base_bdevs[i]);
+ - + - +
- + - + -
+ - + - ]
614 [ + + + - : 4800 : SPDK_CU_ASSERT_FATAL(_out->base_bdevs.base_bdevs[i]);
+ - + - +
- # # ]
615 : 800 : }
616 : 25 : } else {
617 [ + + + + ]: 156 : memcpy(out, g_rpc_req, g_rpc_req_size);
618 : : }
619 : :
620 : 306 : return 0;
621 : 54 : }
622 : :
623 : : struct spdk_json_write_ctx *
624 : 30 : spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
625 : : {
626 : 30 : return (void *)1;
627 : : }
628 : :
629 : : void
630 : 24 : spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
631 : : int error_code, const char *msg)
632 : : {
633 : 24 : g_rpc_err = 1;
634 : 24 : }
635 : :
636 : : void
637 : 36 : spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
638 : : int error_code, const char *fmt, ...)
639 : : {
640 : 36 : g_rpc_err = 1;
641 : 36 : }
642 : :
643 : : struct spdk_bdev *
644 : 4266 : spdk_bdev_get_by_name(const char *bdev_name)
645 : : {
646 : 711 : struct spdk_bdev *bdev;
647 : :
648 [ + + ]: 4266 : if (!TAILQ_EMPTY(&g_bdev_list)) {
649 [ + + - + : 107106 : TAILQ_FOREACH(bdev, &g_bdev_list, internal.link) {
- + - + -
+ ]
650 [ + + + + : 107100 : if (strcmp(bdev_name, bdev->name) == 0) {
+ + + - +
+ ]
651 : 4260 : return bdev;
652 : : }
653 : 17140 : }
654 : 1 : }
655 : :
656 : 6 : return NULL;
657 : 711 : }
658 : :
659 : : int
660 : 6 : spdk_bdev_quiesce(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
661 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
662 : : {
663 [ + - ]: 6 : if (cb_fn) {
664 [ - + + - ]: 6 : cb_fn(cb_arg, 0);
665 : 1 : }
666 : :
667 : 6 : return 0;
668 : : }
669 : :
670 : : int
671 : 6 : spdk_bdev_unquiesce(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
672 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
673 : : {
674 [ + - ]: 6 : if (cb_fn) {
675 [ - + + - ]: 6 : cb_fn(cb_arg, 0);
676 : 1 : }
677 : :
678 : 6 : return 0;
679 : : }
680 : :
681 : : int
682 : 96 : spdk_bdev_quiesce_range(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
683 : : uint64_t offset, uint64_t length,
684 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
685 : : {
686 [ + - ]: 96 : if (cb_fn) {
687 [ - + + - ]: 96 : cb_fn(cb_arg, 0);
688 : 16 : }
689 : :
690 : 96 : return 0;
691 : : }
692 : :
693 : : int
694 : 96 : spdk_bdev_unquiesce_range(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
695 : : uint64_t offset, uint64_t length,
696 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
697 : : {
698 [ + - ]: 96 : if (cb_fn) {
699 [ - + + - ]: 96 : cb_fn(cb_arg, 0);
700 : 16 : }
701 : :
702 : 96 : return 0;
703 : : }
704 : :
705 : : static void
706 : 5844 : bdev_io_cleanup(struct spdk_bdev_io *bdev_io)
707 : : {
708 [ + - + - : 5844 : if (bdev_io->u.bdev.iovs) {
+ - + - +
- ]
709 : 974 : int i;
710 : :
711 [ + + + - : 11706 : for (i = 0; i < bdev_io->u.bdev.iovcnt; i++) {
+ - + - +
+ + - ]
712 [ + - + - : 5862 : free(bdev_io->u.bdev.iovs[i].iov_base);
+ - + - +
- + - +
- ]
713 : 977 : }
714 [ + - + - : 5844 : free(bdev_io->u.bdev.iovs);
+ - + - ]
715 : 974 : }
716 : 5844 : free(bdev_io);
717 : 5844 : }
718 : :
719 : : static void
720 : 5844 : _bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch,
721 : : struct spdk_bdev *bdev, uint64_t lba, uint64_t blocks, int16_t iotype,
722 : : int iovcnt, size_t iov_len)
723 : : {
724 : 5844 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
725 : 974 : int i;
726 : :
727 [ + - + - ]: 5844 : bdev_io->bdev = bdev;
728 [ + - + - : 5844 : bdev_io->u.bdev.offset_blocks = lba;
+ - + - ]
729 [ + - + - : 5844 : bdev_io->u.bdev.num_blocks = blocks;
+ - + - ]
730 [ + - + - ]: 5844 : bdev_io->type = iotype;
731 [ + - + - : 5844 : bdev_io->internal.ch = channel;
+ - ]
732 [ + - + - : 5844 : bdev_io->u.bdev.iovcnt = iovcnt;
+ - + - ]
733 : :
734 [ + + ]: 5844 : if (iovcnt == 0) {
735 [ # # # # : 0 : bdev_io->u.bdev.iovs = NULL;
# # # # ]
736 : 0 : return;
737 : : }
738 : :
739 [ + + # # ]: 5844 : SPDK_CU_ASSERT_FATAL(iov_len * iovcnt == blocks * g_block_len);
740 : :
741 [ + - + - : 5844 : bdev_io->u.bdev.iovs = calloc(iovcnt, sizeof(struct iovec));
+ - + - ]
742 [ + + + - : 5844 : SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs != NULL);
+ - + - +
- # # ]
743 : :
744 [ + + + - ]: 11706 : for (i = 0; i < iovcnt; i++) {
745 [ + - + - : 5862 : struct iovec *iov = &bdev_io->u.bdev.iovs[i];
+ - + - +
- ]
746 : :
747 [ + - + - ]: 5862 : iov->iov_base = calloc(1, iov_len);
748 [ + + + - : 5862 : SPDK_CU_ASSERT_FATAL(iov->iov_base != NULL);
+ - # # ]
749 [ + - + - ]: 5862 : iov->iov_len = iov_len;
750 : 977 : }
751 [ - + ]: 974 : }
752 : :
753 : : static void
754 : 5838 : bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch, struct spdk_bdev *bdev,
755 : : uint64_t lba, uint64_t blocks, int16_t iotype)
756 : : {
757 : 973 : int iovcnt;
758 : 973 : size_t iov_len;
759 : :
760 [ + - + + : 5838 : if (bdev_io->type == SPDK_BDEV_IO_TYPE_UNMAP || bdev_io->type == SPDK_BDEV_IO_TYPE_FLUSH) {
+ - + - +
- - + ]
761 : 0 : iovcnt = 0;
762 : 0 : iov_len = 0;
763 : 0 : } else {
764 : 5838 : iovcnt = 1;
765 : 5838 : iov_len = blocks * g_block_len;
766 : : }
767 : :
768 : 5838 : _bdev_io_initialize(bdev_io, ch, bdev, lba, blocks, iotype, iovcnt, iov_len);
769 : 5838 : }
770 : :
771 : : static void
772 : 6 : verify_reset_io(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
773 : : struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
774 : : {
775 : 6 : uint8_t index = 0;
776 : 1 : struct io_output *output;
777 : :
778 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
779 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
780 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(io_status != INVALID_IO_SUBMIT);
781 [ + + + - : 6 : SPDK_CU_ASSERT_FATAL(ch_ctx->base_channel != NULL);
+ - # # ]
782 : :
783 : 6 : CU_ASSERT(g_io_output_index == num_base_drives);
784 [ + + ]: 198 : for (index = 0; index < g_io_output_index; index++) {
785 [ + - ]: 192 : output = &g_io_output[index];
786 [ + - + - : 192 : CU_ASSERT(ch_ctx->base_channel[index] == output->ch);
+ - + - +
- + - ]
787 [ + - + - : 192 : CU_ASSERT(raid_bdev->base_bdev_info[index].desc == output->desc);
+ - + - +
- + - +
- ]
788 [ + - + - : 192 : CU_ASSERT(bdev_io->type == output->iotype);
+ - + - ]
789 : 32 : }
790 : 6 : CU_ASSERT(g_io_comp_status == io_status);
791 : 6 : }
792 : :
793 : : static void
794 : 48 : verify_io(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
795 : : struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
796 : : {
797 : 48 : uint32_t strip_shift = spdk_u32log2(g_strip_size);
798 [ + + + - : 48 : uint64_t start_strip = bdev_io->u.bdev.offset_blocks >> strip_shift;
+ - + - +
- ]
799 [ + + + - : 48 : uint64_t end_strip = (bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) >>
+ - + - +
- + - + -
+ - + - +
- ]
800 : 8 : strip_shift;
801 : 48 : uint32_t splits_reqd = (end_strip - start_strip + 1);
802 : 8 : uint32_t strip;
803 : 8 : uint64_t pd_strip;
804 : 8 : uint8_t pd_idx;
805 : 8 : uint32_t offset_in_strip;
806 : 8 : uint64_t pd_lba;
807 : 8 : uint64_t pd_blocks;
808 : 48 : uint32_t index = 0;
809 : 8 : struct io_output *output;
810 : :
811 [ + + ]: 48 : if (io_status == INVALID_IO_SUBMIT) {
812 : 6 : CU_ASSERT(g_io_comp_status == false);
813 : 6 : return;
814 : : }
815 [ + + # # ]: 42 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
816 [ + + # # ]: 42 : SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
817 : :
818 : 42 : CU_ASSERT(splits_reqd == g_io_output_index);
819 [ + + ]: 84 : for (strip = start_strip; strip <= end_strip; strip++, index++) {
820 [ + + ]: 42 : pd_strip = strip / num_base_drives;
821 [ + + ]: 42 : pd_idx = strip % num_base_drives;
822 [ + - ]: 42 : if (strip == start_strip) {
823 [ + - + - : 42 : offset_in_strip = bdev_io->u.bdev.offset_blocks & (g_strip_size - 1);
+ - + - ]
824 [ + + ]: 42 : pd_lba = (pd_strip << strip_shift) + offset_in_strip;
825 [ + - ]: 42 : if (strip == end_strip) {
826 [ + - + - : 42 : pd_blocks = bdev_io->u.bdev.num_blocks;
+ - + - ]
827 : 7 : } else {
828 : 0 : pd_blocks = g_strip_size - offset_in_strip;
829 : : }
830 [ # # ]: 7 : } else if (strip == end_strip) {
831 [ # # ]: 0 : pd_lba = pd_strip << strip_shift;
832 [ # # # # : 0 : pd_blocks = ((bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) &
# # # # #
# # # # #
# # ]
833 : 0 : (g_strip_size - 1)) + 1;
834 : 0 : } else {
835 [ # # # # : 0 : pd_lba = pd_strip << raid_bdev->strip_size_shift;
# # ]
836 [ # # # # ]: 0 : pd_blocks = raid_bdev->strip_size;
837 : : }
838 [ + - ]: 42 : output = &g_io_output[index];
839 [ + - + - ]: 42 : CU_ASSERT(pd_lba == output->offset_blocks);
840 [ + - + - ]: 42 : CU_ASSERT(pd_blocks == output->num_blocks);
841 [ + - + - : 42 : CU_ASSERT(ch_ctx->base_channel[pd_idx] == output->ch);
+ - + - +
- + - ]
842 [ + - + - : 42 : CU_ASSERT(raid_bdev->base_bdev_info[pd_idx].desc == output->desc);
+ - + - +
- + - +
- ]
843 [ + - + - : 42 : CU_ASSERT(bdev_io->type == output->iotype);
+ - + - ]
844 : 7 : }
845 : 42 : CU_ASSERT(g_io_comp_status == io_status);
846 [ - + ]: 8 : }
847 : :
848 : : static void
849 : 5778 : verify_io_without_payload(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
850 : : struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev,
851 : : uint32_t io_status)
852 : : {
853 : 5778 : uint32_t strip_shift = spdk_u32log2(g_strip_size);
854 [ + + + - : 5778 : uint64_t start_offset_in_strip = bdev_io->u.bdev.offset_blocks % g_strip_size;
+ - + - +
- ]
855 [ + + + - : 5778 : uint64_t end_offset_in_strip = (bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) %
+ - + - +
- + - + -
+ - + - +
- ]
856 : 963 : g_strip_size;
857 [ + + + - : 5778 : uint64_t start_strip = bdev_io->u.bdev.offset_blocks >> strip_shift;
+ - + - +
- ]
858 [ + + + - : 5778 : uint64_t end_strip = (bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) >>
+ - + - +
- + - + -
+ - + - +
- ]
859 : 963 : strip_shift;
860 : 963 : uint8_t n_disks_involved;
861 : 963 : uint64_t start_strip_disk_idx;
862 : 963 : uint64_t end_strip_disk_idx;
863 : 963 : uint64_t nblocks_in_start_disk;
864 : 963 : uint64_t offset_in_start_disk;
865 : 963 : uint8_t disk_idx;
866 : 963 : uint64_t base_io_idx;
867 : 5778 : uint64_t sum_nblocks = 0;
868 : 963 : struct io_output *output;
869 : :
870 [ - + ]: 5778 : if (io_status == INVALID_IO_SUBMIT) {
871 : 0 : CU_ASSERT(g_io_comp_status == false);
872 : 0 : return;
873 : : }
874 [ + + # # ]: 5778 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
875 [ + + # # ]: 5778 : SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
876 [ + + + - : 5778 : SPDK_CU_ASSERT_FATAL(bdev_io->type != SPDK_BDEV_IO_TYPE_READ);
+ - # # ]
877 [ + + + - : 5778 : SPDK_CU_ASSERT_FATAL(bdev_io->type != SPDK_BDEV_IO_TYPE_WRITE);
+ - # # ]
878 : :
879 [ + + ]: 5778 : n_disks_involved = spdk_min(end_strip - start_strip + 1, num_base_drives);
880 : 5778 : CU_ASSERT(n_disks_involved == g_io_output_index);
881 : :
882 [ + + ]: 5778 : start_strip_disk_idx = start_strip % num_base_drives;
883 [ + + ]: 5778 : end_strip_disk_idx = end_strip % num_base_drives;
884 : :
885 [ + - + - : 5778 : offset_in_start_disk = g_io_output[0].offset_blocks;
+ - ]
886 [ + - + - : 5778 : nblocks_in_start_disk = g_io_output[0].num_blocks;
+ - ]
887 : :
888 [ + + ]: 111996 : for (base_io_idx = 0, disk_idx = start_strip_disk_idx; base_io_idx < n_disks_involved;
889 : 106218 : base_io_idx++, disk_idx++) {
890 : 17703 : uint64_t start_offset_in_disk;
891 : 17703 : uint64_t end_offset_in_disk;
892 : :
893 [ + - ]: 106218 : output = &g_io_output[base_io_idx];
894 : :
895 : : /* round disk_idx */
896 [ + + ]: 106218 : if (disk_idx >= num_base_drives) {
897 [ + + ]: 2970 : disk_idx %= num_base_drives;
898 : 495 : }
899 : :
900 : : /* start_offset_in_disk aligned in strip check:
901 : : * The first base io has a same start_offset_in_strip with the whole raid io.
902 : : * Other base io should have aligned start_offset_in_strip which is 0.
903 : : */
904 [ + - + - ]: 106218 : start_offset_in_disk = output->offset_blocks;
905 [ + + ]: 106218 : if (base_io_idx == 0) {
906 [ + + ]: 5778 : CU_ASSERT(start_offset_in_disk % g_strip_size == start_offset_in_strip);
907 : 963 : } else {
908 [ + + ]: 100440 : CU_ASSERT(start_offset_in_disk % g_strip_size == 0);
909 : : }
910 : :
911 : : /* end_offset_in_disk aligned in strip check:
912 : : * Base io on disk at which end_strip is located, has a same end_offset_in_strip
913 : : * with the whole raid io.
914 : : * Other base io should have aligned end_offset_in_strip.
915 : : */
916 [ + - + - : 106218 : end_offset_in_disk = output->offset_blocks + output->num_blocks - 1;
+ - + - ]
917 [ + + ]: 106218 : if (disk_idx == end_strip_disk_idx) {
918 [ + + ]: 5778 : CU_ASSERT(end_offset_in_disk % g_strip_size == end_offset_in_strip);
919 : 963 : } else {
920 [ + + ]: 100440 : CU_ASSERT(end_offset_in_disk % g_strip_size == g_strip_size - 1);
921 : : }
922 : :
923 : : /* start_offset_in_disk compared with start_disk.
924 : : * 1. For disk_idx which is larger than start_strip_disk_idx: Its start_offset_in_disk
925 : : * mustn't be larger than the start offset of start_offset_in_disk; And the gap
926 : : * must be less than strip size.
927 : : * 2. For disk_idx which is less than start_strip_disk_idx, Its start_offset_in_disk
928 : : * must be larger than the start offset of start_offset_in_disk; And the gap mustn't
929 : : * be less than strip size.
930 : : */
931 [ + + ]: 106218 : if (disk_idx > start_strip_disk_idx) {
932 : 56160 : CU_ASSERT(start_offset_in_disk <= offset_in_start_disk);
933 : 56160 : CU_ASSERT(offset_in_start_disk - start_offset_in_disk < g_strip_size);
934 [ + + ]: 59418 : } else if (disk_idx < start_strip_disk_idx) {
935 : 44280 : CU_ASSERT(start_offset_in_disk > offset_in_start_disk);
936 [ + - + - ]: 44280 : CU_ASSERT(output->offset_blocks - offset_in_start_disk <= g_strip_size);
937 : 7380 : }
938 : :
939 : : /* nblocks compared with start_disk:
940 : : * The gap between them must be within a strip size.
941 : : */
942 [ + + + - : 106218 : if (output->num_blocks <= nblocks_in_start_disk) {
+ + ]
943 [ + - + - ]: 42264 : CU_ASSERT(nblocks_in_start_disk - output->num_blocks <= g_strip_size);
944 : 7044 : } else {
945 [ + - + - ]: 63954 : CU_ASSERT(output->num_blocks - nblocks_in_start_disk < g_strip_size);
946 : : }
947 : :
948 [ + - + - ]: 106218 : sum_nblocks += output->num_blocks;
949 : :
950 [ + - + - : 106218 : CU_ASSERT(ch_ctx->base_channel[disk_idx] == output->ch);
+ - + - +
- + - ]
951 [ + - + - : 106218 : CU_ASSERT(raid_bdev->base_bdev_info[disk_idx].desc == output->desc);
+ - + - +
- + - +
- ]
952 [ + - + - : 106218 : CU_ASSERT(bdev_io->type == output->iotype);
+ - + - ]
953 : 17703 : }
954 : :
955 : : /* Sum of each nblocks should be same with raid bdev_io */
956 [ + - + - : 5778 : CU_ASSERT(bdev_io->u.bdev.num_blocks == sum_nblocks);
+ - + - ]
957 : :
958 : 5778 : CU_ASSERT(g_io_comp_status == io_status);
959 [ - + ]: 963 : }
960 : :
961 : : static void
962 : 252 : verify_raid_bdev_present(const char *name, bool presence)
963 : : {
964 : 42 : struct raid_bdev *pbdev;
965 : 42 : bool pbdev_found;
966 : :
967 : 252 : pbdev_found = false;
968 [ + + + - : 300 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
+ - + - ]
969 [ + + + + : 72 : if (strcmp(pbdev->bdev.name, name) == 0) {
+ + + - +
- + + ]
970 : 24 : pbdev_found = true;
971 : 24 : break;
972 : : }
973 : 8 : }
974 [ + + + + ]: 252 : if (presence == true) {
975 [ + - ]: 24 : CU_ASSERT(pbdev_found == true);
976 : 4 : } else {
977 [ + - ]: 228 : CU_ASSERT(pbdev_found == false);
978 : : }
979 : 252 : }
980 : :
981 : : static void
982 : 108 : verify_raid_bdev(struct rpc_bdev_raid_create *r, bool presence, uint32_t raid_state)
983 : : {
984 : 18 : struct raid_bdev *pbdev;
985 : 18 : struct raid_base_bdev_info *base_info;
986 : 108 : struct spdk_bdev *bdev = NULL;
987 : 18 : bool pbdev_found;
988 : 108 : uint64_t min_blockcnt = 0xFFFFFFFFFFFFFFFF;
989 : :
990 : 108 : pbdev_found = false;
991 [ + + + - : 120 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
+ - + - ]
992 [ + + + + : 120 : if (strcmp(pbdev->bdev.name, r->name) == 0) {
+ + + - +
- + - + -
+ + ]
993 : 108 : pbdev_found = true;
994 [ + + + - ]: 108 : if (presence == false) {
995 : 0 : break;
996 : : }
997 [ + - + - ]: 108 : CU_ASSERT(pbdev->base_bdev_info != NULL);
998 [ + + + - : 108 : CU_ASSERT(pbdev->strip_size == ((r->strip_size_kb * 1024) / g_block_len));
+ - + - +
- ]
999 [ + + + - : 108 : CU_ASSERT(pbdev->strip_size_shift == spdk_u32log2(((r->strip_size_kb * 1024) /
+ - + - +
- ]
1000 : : g_block_len)));
1001 [ + - + - ]: 108 : CU_ASSERT(pbdev->blocklen_shift == spdk_u32log2(g_block_len));
1002 [ + - + - ]: 108 : CU_ASSERT((uint32_t)pbdev->state == raid_state);
1003 [ + - + - : 108 : CU_ASSERT(pbdev->num_base_bdevs == r->base_bdevs.num_base_bdevs);
+ - + - +
- ]
1004 [ + - + - : 108 : CU_ASSERT(pbdev->num_base_bdevs_discovered == r->base_bdevs.num_base_bdevs);
+ - + - +
- ]
1005 [ + - + - : 108 : CU_ASSERT(pbdev->level == r->level);
+ - + - ]
1006 [ + - + - ]: 108 : CU_ASSERT(pbdev->base_bdev_info != NULL);
1007 [ + + + - : 3564 : RAID_FOR_EACH_BASE_BDEV(pbdev, base_info) {
+ - + - +
- + - + -
+ + + - ]
1008 [ + - + - ]: 3456 : CU_ASSERT(base_info->desc != NULL);
1009 [ + - + - ]: 3456 : bdev = spdk_bdev_desc_get_bdev(base_info->desc);
1010 : 3456 : CU_ASSERT(bdev != NULL);
1011 [ + + + - : 3456 : CU_ASSERT(base_info->remove_scheduled == false);
+ - ]
1012 [ + + + + : 3456 : CU_ASSERT((pbdev->sb != NULL && base_info->data_offset != 0) ||
+ + + - +
- + - + -
+ - - + +
- + - ]
1013 : : (pbdev->sb == NULL && base_info->data_offset == 0));
1014 [ + - + - : 3456 : CU_ASSERT(base_info->data_offset + base_info->data_size == bdev->blockcnt);
+ - + - +
- + - ]
1015 : :
1016 [ + - + + : 3456 : if (bdev && base_info->data_size < min_blockcnt) {
+ - + + ]
1017 [ + - + - ]: 108 : min_blockcnt = base_info->data_size;
1018 : 18 : }
1019 : 576 : }
1020 [ + + + + : 108 : CU_ASSERT((((min_blockcnt / (r->strip_size_kb * 1024 / g_block_len)) *
+ + + - +
- + - + -
+ - + - +
- + - + -
+ - ]
1021 : : (r->strip_size_kb * 1024 / g_block_len)) *
1022 : : r->base_bdevs.num_base_bdevs) == pbdev->bdev.blockcnt);
1023 [ + + + - : 108 : CU_ASSERT(strcmp(pbdev->bdev.product_name, "Raid Volume") == 0);
+ - + - +
- ]
1024 [ + - + - : 108 : CU_ASSERT(pbdev->bdev.write_cache == 0);
+ - ]
1025 [ + - + - : 108 : CU_ASSERT(pbdev->bdev.blocklen == g_block_len);
+ - ]
1026 [ + - + - : 108 : if (pbdev->num_base_bdevs > 1) {
+ - ]
1027 [ + - + - : 108 : CU_ASSERT(pbdev->bdev.optimal_io_boundary == pbdev->strip_size);
+ - + - +
- ]
1028 [ + + + - : 108 : CU_ASSERT(pbdev->bdev.split_on_optimal_io_boundary == true);
+ - + - ]
1029 : 18 : } else {
1030 [ # # # # : 0 : CU_ASSERT(pbdev->bdev.optimal_io_boundary == 0);
# # ]
1031 [ # # # # : 0 : CU_ASSERT(pbdev->bdev.split_on_optimal_io_boundary == false);
# # # # ]
1032 : : }
1033 [ + - + - : 108 : CU_ASSERT(pbdev->bdev.ctxt == pbdev);
+ - ]
1034 [ + - + - : 108 : CU_ASSERT(pbdev->bdev.fn_table == &g_raid_bdev_fn_table);
+ - ]
1035 [ + - + - : 108 : CU_ASSERT(pbdev->bdev.module == &g_raid_if);
+ - ]
1036 : 108 : break;
1037 : : }
1038 : 2 : }
1039 [ + - + - ]: 108 : if (presence == true) {
1040 [ + - ]: 108 : CU_ASSERT(pbdev_found == true);
1041 : 18 : } else {
1042 [ # # ]: 0 : CU_ASSERT(pbdev_found == false);
1043 : : }
1044 : 108 : }
1045 : :
1046 : : static void
1047 : 12 : verify_get_raids(struct rpc_bdev_raid_create *construct_req,
1048 : : uint8_t g_max_raids,
1049 : : char **g_get_raids_output, uint32_t g_get_raids_count)
1050 : : {
1051 : 2 : uint8_t i, j;
1052 : 2 : bool found;
1053 : :
1054 : 12 : CU_ASSERT(g_max_raids == g_get_raids_count);
1055 [ + + ]: 12 : if (g_max_raids == g_get_raids_count) {
1056 [ + + ]: 36 : for (i = 0; i < g_max_raids; i++) {
1057 : 24 : found = false;
1058 [ + + ]: 24 : for (j = 0; j < g_max_raids; j++) {
1059 [ + - + - : 28 : if (construct_req[i].name &&
+ - + - -
+ ]
1060 [ + + + + : 24 : strcmp(construct_req[i].name, g_get_raids_output[i]) == 0) {
+ - + - +
- + - +
- ]
1061 : 24 : found = true;
1062 : 24 : break;
1063 : : }
1064 : 0 : }
1065 [ - + ]: 24 : CU_ASSERT(found == true);
1066 : 4 : }
1067 : 2 : }
1068 : 12 : }
1069 : :
1070 : : static void
1071 : 120 : create_base_bdevs(uint32_t bbdev_start_idx)
1072 : : {
1073 : 20 : uint8_t i;
1074 : 20 : struct spdk_bdev *base_bdev;
1075 : 100 : char name[16];
1076 : :
1077 [ + + ]: 3960 : for (i = 0; i < g_max_base_drives; i++, bbdev_start_idx++) {
1078 [ - + ]: 3840 : snprintf(name, 16, "%s%u%s", "Nvme", bbdev_start_idx, "n1");
1079 : 3840 : base_bdev = calloc(1, sizeof(struct spdk_bdev));
1080 [ + + # # ]: 3840 : SPDK_CU_ASSERT_FATAL(base_bdev != NULL);
1081 [ + + + - : 3840 : base_bdev->name = strdup(name);
+ - ]
1082 [ + - ]: 3840 : spdk_uuid_generate(&base_bdev->uuid);
1083 [ + + + - : 3840 : SPDK_CU_ASSERT_FATAL(base_bdev->name != NULL);
+ - # # ]
1084 [ + - + - ]: 3840 : base_bdev->blocklen = g_block_len;
1085 [ + - + - ]: 3840 : base_bdev->blockcnt = BLOCK_CNT;
1086 [ + - + - : 3840 : TAILQ_INSERT_TAIL(&g_bdev_list, base_bdev, internal.link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1087 : 640 : }
1088 : 120 : }
1089 : :
1090 : : static void
1091 : 156 : create_test_req(struct rpc_bdev_raid_create *r, const char *raid_name,
1092 : : uint8_t bbdev_start_idx, bool create_base_bdev, bool superblock_enabled)
1093 : : {
1094 : 26 : uint8_t i;
1095 : 130 : char name[16];
1096 : 156 : uint8_t bbdev_idx = bbdev_start_idx;
1097 : :
1098 [ + + + - : 156 : r->name = strdup(raid_name);
+ - ]
1099 [ + + + - : 156 : SPDK_CU_ASSERT_FATAL(r->name != NULL);
+ - # # ]
1100 [ + - + - : 156 : r->strip_size_kb = (g_strip_size * g_block_len) / 1024;
+ - ]
1101 [ + - + - ]: 156 : r->level = RAID0;
1102 [ + - + - : 156 : r->superblock_enabled = superblock_enabled;
+ - ]
1103 [ + - + - : 156 : r->base_bdevs.num_base_bdevs = g_max_base_drives;
+ - ]
1104 [ + + ]: 5148 : for (i = 0; i < g_max_base_drives; i++, bbdev_idx++) {
1105 [ - + ]: 4992 : snprintf(name, 16, "%s%u%s", "Nvme", bbdev_idx, "n1");
1106 [ + + + - : 4992 : r->base_bdevs.base_bdevs[i] = strdup(name);
+ - + - +
- ]
1107 [ + + + - : 4992 : SPDK_CU_ASSERT_FATAL(r->base_bdevs.base_bdevs[i] != NULL);
+ - + - +
- # # ]
1108 : 832 : }
1109 [ + + + + ]: 156 : if (create_base_bdev == true) {
1110 : 120 : create_base_bdevs(bbdev_start_idx);
1111 : 20 : }
1112 : 156 : g_rpc_req = r;
1113 : 156 : g_rpc_req_size = sizeof(*r);
1114 : 156 : }
1115 : :
1116 : : static void
1117 : 156 : create_raid_bdev_create_req(struct rpc_bdev_raid_create *r, const char *raid_name,
1118 : : uint8_t bbdev_start_idx, bool create_base_bdev,
1119 : : uint8_t json_decode_obj_err, bool superblock_enabled)
1120 : : {
1121 [ + - + - ]: 156 : create_test_req(r, raid_name, bbdev_start_idx, create_base_bdev, superblock_enabled);
1122 : :
1123 : 156 : g_rpc_err = 0;
1124 : 156 : g_json_decode_obj_create = 1;
1125 : 156 : g_json_decode_obj_err = json_decode_obj_err;
1126 : 156 : g_config_level_create = 0;
1127 : 156 : g_test_multi_raids = 0;
1128 : 156 : }
1129 : :
1130 : : static void
1131 : 156 : free_test_req(struct rpc_bdev_raid_create *r)
1132 : : {
1133 : 26 : uint8_t i;
1134 : :
1135 [ + - + - ]: 156 : free(r->name);
1136 [ + + + - : 5148 : for (i = 0; i < r->base_bdevs.num_base_bdevs; i++) {
+ - + + ]
1137 [ + - + - : 4992 : free(r->base_bdevs.base_bdevs[i]);
+ - + - ]
1138 : 832 : }
1139 : 156 : }
1140 : :
1141 : : static void
1142 : 126 : create_raid_bdev_delete_req(struct rpc_bdev_raid_delete *r, const char *raid_name,
1143 : : uint8_t json_decode_obj_err)
1144 : : {
1145 [ + + + - : 126 : r->name = strdup(raid_name);
+ - ]
1146 [ + + + - : 126 : SPDK_CU_ASSERT_FATAL(r->name != NULL);
+ - # # ]
1147 : :
1148 : 126 : g_rpc_req = r;
1149 : 126 : g_rpc_req_size = sizeof(*r);
1150 : 126 : g_rpc_err = 0;
1151 : 126 : g_json_decode_obj_create = 0;
1152 : 126 : g_json_decode_obj_err = json_decode_obj_err;
1153 : 126 : g_config_level_create = 0;
1154 : 126 : g_test_multi_raids = 0;
1155 : 126 : }
1156 : :
1157 : : static void
1158 : 42 : create_get_raids_req(struct rpc_bdev_raid_get_bdevs *r, const char *category,
1159 : : uint8_t json_decode_obj_err)
1160 : : {
1161 [ + + + - : 42 : r->category = strdup(category);
+ - ]
1162 [ + + + - : 42 : SPDK_CU_ASSERT_FATAL(r->category != NULL);
+ - # # ]
1163 : :
1164 : 42 : g_rpc_req = r;
1165 : 42 : g_rpc_req_size = sizeof(*r);
1166 : 42 : g_rpc_err = 0;
1167 : 42 : g_json_decode_obj_create = 0;
1168 : 42 : g_json_decode_obj_err = json_decode_obj_err;
1169 : 42 : g_config_level_create = 0;
1170 : 42 : g_test_multi_raids = 1;
1171 : 42 : g_get_raids_count = 0;
1172 : 42 : }
1173 : :
1174 : : static void
1175 : 6 : test_create_raid(void)
1176 : : {
1177 : 5 : struct rpc_bdev_raid_create req;
1178 : 5 : struct rpc_bdev_raid_delete delete_req;
1179 : :
1180 : 6 : set_globals();
1181 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1182 : :
1183 : 6 : verify_raid_bdev_present("raid1", false);
1184 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1185 : 6 : rpc_bdev_raid_create(NULL, NULL);
1186 : 6 : CU_ASSERT(g_rpc_err == 0);
1187 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1188 : 6 : free_test_req(&req);
1189 : :
1190 : 6 : create_raid_bdev_delete_req(&delete_req, "raid1", 0);
1191 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1192 : 6 : CU_ASSERT(g_rpc_err == 0);
1193 : 6 : raid_bdev_exit();
1194 : 6 : base_bdevs_cleanup();
1195 : 6 : reset_globals();
1196 : 6 : }
1197 : :
1198 : : static void
1199 : 6 : test_delete_raid(void)
1200 : : {
1201 : 5 : struct rpc_bdev_raid_create construct_req;
1202 : 5 : struct rpc_bdev_raid_delete delete_req;
1203 : :
1204 : 6 : set_globals();
1205 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1206 : :
1207 : 6 : verify_raid_bdev_present("raid1", false);
1208 : 6 : create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
1209 : 6 : rpc_bdev_raid_create(NULL, NULL);
1210 : 6 : CU_ASSERT(g_rpc_err == 0);
1211 : 6 : verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
1212 : 6 : free_test_req(&construct_req);
1213 : :
1214 : 6 : create_raid_bdev_delete_req(&delete_req, "raid1", 0);
1215 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1216 : 6 : CU_ASSERT(g_rpc_err == 0);
1217 : 6 : verify_raid_bdev_present("raid1", false);
1218 : :
1219 : 6 : raid_bdev_exit();
1220 : 6 : base_bdevs_cleanup();
1221 : 6 : reset_globals();
1222 : 6 : }
1223 : :
1224 : : static void
1225 : 6 : test_create_raid_invalid_args(void)
1226 : : {
1227 : 5 : struct rpc_bdev_raid_create req;
1228 : 5 : struct rpc_bdev_raid_delete destroy_req;
1229 : 1 : struct raid_bdev *raid_bdev;
1230 : :
1231 : 6 : set_globals();
1232 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1233 : :
1234 : 6 : verify_raid_bdev_present("raid1", false);
1235 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1236 [ + - ]: 6 : req.level = INVALID_RAID_LEVEL;
1237 : 6 : rpc_bdev_raid_create(NULL, NULL);
1238 : 6 : CU_ASSERT(g_rpc_err == 1);
1239 : 6 : free_test_req(&req);
1240 : 6 : verify_raid_bdev_present("raid1", false);
1241 : :
1242 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, false, 1, false);
1243 : 6 : rpc_bdev_raid_create(NULL, NULL);
1244 : 6 : CU_ASSERT(g_rpc_err == 1);
1245 : 6 : free_test_req(&req);
1246 : 6 : verify_raid_bdev_present("raid1", false);
1247 : :
1248 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
1249 [ + - ]: 6 : req.strip_size_kb = 1231;
1250 : 6 : rpc_bdev_raid_create(NULL, NULL);
1251 : 6 : CU_ASSERT(g_rpc_err == 1);
1252 : 6 : free_test_req(&req);
1253 : 6 : verify_raid_bdev_present("raid1", false);
1254 : :
1255 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
1256 : 6 : rpc_bdev_raid_create(NULL, NULL);
1257 : 6 : CU_ASSERT(g_rpc_err == 0);
1258 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1259 : 6 : free_test_req(&req);
1260 : :
1261 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
1262 : 6 : rpc_bdev_raid_create(NULL, NULL);
1263 : 6 : CU_ASSERT(g_rpc_err == 1);
1264 : 6 : free_test_req(&req);
1265 : :
1266 : 6 : create_raid_bdev_create_req(&req, "raid2", 0, false, 0, false);
1267 : 6 : rpc_bdev_raid_create(NULL, NULL);
1268 : 6 : CU_ASSERT(g_rpc_err == 1);
1269 : 6 : free_test_req(&req);
1270 : 6 : verify_raid_bdev_present("raid2", false);
1271 : :
1272 : 6 : create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
1273 [ + - + - : 6 : free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
+ - + - ]
1274 [ + + + - : 6 : req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme0n1");
+ - + - +
- ]
1275 [ + + + - : 6 : SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
+ - + - +
- # # ]
1276 : 6 : rpc_bdev_raid_create(NULL, NULL);
1277 : 6 : CU_ASSERT(g_rpc_err == 1);
1278 : 6 : free_test_req(&req);
1279 : 6 : verify_raid_bdev_present("raid2", false);
1280 : :
1281 : 6 : create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
1282 [ + - + - : 6 : free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
+ - + - ]
1283 [ + + + - : 6 : req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme100000n1");
+ - + - +
- ]
1284 [ + + + - : 6 : SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
+ - + - +
- # # ]
1285 : 6 : rpc_bdev_raid_create(NULL, NULL);
1286 : 6 : CU_ASSERT(g_rpc_err == 0);
1287 : 6 : free_test_req(&req);
1288 : 6 : verify_raid_bdev_present("raid2", true);
1289 : 6 : raid_bdev = raid_bdev_find_by_name("raid2");
1290 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
1291 : 6 : check_and_remove_raid_bdev(raid_bdev);
1292 : :
1293 : 6 : create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, false, 0, false);
1294 : 6 : rpc_bdev_raid_create(NULL, NULL);
1295 : 6 : CU_ASSERT(g_rpc_err == 0);
1296 : 6 : free_test_req(&req);
1297 : 6 : verify_raid_bdev_present("raid2", true);
1298 : 6 : verify_raid_bdev_present("raid1", true);
1299 : :
1300 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1301 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1302 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid2", 0);
1303 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1304 : 6 : raid_bdev_exit();
1305 : 6 : base_bdevs_cleanup();
1306 : 6 : reset_globals();
1307 : 6 : }
1308 : :
1309 : : static void
1310 : 6 : test_delete_raid_invalid_args(void)
1311 : : {
1312 : 5 : struct rpc_bdev_raid_create construct_req;
1313 : 5 : struct rpc_bdev_raid_delete destroy_req;
1314 : :
1315 : 6 : set_globals();
1316 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1317 : :
1318 : 6 : verify_raid_bdev_present("raid1", false);
1319 : 6 : create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
1320 : 6 : rpc_bdev_raid_create(NULL, NULL);
1321 : 6 : CU_ASSERT(g_rpc_err == 0);
1322 : 6 : verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
1323 : 6 : free_test_req(&construct_req);
1324 : :
1325 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid2", 0);
1326 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1327 : 6 : CU_ASSERT(g_rpc_err == 1);
1328 : :
1329 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 1);
1330 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1331 : 6 : CU_ASSERT(g_rpc_err == 1);
1332 : 6 : free(destroy_req.name);
1333 : 6 : verify_raid_bdev_present("raid1", true);
1334 : :
1335 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1336 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1337 : 6 : CU_ASSERT(g_rpc_err == 0);
1338 : 6 : verify_raid_bdev_present("raid1", false);
1339 : :
1340 : 6 : raid_bdev_exit();
1341 : 6 : base_bdevs_cleanup();
1342 : 6 : reset_globals();
1343 : 6 : }
1344 : :
1345 : : static void
1346 : 6 : test_io_channel(void)
1347 : : {
1348 : 5 : struct rpc_bdev_raid_create req;
1349 : 5 : struct rpc_bdev_raid_delete destroy_req;
1350 : 1 : struct raid_bdev *pbdev;
1351 : 1 : struct spdk_io_channel *ch;
1352 : 1 : struct raid_bdev_io_channel *ch_ctx;
1353 : :
1354 : 6 : set_globals();
1355 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1356 : :
1357 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1358 : 6 : verify_raid_bdev_present("raid1", false);
1359 : 6 : rpc_bdev_raid_create(NULL, NULL);
1360 : 6 : CU_ASSERT(g_rpc_err == 0);
1361 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1362 : :
1363 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1364 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
1365 : 6 : break;
1366 : : }
1367 : 0 : }
1368 : 6 : CU_ASSERT(pbdev != NULL);
1369 : :
1370 : 6 : ch = spdk_get_io_channel(pbdev);
1371 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1372 : :
1373 : 6 : ch_ctx = spdk_io_channel_get_ctx(ch);
1374 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1375 : :
1376 : 6 : free_test_req(&req);
1377 : :
1378 : 6 : spdk_put_io_channel(ch);
1379 : :
1380 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1381 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1382 : 6 : CU_ASSERT(g_rpc_err == 0);
1383 : 6 : verify_raid_bdev_present("raid1", false);
1384 : :
1385 : 6 : raid_bdev_exit();
1386 : 6 : base_bdevs_cleanup();
1387 : 6 : reset_globals();
1388 : 6 : }
1389 : :
1390 : : static void
1391 : 6 : test_write_io(void)
1392 : : {
1393 : 5 : struct rpc_bdev_raid_create req;
1394 : 5 : struct rpc_bdev_raid_delete destroy_req;
1395 : 1 : struct raid_bdev *pbdev;
1396 : 1 : struct spdk_io_channel *ch;
1397 : 1 : struct raid_bdev_io_channel *ch_ctx;
1398 : 1 : uint8_t i;
1399 : 1 : struct spdk_bdev_io *bdev_io;
1400 : 1 : uint64_t io_len;
1401 : 6 : uint64_t lba = 0;
1402 : :
1403 : 6 : set_globals();
1404 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1405 : :
1406 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1407 : 6 : verify_raid_bdev_present("raid1", false);
1408 : 6 : rpc_bdev_raid_create(NULL, NULL);
1409 : 6 : CU_ASSERT(g_rpc_err == 0);
1410 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1411 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1412 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
1413 : 6 : break;
1414 : : }
1415 : 0 : }
1416 : 6 : CU_ASSERT(pbdev != NULL);
1417 : :
1418 : 6 : ch = spdk_get_io_channel(pbdev);
1419 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1420 : :
1421 : 6 : ch_ctx = spdk_io_channel_get_ctx(ch);
1422 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1423 : :
1424 : : /* test 2 IO sizes based on global strip size set earlier */
1425 [ + + ]: 18 : for (i = 0; i < 2; i++) {
1426 : 12 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1427 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1428 [ + + + - ]: 12 : io_len = (g_strip_size / 2) << i;
1429 [ + - ]: 12 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_WRITE);
1430 : 12 : lba += g_strip_size;
1431 [ + + + + ]: 12 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
1432 : 12 : g_io_output_index = 0;
1433 : 12 : raid_bdev_submit_request(ch, bdev_io);
1434 [ + + + - ]: 12 : verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1435 [ + - ]: 2 : g_child_io_status_flag);
1436 : 12 : bdev_io_cleanup(bdev_io);
1437 : 2 : }
1438 : :
1439 : 6 : free_test_req(&req);
1440 : 6 : spdk_put_io_channel(ch);
1441 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1442 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1443 : 6 : CU_ASSERT(g_rpc_err == 0);
1444 : 6 : verify_raid_bdev_present("raid1", false);
1445 : :
1446 : 6 : raid_bdev_exit();
1447 : 6 : base_bdevs_cleanup();
1448 : 6 : reset_globals();
1449 : 6 : }
1450 : :
1451 : : static void
1452 : 6 : test_read_io(void)
1453 : : {
1454 : 5 : struct rpc_bdev_raid_create req;
1455 : 5 : struct rpc_bdev_raid_delete destroy_req;
1456 : 1 : struct raid_bdev *pbdev;
1457 : 1 : struct spdk_io_channel *ch;
1458 : 1 : struct raid_bdev_io_channel *ch_ctx;
1459 : 1 : uint8_t i;
1460 : 1 : struct spdk_bdev_io *bdev_io;
1461 : 1 : uint64_t io_len;
1462 : 1 : uint64_t lba;
1463 : :
1464 : 6 : set_globals();
1465 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1466 : :
1467 : 6 : verify_raid_bdev_present("raid1", false);
1468 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1469 : 6 : rpc_bdev_raid_create(NULL, NULL);
1470 : 6 : CU_ASSERT(g_rpc_err == 0);
1471 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1472 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1473 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
1474 : 6 : break;
1475 : : }
1476 : 0 : }
1477 : 6 : CU_ASSERT(pbdev != NULL);
1478 : :
1479 : 6 : ch = spdk_get_io_channel(pbdev);
1480 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1481 : :
1482 : 6 : ch_ctx = spdk_io_channel_get_ctx(ch);
1483 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1484 : :
1485 : : /* test 2 IO sizes based on global strip size set earlier */
1486 : 6 : lba = 0;
1487 [ + + ]: 18 : for (i = 0; i < 2; i++) {
1488 : 12 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1489 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1490 [ + + + - ]: 12 : io_len = (g_strip_size / 2) << i;
1491 [ + - ]: 12 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_READ);
1492 : 12 : lba += g_strip_size;
1493 [ + + + + ]: 12 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
1494 : 12 : g_io_output_index = 0;
1495 : 12 : raid_bdev_submit_request(ch, bdev_io);
1496 [ + + + - ]: 12 : verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1497 [ + - ]: 2 : g_child_io_status_flag);
1498 : 12 : bdev_io_cleanup(bdev_io);
1499 : 2 : }
1500 : :
1501 : 6 : free_test_req(&req);
1502 : 6 : spdk_put_io_channel(ch);
1503 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1504 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1505 : 6 : CU_ASSERT(g_rpc_err == 0);
1506 : 6 : verify_raid_bdev_present("raid1", false);
1507 : :
1508 : 6 : raid_bdev_exit();
1509 : 6 : base_bdevs_cleanup();
1510 : 6 : reset_globals();
1511 : 6 : }
1512 : :
1513 : : static void
1514 : 216 : raid_bdev_io_generate_by_strips(uint64_t n_strips)
1515 : : {
1516 : 36 : uint64_t lba;
1517 : 36 : uint64_t nblocks;
1518 : 36 : uint64_t start_offset;
1519 : 36 : uint64_t end_offset;
1520 : 180 : uint64_t offsets_in_strip[3];
1521 : 36 : uint64_t start_bdev_idx;
1522 : 36 : uint64_t start_bdev_offset;
1523 : 180 : uint64_t start_bdev_idxs[3];
1524 : 36 : int i, j, l;
1525 : :
1526 : : /* 3 different situations of offset in strip */
1527 [ + - + - ]: 216 : offsets_in_strip[0] = 0;
1528 [ + - + - : 216 : offsets_in_strip[1] = g_strip_size >> 1;
+ - + - ]
1529 [ + - + - : 216 : offsets_in_strip[2] = g_strip_size - 1;
+ - ]
1530 : :
1531 : : /* 3 different situations of start_bdev_idx */
1532 [ + - + - ]: 216 : start_bdev_idxs[0] = 0;
1533 [ + - + - : 216 : start_bdev_idxs[1] = g_max_base_drives >> 1;
+ - + - ]
1534 [ + - + - : 216 : start_bdev_idxs[2] = g_max_base_drives - 1;
+ - + - ]
1535 : :
1536 : : /* consider different offset in strip */
1537 [ + + + - ]: 864 : for (i = 0; i < 3; i++) {
1538 [ + - + - : 648 : start_offset = offsets_in_strip[i];
+ - ]
1539 [ + + + - ]: 2592 : for (j = 0; j < 3; j++) {
1540 [ + - + - : 1944 : end_offset = offsets_in_strip[j];
+ - ]
1541 [ + + + + ]: 1944 : if (n_strips == 1 && start_offset > end_offset) {
1542 : 18 : continue;
1543 : : }
1544 : :
1545 : : /* consider at which base_bdev lba is started. */
1546 [ + + + - ]: 7704 : for (l = 0; l < 3; l++) {
1547 [ + - + - : 5778 : start_bdev_idx = start_bdev_idxs[l];
+ - ]
1548 : 5778 : start_bdev_offset = start_bdev_idx * g_strip_size;
1549 : 5778 : lba = g_lba_offset + start_bdev_offset + start_offset;
1550 : 5778 : nblocks = (n_strips - 1) * g_strip_size + end_offset - start_offset + 1;
1551 : :
1552 [ + - + - : 5778 : g_io_ranges[g_io_range_idx].lba = lba;
+ - + - ]
1553 [ + - + - : 5778 : g_io_ranges[g_io_range_idx].nblocks = nblocks;
+ - + - ]
1554 : :
1555 [ + + # # ]: 5778 : SPDK_CU_ASSERT_FATAL(g_io_range_idx < MAX_TEST_IO_RANGE);
1556 : 5778 : g_io_range_idx++;
1557 : 963 : }
1558 : 321 : }
1559 : 108 : }
1560 : 216 : }
1561 : :
1562 : : static void
1563 : 6 : raid_bdev_io_generate(void)
1564 : : {
1565 : 1 : uint64_t n_strips;
1566 : 6 : uint64_t n_strips_span = g_max_base_drives;
1567 [ + - + - : 6 : uint64_t n_strips_times[5] = {g_max_base_drives + 1, g_max_base_drives * 2 - 1,
+ - ]
1568 [ + - + - : 6 : g_max_base_drives * 2, g_max_base_drives * 3,
+ - ]
1569 [ + - ]: 6 : g_max_base_drives * 4
1570 : : };
1571 : 1 : uint32_t i;
1572 : :
1573 : 6 : g_io_range_idx = 0;
1574 : :
1575 : : /* consider different number of strips from 1 to strips spanned base bdevs,
1576 : : * and even to times of strips spanned base bdevs
1577 : : */
1578 [ + + ]: 192 : for (n_strips = 1; n_strips < n_strips_span; n_strips++) {
1579 : 186 : raid_bdev_io_generate_by_strips(n_strips);
1580 : 31 : }
1581 : :
1582 [ + + ]: 36 : for (i = 0; i < SPDK_COUNTOF(n_strips_times); i++) {
1583 [ + - + - : 30 : n_strips = n_strips_times[i];
+ - ]
1584 : 30 : raid_bdev_io_generate_by_strips(n_strips);
1585 : 5 : }
1586 : 6 : }
1587 : :
1588 : : static void
1589 : 6 : test_unmap_io(void)
1590 : : {
1591 : 5 : struct rpc_bdev_raid_create req;
1592 : 5 : struct rpc_bdev_raid_delete destroy_req;
1593 : 1 : struct raid_bdev *pbdev;
1594 : 1 : struct spdk_io_channel *ch;
1595 : 1 : struct raid_bdev_io_channel *ch_ctx;
1596 : 1 : struct spdk_bdev_io *bdev_io;
1597 : 1 : uint32_t count;
1598 : 1 : uint64_t io_len;
1599 : 1 : uint64_t lba;
1600 : :
1601 : 6 : set_globals();
1602 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1603 : :
1604 : 6 : verify_raid_bdev_present("raid1", false);
1605 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1606 : 6 : rpc_bdev_raid_create(NULL, NULL);
1607 : 6 : CU_ASSERT(g_rpc_err == 0);
1608 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1609 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1610 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
1611 : 6 : break;
1612 : : }
1613 : 0 : }
1614 : 6 : CU_ASSERT(pbdev != NULL);
1615 : :
1616 : 6 : ch = spdk_get_io_channel(pbdev);
1617 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1618 : :
1619 : 6 : ch_ctx = spdk_io_channel_get_ctx(ch);
1620 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1621 : :
1622 : 6 : CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_UNMAP) == true);
1623 : 6 : CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_FLUSH) == true);
1624 : :
1625 : 6 : raid_bdev_io_generate();
1626 [ + + ]: 5784 : for (count = 0; count < g_io_range_idx; count++) {
1627 : 5778 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1628 [ + + # # ]: 5778 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1629 [ + - + - : 5778 : io_len = g_io_ranges[count].nblocks;
+ - + - ]
1630 [ + - + - : 5778 : lba = g_io_ranges[count].lba;
+ - + - ]
1631 [ + - ]: 5778 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_UNMAP);
1632 [ + + ]: 5778 : memset(g_io_output, 0, g_max_base_drives * sizeof(struct io_output));
1633 : 5778 : g_io_output_index = 0;
1634 : 5778 : raid_bdev_submit_request(ch, bdev_io);
1635 [ + + + - ]: 5778 : verify_io_without_payload(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1636 [ + - ]: 963 : g_child_io_status_flag);
1637 : 5778 : bdev_io_cleanup(bdev_io);
1638 : 963 : }
1639 : :
1640 : 6 : free_test_req(&req);
1641 : 6 : spdk_put_io_channel(ch);
1642 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1643 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1644 : 6 : CU_ASSERT(g_rpc_err == 0);
1645 : 6 : verify_raid_bdev_present("raid1", false);
1646 : :
1647 : 6 : raid_bdev_exit();
1648 : 6 : base_bdevs_cleanup();
1649 : 6 : reset_globals();
1650 : 6 : }
1651 : :
1652 : : /* Test IO failures */
1653 : : static void
1654 : 6 : test_io_failure(void)
1655 : : {
1656 : 5 : struct rpc_bdev_raid_create req;
1657 : 5 : struct rpc_bdev_raid_delete destroy_req;
1658 : 1 : struct raid_bdev *pbdev;
1659 : 1 : struct spdk_io_channel *ch;
1660 : 1 : struct raid_bdev_io_channel *ch_ctx;
1661 : 1 : struct spdk_bdev_io *bdev_io;
1662 : 1 : uint32_t count;
1663 : 1 : uint64_t io_len;
1664 : 1 : uint64_t lba;
1665 : :
1666 : 6 : set_globals();
1667 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1668 : :
1669 : 6 : verify_raid_bdev_present("raid1", false);
1670 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1671 : 6 : rpc_bdev_raid_create(NULL, NULL);
1672 : 6 : CU_ASSERT(g_rpc_err == 0);
1673 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1674 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1675 [ + + + + : 6 : if (strcmp(pbdev->bdev.name, req.name) == 0) {
+ - + - +
- + - ]
1676 : 6 : break;
1677 : : }
1678 : 0 : }
1679 : 6 : CU_ASSERT(pbdev != NULL);
1680 : :
1681 : 6 : ch = spdk_get_io_channel(pbdev);
1682 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1683 : :
1684 : 6 : ch_ctx = spdk_io_channel_get_ctx(ch);
1685 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1686 : :
1687 : 6 : lba = 0;
1688 [ + + ]: 12 : for (count = 0; count < 1; count++) {
1689 : 6 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1690 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1691 [ + + + - ]: 6 : io_len = (g_strip_size / 2) << count;
1692 [ + - ]: 6 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_INVALID);
1693 : 6 : lba += g_strip_size;
1694 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
1695 : 6 : g_io_output_index = 0;
1696 : 6 : raid_bdev_submit_request(ch, bdev_io);
1697 [ + - + - ]: 6 : verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1698 : : INVALID_IO_SUBMIT);
1699 : 6 : bdev_io_cleanup(bdev_io);
1700 : 1 : }
1701 : :
1702 : :
1703 : 6 : lba = 0;
1704 : 6 : g_child_io_status_flag = false;
1705 [ + + ]: 12 : for (count = 0; count < 1; count++) {
1706 : 6 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1707 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1708 [ + + + - ]: 6 : io_len = (g_strip_size / 2) << count;
1709 [ + - ]: 6 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_WRITE);
1710 : 6 : lba += g_strip_size;
1711 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
1712 : 6 : g_io_output_index = 0;
1713 : 6 : raid_bdev_submit_request(ch, bdev_io);
1714 [ + + + - ]: 6 : verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1715 [ + - ]: 1 : g_child_io_status_flag);
1716 : 6 : bdev_io_cleanup(bdev_io);
1717 : 1 : }
1718 : :
1719 : 6 : free_test_req(&req);
1720 : 6 : spdk_put_io_channel(ch);
1721 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1722 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1723 : 6 : CU_ASSERT(g_rpc_err == 0);
1724 : 6 : verify_raid_bdev_present("raid1", false);
1725 : :
1726 : 6 : raid_bdev_exit();
1727 : 6 : base_bdevs_cleanup();
1728 : 6 : reset_globals();
1729 : 6 : }
1730 : :
1731 : : /* Test reset IO */
1732 : : static void
1733 : 6 : test_reset_io(void)
1734 : : {
1735 : 5 : struct rpc_bdev_raid_create req;
1736 : 5 : struct rpc_bdev_raid_delete destroy_req;
1737 : 1 : struct raid_bdev *pbdev;
1738 : 1 : struct spdk_io_channel *ch;
1739 : 1 : struct raid_bdev_io_channel *ch_ctx;
1740 : 1 : struct spdk_bdev_io *bdev_io;
1741 : :
1742 : 6 : set_globals();
1743 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1744 : :
1745 : 6 : verify_raid_bdev_present("raid1", false);
1746 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1747 : 6 : rpc_bdev_raid_create(NULL, NULL);
1748 : 6 : CU_ASSERT(g_rpc_err == 0);
1749 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1750 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1751 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
1752 : 6 : break;
1753 : : }
1754 : 0 : }
1755 : 6 : CU_ASSERT(pbdev != NULL);
1756 : :
1757 : 6 : ch = spdk_get_io_channel(pbdev);
1758 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1759 : :
1760 : 6 : ch_ctx = spdk_io_channel_get_ctx(ch);
1761 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1762 : :
1763 : 6 : g_bdev_io_submit_status = 0;
1764 : 6 : g_child_io_status_flag = true;
1765 : :
1766 : 6 : CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_RESET) == true);
1767 : :
1768 : 6 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1769 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1770 [ + - ]: 6 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, 1, SPDK_BDEV_IO_TYPE_RESET);
1771 [ + + ]: 6 : memset(g_io_output, 0, g_max_base_drives * sizeof(struct io_output));
1772 : 6 : g_io_output_index = 0;
1773 : 6 : raid_bdev_submit_request(ch, bdev_io);
1774 [ + - + - ]: 6 : verify_reset_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1775 : : true);
1776 : 6 : bdev_io_cleanup(bdev_io);
1777 : :
1778 : 6 : free_test_req(&req);
1779 : 6 : spdk_put_io_channel(ch);
1780 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1781 : 6 : rpc_bdev_raid_delete(NULL, NULL);
1782 : 6 : CU_ASSERT(g_rpc_err == 0);
1783 : 6 : verify_raid_bdev_present("raid1", false);
1784 : :
1785 : 6 : raid_bdev_exit();
1786 : 6 : base_bdevs_cleanup();
1787 : 6 : reset_globals();
1788 : 6 : }
1789 : :
1790 : : /* Create multiple raids, destroy raids without IO, get_raids related tests */
1791 : : static void
1792 : 6 : test_multi_raid_no_io(void)
1793 : : {
1794 : 1 : struct rpc_bdev_raid_create *construct_req;
1795 : 5 : struct rpc_bdev_raid_delete destroy_req;
1796 : 5 : struct rpc_bdev_raid_get_bdevs get_raids_req;
1797 : 1 : uint8_t i;
1798 : 5 : char name[16];
1799 : 6 : uint8_t bbdev_idx = 0;
1800 : :
1801 : 6 : set_globals();
1802 : 6 : construct_req = calloc(MAX_RAIDS, sizeof(struct rpc_bdev_raid_create));
1803 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(construct_req != NULL);
1804 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1805 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1806 [ - + ]: 12 : snprintf(name, 16, "%s%u", "raid", i);
1807 : 12 : verify_raid_bdev_present(name, false);
1808 [ + - ]: 12 : create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0, false);
1809 [ + - ]: 12 : bbdev_idx += g_max_base_drives;
1810 : 12 : rpc_bdev_raid_create(NULL, NULL);
1811 : 12 : CU_ASSERT(g_rpc_err == 0);
1812 [ + - ]: 12 : verify_raid_bdev(&construct_req[i], true, RAID_BDEV_STATE_ONLINE);
1813 : 2 : }
1814 : :
1815 : 6 : create_get_raids_req(&get_raids_req, "all", 0);
1816 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1817 : 6 : CU_ASSERT(g_rpc_err == 0);
1818 : 6 : verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
1819 [ + + ]: 18 : for (i = 0; i < g_get_raids_count; i++) {
1820 [ + - + - : 12 : free(g_get_raids_output[i]);
+ - ]
1821 : 2 : }
1822 : :
1823 : 6 : create_get_raids_req(&get_raids_req, "online", 0);
1824 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1825 : 6 : CU_ASSERT(g_rpc_err == 0);
1826 : 6 : verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
1827 [ + + ]: 18 : for (i = 0; i < g_get_raids_count; i++) {
1828 [ + - + - : 12 : free(g_get_raids_output[i]);
+ - ]
1829 : 2 : }
1830 : :
1831 : 6 : create_get_raids_req(&get_raids_req, "configuring", 0);
1832 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1833 : 6 : CU_ASSERT(g_rpc_err == 0);
1834 : 6 : CU_ASSERT(g_get_raids_count == 0);
1835 : :
1836 : 6 : create_get_raids_req(&get_raids_req, "offline", 0);
1837 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1838 : 6 : CU_ASSERT(g_rpc_err == 0);
1839 : 6 : CU_ASSERT(g_get_raids_count == 0);
1840 : :
1841 : 6 : create_get_raids_req(&get_raids_req, "invalid_category", 0);
1842 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1843 : 6 : CU_ASSERT(g_rpc_err == 1);
1844 : 6 : CU_ASSERT(g_get_raids_count == 0);
1845 : :
1846 : 6 : create_get_raids_req(&get_raids_req, "all", 1);
1847 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1848 : 6 : CU_ASSERT(g_rpc_err == 1);
1849 : 6 : free(get_raids_req.category);
1850 : 6 : CU_ASSERT(g_get_raids_count == 0);
1851 : :
1852 : 6 : create_get_raids_req(&get_raids_req, "all", 0);
1853 : 6 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1854 : 6 : CU_ASSERT(g_rpc_err == 0);
1855 : 6 : CU_ASSERT(g_get_raids_count == g_max_raids);
1856 [ + + ]: 18 : for (i = 0; i < g_get_raids_count; i++) {
1857 [ + - + - : 12 : free(g_get_raids_output[i]);
+ - ]
1858 : 2 : }
1859 : :
1860 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1861 [ + + + - : 12 : SPDK_CU_ASSERT_FATAL(construct_req[i].name != NULL);
+ - + - #
# ]
1862 [ + + + - : 12 : snprintf(name, 16, "%s", construct_req[i].name);
+ - ]
1863 : 12 : create_raid_bdev_delete_req(&destroy_req, name, 0);
1864 : 12 : rpc_bdev_raid_delete(NULL, NULL);
1865 : 12 : CU_ASSERT(g_rpc_err == 0);
1866 : 12 : verify_raid_bdev_present(name, false);
1867 : 2 : }
1868 : 6 : raid_bdev_exit();
1869 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1870 [ + - ]: 12 : free_test_req(&construct_req[i]);
1871 : 2 : }
1872 : 6 : free(construct_req);
1873 : 6 : base_bdevs_cleanup();
1874 : 6 : reset_globals();
1875 : 6 : }
1876 : :
1877 : : /* Create multiple raids, fire IOs on raids */
1878 : : static void
1879 : 6 : test_multi_raid_with_io(void)
1880 : : {
1881 : 1 : struct rpc_bdev_raid_create *construct_req;
1882 : 5 : struct rpc_bdev_raid_delete destroy_req;
1883 : 1 : uint8_t i;
1884 : 5 : char name[16];
1885 : 6 : uint8_t bbdev_idx = 0;
1886 : 1 : struct raid_bdev *pbdev;
1887 : 1 : struct spdk_io_channel **channels;
1888 : 1 : struct spdk_bdev_io *bdev_io;
1889 : 1 : uint64_t io_len;
1890 : 6 : uint64_t lba = 0;
1891 : 1 : int16_t iotype;
1892 : :
1893 : 6 : set_globals();
1894 : 6 : construct_req = calloc(g_max_raids, sizeof(struct rpc_bdev_raid_create));
1895 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(construct_req != NULL);
1896 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1897 : 6 : channels = calloc(g_max_raids, sizeof(*channels));
1898 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(channels != NULL);
1899 : :
1900 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1901 : 12 : snprintf(name, 16, "%s%u", "raid", i);
1902 : 12 : verify_raid_bdev_present(name, false);
1903 [ + - ]: 12 : create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0, false);
1904 [ + - ]: 12 : bbdev_idx += g_max_base_drives;
1905 : 12 : rpc_bdev_raid_create(NULL, NULL);
1906 : 12 : CU_ASSERT(g_rpc_err == 0);
1907 [ + - ]: 12 : verify_raid_bdev(&construct_req[i], true, RAID_BDEV_STATE_ONLINE);
1908 [ + - + - : 18 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
+ - + - ]
1909 [ + + + + : 18 : if (strcmp(pbdev->bdev.name, construct_req[i].name) == 0) {
+ + + - +
- + - + -
+ - + + ]
1910 : 12 : break;
1911 : : }
1912 : 1 : }
1913 : 12 : CU_ASSERT(pbdev != NULL);
1914 : :
1915 [ + - + - ]: 12 : channels[i] = spdk_get_io_channel(pbdev);
1916 [ + + + - : 12 : SPDK_CU_ASSERT_FATAL(channels[i] != NULL);
+ - # # ]
1917 : 2 : }
1918 : :
1919 : : /* This will perform a write on the first raid and a read on the second. It can be
1920 : : * expanded in the future to perform r/w on each raid device in the event that
1921 : : * multiple raid levels are supported.
1922 : : */
1923 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1924 [ + - + - ]: 12 : struct spdk_io_channel *ch = channels[i];
1925 : 12 : struct raid_bdev_io_channel *ch_ctx = spdk_io_channel_get_ctx(ch);
1926 : :
1927 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1928 : 12 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1929 [ + + # # ]: 12 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1930 : 12 : io_len = g_strip_size;
1931 [ + + ]: 12 : iotype = (i) ? SPDK_BDEV_IO_TYPE_WRITE : SPDK_BDEV_IO_TYPE_READ;
1932 [ + + + + ]: 12 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
1933 : 12 : g_io_output_index = 0;
1934 [ + - + - : 18 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
+ - + - ]
1935 [ + + + + : 18 : if (strcmp(pbdev->bdev.name, construct_req[i].name) == 0) {
+ + + - +
- + - + -
+ - + + ]
1936 : 12 : break;
1937 : : }
1938 : 1 : }
1939 [ + - ]: 12 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, lba, io_len, iotype);
1940 : 12 : CU_ASSERT(pbdev != NULL);
1941 : 12 : raid_bdev_submit_request(ch, bdev_io);
1942 [ - + ]: 12 : verify_io(bdev_io, g_max_base_drives, ch_ctx, pbdev,
1943 [ + - ]: 2 : g_child_io_status_flag);
1944 : 12 : bdev_io_cleanup(bdev_io);
1945 : 2 : }
1946 : :
1947 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1948 [ + - + - ]: 12 : spdk_put_io_channel(channels[i]);
1949 [ + - + - : 12 : snprintf(name, 16, "%s", construct_req[i].name);
+ - ]
1950 : 12 : create_raid_bdev_delete_req(&destroy_req, name, 0);
1951 : 12 : rpc_bdev_raid_delete(NULL, NULL);
1952 : 12 : CU_ASSERT(g_rpc_err == 0);
1953 : 12 : verify_raid_bdev_present(name, false);
1954 : 2 : }
1955 : 6 : raid_bdev_exit();
1956 [ + + ]: 18 : for (i = 0; i < g_max_raids; i++) {
1957 [ + - ]: 12 : free_test_req(&construct_req[i]);
1958 : 2 : }
1959 : 6 : free(construct_req);
1960 : 6 : free(channels);
1961 : 6 : base_bdevs_cleanup();
1962 : 6 : reset_globals();
1963 : 6 : }
1964 : :
1965 : : static void
1966 : 6 : test_io_type_supported(void)
1967 : : {
1968 : 6 : CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_READ) == true);
1969 : 6 : CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_WRITE) == true);
1970 : 6 : CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_INVALID) == false);
1971 : 6 : }
1972 : :
1973 : : static void
1974 : 6 : test_raid_json_dump_info(void)
1975 : : {
1976 : 5 : struct rpc_bdev_raid_create req;
1977 : 5 : struct rpc_bdev_raid_delete destroy_req;
1978 : 1 : struct raid_bdev *pbdev;
1979 : :
1980 : 6 : set_globals();
1981 : 6 : CU_ASSERT(raid_bdev_init() == 0);
1982 : :
1983 : 6 : verify_raid_bdev_present("raid1", false);
1984 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1985 : 6 : rpc_bdev_raid_create(NULL, NULL);
1986 : 6 : CU_ASSERT(g_rpc_err == 0);
1987 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1988 : :
1989 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
1990 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- - + ]
1991 : 6 : break;
1992 : : }
1993 : 0 : }
1994 : 6 : CU_ASSERT(pbdev != NULL);
1995 : :
1996 : 6 : CU_ASSERT(raid_bdev_dump_info_json(pbdev, NULL) == 0);
1997 : :
1998 : 6 : free_test_req(&req);
1999 : :
2000 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
2001 : 6 : rpc_bdev_raid_delete(NULL, NULL);
2002 : 6 : CU_ASSERT(g_rpc_err == 0);
2003 : 6 : verify_raid_bdev_present("raid1", false);
2004 : :
2005 : 6 : raid_bdev_exit();
2006 : 6 : base_bdevs_cleanup();
2007 : 6 : reset_globals();
2008 : 6 : }
2009 : :
2010 : : static void
2011 : 6 : test_context_size(void)
2012 : : {
2013 : 6 : CU_ASSERT(raid_bdev_get_ctx_size() == sizeof(struct raid_bdev_io));
2014 : 6 : }
2015 : :
2016 : : static void
2017 : 6 : test_raid_level_conversions(void)
2018 : : {
2019 : 1 : const char *raid_str;
2020 : :
2021 : 6 : CU_ASSERT(raid_bdev_str_to_level("abcd123") == INVALID_RAID_LEVEL);
2022 : 6 : CU_ASSERT(raid_bdev_str_to_level("0") == RAID0);
2023 : 6 : CU_ASSERT(raid_bdev_str_to_level("raid0") == RAID0);
2024 : 6 : CU_ASSERT(raid_bdev_str_to_level("RAID0") == RAID0);
2025 : :
2026 : 6 : raid_str = raid_bdev_level_to_str(INVALID_RAID_LEVEL);
2027 [ + - + - ]: 6 : CU_ASSERT(raid_str != NULL && strlen(raid_str) == 0);
2028 : 6 : raid_str = raid_bdev_level_to_str(1234);
2029 [ + - + - ]: 6 : CU_ASSERT(raid_str != NULL && strlen(raid_str) == 0);
2030 : 6 : raid_str = raid_bdev_level_to_str(RAID0);
2031 [ + - + + : 6 : CU_ASSERT(raid_str != NULL && strcmp(raid_str, "raid0") == 0);
+ - ]
2032 : 6 : }
2033 : :
2034 : : static void
2035 : 6 : test_create_raid_superblock(void)
2036 : : {
2037 : 5 : struct rpc_bdev_raid_create req;
2038 : 5 : struct rpc_bdev_raid_delete delete_req;
2039 : :
2040 : 6 : set_globals();
2041 : 6 : CU_ASSERT(raid_bdev_init() == 0);
2042 : :
2043 : 6 : verify_raid_bdev_present("raid1", false);
2044 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, true);
2045 : 6 : rpc_bdev_raid_create(NULL, NULL);
2046 : 6 : CU_ASSERT(g_rpc_err == 0);
2047 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
2048 : 6 : free_test_req(&req);
2049 : :
2050 : 6 : create_raid_bdev_delete_req(&delete_req, "raid1", 0);
2051 : 6 : rpc_bdev_raid_delete(NULL, NULL);
2052 : 6 : CU_ASSERT(g_rpc_err == 0);
2053 : 6 : raid_bdev_exit();
2054 : 6 : base_bdevs_cleanup();
2055 : 6 : reset_globals();
2056 : 6 : }
2057 : :
2058 : : static void
2059 : 96 : complete_process_request(void *ctx)
2060 : : {
2061 : 96 : struct raid_bdev_process_request *process_req = ctx;
2062 : :
2063 : 96 : raid_bdev_process_request_complete(process_req, 0);
2064 : 96 : }
2065 : :
2066 : : static int
2067 : 96 : submit_process_request(struct raid_bdev_process_request *process_req,
2068 : : struct raid_bdev_io_channel *raid_ch)
2069 : : {
2070 : 96 : struct raid_bdev *raid_bdev = spdk_io_channel_get_io_device(spdk_io_channel_from_ctx(raid_ch));
2071 : :
2072 [ + - + - : 96 : *(uint64_t *)raid_bdev->module_private += process_req->num_blocks;
+ - + - +
- ]
2073 : :
2074 : 96 : spdk_thread_send_msg(spdk_get_thread(), complete_process_request, process_req);
2075 : :
2076 [ + - + - ]: 96 : return process_req->num_blocks;
2077 : 16 : }
2078 : :
2079 : : static void
2080 : 6 : test_raid_process(void)
2081 : : {
2082 : 5 : struct rpc_bdev_raid_create req;
2083 : 5 : struct rpc_bdev_raid_delete destroy_req;
2084 : 1 : struct raid_bdev *pbdev;
2085 : 1 : struct spdk_bdev *base_bdev;
2086 : 1 : struct spdk_thread *process_thread;
2087 : 6 : uint64_t num_blocks_processed = 0;
2088 : :
2089 : 6 : set_globals();
2090 : 6 : CU_ASSERT(raid_bdev_init() == 0);
2091 : :
2092 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
2093 : 6 : verify_raid_bdev_present("raid1", false);
2094 [ + + + - : 198 : TAILQ_FOREACH(base_bdev, &g_bdev_list, internal.link) {
+ - + - +
- ]
2095 [ + - + - ]: 192 : base_bdev->blockcnt = 128;
2096 : 32 : }
2097 : 6 : rpc_bdev_raid_create(NULL, NULL);
2098 : 6 : CU_ASSERT(g_rpc_err == 0);
2099 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
2100 : 6 : free_test_req(&req);
2101 : :
2102 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
2103 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
2104 : 6 : break;
2105 : : }
2106 : 0 : }
2107 : 6 : CU_ASSERT(pbdev != NULL);
2108 : :
2109 [ + - + - : 6 : pbdev->module->submit_process_request = submit_process_request;
+ - + - ]
2110 [ + - + - ]: 6 : pbdev->module_private = &num_blocks_processed;
2111 : :
2112 [ + - + - : 6 : CU_ASSERT(raid_bdev_start_rebuild(&pbdev->base_bdev_info[0]) == 0);
+ - ]
2113 : 6 : poll_threads();
2114 : :
2115 [ + + + - : 6 : SPDK_CU_ASSERT_FATAL(pbdev->process != NULL);
+ - # # ]
2116 : :
2117 : 6 : process_thread = spdk_thread_get_by_id(spdk_thread_get_id(spdk_get_thread()) + 1);
2118 : :
2119 [ + + ]: 324 : while (spdk_thread_poll(process_thread, 0, 0) > 0) {
2120 : 318 : poll_threads();
2121 : : }
2122 : :
2123 [ + - + - ]: 6 : CU_ASSERT(pbdev->process == NULL);
2124 [ + - + - : 6 : CU_ASSERT(num_blocks_processed == pbdev->bdev.blockcnt);
+ - ]
2125 : :
2126 : 6 : poll_threads();
2127 : :
2128 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
2129 : 6 : rpc_bdev_raid_delete(NULL, NULL);
2130 : 6 : CU_ASSERT(g_rpc_err == 0);
2131 : 6 : verify_raid_bdev_present("raid1", false);
2132 : :
2133 : 6 : raid_bdev_exit();
2134 : 6 : base_bdevs_cleanup();
2135 : 6 : reset_globals();
2136 : 6 : }
2137 : :
2138 : : static void
2139 : 6 : test_raid_io_split(void)
2140 : : {
2141 : 5 : struct rpc_bdev_raid_create req;
2142 : 5 : struct rpc_bdev_raid_delete destroy_req;
2143 : 1 : struct raid_bdev *pbdev;
2144 : 1 : struct spdk_io_channel *ch;
2145 : 1 : struct raid_bdev_io_channel *raid_ch;
2146 : 1 : struct spdk_bdev_io *bdev_io;
2147 : 1 : struct raid_bdev_io *raid_io;
2148 : 1 : uint64_t split_offset;
2149 : 5 : struct iovec iovs_orig[4];
2150 : 6 : struct raid_bdev_process process = { };
2151 : :
2152 : 6 : set_globals();
2153 : 6 : CU_ASSERT(raid_bdev_init() == 0);
2154 : :
2155 : 6 : verify_raid_bdev_present("raid1", false);
2156 : 6 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
2157 : 6 : rpc_bdev_raid_create(NULL, NULL);
2158 : 6 : CU_ASSERT(g_rpc_err == 0);
2159 : 6 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
2160 : :
2161 [ + + # # : 6 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
# # # # ]
2162 [ + + + - : 6 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
+ - + - +
- + - ]
2163 : 6 : break;
2164 : : }
2165 : 0 : }
2166 : 6 : CU_ASSERT(pbdev != NULL);
2167 [ + - + - : 6 : pbdev->bdev.md_len = 8;
+ - ]
2168 : :
2169 : 6 : process.raid_bdev = pbdev;
2170 [ + - + - : 6 : process.target = &pbdev->base_bdev_info[0];
+ - + - ]
2171 [ + - + - ]: 6 : pbdev->process = &process;
2172 : 6 : ch = spdk_get_io_channel(pbdev);
2173 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(ch != NULL);
2174 : 6 : raid_ch = spdk_io_channel_get_ctx(ch);
2175 : 6 : g_bdev_io_defer_completion = true;
2176 : :
2177 : : /* test split of bdev_io with 1 iovec */
2178 : 6 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
2179 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
2180 [ + - ]: 6 : raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
2181 [ + - ]: 6 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, g_strip_size, SPDK_BDEV_IO_TYPE_WRITE);
2182 [ + + + - : 6 : memcpy(iovs_orig, bdev_io->u.bdev.iovs, sizeof(*iovs_orig) * bdev_io->u.bdev.iovcnt);
+ - + - +
- + - + -
+ - + - +
- ]
2183 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
2184 [ + - + - : 6 : bdev_io->u.bdev.md_buf = (void *)0x1000000;
+ - + - ]
2185 : 6 : g_io_output_index = 0;
2186 : :
2187 : 6 : split_offset = 1;
2188 [ + - + - : 6 : raid_ch->process.offset = split_offset;
+ - ]
2189 : 6 : raid_bdev_submit_request(ch, bdev_io);
2190 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
2191 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == split_offset);
2192 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 1);
2193 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2194 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == raid_io->split.iov);
+ - + - +
- ]
2195 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base + split_offset * g_block_len);
+ - + - +
- ]
2196 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig->iov_len - split_offset * g_block_len);
+ - + - +
- + - ]
2197 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
+ - + - +
- + - + -
+ - + - ]
2198 : 6 : complete_deferred_ios();
2199 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == split_offset);
2200 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2201 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 1);
2202 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base);
+ - + - +
- ]
2203 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == split_offset * g_block_len);
+ - + - +
- ]
2204 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2205 : 6 : complete_deferred_ios();
2206 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
2207 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2208 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 1);
2209 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base);
+ - + - +
- ]
2210 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig->iov_len);
+ - + - +
- + - ]
2211 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2212 : :
2213 [ + + ]: 6 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
2214 : 6 : CU_ASSERT(g_io_output_index == 2);
2215 [ + - + - : 6 : CU_ASSERT(g_io_output[0].offset_blocks == split_offset);
+ - ]
2216 [ + - + - : 6 : CU_ASSERT(g_io_output[0].num_blocks == g_strip_size - split_offset);
+ - ]
2217 [ + - + - : 6 : CU_ASSERT(g_io_output[1].offset_blocks == 0);
+ - ]
2218 [ + - + - : 6 : CU_ASSERT(g_io_output[1].num_blocks == split_offset);
+ - ]
2219 : 6 : bdev_io_cleanup(bdev_io);
2220 : :
2221 : : /* test split of bdev_io with 4 iovecs */
2222 : 6 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
2223 [ + + # # ]: 6 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
2224 [ + - ]: 6 : raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
2225 [ + - ]: 6 : _bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, g_strip_size, SPDK_BDEV_IO_TYPE_WRITE,
2226 [ + - ]: 6 : 4, g_strip_size / 4 * g_block_len);
2227 [ + + + - : 6 : memcpy(iovs_orig, bdev_io->u.bdev.iovs, sizeof(*iovs_orig) * bdev_io->u.bdev.iovcnt);
+ - + - +
- + - + -
+ - + - +
- ]
2228 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
2229 [ + - + - : 6 : bdev_io->u.bdev.md_buf = (void *)0x1000000;
+ - + - ]
2230 : 6 : g_io_output_index = 0;
2231 : :
2232 : 6 : split_offset = 1; /* split at the first iovec */
2233 [ + - + - : 6 : raid_ch->process.offset = split_offset;
+ - ]
2234 : 6 : raid_bdev_submit_request(ch, bdev_io);
2235 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
2236 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == split_offset);
2237 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 4);
2238 [ + - + - : 6 : CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[0]);
+ - + - +
- + - + -
+ - ]
2239 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[0]);
+ - + - +
- + - +
- ]
2240 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[0].iov_base + g_block_len);
+ - + - +
- + - +
- ]
2241 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig[0].iov_len - g_block_len);
+ - + - +
- + - + -
+ - ]
2242 [ + + + + : 6 : CU_ASSERT(memcmp(raid_io->iovs + 1, iovs_orig + 1, sizeof(*iovs_orig) * 3) == 0);
+ - + - +
- + - +
- ]
2243 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
+ - + - +
- + - + -
+ - + - ]
2244 : 6 : complete_deferred_ios();
2245 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == split_offset);
2246 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2247 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 1);
2248 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2249 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[0].iov_base);
+ - + - +
- + - +
- ]
2250 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == g_block_len);
+ - + - +
- ]
2251 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2252 : 6 : complete_deferred_ios();
2253 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
2254 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2255 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 4);
2256 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2257 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
+ - + - +
- + - ]
2258 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2259 : :
2260 [ + + ]: 6 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
2261 : 6 : CU_ASSERT(g_io_output_index == 2);
2262 [ + - + - : 6 : CU_ASSERT(g_io_output[0].offset_blocks == split_offset);
+ - ]
2263 [ + - + - : 6 : CU_ASSERT(g_io_output[0].num_blocks == g_strip_size - split_offset);
+ - ]
2264 [ + - + - : 6 : CU_ASSERT(g_io_output[1].offset_blocks == 0);
+ - ]
2265 [ + - + - : 6 : CU_ASSERT(g_io_output[1].num_blocks == split_offset);
+ - ]
2266 : :
2267 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
2268 : 6 : g_io_output_index = 0;
2269 : :
2270 [ + - ]: 6 : split_offset = g_strip_size / 2; /* split exactly between second and third iovec */
2271 [ + - + - : 6 : raid_ch->process.offset = split_offset;
+ - ]
2272 : 6 : raid_bdev_submit_request(ch, bdev_io);
2273 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
2274 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == split_offset);
2275 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 2);
2276 [ + - + - : 6 : CU_ASSERT(raid_io->split.iov == NULL);
+ - ]
2277 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[2]);
+ - + - +
- + - +
- ]
2278 [ + + + + : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig + 2, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
+ - + - +
- + - + -
+ - ]
2279 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
+ - + - +
- + - + -
+ - + - ]
2280 : 6 : complete_deferred_ios();
2281 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == split_offset);
2282 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2283 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 2);
2284 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2285 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
+ - + - +
- + - ]
2286 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2287 : 6 : complete_deferred_ios();
2288 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
2289 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2290 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 4);
2291 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2292 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
+ - + - +
- + - ]
2293 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2294 : :
2295 [ + + ]: 6 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
2296 : 6 : CU_ASSERT(g_io_output_index == 2);
2297 [ + - + - : 6 : CU_ASSERT(g_io_output[0].offset_blocks == split_offset);
+ - ]
2298 [ + - + - : 6 : CU_ASSERT(g_io_output[0].num_blocks == g_strip_size - split_offset);
+ - ]
2299 [ + - + - : 6 : CU_ASSERT(g_io_output[1].offset_blocks == 0);
+ - ]
2300 [ + - + - : 6 : CU_ASSERT(g_io_output[1].num_blocks == split_offset);
+ - ]
2301 : :
2302 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
2303 : 6 : g_io_output_index = 0;
2304 : :
2305 [ + - ]: 6 : split_offset = g_strip_size / 2 + 1; /* split at the third iovec */
2306 [ + - + - : 6 : raid_ch->process.offset = split_offset;
+ - ]
2307 : 6 : raid_bdev_submit_request(ch, bdev_io);
2308 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
2309 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == split_offset);
2310 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 2);
2311 [ + - + - : 6 : CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[2]);
+ - + - +
- + - + -
+ - ]
2312 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[2]);
+ - + - +
- + - +
- ]
2313 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[2].iov_base + g_block_len);
+ - + - +
- + - + -
+ - + - ]
2314 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig[2].iov_len - g_block_len);
+ - + - +
- + - + -
+ - + - ]
2315 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[1].iov_base == iovs_orig[3].iov_base);
+ - + - +
- + - + -
+ - + - ]
2316 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[1].iov_len == iovs_orig[3].iov_len);
+ - + - +
- + - + -
+ - + - ]
2317 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
+ - + - +
- + - + -
+ - + - ]
2318 : 6 : complete_deferred_ios();
2319 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == split_offset);
2320 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2321 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 3);
2322 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2323 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * 2) == 0);
+ - + - ]
2324 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[2].iov_base == iovs_orig[2].iov_base);
+ - + - +
- + - + -
+ - + - ]
2325 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[2].iov_len == g_block_len);
+ - + - +
- ]
2326 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2327 : 6 : complete_deferred_ios();
2328 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
2329 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2330 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 4);
2331 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2332 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
+ - + - +
- + - ]
2333 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2334 : :
2335 [ + + ]: 6 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
2336 : 6 : CU_ASSERT(g_io_output_index == 2);
2337 [ + - + - : 6 : CU_ASSERT(g_io_output[0].offset_blocks == split_offset);
+ - ]
2338 [ + - + - : 6 : CU_ASSERT(g_io_output[0].num_blocks == g_strip_size - split_offset);
+ - ]
2339 [ + - + - : 6 : CU_ASSERT(g_io_output[1].offset_blocks == 0);
+ - ]
2340 [ + - + - : 6 : CU_ASSERT(g_io_output[1].num_blocks == split_offset);
+ - ]
2341 : :
2342 [ + + + + ]: 6 : memset(g_io_output, 0, ((g_max_io_size / g_strip_size) + 1) * sizeof(struct io_output));
2343 : 6 : g_io_output_index = 0;
2344 : :
2345 : 6 : split_offset = g_strip_size - 1; /* split at the last iovec */
2346 [ + - + - : 6 : raid_ch->process.offset = split_offset;
+ - ]
2347 : 6 : raid_bdev_submit_request(ch, bdev_io);
2348 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
2349 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == split_offset);
2350 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 1);
2351 [ + - + - : 6 : CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[3]);
+ - + - +
- + - + -
+ - ]
2352 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[3]);
+ - + - +
- + - +
- ]
2353 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[3].iov_base + iovs_orig[3].iov_len - g_block_len);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
2354 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[0].iov_len == g_block_len);
+ - + - +
- ]
2355 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
+ - + - +
- + - + -
+ - + - ]
2356 : 6 : complete_deferred_ios();
2357 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == split_offset);
2358 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2359 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 4);
2360 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2361 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * 3) == 0);
+ - + - ]
2362 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[3].iov_base == iovs_orig[3].iov_base);
+ - + - +
- + - + -
+ - + - ]
2363 [ + - + - : 6 : CU_ASSERT(raid_io->iovs[3].iov_len == iovs_orig[3].iov_len - g_block_len);
+ - + - +
- + - + -
+ - + - ]
2364 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2365 : 6 : complete_deferred_ios();
2366 [ + - + - ]: 6 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
2367 [ + - + - ]: 6 : CU_ASSERT(raid_io->offset_blocks == 0);
2368 [ + - + - ]: 6 : CU_ASSERT(raid_io->iovcnt == 4);
2369 [ + - + - : 6 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
+ - + - +
- + - ]
2370 [ + + + - : 6 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
+ - + - +
- + - ]
2371 [ + - + - : 6 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
+ - + - +
- + - ]
2372 : :
2373 [ + + ]: 6 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
2374 : 6 : CU_ASSERT(g_io_output_index == 2);
2375 [ + - + - : 6 : CU_ASSERT(g_io_output[0].offset_blocks == split_offset);
+ - ]
2376 [ + - + - : 6 : CU_ASSERT(g_io_output[0].num_blocks == g_strip_size - split_offset);
+ - ]
2377 [ + - + - : 6 : CU_ASSERT(g_io_output[1].offset_blocks == 0);
+ - ]
2378 [ + - + - : 6 : CU_ASSERT(g_io_output[1].num_blocks == split_offset);
+ - ]
2379 : 6 : bdev_io_cleanup(bdev_io);
2380 : :
2381 : 6 : spdk_put_io_channel(ch);
2382 : 6 : free_test_req(&req);
2383 [ + - + - ]: 6 : pbdev->process = NULL;
2384 : :
2385 : 6 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
2386 : 6 : rpc_bdev_raid_delete(NULL, NULL);
2387 : 6 : CU_ASSERT(g_rpc_err == 0);
2388 : 6 : verify_raid_bdev_present("raid1", false);
2389 : :
2390 : 6 : raid_bdev_exit();
2391 : 6 : base_bdevs_cleanup();
2392 : 6 : reset_globals();
2393 : 6 : }
2394 : :
2395 : : static int
2396 : 102 : test_bdev_ioch_create(void *io_device, void *ctx_buf)
2397 : : {
2398 : 102 : return 0;
2399 : : }
2400 : :
2401 : : static void
2402 : 102 : test_bdev_ioch_destroy(void *io_device, void *ctx_buf)
2403 : : {
2404 : 102 : }
2405 : :
2406 : : int
2407 : 6 : main(int argc, char **argv)
2408 : : {
2409 : 6 : CU_pSuite suite = NULL;
2410 : 1 : unsigned int num_failures;
2411 : :
2412 : 6 : CU_initialize_registry();
2413 : :
2414 : 6 : suite = CU_add_suite("raid", NULL, NULL);
2415 : :
2416 : 6 : CU_ADD_TEST(suite, test_create_raid);
2417 : 6 : CU_ADD_TEST(suite, test_create_raid_superblock);
2418 : 6 : CU_ADD_TEST(suite, test_delete_raid);
2419 : 6 : CU_ADD_TEST(suite, test_create_raid_invalid_args);
2420 : 6 : CU_ADD_TEST(suite, test_delete_raid_invalid_args);
2421 : 6 : CU_ADD_TEST(suite, test_io_channel);
2422 : 6 : CU_ADD_TEST(suite, test_reset_io);
2423 : 6 : CU_ADD_TEST(suite, test_write_io);
2424 : 6 : CU_ADD_TEST(suite, test_read_io);
2425 : 6 : CU_ADD_TEST(suite, test_unmap_io);
2426 : 6 : CU_ADD_TEST(suite, test_io_failure);
2427 : 6 : CU_ADD_TEST(suite, test_multi_raid_no_io);
2428 : 6 : CU_ADD_TEST(suite, test_multi_raid_with_io);
2429 : 6 : CU_ADD_TEST(suite, test_io_type_supported);
2430 : 6 : CU_ADD_TEST(suite, test_raid_json_dump_info);
2431 : 6 : CU_ADD_TEST(suite, test_context_size);
2432 : 6 : CU_ADD_TEST(suite, test_raid_level_conversions);
2433 : 6 : CU_ADD_TEST(suite, test_raid_process);
2434 : 6 : CU_ADD_TEST(suite, test_raid_io_split);
2435 : :
2436 : 6 : allocate_threads(1);
2437 : 6 : set_thread(0);
2438 : 6 : spdk_io_device_register(&g_bdev_ch_io_device, test_bdev_ioch_create, test_bdev_ioch_destroy, 0,
2439 : : NULL);
2440 : :
2441 : 6 : set_test_opts();
2442 : 6 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
2443 : 6 : CU_cleanup_registry();
2444 : :
2445 : 6 : spdk_io_device_unregister(&g_bdev_ch_io_device, NULL);
2446 : 6 : free_threads();
2447 : :
2448 : 7 : return num_failures;
2449 : 1 : }
|