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