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/util.h"
9 : : #include "spdk_internal/cunit.h"
10 : : #include "spdk/env.h"
11 : : #include "spdk_internal/mock.h"
12 : : #include "thread/thread_internal.h"
13 : : #include "bdev/raid/bdev_raid.c"
14 : : #include "bdev/raid/bdev_raid_rpc.c"
15 : : #include "common/lib/test_env.c"
16 : :
17 : : #define MAX_BASE_DRIVES 32
18 : : #define MAX_RAIDS 2
19 : : #define BLOCK_CNT (1024ul * 1024ul * 1024ul * 1024ul)
20 : : #define MD_SIZE 8
21 : :
22 : : struct spdk_bdev_channel {
23 : : struct spdk_io_channel *channel;
24 : : };
25 : :
26 : : struct spdk_bdev_desc {
27 : : struct spdk_bdev *bdev;
28 : : };
29 : :
30 : : /* Data structure to capture the output of IO for verification */
31 : : struct io_output {
32 : : struct spdk_bdev_desc *desc;
33 : : struct spdk_io_channel *ch;
34 : : enum spdk_bdev_io_type iotype;
35 : : };
36 : :
37 : : /* Globals */
38 : : struct io_output *g_io_output = NULL;
39 : : uint32_t g_io_output_index;
40 : : uint32_t g_io_comp_status;
41 : : bool g_child_io_status_flag;
42 : : void *g_rpc_req;
43 : : uint32_t g_rpc_req_size;
44 : : TAILQ_HEAD(bdev, spdk_bdev);
45 : : struct bdev g_bdev_list;
46 : : uint32_t g_block_len;
47 : : uint32_t g_strip_size;
48 : : uint32_t g_max_io_size;
49 : : uint8_t g_max_base_drives;
50 : : uint8_t g_max_raids;
51 : : uint8_t g_rpc_err;
52 : : char *g_get_raids_output[MAX_RAIDS];
53 : : uint32_t g_get_raids_count;
54 : : uint8_t g_json_decode_obj_err;
55 : : uint8_t g_json_decode_obj_create;
56 : : uint8_t g_test_multi_raids;
57 : : uint64_t g_bdev_ch_io_device;
58 : : bool g_bdev_io_defer_completion;
59 : : TAILQ_HEAD(, spdk_bdev_io) g_deferred_ios = TAILQ_HEAD_INITIALIZER(g_deferred_ios);
60 : : struct spdk_thread *g_app_thread;
61 : : struct spdk_thread *g_latest_thread;
62 : :
63 : : static int
64 : 70 : ut_raid_start(struct raid_bdev *raid_bdev)
65 : : {
66 : 70 : uint64_t min_blockcnt = UINT64_MAX;
67 : : struct raid_base_bdev_info *base_info;
68 : :
69 [ + + ]: 2310 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
70 : 2240 : min_blockcnt = spdk_min(min_blockcnt, base_info->data_size);
71 : : }
72 : 70 : raid_bdev->bdev.blockcnt = min_blockcnt;
73 : :
74 : 70 : return 0;
75 : : }
76 : :
77 : : static void
78 : 50 : ut_raid_submit_rw_request_defered_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
79 : : {
80 : 50 : struct raid_bdev_io *raid_io = cb_arg;
81 : :
82 [ + - ]: 50 : raid_bdev_io_complete(raid_io, success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED);
83 : 50 : }
84 : :
85 : : static void
86 : 50 : ut_raid_submit_rw_request(struct raid_bdev_io *raid_io)
87 : : {
88 [ + + + - ]: 50 : if (g_bdev_io_defer_completion) {
89 : 50 : struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(raid_io);
90 : :
91 : 50 : bdev_io->internal.cb = ut_raid_submit_rw_request_defered_cb;
92 : 50 : bdev_io->internal.caller_ctx = raid_io;
93 : 50 : TAILQ_INSERT_TAIL(&g_deferred_ios, bdev_io, internal.link);
94 : 50 : return;
95 : : }
96 : 0 : raid_bdev_io_complete(raid_io,
97 [ # # # # ]: 0 : g_child_io_status_flag ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED);
98 : : }
99 : :
100 : : static void
101 : 0 : ut_raid_submit_null_payload_request(struct raid_bdev_io *raid_io)
102 : : {
103 : 0 : raid_bdev_io_complete(raid_io,
104 [ # # # # ]: 0 : g_child_io_status_flag ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED);
105 : 0 : }
106 : :
107 : : static void
108 : 10 : ut_raid_complete_process_request(void *ctx)
109 : : {
110 : 10 : struct raid_bdev_process_request *process_req = ctx;
111 : :
112 : 10 : raid_bdev_process_request_complete(process_req, 0);
113 : 10 : }
114 : :
115 : : static int
116 : 10 : ut_raid_submit_process_request(struct raid_bdev_process_request *process_req,
117 : : struct raid_bdev_io_channel *raid_ch)
118 : : {
119 : 10 : struct raid_bdev *raid_bdev = spdk_io_channel_get_io_device(spdk_io_channel_from_ctx(raid_ch));
120 : :
121 : 10 : *(uint64_t *)raid_bdev->module_private += process_req->num_blocks;
122 : :
123 : 10 : spdk_thread_send_msg(spdk_get_thread(), ut_raid_complete_process_request, process_req);
124 : :
125 : 10 : return process_req->num_blocks;
126 : : }
127 : :
128 : : static struct raid_bdev_module g_ut_raid_module = {
129 : : .level = 123,
130 : : .base_bdevs_min = 1,
131 : : .start = ut_raid_start,
132 : : .submit_rw_request = ut_raid_submit_rw_request,
133 : : .submit_null_payload_request = ut_raid_submit_null_payload_request,
134 : : .submit_process_request = ut_raid_submit_process_request,
135 : : };
136 : 5 : RAID_MODULE_REGISTER(&g_ut_raid_module)
137 : :
138 : 0 : DEFINE_STUB_V(spdk_bdev_module_examine_done, (struct spdk_bdev_module *module));
139 : 5 : DEFINE_STUB_V(spdk_bdev_module_list_add, (struct spdk_bdev_module *bdev_module));
140 [ - + - + ]: 160 : DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev,
141 : : enum spdk_bdev_io_type io_type), true);
142 : 2560 : DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
143 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_flush_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
144 : : uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
145 : : void *cb_arg), 0);
146 : 30 : DEFINE_STUB_V(spdk_rpc_register_method, (const char *method, spdk_rpc_method_handler func,
147 : : uint32_t state_mask));
148 : 25 : DEFINE_STUB_V(spdk_jsonrpc_end_result, (struct spdk_jsonrpc_request *request,
149 : : struct spdk_json_write_ctx *w));
150 : 145 : DEFINE_STUB_V(spdk_jsonrpc_send_bool_response, (struct spdk_jsonrpc_request *request,
151 : : bool value));
152 [ # # ]: 0 : DEFINE_STUB(spdk_json_decode_string, int, (const struct spdk_json_val *val, void *out), 0);
153 [ # # ]: 0 : DEFINE_STUB(spdk_json_decode_uint32, int, (const struct spdk_json_val *val, void *out), 0);
154 [ # # ]: 0 : DEFINE_STUB(spdk_json_decode_uuid, int, (const struct spdk_json_val *val, void *out), 0);
155 [ # # ]: 0 : DEFINE_STUB(spdk_json_decode_array, int, (const struct spdk_json_val *values,
156 : : spdk_json_decode_fn decode_func,
157 : : void *out, size_t max_size, size_t *out_size, size_t stride), 0);
158 [ # # ]: 0 : DEFINE_STUB(spdk_json_decode_bool, int, (const struct spdk_json_val *val, void *out), 0);
159 [ - + ]: 1155 : DEFINE_STUB(spdk_json_write_name, int, (struct spdk_json_write_ctx *w, const char *name), 0);
160 [ - + ]: 1150 : DEFINE_STUB(spdk_json_write_object_begin, int, (struct spdk_json_write_ctx *w), 0);
161 [ - + ]: 5 : DEFINE_STUB(spdk_json_write_named_object_begin, int, (struct spdk_json_write_ctx *w,
162 : : const char *name), 0);
163 [ - + ]: 1120 : DEFINE_STUB(spdk_json_write_string, int, (struct spdk_json_write_ctx *w, const char *val), 0);
164 [ - + ]: 1155 : DEFINE_STUB(spdk_json_write_object_end, int, (struct spdk_json_write_ctx *w), 0);
165 [ - + ]: 60 : DEFINE_STUB(spdk_json_write_array_begin, int, (struct spdk_json_write_ctx *w), 0);
166 [ - + ]: 60 : DEFINE_STUB(spdk_json_write_array_end, int, (struct spdk_json_write_ctx *w), 0);
167 [ # # ]: 0 : DEFINE_STUB(spdk_json_write_named_array_begin, int, (struct spdk_json_write_ctx *w,
168 : : const char *name), 0);
169 [ # # ]: 0 : DEFINE_STUB(spdk_json_write_null, int, (struct spdk_json_write_ctx *w), 0);
170 [ - + ]: 2240 : DEFINE_STUB(spdk_json_write_named_uint64, int, (struct spdk_json_write_ctx *w, const char *name,
171 : : uint64_t val), 0);
172 [ - + ]: 40 : DEFINE_STUB(spdk_strerror, const char *, (int errnum), NULL);
173 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_queue_io_wait, int, (struct spdk_bdev *bdev, struct spdk_io_channel *ch,
174 : : struct spdk_bdev_io_wait_entry *entry), 0);
175 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_get_memory_domains, int, (struct spdk_bdev *bdev,
176 : : struct spdk_memory_domain **domains, int array_size), 0);
177 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test_bdev");
178 [ - + ]: 2550 : DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, (const struct spdk_bdev *bdev), MD_SIZE);
179 [ - + - + ]: 2550 : DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), false);
180 [ - + - + ]: 160 : DEFINE_STUB(spdk_bdev_is_md_separate, bool, (const struct spdk_bdev *bdev), true);
181 [ - + ]: 5175 : DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev),
182 : : SPDK_DIF_DISABLE);
183 [ - + - + ]: 2550 : DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false);
184 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0);
185 [ - + ]: 1155 : DEFINE_STUB(spdk_json_write_named_uuid, int, (struct spdk_json_write_ctx *w, const char *name,
186 : : const struct spdk_uuid *val), 0);
187 : 5 : DEFINE_STUB_V(raid_bdev_init_superblock, (struct raid_bdev *raid_bdev));
188 [ - + ]: 5 : DEFINE_STUB(raid_bdev_alloc_superblock, int, (struct raid_bdev *raid_bdev, uint32_t block_size), 0);
189 : 85 : DEFINE_STUB_V(raid_bdev_free_superblock, (struct raid_bdev *raid_bdev));
190 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_readv_blocks_ext, int, (struct spdk_bdev_desc *desc,
191 : : struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, uint64_t offset_blocks,
192 : : uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
193 : : struct spdk_bdev_ext_io_opts *opts), 0);
194 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_writev_blocks_ext, int, (struct spdk_bdev_desc *desc,
195 : : struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, uint64_t offset_blocks,
196 : : uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
197 : : struct spdk_bdev_ext_io_opts *opts), 0);
198 : :
199 : : uint32_t
200 : 410 : spdk_bdev_get_data_block_size(const struct spdk_bdev *bdev)
201 : : {
202 : 410 : return g_block_len;
203 : : }
204 : :
205 : : int
206 : 2550 : raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
207 : : raid_bdev_load_sb_cb cb, void *cb_ctx)
208 : : {
209 : 2550 : cb(NULL, -EINVAL, cb_ctx);
210 : :
211 : 2550 : return 0;
212 : : }
213 : :
214 : : void
215 : 5 : raid_bdev_write_superblock(struct raid_bdev *raid_bdev, raid_bdev_write_sb_cb cb, void *cb_ctx)
216 : : {
217 : 5 : cb(0, raid_bdev, cb_ctx);
218 : 5 : }
219 : :
220 : : const struct spdk_uuid *
221 : 2560 : spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
222 : : {
223 : 2560 : return &bdev->uuid;
224 : : }
225 : :
226 : : struct spdk_io_channel *
227 : 3365 : spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
228 : : {
229 : 3365 : return spdk_get_io_channel(&g_bdev_ch_io_device);
230 : : }
231 : :
232 : : static int
233 : 5 : set_test_opts(void)
234 : : {
235 : 5 : g_max_base_drives = MAX_BASE_DRIVES;
236 : 5 : g_max_raids = MAX_RAIDS;
237 : 5 : g_block_len = 4096;
238 : 5 : g_strip_size = 64;
239 : 5 : g_max_io_size = 1024;
240 : :
241 [ - + ]: 5 : printf("Test Options\n");
242 [ - + ]: 5 : printf("blocklen = %u, strip_size = %u, max_io_size = %u, g_max_base_drives = %u, "
243 : : "g_max_raids = %u\n",
244 : : g_block_len, g_strip_size, g_max_io_size, g_max_base_drives, g_max_raids);
245 : :
246 : 5 : return 0;
247 : : }
248 : :
249 : : /* Set globals before every test run */
250 : : static void
251 : 60 : set_globals(void)
252 : : {
253 : : uint32_t max_splits;
254 : :
255 [ - + ]: 60 : if (g_max_io_size < g_strip_size) {
256 : 0 : max_splits = 2;
257 : : } else {
258 [ - + ]: 60 : max_splits = (g_max_io_size / g_strip_size) + 1;
259 : : }
260 [ + - ]: 60 : if (max_splits < g_max_base_drives) {
261 : 60 : max_splits = g_max_base_drives;
262 : : }
263 : :
264 : 60 : g_io_output = calloc(max_splits, sizeof(struct io_output));
265 [ - + ]: 60 : SPDK_CU_ASSERT_FATAL(g_io_output != NULL);
266 : 60 : g_io_output_index = 0;
267 [ - + ]: 60 : memset(g_get_raids_output, 0, sizeof(g_get_raids_output));
268 : 60 : g_get_raids_count = 0;
269 : 60 : g_io_comp_status = 0;
270 : 60 : g_rpc_err = 0;
271 : 60 : g_test_multi_raids = 0;
272 : 60 : g_child_io_status_flag = true;
273 : 60 : TAILQ_INIT(&g_bdev_list);
274 : 60 : g_rpc_req = NULL;
275 : 60 : g_rpc_req_size = 0;
276 : 60 : g_json_decode_obj_err = 0;
277 : 60 : g_json_decode_obj_create = 0;
278 : 60 : g_bdev_io_defer_completion = false;
279 : 60 : }
280 : :
281 : : static void
282 : 60 : base_bdevs_cleanup(void)
283 : : {
284 : : struct spdk_bdev *bdev;
285 : : struct spdk_bdev *bdev_next;
286 : :
287 [ + - ]: 60 : if (!TAILQ_EMPTY(&g_bdev_list)) {
288 [ + + ]: 2460 : TAILQ_FOREACH_SAFE(bdev, &g_bdev_list, internal.link, bdev_next) {
289 : 2400 : free(bdev->name);
290 [ + + ]: 2400 : TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
291 : 2400 : free(bdev);
292 : : }
293 : : }
294 : 60 : }
295 : :
296 : : static void
297 : 5 : check_and_remove_raid_bdev(struct raid_bdev *raid_bdev)
298 : : {
299 : : struct raid_base_bdev_info *base_info;
300 : :
301 [ - + ]: 5 : assert(raid_bdev != NULL);
302 [ - + ]: 5 : assert(raid_bdev->base_bdev_info != NULL);
303 : :
304 [ + + ]: 165 : RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
305 [ + + ]: 160 : if (base_info->desc) {
306 : 155 : raid_bdev_free_base_bdev_resource(base_info);
307 : : }
308 : : }
309 [ - + ]: 5 : assert(raid_bdev->num_base_bdevs_discovered == 0);
310 : 5 : raid_bdev_cleanup_and_free(raid_bdev);
311 : 5 : }
312 : :
313 : : /* Reset globals */
314 : : static void
315 : 60 : reset_globals(void)
316 : : {
317 [ + - ]: 60 : if (g_io_output) {
318 : 60 : free(g_io_output);
319 : 60 : g_io_output = NULL;
320 : : }
321 : 60 : g_rpc_req = NULL;
322 : 60 : g_rpc_req_size = 0;
323 : 60 : }
324 : :
325 : : void
326 : 0 : spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb,
327 : : uint64_t len)
328 : : {
329 : 0 : cb(bdev_io->internal.ch->channel, bdev_io, true);
330 : 0 : }
331 : :
332 : : /* Store the IO completion status in global variable to verify by various tests */
333 : : void
334 : 30 : spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
335 : : {
336 : 30 : g_io_comp_status = ((status == SPDK_BDEV_IO_STATUS_SUCCESS) ? true : false);
337 : 30 : }
338 : :
339 : : static void
340 : 50 : complete_deferred_ios(void)
341 : : {
342 : : struct spdk_bdev_io *child_io, *tmp;
343 : :
344 [ + + ]: 100 : TAILQ_FOREACH_SAFE(child_io, &g_deferred_ios, internal.link, tmp) {
345 [ - + ]: 50 : TAILQ_REMOVE(&g_deferred_ios, child_io, internal.link);
346 [ - + ]: 50 : child_io->internal.cb(child_io, g_child_io_status_flag, child_io->internal.caller_ctx);
347 : : }
348 : 50 : }
349 : :
350 : : int
351 : 160 : spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
352 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
353 : : {
354 : 160 : struct io_output *output = &g_io_output[g_io_output_index];
355 : : struct spdk_bdev_io *child_io;
356 : :
357 : 160 : output->desc = desc;
358 : 160 : output->ch = ch;
359 : 160 : output->iotype = SPDK_BDEV_IO_TYPE_RESET;
360 : :
361 : 160 : g_io_output_index++;
362 : :
363 : 160 : child_io = calloc(1, sizeof(struct spdk_bdev_io));
364 [ - + ]: 160 : SPDK_CU_ASSERT_FATAL(child_io != NULL);
365 [ - + ]: 160 : cb(child_io, g_child_io_status_flag, cb_arg);
366 : :
367 : 160 : return 0;
368 : : }
369 : :
370 : : void
371 : 70 : spdk_bdev_destruct_done(struct spdk_bdev *bdev, int bdeverrno)
372 : : {
373 : 70 : CU_ASSERT(bdeverrno == 0);
374 [ - + ]: 70 : SPDK_CU_ASSERT_FATAL(bdev->internal.unregister_cb != NULL);
375 : 70 : bdev->internal.unregister_cb(bdev->internal.unregister_ctx, bdeverrno);
376 : 70 : }
377 : :
378 : : int
379 : 70 : spdk_bdev_register(struct spdk_bdev *bdev)
380 : : {
381 : 70 : TAILQ_INSERT_TAIL(&g_bdev_list, bdev, internal.link);
382 : 70 : return 0;
383 : : }
384 : :
385 : : static void
386 : 205 : poll_app_thread(void)
387 : : {
388 [ + + ]: 330 : while (spdk_thread_poll(g_app_thread, 0, 0) > 0) {
389 : : }
390 : 205 : }
391 : :
392 : : void
393 : 70 : spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
394 : : {
395 : : int ret;
396 : :
397 [ - + ]: 70 : SPDK_CU_ASSERT_FATAL(spdk_bdev_get_by_name(bdev->name) == bdev);
398 [ + + ]: 70 : TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
399 : :
400 : 70 : bdev->internal.unregister_cb = cb_fn;
401 : 70 : bdev->internal.unregister_ctx = cb_arg;
402 : :
403 : 70 : ret = bdev->fn_table->destruct(bdev->ctxt);
404 : 70 : CU_ASSERT(ret == 1);
405 : :
406 : 70 : poll_app_thread();
407 : 70 : }
408 : :
409 : : int
410 : 2635 : spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb,
411 : : void *event_ctx, struct spdk_bdev_desc **_desc)
412 : : {
413 : : struct spdk_bdev *bdev;
414 : :
415 : 2635 : bdev = spdk_bdev_get_by_name(bdev_name);
416 [ + + ]: 2635 : if (bdev == NULL) {
417 : 5 : return -ENODEV;
418 : : }
419 : :
420 : 2630 : *_desc = (void *)bdev;
421 : 2630 : return 0;
422 : : }
423 : :
424 : : struct spdk_bdev *
425 : 7350 : spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
426 : : {
427 : 7350 : return (void *)desc;
428 : : }
429 : :
430 : : int
431 : 140 : spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
432 : : {
433 [ + + ]: 140 : if (!g_test_multi_raids) {
434 : 20 : struct rpc_bdev_raid_create *req = g_rpc_req;
435 [ + + + + ]: 20 : if (strcmp(name, "strip_size_kb") == 0) {
436 : 5 : CU_ASSERT(req->strip_size_kb == val);
437 [ - + - + ]: 15 : } else if (strcmp(name, "blocklen_shift") == 0) {
438 : 0 : CU_ASSERT(spdk_u32log2(g_block_len) == val);
439 [ + + + + ]: 15 : } else if (strcmp(name, "num_base_bdevs") == 0) {
440 : 5 : CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
441 [ - + - + ]: 10 : } else if (strcmp(name, "state") == 0) {
442 : 0 : CU_ASSERT(val == RAID_BDEV_STATE_ONLINE);
443 [ - + - + ]: 10 : } else if (strcmp(name, "destruct_called") == 0) {
444 : 0 : CU_ASSERT(val == 0);
445 [ + + + + ]: 10 : } else if (strcmp(name, "num_base_bdevs_discovered") == 0) {
446 : 5 : CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
447 : : }
448 : : }
449 : 140 : return 0;
450 : : }
451 : :
452 : : int
453 : 130 : spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
454 : : {
455 [ + + ]: 130 : if (g_test_multi_raids) {
456 [ + + + + ]: 120 : if (strcmp(name, "name") == 0) {
457 [ - + ]: 30 : g_get_raids_output[g_get_raids_count] = strdup(val);
458 [ - + ]: 30 : SPDK_CU_ASSERT_FATAL(g_get_raids_output[g_get_raids_count] != NULL);
459 : 30 : g_get_raids_count++;
460 : : }
461 : : } else {
462 : 10 : struct rpc_bdev_raid_create *req = g_rpc_req;
463 [ + + + + ]: 10 : if (strcmp(name, "raid_level") == 0) {
464 [ - + - + ]: 5 : CU_ASSERT(strcmp(val, raid_bdev_level_to_str(req->level)) == 0);
465 : : }
466 : : }
467 : 130 : return 0;
468 : : }
469 : :
470 : : int
471 : 1155 : spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
472 : : {
473 [ + + ]: 1155 : if (!g_test_multi_raids) {
474 : 165 : struct rpc_bdev_raid_create *req = g_rpc_req;
475 [ + + + + ]: 165 : if (strcmp(name, "superblock") == 0) {
476 [ - + ]: 5 : CU_ASSERT(val == req->superblock_enabled);
477 : : }
478 : : }
479 : 1155 : return 0;
480 : : }
481 : :
482 : : void
483 : 160 : spdk_bdev_free_io(struct spdk_bdev_io *bdev_io)
484 : : {
485 [ + - ]: 160 : if (bdev_io) {
486 : 160 : free(bdev_io);
487 : : }
488 : 160 : }
489 : :
490 : : void
491 : 2550 : spdk_bdev_module_release_bdev(struct spdk_bdev *bdev)
492 : : {
493 : 2550 : CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE);
494 : 2550 : CU_ASSERT(bdev->internal.claim.v1.module != NULL);
495 : 2550 : bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE;
496 : 2550 : bdev->internal.claim.v1.module = NULL;
497 : 2550 : }
498 : :
499 : : int
500 : 2560 : spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
501 : : struct spdk_bdev_module *module)
502 : : {
503 [ + + ]: 2560 : if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) {
504 : 10 : CU_ASSERT(bdev->internal.claim.v1.module != NULL);
505 : 10 : return -1;
506 : : }
507 : 2550 : CU_ASSERT(bdev->internal.claim.v1.module == NULL);
508 : 2550 : bdev->internal.claim_type = SPDK_BDEV_CLAIM_EXCL_WRITE;
509 : 2550 : bdev->internal.claim.v1.module = module;
510 : 2550 : return 0;
511 : : }
512 : :
513 : : int
514 : 220 : spdk_json_decode_object(const struct spdk_json_val *values,
515 : : const struct spdk_json_object_decoder *decoders, size_t num_decoders,
516 : : void *out)
517 : : {
518 : : struct rpc_bdev_raid_create *req, *_out;
519 : : size_t i;
520 : :
521 [ + + ]: 220 : if (g_json_decode_obj_err) {
522 : 15 : return -1;
523 [ + + ]: 205 : } else if (g_json_decode_obj_create) {
524 : 100 : req = g_rpc_req;
525 : 100 : _out = out;
526 : :
527 [ - + ]: 100 : _out->name = strdup(req->name);
528 [ - + ]: 100 : SPDK_CU_ASSERT_FATAL(_out->name != NULL);
529 : 100 : _out->strip_size_kb = req->strip_size_kb;
530 : 100 : _out->level = req->level;
531 [ - + ]: 100 : _out->superblock_enabled = req->superblock_enabled;
532 : 100 : _out->base_bdevs.num_base_bdevs = req->base_bdevs.num_base_bdevs;
533 [ + + ]: 3300 : for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) {
534 [ - + ]: 3200 : _out->base_bdevs.base_bdevs[i] = strdup(req->base_bdevs.base_bdevs[i]);
535 [ - + ]: 3200 : SPDK_CU_ASSERT_FATAL(_out->base_bdevs.base_bdevs[i]);
536 : : }
537 : : } else {
538 [ - + - + ]: 105 : memcpy(out, g_rpc_req, g_rpc_req_size);
539 : : }
540 : :
541 : 205 : return 0;
542 : : }
543 : :
544 : : struct spdk_json_write_ctx *
545 : 25 : spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
546 : : {
547 : 25 : return (void *)1;
548 : : }
549 : :
550 : : void
551 : 20 : spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
552 : : int error_code, const char *msg)
553 : : {
554 : 20 : g_rpc_err = 1;
555 : 20 : }
556 : :
557 : : void
558 : 30 : spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
559 : : int error_code, const char *fmt, ...)
560 : : {
561 : 30 : g_rpc_err = 1;
562 : 30 : }
563 : :
564 : : struct spdk_bdev *
565 : 5270 : spdk_bdev_get_by_name(const char *bdev_name)
566 : : {
567 : : struct spdk_bdev *bdev;
568 : :
569 [ + - ]: 5270 : if (!TAILQ_EMPTY(&g_bdev_list)) {
570 [ + + ]: 132010 : TAILQ_FOREACH(bdev, &g_bdev_list, internal.link) {
571 [ + + - + : 132000 : if (strcmp(bdev_name, bdev->name) == 0) {
+ + ]
572 : 5260 : return bdev;
573 : : }
574 : : }
575 : : }
576 : :
577 : 10 : return NULL;
578 : : }
579 : :
580 : : int
581 : 10 : spdk_bdev_quiesce(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
582 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
583 : : {
584 [ + - ]: 10 : if (cb_fn) {
585 : 10 : cb_fn(cb_arg, 0);
586 : : }
587 : :
588 : 10 : return 0;
589 : : }
590 : :
591 : : int
592 : 10 : spdk_bdev_unquiesce(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
593 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
594 : : {
595 [ + - ]: 10 : if (cb_fn) {
596 : 10 : cb_fn(cb_arg, 0);
597 : : }
598 : :
599 : 10 : return 0;
600 : : }
601 : :
602 : : int
603 : 10 : spdk_bdev_quiesce_range(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
604 : : uint64_t offset, uint64_t length,
605 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
606 : : {
607 [ + - ]: 10 : if (cb_fn) {
608 : 10 : cb_fn(cb_arg, 0);
609 : : }
610 : :
611 : 10 : return 0;
612 : : }
613 : :
614 : : int
615 : 10 : spdk_bdev_unquiesce_range(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
616 : : uint64_t offset, uint64_t length,
617 : : spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
618 : : {
619 [ + - ]: 10 : if (cb_fn) {
620 : 10 : cb_fn(cb_arg, 0);
621 : : }
622 : :
623 : 10 : return 0;
624 : : }
625 : :
626 : : static void
627 : 15 : bdev_io_cleanup(struct spdk_bdev_io *bdev_io)
628 : : {
629 [ + + ]: 15 : if (bdev_io->u.bdev.iovs) {
630 : : int i;
631 : :
632 [ + + ]: 35 : for (i = 0; i < bdev_io->u.bdev.iovcnt; i++) {
633 : 25 : free(bdev_io->u.bdev.iovs[i].iov_base);
634 : : }
635 : 10 : free(bdev_io->u.bdev.iovs);
636 : : }
637 : :
638 : 15 : free(bdev_io);
639 : 15 : }
640 : :
641 : : static void
642 : 15 : _bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch,
643 : : struct spdk_bdev *bdev, uint64_t lba, uint64_t blocks, int16_t iotype,
644 : : int iovcnt, size_t iov_len)
645 : : {
646 : 15 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
647 : : int i;
648 : :
649 : 15 : bdev_io->bdev = bdev;
650 : 15 : bdev_io->u.bdev.offset_blocks = lba;
651 : 15 : bdev_io->u.bdev.num_blocks = blocks;
652 : 15 : bdev_io->type = iotype;
653 : 15 : bdev_io->internal.ch = channel;
654 : 15 : bdev_io->u.bdev.iovcnt = iovcnt;
655 : :
656 [ + + ]: 15 : if (iovcnt == 0) {
657 : 5 : bdev_io->u.bdev.iovs = NULL;
658 : 5 : return;
659 : : }
660 : :
661 [ - + ]: 10 : SPDK_CU_ASSERT_FATAL(iov_len * iovcnt == blocks * g_block_len);
662 : :
663 : 10 : bdev_io->u.bdev.iovs = calloc(iovcnt, sizeof(struct iovec));
664 [ - + ]: 10 : SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs != NULL);
665 : :
666 [ + + ]: 35 : for (i = 0; i < iovcnt; i++) {
667 : 25 : struct iovec *iov = &bdev_io->u.bdev.iovs[i];
668 : :
669 : 25 : iov->iov_base = calloc(1, iov_len);
670 [ - + ]: 25 : SPDK_CU_ASSERT_FATAL(iov->iov_base != NULL);
671 : 25 : iov->iov_len = iov_len;
672 : : }
673 : :
674 : 10 : bdev_io->u.bdev.md_buf = (void *)0x10000000;
675 : : }
676 : :
677 : : static void
678 : 5 : bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch, struct spdk_bdev *bdev,
679 : : uint64_t lba, uint64_t blocks, int16_t iotype)
680 : : {
681 : 5 : _bdev_io_initialize(bdev_io, ch, bdev, lba, blocks, iotype, 0, 0);
682 : 5 : }
683 : :
684 : : static void
685 : 5 : verify_reset_io(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
686 : : struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
687 : : {
688 : 5 : uint8_t index = 0;
689 : : struct io_output *output;
690 : :
691 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
692 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
693 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(ch_ctx->base_channel != NULL);
694 : :
695 : 5 : CU_ASSERT(g_io_output_index == num_base_drives);
696 [ + + ]: 165 : for (index = 0; index < g_io_output_index; index++) {
697 : 160 : output = &g_io_output[index];
698 : 160 : CU_ASSERT(ch_ctx->base_channel[index] == output->ch);
699 : 160 : CU_ASSERT(raid_bdev->base_bdev_info[index].desc == output->desc);
700 : 160 : CU_ASSERT(bdev_io->type == output->iotype);
701 : : }
702 : 5 : CU_ASSERT(g_io_comp_status == io_status);
703 : 5 : }
704 : :
705 : : static void
706 : 160 : verify_raid_bdev_present(const char *name, bool presence)
707 : : {
708 : : struct raid_bdev *pbdev;
709 : : bool pbdev_found;
710 : :
711 : 160 : pbdev_found = false;
712 [ + + ]: 190 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
713 [ + + - + : 50 : if (strcmp(pbdev->bdev.name, name) == 0) {
+ + ]
714 : 20 : pbdev_found = true;
715 : 20 : break;
716 : : }
717 : : }
718 [ + + ]: 160 : if (presence == true) {
719 : 20 : CU_ASSERT(pbdev_found == true);
720 : : } else {
721 : 140 : CU_ASSERT(pbdev_found == false);
722 : : }
723 : 160 : }
724 : :
725 : : static void
726 : 65 : verify_raid_bdev(struct rpc_bdev_raid_create *r, bool presence, uint32_t raid_state)
727 : : {
728 : : struct raid_bdev *pbdev;
729 : : struct raid_base_bdev_info *base_info;
730 : 65 : struct spdk_bdev *bdev = NULL;
731 : : bool pbdev_found;
732 : 65 : uint64_t min_blockcnt = 0xFFFFFFFFFFFFFFFF;
733 : :
734 : 65 : pbdev_found = false;
735 [ + - ]: 70 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
736 [ + + - + : 70 : if (strcmp(pbdev->bdev.name, r->name) == 0) {
+ + ]
737 : 65 : pbdev_found = true;
738 [ - + ]: 65 : if (presence == false) {
739 : 0 : break;
740 : : }
741 : 65 : CU_ASSERT(pbdev->base_bdev_info != NULL);
742 [ - + ]: 65 : CU_ASSERT(pbdev->strip_size == ((r->strip_size_kb * 1024) / g_block_len));
743 [ - + ]: 65 : CU_ASSERT(pbdev->strip_size_shift == spdk_u32log2(((r->strip_size_kb * 1024) /
744 : : g_block_len)));
745 : 65 : CU_ASSERT((uint32_t)pbdev->state == raid_state);
746 : 65 : CU_ASSERT(pbdev->num_base_bdevs == r->base_bdevs.num_base_bdevs);
747 : 65 : CU_ASSERT(pbdev->num_base_bdevs_discovered == r->base_bdevs.num_base_bdevs);
748 : 65 : CU_ASSERT(pbdev->level == r->level);
749 : 65 : CU_ASSERT(pbdev->base_bdev_info != NULL);
750 [ + + ]: 2145 : RAID_FOR_EACH_BASE_BDEV(pbdev, base_info) {
751 : 2080 : CU_ASSERT(base_info->desc != NULL);
752 : 2080 : bdev = spdk_bdev_desc_get_bdev(base_info->desc);
753 : 2080 : CU_ASSERT(bdev != NULL);
754 [ - + ]: 2080 : CU_ASSERT(base_info->remove_scheduled == false);
755 [ + + + + : 2080 : CU_ASSERT((pbdev->superblock_enabled && base_info->data_offset != 0) ||
+ + + + +
- + - ]
756 : : (!pbdev->superblock_enabled && base_info->data_offset == 0));
757 : 2080 : CU_ASSERT(base_info->data_offset + base_info->data_size == bdev->blockcnt);
758 : :
759 [ + - + + ]: 2080 : if (bdev && base_info->data_size < min_blockcnt) {
760 : 65 : min_blockcnt = base_info->data_size;
761 : : }
762 : : }
763 [ - + ]: 65 : CU_ASSERT(strcmp(pbdev->bdev.product_name, "Raid Volume") == 0);
764 : 65 : CU_ASSERT(pbdev->bdev.write_cache == 0);
765 : 65 : CU_ASSERT(pbdev->bdev.blocklen == g_block_len);
766 : 65 : CU_ASSERT(pbdev->bdev.ctxt == pbdev);
767 : 65 : CU_ASSERT(pbdev->bdev.fn_table == &g_raid_bdev_fn_table);
768 : 65 : CU_ASSERT(pbdev->bdev.module == &g_raid_if);
769 : 65 : break;
770 : : }
771 : : }
772 [ + - ]: 65 : if (presence == true) {
773 : 65 : CU_ASSERT(pbdev_found == true);
774 : : } else {
775 : 0 : CU_ASSERT(pbdev_found == false);
776 : : }
777 : 65 : }
778 : :
779 : : static void
780 : 10 : verify_get_raids(struct rpc_bdev_raid_create *construct_req,
781 : : uint8_t g_max_raids,
782 : : char **g_get_raids_output, uint32_t g_get_raids_count)
783 : : {
784 : : uint8_t i, j;
785 : : bool found;
786 : :
787 : 10 : CU_ASSERT(g_max_raids == g_get_raids_count);
788 [ + - ]: 10 : if (g_max_raids == g_get_raids_count) {
789 [ + + ]: 30 : for (i = 0; i < g_max_raids; i++) {
790 : 20 : found = false;
791 [ + - ]: 20 : for (j = 0; j < g_max_raids; j++) {
792 [ + - ]: 20 : if (construct_req[i].name &&
793 [ + + - + : 20 : strcmp(construct_req[i].name, g_get_raids_output[i]) == 0) {
+ - ]
794 : 20 : found = true;
795 : 20 : break;
796 : : }
797 : : }
798 : 20 : CU_ASSERT(found == true);
799 : : }
800 : : }
801 : 10 : }
802 : :
803 : : static void
804 : 75 : create_base_bdevs(uint32_t bbdev_start_idx)
805 : : {
806 : : uint8_t i;
807 : : struct spdk_bdev *base_bdev;
808 : 60 : char name[16];
809 : :
810 [ + + ]: 2475 : for (i = 0; i < g_max_base_drives; i++, bbdev_start_idx++) {
811 [ - + ]: 2400 : snprintf(name, 16, "%s%u%s", "Nvme", bbdev_start_idx, "n1");
812 : 2400 : base_bdev = calloc(1, sizeof(struct spdk_bdev));
813 [ - + ]: 2400 : SPDK_CU_ASSERT_FATAL(base_bdev != NULL);
814 [ - + ]: 2400 : base_bdev->name = strdup(name);
815 : 2400 : spdk_uuid_generate(&base_bdev->uuid);
816 [ - + ]: 2400 : SPDK_CU_ASSERT_FATAL(base_bdev->name != NULL);
817 : 2400 : base_bdev->blocklen = g_block_len;
818 : 2400 : base_bdev->blockcnt = BLOCK_CNT;
819 : 2400 : TAILQ_INSERT_TAIL(&g_bdev_list, base_bdev, internal.link);
820 : : }
821 : 75 : }
822 : :
823 : : static void
824 : 105 : create_test_req(struct rpc_bdev_raid_create *r, const char *raid_name,
825 : : uint8_t bbdev_start_idx, bool create_base_bdev, bool superblock_enabled)
826 : : {
827 : : uint8_t i;
828 : 84 : char name[16];
829 : 105 : uint8_t bbdev_idx = bbdev_start_idx;
830 : :
831 [ - + ]: 105 : r->name = strdup(raid_name);
832 [ - + ]: 105 : SPDK_CU_ASSERT_FATAL(r->name != NULL);
833 : 105 : r->strip_size_kb = (g_strip_size * g_block_len) / 1024;
834 : 105 : r->level = 123;
835 : 105 : r->superblock_enabled = superblock_enabled;
836 : 105 : r->base_bdevs.num_base_bdevs = g_max_base_drives;
837 [ + + ]: 3465 : for (i = 0; i < g_max_base_drives; i++, bbdev_idx++) {
838 [ - + ]: 3360 : snprintf(name, 16, "%s%u%s", "Nvme", bbdev_idx, "n1");
839 [ - + ]: 3360 : r->base_bdevs.base_bdevs[i] = strdup(name);
840 [ - + ]: 3360 : SPDK_CU_ASSERT_FATAL(r->base_bdevs.base_bdevs[i] != NULL);
841 : : }
842 [ + + ]: 105 : if (create_base_bdev == true) {
843 : 75 : create_base_bdevs(bbdev_start_idx);
844 : : }
845 : 105 : g_rpc_req = r;
846 : 105 : g_rpc_req_size = sizeof(*r);
847 : 105 : }
848 : :
849 : : static void
850 : 105 : create_raid_bdev_create_req(struct rpc_bdev_raid_create *r, const char *raid_name,
851 : : uint8_t bbdev_start_idx, bool create_base_bdev,
852 : : uint8_t json_decode_obj_err, bool superblock_enabled)
853 : : {
854 : 105 : create_test_req(r, raid_name, bbdev_start_idx, create_base_bdev, superblock_enabled);
855 : :
856 : 105 : g_rpc_err = 0;
857 : 105 : g_json_decode_obj_create = 1;
858 : 105 : g_json_decode_obj_err = json_decode_obj_err;
859 : 105 : g_test_multi_raids = 0;
860 : 105 : }
861 : :
862 : : static void
863 : 105 : free_test_req(struct rpc_bdev_raid_create *r)
864 : : {
865 : : uint8_t i;
866 : :
867 : 105 : free(r->name);
868 [ + + ]: 3465 : for (i = 0; i < r->base_bdevs.num_base_bdevs; i++) {
869 : 3360 : free(r->base_bdevs.base_bdevs[i]);
870 : : }
871 : 105 : }
872 : :
873 : : static void
874 : 80 : create_raid_bdev_delete_req(struct rpc_bdev_raid_delete *r, const char *raid_name,
875 : : uint8_t json_decode_obj_err)
876 : : {
877 [ - + ]: 80 : r->name = strdup(raid_name);
878 [ - + ]: 80 : SPDK_CU_ASSERT_FATAL(r->name != NULL);
879 : :
880 : 80 : g_rpc_req = r;
881 : 80 : g_rpc_req_size = sizeof(*r);
882 : 80 : g_rpc_err = 0;
883 : 80 : g_json_decode_obj_create = 0;
884 : 80 : g_json_decode_obj_err = json_decode_obj_err;
885 : 80 : g_test_multi_raids = 0;
886 : 80 : }
887 : :
888 : : static void
889 : 35 : create_get_raids_req(struct rpc_bdev_raid_get_bdevs *r, const char *category,
890 : : uint8_t json_decode_obj_err)
891 : : {
892 [ - + ]: 35 : r->category = strdup(category);
893 [ - + ]: 35 : SPDK_CU_ASSERT_FATAL(r->category != NULL);
894 : :
895 : 35 : g_rpc_req = r;
896 : 35 : g_rpc_req_size = sizeof(*r);
897 : 35 : g_rpc_err = 0;
898 : 35 : g_json_decode_obj_create = 0;
899 : 35 : g_json_decode_obj_err = json_decode_obj_err;
900 : 35 : g_test_multi_raids = 1;
901 : 35 : g_get_raids_count = 0;
902 : 35 : }
903 : :
904 : : static void
905 : 5 : test_create_raid(void)
906 : : {
907 : 4 : struct rpc_bdev_raid_create req;
908 : 4 : struct rpc_bdev_raid_delete delete_req;
909 : :
910 : 5 : set_globals();
911 : 5 : CU_ASSERT(raid_bdev_init() == 0);
912 : :
913 : 5 : verify_raid_bdev_present("raid1", false);
914 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
915 : 5 : rpc_bdev_raid_create(NULL, NULL);
916 : 5 : CU_ASSERT(g_rpc_err == 0);
917 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
918 : 5 : free_test_req(&req);
919 : :
920 : 5 : create_raid_bdev_delete_req(&delete_req, "raid1", 0);
921 : 5 : rpc_bdev_raid_delete(NULL, NULL);
922 : 5 : CU_ASSERT(g_rpc_err == 0);
923 : 5 : raid_bdev_exit();
924 : 5 : base_bdevs_cleanup();
925 : 5 : reset_globals();
926 : 5 : }
927 : :
928 : : static void
929 : 5 : test_delete_raid(void)
930 : : {
931 : 4 : struct rpc_bdev_raid_create construct_req;
932 : 4 : struct rpc_bdev_raid_delete delete_req;
933 : :
934 : 5 : set_globals();
935 : 5 : CU_ASSERT(raid_bdev_init() == 0);
936 : :
937 : 5 : verify_raid_bdev_present("raid1", false);
938 : 5 : create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
939 : 5 : rpc_bdev_raid_create(NULL, NULL);
940 : 5 : CU_ASSERT(g_rpc_err == 0);
941 : 5 : verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
942 : 5 : free_test_req(&construct_req);
943 : :
944 : 5 : create_raid_bdev_delete_req(&delete_req, "raid1", 0);
945 : 5 : rpc_bdev_raid_delete(NULL, NULL);
946 : 5 : CU_ASSERT(g_rpc_err == 0);
947 : 5 : verify_raid_bdev_present("raid1", false);
948 : :
949 : 5 : raid_bdev_exit();
950 : 5 : base_bdevs_cleanup();
951 : 5 : reset_globals();
952 : 5 : }
953 : :
954 : : static void
955 : 5 : test_create_raid_invalid_args(void)
956 : : {
957 : 4 : struct rpc_bdev_raid_create req;
958 : 4 : struct rpc_bdev_raid_delete destroy_req;
959 : : struct raid_bdev *raid_bdev;
960 : :
961 : 5 : set_globals();
962 : 5 : CU_ASSERT(raid_bdev_init() == 0);
963 : :
964 : 5 : verify_raid_bdev_present("raid1", false);
965 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
966 : 5 : req.level = INVALID_RAID_LEVEL;
967 : 5 : rpc_bdev_raid_create(NULL, NULL);
968 : 5 : CU_ASSERT(g_rpc_err == 1);
969 : 5 : free_test_req(&req);
970 : 5 : verify_raid_bdev_present("raid1", false);
971 : :
972 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, false, 1, false);
973 : 5 : rpc_bdev_raid_create(NULL, NULL);
974 : 5 : CU_ASSERT(g_rpc_err == 1);
975 : 5 : free_test_req(&req);
976 : 5 : verify_raid_bdev_present("raid1", false);
977 : :
978 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
979 : 5 : req.strip_size_kb = 1231;
980 : 5 : rpc_bdev_raid_create(NULL, NULL);
981 : 5 : CU_ASSERT(g_rpc_err == 1);
982 : 5 : free_test_req(&req);
983 : 5 : verify_raid_bdev_present("raid1", false);
984 : :
985 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
986 : 5 : rpc_bdev_raid_create(NULL, NULL);
987 : 5 : CU_ASSERT(g_rpc_err == 0);
988 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
989 : 5 : free_test_req(&req);
990 : :
991 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
992 : 5 : rpc_bdev_raid_create(NULL, NULL);
993 : 5 : CU_ASSERT(g_rpc_err == 1);
994 : 5 : free_test_req(&req);
995 : :
996 : 5 : create_raid_bdev_create_req(&req, "raid2", 0, false, 0, false);
997 : 5 : rpc_bdev_raid_create(NULL, NULL);
998 : 5 : CU_ASSERT(g_rpc_err == 1);
999 : 5 : free_test_req(&req);
1000 : 5 : verify_raid_bdev_present("raid2", false);
1001 : :
1002 : 5 : create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
1003 : 5 : free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
1004 [ - + ]: 5 : req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme0n1");
1005 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
1006 : 5 : rpc_bdev_raid_create(NULL, NULL);
1007 : 5 : CU_ASSERT(g_rpc_err == 1);
1008 : 5 : free_test_req(&req);
1009 : 5 : verify_raid_bdev_present("raid2", false);
1010 : :
1011 : 5 : create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
1012 : 5 : free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
1013 [ - + ]: 5 : req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme100000n1");
1014 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
1015 : 5 : rpc_bdev_raid_create(NULL, NULL);
1016 : 5 : CU_ASSERT(g_rpc_err == 0);
1017 : 5 : free_test_req(&req);
1018 : 5 : verify_raid_bdev_present("raid2", true);
1019 : 5 : raid_bdev = raid_bdev_find_by_name("raid2");
1020 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
1021 : 5 : check_and_remove_raid_bdev(raid_bdev);
1022 : :
1023 : 5 : create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, false, 0, false);
1024 : 5 : rpc_bdev_raid_create(NULL, NULL);
1025 : 5 : CU_ASSERT(g_rpc_err == 0);
1026 : 5 : free_test_req(&req);
1027 : 5 : verify_raid_bdev_present("raid2", true);
1028 : 5 : verify_raid_bdev_present("raid1", true);
1029 : :
1030 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1031 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1032 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid2", 0);
1033 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1034 : 5 : raid_bdev_exit();
1035 : 5 : base_bdevs_cleanup();
1036 : 5 : reset_globals();
1037 : 5 : }
1038 : :
1039 : : static void
1040 : 5 : test_delete_raid_invalid_args(void)
1041 : : {
1042 : 4 : struct rpc_bdev_raid_create construct_req;
1043 : 4 : struct rpc_bdev_raid_delete destroy_req;
1044 : :
1045 : 5 : set_globals();
1046 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1047 : :
1048 : 5 : verify_raid_bdev_present("raid1", false);
1049 : 5 : create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
1050 : 5 : rpc_bdev_raid_create(NULL, NULL);
1051 : 5 : CU_ASSERT(g_rpc_err == 0);
1052 : 5 : verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
1053 : 5 : free_test_req(&construct_req);
1054 : :
1055 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid2", 0);
1056 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1057 : 5 : CU_ASSERT(g_rpc_err == 1);
1058 : :
1059 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 1);
1060 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1061 : 5 : CU_ASSERT(g_rpc_err == 1);
1062 : 5 : free(destroy_req.name);
1063 : 5 : verify_raid_bdev_present("raid1", true);
1064 : :
1065 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1066 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1067 : 5 : CU_ASSERT(g_rpc_err == 0);
1068 : 5 : verify_raid_bdev_present("raid1", false);
1069 : :
1070 : 5 : raid_bdev_exit();
1071 : 5 : base_bdevs_cleanup();
1072 : 5 : reset_globals();
1073 : 5 : }
1074 : :
1075 : : static void
1076 : 5 : test_io_channel(void)
1077 : : {
1078 : 4 : struct rpc_bdev_raid_create req;
1079 : 4 : struct rpc_bdev_raid_delete destroy_req;
1080 : : struct raid_bdev *pbdev;
1081 : : struct spdk_io_channel *ch;
1082 : : struct raid_bdev_io_channel *ch_ctx;
1083 : :
1084 : 5 : set_globals();
1085 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1086 : :
1087 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1088 : 5 : verify_raid_bdev_present("raid1", false);
1089 : 5 : rpc_bdev_raid_create(NULL, NULL);
1090 : 5 : CU_ASSERT(g_rpc_err == 0);
1091 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1092 : :
1093 [ + - ]: 5 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1094 [ + + + - ]: 5 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1095 : 5 : break;
1096 : : }
1097 : : }
1098 : 5 : CU_ASSERT(pbdev != NULL);
1099 : :
1100 : 5 : ch = spdk_get_io_channel(pbdev);
1101 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1102 : :
1103 : 5 : ch_ctx = spdk_io_channel_get_ctx(ch);
1104 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1105 : :
1106 : 5 : free_test_req(&req);
1107 : :
1108 : 5 : spdk_put_io_channel(ch);
1109 : :
1110 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1111 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1112 : 5 : CU_ASSERT(g_rpc_err == 0);
1113 : 5 : verify_raid_bdev_present("raid1", false);
1114 : :
1115 : 5 : raid_bdev_exit();
1116 : 5 : base_bdevs_cleanup();
1117 : 5 : reset_globals();
1118 : 5 : }
1119 : :
1120 : : /* Test reset IO */
1121 : : static void
1122 : 5 : test_reset_io(void)
1123 : : {
1124 : 4 : struct rpc_bdev_raid_create req;
1125 : 4 : struct rpc_bdev_raid_delete destroy_req;
1126 : : struct raid_bdev *pbdev;
1127 : : struct spdk_io_channel *ch;
1128 : : struct raid_bdev_io_channel *ch_ctx;
1129 : : struct spdk_bdev_io *bdev_io;
1130 : :
1131 : 5 : set_globals();
1132 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1133 : :
1134 : 5 : verify_raid_bdev_present("raid1", false);
1135 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1136 : 5 : rpc_bdev_raid_create(NULL, NULL);
1137 : 5 : CU_ASSERT(g_rpc_err == 0);
1138 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1139 [ + - ]: 5 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1140 [ + + + - ]: 5 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1141 : 5 : break;
1142 : : }
1143 : : }
1144 : 5 : CU_ASSERT(pbdev != NULL);
1145 : :
1146 : 5 : ch = spdk_get_io_channel(pbdev);
1147 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1148 : :
1149 : 5 : ch_ctx = spdk_io_channel_get_ctx(ch);
1150 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
1151 : :
1152 : 5 : g_child_io_status_flag = true;
1153 : :
1154 : 5 : CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_RESET) == true);
1155 : :
1156 : 5 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1157 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1158 : 5 : bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, 1, SPDK_BDEV_IO_TYPE_RESET);
1159 [ - + ]: 5 : memset(g_io_output, 0, g_max_base_drives * sizeof(struct io_output));
1160 : 5 : g_io_output_index = 0;
1161 : 5 : raid_bdev_submit_request(ch, bdev_io);
1162 : 5 : verify_reset_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
1163 : : true);
1164 : 5 : bdev_io_cleanup(bdev_io);
1165 : :
1166 : 5 : free_test_req(&req);
1167 : 5 : spdk_put_io_channel(ch);
1168 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1169 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1170 : 5 : CU_ASSERT(g_rpc_err == 0);
1171 : 5 : verify_raid_bdev_present("raid1", false);
1172 : :
1173 : 5 : raid_bdev_exit();
1174 : 5 : base_bdevs_cleanup();
1175 : 5 : reset_globals();
1176 : 5 : }
1177 : :
1178 : : /* Create multiple raids, destroy raids without IO, get_raids related tests */
1179 : : static void
1180 : 5 : test_multi_raid(void)
1181 : : {
1182 : : struct rpc_bdev_raid_create *construct_req;
1183 : 4 : struct rpc_bdev_raid_delete destroy_req;
1184 : 4 : struct rpc_bdev_raid_get_bdevs get_raids_req;
1185 : : uint8_t i;
1186 : 4 : char name[16];
1187 : 5 : uint8_t bbdev_idx = 0;
1188 : :
1189 : 5 : set_globals();
1190 : 5 : construct_req = calloc(MAX_RAIDS, sizeof(struct rpc_bdev_raid_create));
1191 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(construct_req != NULL);
1192 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1193 [ + + ]: 15 : for (i = 0; i < g_max_raids; i++) {
1194 [ - + ]: 10 : snprintf(name, 16, "%s%u", "raid", i);
1195 : 10 : verify_raid_bdev_present(name, false);
1196 : 10 : create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0, false);
1197 : 10 : bbdev_idx += g_max_base_drives;
1198 : 10 : rpc_bdev_raid_create(NULL, NULL);
1199 : 10 : CU_ASSERT(g_rpc_err == 0);
1200 : 10 : verify_raid_bdev(&construct_req[i], true, RAID_BDEV_STATE_ONLINE);
1201 : : }
1202 : :
1203 : 5 : create_get_raids_req(&get_raids_req, "all", 0);
1204 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1205 : 5 : CU_ASSERT(g_rpc_err == 0);
1206 : 5 : verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
1207 [ + + ]: 15 : for (i = 0; i < g_get_raids_count; i++) {
1208 : 10 : free(g_get_raids_output[i]);
1209 : : }
1210 : :
1211 : 5 : create_get_raids_req(&get_raids_req, "online", 0);
1212 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1213 : 5 : CU_ASSERT(g_rpc_err == 0);
1214 : 5 : verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
1215 [ + + ]: 15 : for (i = 0; i < g_get_raids_count; i++) {
1216 : 10 : free(g_get_raids_output[i]);
1217 : : }
1218 : :
1219 : 5 : create_get_raids_req(&get_raids_req, "configuring", 0);
1220 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1221 : 5 : CU_ASSERT(g_rpc_err == 0);
1222 : 5 : CU_ASSERT(g_get_raids_count == 0);
1223 : :
1224 : 5 : create_get_raids_req(&get_raids_req, "offline", 0);
1225 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1226 : 5 : CU_ASSERT(g_rpc_err == 0);
1227 : 5 : CU_ASSERT(g_get_raids_count == 0);
1228 : :
1229 : 5 : create_get_raids_req(&get_raids_req, "invalid_category", 0);
1230 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1231 : 5 : CU_ASSERT(g_rpc_err == 1);
1232 : 5 : CU_ASSERT(g_get_raids_count == 0);
1233 : :
1234 : 5 : create_get_raids_req(&get_raids_req, "all", 1);
1235 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1236 : 5 : CU_ASSERT(g_rpc_err == 1);
1237 : 5 : free(get_raids_req.category);
1238 : 5 : CU_ASSERT(g_get_raids_count == 0);
1239 : :
1240 : 5 : create_get_raids_req(&get_raids_req, "all", 0);
1241 : 5 : rpc_bdev_raid_get_bdevs(NULL, NULL);
1242 : 5 : CU_ASSERT(g_rpc_err == 0);
1243 : 5 : CU_ASSERT(g_get_raids_count == g_max_raids);
1244 [ + + ]: 15 : for (i = 0; i < g_get_raids_count; i++) {
1245 : 10 : free(g_get_raids_output[i]);
1246 : : }
1247 : :
1248 [ + + ]: 15 : for (i = 0; i < g_max_raids; i++) {
1249 [ - + ]: 10 : SPDK_CU_ASSERT_FATAL(construct_req[i].name != NULL);
1250 [ - + ]: 10 : snprintf(name, 16, "%s", construct_req[i].name);
1251 : 10 : create_raid_bdev_delete_req(&destroy_req, name, 0);
1252 : 10 : rpc_bdev_raid_delete(NULL, NULL);
1253 : 10 : CU_ASSERT(g_rpc_err == 0);
1254 : 10 : verify_raid_bdev_present(name, false);
1255 : : }
1256 : 5 : raid_bdev_exit();
1257 [ + + ]: 15 : for (i = 0; i < g_max_raids; i++) {
1258 : 10 : free_test_req(&construct_req[i]);
1259 : : }
1260 : 5 : free(construct_req);
1261 : 5 : base_bdevs_cleanup();
1262 : 5 : reset_globals();
1263 : 5 : }
1264 : :
1265 : : static void
1266 : 5 : test_io_type_supported(void)
1267 : : {
1268 : 5 : CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_READ) == true);
1269 : 5 : CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_WRITE) == true);
1270 : 5 : CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_INVALID) == false);
1271 : 5 : }
1272 : :
1273 : : static void
1274 : 5 : test_raid_json_dump_info(void)
1275 : : {
1276 : 4 : struct rpc_bdev_raid_create req;
1277 : 4 : struct rpc_bdev_raid_delete destroy_req;
1278 : : struct raid_bdev *pbdev;
1279 : :
1280 : 5 : set_globals();
1281 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1282 : :
1283 : 5 : verify_raid_bdev_present("raid1", false);
1284 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1285 : 5 : rpc_bdev_raid_create(NULL, NULL);
1286 : 5 : CU_ASSERT(g_rpc_err == 0);
1287 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1288 : :
1289 [ + - ]: 5 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1290 [ + + + - ]: 5 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1291 : 5 : break;
1292 : : }
1293 : : }
1294 : 5 : CU_ASSERT(pbdev != NULL);
1295 : :
1296 : 5 : CU_ASSERT(raid_bdev_dump_info_json(pbdev, NULL) == 0);
1297 : :
1298 : 5 : free_test_req(&req);
1299 : :
1300 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1301 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1302 : 5 : CU_ASSERT(g_rpc_err == 0);
1303 : 5 : verify_raid_bdev_present("raid1", false);
1304 : :
1305 : 5 : raid_bdev_exit();
1306 : 5 : base_bdevs_cleanup();
1307 : 5 : reset_globals();
1308 : 5 : }
1309 : :
1310 : : static void
1311 : 5 : test_context_size(void)
1312 : : {
1313 : 5 : CU_ASSERT(raid_bdev_get_ctx_size() == sizeof(struct raid_bdev_io));
1314 : 5 : }
1315 : :
1316 : : static void
1317 : 5 : test_raid_level_conversions(void)
1318 : : {
1319 : : const char *raid_str;
1320 : :
1321 : 5 : CU_ASSERT(raid_bdev_str_to_level("abcd123") == INVALID_RAID_LEVEL);
1322 : 5 : CU_ASSERT(raid_bdev_str_to_level("0") == RAID0);
1323 : 5 : CU_ASSERT(raid_bdev_str_to_level("raid0") == RAID0);
1324 : 5 : CU_ASSERT(raid_bdev_str_to_level("RAID0") == RAID0);
1325 : :
1326 : 5 : raid_str = raid_bdev_level_to_str(INVALID_RAID_LEVEL);
1327 [ + - + - ]: 5 : CU_ASSERT(raid_str != NULL && strlen(raid_str) == 0);
1328 : 5 : raid_str = raid_bdev_level_to_str(1234);
1329 [ + - + - ]: 5 : CU_ASSERT(raid_str != NULL && strlen(raid_str) == 0);
1330 : 5 : raid_str = raid_bdev_level_to_str(RAID0);
1331 [ + - + + : 5 : CU_ASSERT(raid_str != NULL && strcmp(raid_str, "raid0") == 0);
+ - ]
1332 : 5 : }
1333 : :
1334 : : static void
1335 : 5 : test_create_raid_superblock(void)
1336 : : {
1337 : 4 : struct rpc_bdev_raid_create req;
1338 : 4 : struct rpc_bdev_raid_delete delete_req;
1339 : :
1340 : 5 : set_globals();
1341 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1342 : :
1343 : 5 : verify_raid_bdev_present("raid1", false);
1344 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, true);
1345 : 5 : rpc_bdev_raid_create(NULL, NULL);
1346 : 5 : CU_ASSERT(g_rpc_err == 0);
1347 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1348 : 5 : free_test_req(&req);
1349 : :
1350 : 5 : create_raid_bdev_delete_req(&delete_req, "raid1", 0);
1351 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1352 : 5 : CU_ASSERT(g_rpc_err == 0);
1353 : 5 : raid_bdev_exit();
1354 : 5 : base_bdevs_cleanup();
1355 : 5 : reset_globals();
1356 : 5 : }
1357 : :
1358 : : static void
1359 : 5 : test_raid_process(void)
1360 : : {
1361 : 4 : struct rpc_bdev_raid_create req;
1362 : 4 : struct rpc_bdev_raid_delete destroy_req;
1363 : : struct raid_bdev *pbdev;
1364 : : struct spdk_bdev *base_bdev;
1365 : : struct spdk_thread *process_thread;
1366 : 5 : uint64_t num_blocks_processed = 0;
1367 : :
1368 : 5 : set_globals();
1369 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1370 : :
1371 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1372 : 5 : verify_raid_bdev_present("raid1", false);
1373 [ + + ]: 165 : TAILQ_FOREACH(base_bdev, &g_bdev_list, internal.link) {
1374 : 160 : base_bdev->blockcnt = 128;
1375 : : }
1376 : 5 : rpc_bdev_raid_create(NULL, NULL);
1377 : 5 : CU_ASSERT(g_rpc_err == 0);
1378 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1379 : 5 : free_test_req(&req);
1380 : :
1381 [ + - ]: 5 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1382 [ + + + - ]: 5 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1383 : 5 : break;
1384 : : }
1385 : : }
1386 : 5 : CU_ASSERT(pbdev != NULL);
1387 : :
1388 : 5 : pbdev->module_private = &num_blocks_processed;
1389 : 5 : pbdev->min_base_bdevs_operational = 0;
1390 : :
1391 : 5 : CU_ASSERT(raid_bdev_start_rebuild(&pbdev->base_bdev_info[0]) == 0);
1392 : 5 : poll_app_thread();
1393 : :
1394 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(pbdev->process != NULL);
1395 : :
1396 : 5 : process_thread = g_latest_thread;
1397 : 5 : spdk_thread_poll(process_thread, 0, 0);
1398 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(pbdev->process->thread == process_thread);
1399 : :
1400 [ + + ]: 35 : while (spdk_thread_poll(process_thread, 0, 0) > 0) {
1401 : 30 : poll_app_thread();
1402 : : }
1403 : :
1404 : 5 : CU_ASSERT(pbdev->process == NULL);
1405 : 5 : CU_ASSERT(num_blocks_processed == pbdev->bdev.blockcnt);
1406 : :
1407 : 5 : poll_app_thread();
1408 : :
1409 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1410 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1411 : 5 : CU_ASSERT(g_rpc_err == 0);
1412 : 5 : verify_raid_bdev_present("raid1", false);
1413 : :
1414 : 5 : raid_bdev_exit();
1415 : 5 : base_bdevs_cleanup();
1416 : 5 : reset_globals();
1417 : 5 : }
1418 : :
1419 : : static void
1420 : 5 : test_raid_process_with_qos(void)
1421 : : {
1422 : 4 : struct rpc_bdev_raid_create req;
1423 : 4 : struct rpc_bdev_raid_delete destroy_req;
1424 : : struct raid_bdev *pbdev;
1425 : : struct spdk_bdev *base_bdev;
1426 : : struct spdk_thread *process_thread;
1427 : 5 : uint64_t num_blocks_processed = 0;
1428 : 4 : struct spdk_raid_bdev_opts opts;
1429 : 5 : int i = 0;
1430 : :
1431 : 5 : set_globals();
1432 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1433 : :
1434 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1435 : 5 : verify_raid_bdev_present("raid1", false);
1436 [ + + ]: 165 : TAILQ_FOREACH(base_bdev, &g_bdev_list, internal.link) {
1437 : 160 : base_bdev->blockcnt = 128;
1438 : : }
1439 : 5 : rpc_bdev_raid_create(NULL, NULL);
1440 : 5 : CU_ASSERT(g_rpc_err == 0);
1441 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1442 : 5 : free_test_req(&req);
1443 : :
1444 [ + - ]: 5 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1445 [ + + + - ]: 5 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1446 : 5 : break;
1447 : : }
1448 : : }
1449 : 5 : CU_ASSERT(pbdev != NULL);
1450 : :
1451 : 5 : pbdev->module_private = &num_blocks_processed;
1452 : 5 : pbdev->min_base_bdevs_operational = 0;
1453 : :
1454 : 5 : opts.process_window_size_kb = 1024;
1455 : 5 : opts.process_max_bandwidth_mb_sec = 1;
1456 : 5 : CU_ASSERT(raid_bdev_set_opts(&opts) == 0);
1457 : 5 : CU_ASSERT(raid_bdev_start_rebuild(&pbdev->base_bdev_info[0]) == 0);
1458 : 5 : poll_app_thread();
1459 : :
1460 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(pbdev->process != NULL);
1461 : :
1462 : 5 : process_thread = g_latest_thread;
1463 : :
1464 [ + + ]: 55 : for (i = 0; i < 10; i++) {
1465 : 50 : spdk_thread_poll(process_thread, 0, 0);
1466 : 50 : poll_app_thread();
1467 : : }
1468 : 5 : CU_ASSERT(pbdev->process->window_offset == 0);
1469 : :
1470 : 5 : spdk_delay_us(SPDK_SEC_TO_USEC);
1471 [ + + ]: 40 : while (spdk_thread_poll(process_thread, 0, 0) > 0) {
1472 : 35 : spdk_delay_us(SPDK_SEC_TO_USEC);
1473 : 35 : poll_app_thread();
1474 : : }
1475 : :
1476 : 5 : CU_ASSERT(pbdev->process == NULL);
1477 : 5 : CU_ASSERT(num_blocks_processed == pbdev->bdev.blockcnt);
1478 : :
1479 : 5 : poll_app_thread();
1480 : :
1481 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1482 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1483 : 5 : CU_ASSERT(g_rpc_err == 0);
1484 : 5 : verify_raid_bdev_present("raid1", false);
1485 : :
1486 : 5 : raid_bdev_exit();
1487 : 5 : base_bdevs_cleanup();
1488 : 5 : reset_globals();
1489 : 5 : }
1490 : :
1491 : : static void
1492 : 5 : test_raid_io_split(void)
1493 : : {
1494 : 4 : struct rpc_bdev_raid_create req;
1495 : 4 : struct rpc_bdev_raid_delete destroy_req;
1496 : : struct raid_bdev *pbdev;
1497 : : struct spdk_io_channel *ch;
1498 : : struct raid_bdev_io_channel *raid_ch;
1499 : : struct spdk_bdev_io *bdev_io;
1500 : : struct raid_bdev_io *raid_io;
1501 : : uint64_t split_offset;
1502 : 4 : struct iovec iovs_orig[4];
1503 : 5 : struct raid_bdev_process process = { };
1504 : :
1505 : 5 : set_globals();
1506 : 5 : CU_ASSERT(raid_bdev_init() == 0);
1507 : :
1508 : 5 : verify_raid_bdev_present("raid1", false);
1509 : 5 : create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1510 : 5 : rpc_bdev_raid_create(NULL, NULL);
1511 : 5 : CU_ASSERT(g_rpc_err == 0);
1512 : 5 : verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1513 : :
1514 [ + - ]: 5 : TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1515 [ + + + - ]: 5 : if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1516 : 5 : break;
1517 : : }
1518 : : }
1519 : 5 : CU_ASSERT(pbdev != NULL);
1520 : 5 : pbdev->bdev.md_len = 8;
1521 : :
1522 : 5 : process.raid_bdev = pbdev;
1523 : 5 : process.target = &pbdev->base_bdev_info[0];
1524 : 5 : pbdev->process = &process;
1525 : 5 : ch = spdk_get_io_channel(pbdev);
1526 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(ch != NULL);
1527 : 5 : raid_ch = spdk_io_channel_get_ctx(ch);
1528 : 5 : g_bdev_io_defer_completion = true;
1529 : :
1530 : : /* test split of bdev_io with 1 iovec */
1531 : 5 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1532 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1533 : 5 : raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
1534 : 5 : _bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, g_strip_size, SPDK_BDEV_IO_TYPE_WRITE, 1,
1535 : 5 : g_strip_size * g_block_len);
1536 [ - + ]: 5 : memcpy(iovs_orig, bdev_io->u.bdev.iovs, sizeof(*iovs_orig) * bdev_io->u.bdev.iovcnt);
1537 : :
1538 : 5 : split_offset = 1;
1539 : 5 : raid_ch->process.offset = split_offset;
1540 : 5 : raid_bdev_submit_request(ch, bdev_io);
1541 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1542 : 5 : CU_ASSERT(raid_io->offset_blocks == split_offset);
1543 : 5 : CU_ASSERT(raid_io->iovcnt == 1);
1544 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1545 : 5 : CU_ASSERT(raid_io->iovs == raid_io->split.iov);
1546 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base + split_offset * g_block_len);
1547 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig->iov_len - split_offset * g_block_len);
1548 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1549 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1550 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1551 : : }
1552 : 5 : complete_deferred_ios();
1553 : 5 : CU_ASSERT(raid_io->num_blocks == split_offset);
1554 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1555 : 5 : CU_ASSERT(raid_io->iovcnt == 1);
1556 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base);
1557 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == split_offset * g_block_len);
1558 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1559 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1560 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1561 : : }
1562 : 5 : complete_deferred_ios();
1563 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
1564 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1565 : 5 : CU_ASSERT(raid_io->iovcnt == 1);
1566 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base);
1567 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig->iov_len);
1568 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1569 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1570 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1571 : : }
1572 : :
1573 [ - + ]: 5 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1574 : :
1575 : 5 : bdev_io_cleanup(bdev_io);
1576 : :
1577 : : /* test split of bdev_io with 4 iovecs */
1578 : 5 : bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1579 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1580 : 5 : raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
1581 : 5 : _bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, g_strip_size, SPDK_BDEV_IO_TYPE_WRITE,
1582 : 5 : 4, g_strip_size / 4 * g_block_len);
1583 [ - + ]: 5 : memcpy(iovs_orig, bdev_io->u.bdev.iovs, sizeof(*iovs_orig) * bdev_io->u.bdev.iovcnt);
1584 : :
1585 : 5 : split_offset = 1; /* split at the first iovec */
1586 : 5 : raid_ch->process.offset = split_offset;
1587 : 5 : raid_bdev_submit_request(ch, bdev_io);
1588 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1589 : 5 : CU_ASSERT(raid_io->offset_blocks == split_offset);
1590 : 5 : CU_ASSERT(raid_io->iovcnt == 4);
1591 : 5 : CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[0]);
1592 : 5 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[0]);
1593 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[0].iov_base + g_block_len);
1594 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig[0].iov_len - g_block_len);
1595 [ - + - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs + 1, iovs_orig + 1, sizeof(*iovs_orig) * 3) == 0);
1596 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1597 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1598 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1599 : : }
1600 : 5 : complete_deferred_ios();
1601 : 5 : CU_ASSERT(raid_io->num_blocks == split_offset);
1602 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1603 : 5 : CU_ASSERT(raid_io->iovcnt == 1);
1604 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1605 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[0].iov_base);
1606 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == g_block_len);
1607 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1608 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1609 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1610 : : }
1611 : 5 : complete_deferred_ios();
1612 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
1613 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1614 : 5 : CU_ASSERT(raid_io->iovcnt == 4);
1615 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1616 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1617 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1618 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1619 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1620 : : }
1621 : :
1622 [ - + ]: 5 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1623 : :
1624 : 5 : split_offset = g_strip_size / 2; /* split exactly between second and third iovec */
1625 : 5 : raid_ch->process.offset = split_offset;
1626 : 5 : raid_bdev_submit_request(ch, bdev_io);
1627 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1628 : 5 : CU_ASSERT(raid_io->offset_blocks == split_offset);
1629 : 5 : CU_ASSERT(raid_io->iovcnt == 2);
1630 : 5 : CU_ASSERT(raid_io->split.iov == NULL);
1631 : 5 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[2]);
1632 [ - + - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig + 2, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1633 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1634 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1635 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1636 : : }
1637 : 5 : complete_deferred_ios();
1638 : 5 : CU_ASSERT(raid_io->num_blocks == split_offset);
1639 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1640 : 5 : CU_ASSERT(raid_io->iovcnt == 2);
1641 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1642 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1643 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1644 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1645 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1646 : : }
1647 : 5 : complete_deferred_ios();
1648 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
1649 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1650 : 5 : CU_ASSERT(raid_io->iovcnt == 4);
1651 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1652 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1653 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1654 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1655 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1656 : : }
1657 : :
1658 [ - + ]: 5 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1659 : :
1660 : 5 : split_offset = g_strip_size / 2 + 1; /* split at the third iovec */
1661 : 5 : raid_ch->process.offset = split_offset;
1662 : 5 : raid_bdev_submit_request(ch, bdev_io);
1663 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1664 : 5 : CU_ASSERT(raid_io->offset_blocks == split_offset);
1665 : 5 : CU_ASSERT(raid_io->iovcnt == 2);
1666 : 5 : CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[2]);
1667 : 5 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[2]);
1668 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[2].iov_base + g_block_len);
1669 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig[2].iov_len - g_block_len);
1670 : 5 : CU_ASSERT(raid_io->iovs[1].iov_base == iovs_orig[3].iov_base);
1671 : 5 : CU_ASSERT(raid_io->iovs[1].iov_len == iovs_orig[3].iov_len);
1672 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1673 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1674 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1675 : : }
1676 : 5 : complete_deferred_ios();
1677 : 5 : CU_ASSERT(raid_io->num_blocks == split_offset);
1678 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1679 : 5 : CU_ASSERT(raid_io->iovcnt == 3);
1680 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1681 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * 2) == 0);
1682 : 5 : CU_ASSERT(raid_io->iovs[2].iov_base == iovs_orig[2].iov_base);
1683 : 5 : CU_ASSERT(raid_io->iovs[2].iov_len == g_block_len);
1684 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1685 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1686 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1687 : : }
1688 : 5 : complete_deferred_ios();
1689 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
1690 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1691 : 5 : CU_ASSERT(raid_io->iovcnt == 4);
1692 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1693 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1694 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1695 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1696 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1697 : : }
1698 : :
1699 [ - + ]: 5 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1700 : :
1701 : 5 : split_offset = g_strip_size - 1; /* split at the last iovec */
1702 : 5 : raid_ch->process.offset = split_offset;
1703 : 5 : raid_bdev_submit_request(ch, bdev_io);
1704 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1705 : 5 : CU_ASSERT(raid_io->offset_blocks == split_offset);
1706 : 5 : CU_ASSERT(raid_io->iovcnt == 1);
1707 : 5 : CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[3]);
1708 : 5 : CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[3]);
1709 : 5 : CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[3].iov_base + iovs_orig[3].iov_len - g_block_len);
1710 : 5 : CU_ASSERT(raid_io->iovs[0].iov_len == g_block_len);
1711 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1712 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1713 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1714 : : }
1715 : 5 : complete_deferred_ios();
1716 : 5 : CU_ASSERT(raid_io->num_blocks == split_offset);
1717 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1718 : 5 : CU_ASSERT(raid_io->iovcnt == 4);
1719 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1720 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * 3) == 0);
1721 : 5 : CU_ASSERT(raid_io->iovs[3].iov_base == iovs_orig[3].iov_base);
1722 : 5 : CU_ASSERT(raid_io->iovs[3].iov_len == iovs_orig[3].iov_len - g_block_len);
1723 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1724 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1725 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1726 : : }
1727 : 5 : complete_deferred_ios();
1728 : 5 : CU_ASSERT(raid_io->num_blocks == g_strip_size);
1729 : 5 : CU_ASSERT(raid_io->offset_blocks == 0);
1730 : 5 : CU_ASSERT(raid_io->iovcnt == 4);
1731 : 5 : CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1732 [ - + ]: 5 : CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1733 [ - + ]: 5 : if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1734 [ # # ]: 0 : !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1735 : 0 : CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1736 : : }
1737 : :
1738 [ - + ]: 5 : CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1739 : :
1740 : 5 : bdev_io_cleanup(bdev_io);
1741 : :
1742 : 5 : spdk_put_io_channel(ch);
1743 : 5 : free_test_req(&req);
1744 : 5 : pbdev->process = NULL;
1745 : :
1746 : 5 : create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1747 : 5 : rpc_bdev_raid_delete(NULL, NULL);
1748 : 5 : CU_ASSERT(g_rpc_err == 0);
1749 : 5 : verify_raid_bdev_present("raid1", false);
1750 : :
1751 : 5 : raid_bdev_exit();
1752 : 5 : base_bdevs_cleanup();
1753 : 5 : reset_globals();
1754 : 5 : }
1755 : :
1756 : : static int
1757 : 15 : test_new_thread_fn(struct spdk_thread *thread)
1758 : : {
1759 : 15 : g_latest_thread = thread;
1760 : :
1761 : 15 : return 0;
1762 : : }
1763 : :
1764 : : static int
1765 : 70 : test_bdev_ioch_create(void *io_device, void *ctx_buf)
1766 : : {
1767 : 70 : return 0;
1768 : : }
1769 : :
1770 : : static void
1771 : 60 : test_bdev_ioch_destroy(void *io_device, void *ctx_buf)
1772 : : {
1773 : 60 : }
1774 : :
1775 : : int
1776 : 5 : main(int argc, char **argv)
1777 : : {
1778 : 5 : CU_pSuite suite = NULL;
1779 : : unsigned int num_failures;
1780 : :
1781 : 5 : CU_initialize_registry();
1782 : :
1783 : 5 : suite = CU_add_suite("raid", set_test_opts, NULL);
1784 : 5 : CU_ADD_TEST(suite, test_create_raid);
1785 : 5 : CU_ADD_TEST(suite, test_create_raid_superblock);
1786 : 5 : CU_ADD_TEST(suite, test_delete_raid);
1787 : 5 : CU_ADD_TEST(suite, test_create_raid_invalid_args);
1788 : 5 : CU_ADD_TEST(suite, test_delete_raid_invalid_args);
1789 : 5 : CU_ADD_TEST(suite, test_io_channel);
1790 : 5 : CU_ADD_TEST(suite, test_reset_io);
1791 : 5 : CU_ADD_TEST(suite, test_multi_raid);
1792 : 5 : CU_ADD_TEST(suite, test_io_type_supported);
1793 : 5 : CU_ADD_TEST(suite, test_raid_json_dump_info);
1794 : 5 : CU_ADD_TEST(suite, test_context_size);
1795 : 5 : CU_ADD_TEST(suite, test_raid_level_conversions);
1796 : 5 : CU_ADD_TEST(suite, test_raid_io_split);
1797 : 5 : CU_ADD_TEST(suite, test_raid_process);
1798 : 5 : CU_ADD_TEST(suite, test_raid_process_with_qos);
1799 : :
1800 : 5 : spdk_thread_lib_init(test_new_thread_fn, 0);
1801 : 5 : g_app_thread = spdk_thread_create("app_thread", NULL);
1802 : 5 : spdk_set_thread(g_app_thread);
1803 : 5 : spdk_io_device_register(&g_bdev_ch_io_device, test_bdev_ioch_create, test_bdev_ioch_destroy, 0,
1804 : : NULL);
1805 : :
1806 : 5 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
1807 : 5 : CU_cleanup_registry();
1808 : :
1809 : 5 : spdk_io_device_unregister(&g_bdev_ch_io_device, NULL);
1810 : 5 : spdk_thread_exit(g_app_thread);
1811 : 5 : spdk_thread_poll(g_app_thread, 0, 0);
1812 : 5 : spdk_thread_destroy(g_app_thread);
1813 : 5 : spdk_thread_lib_fini();
1814 : :
1815 : 5 : return num_failures;
1816 : : }
|