xref: /spdk/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c (revision 89fd17309ebf03a59fb073615058a70b852baa8d)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2018 Intel Corporation.
311495b5cSArtur Paszkiewicz  *   All rights reserved.
44bb902a6SMike Gerdts  *   Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
511495b5cSArtur Paszkiewicz  */
611495b5cSArtur Paszkiewicz 
711495b5cSArtur Paszkiewicz #include "spdk/stdinc.h"
8*89fd1730Sxupeng9 #include "spdk/util.h"
9ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
1011495b5cSArtur Paszkiewicz #include "spdk/env.h"
1111495b5cSArtur Paszkiewicz #include "spdk_internal/mock.h"
125fc0475cSJiewei Ke #include "thread/thread_internal.h"
1311495b5cSArtur Paszkiewicz #include "bdev/raid/bdev_raid.c"
1411495b5cSArtur Paszkiewicz #include "bdev/raid/bdev_raid_rpc.c"
15fff473bbSArtur Paszkiewicz #include "common/lib/test_env.c"
1611495b5cSArtur Paszkiewicz 
1711495b5cSArtur Paszkiewicz #define MAX_BASE_DRIVES 32
1811495b5cSArtur Paszkiewicz #define MAX_RAIDS 2
1911495b5cSArtur Paszkiewicz #define BLOCK_CNT (1024ul * 1024ul * 1024ul * 1024ul)
20192db8deSSlawomir Ptak #define MD_SIZE 8
2111495b5cSArtur Paszkiewicz 
2211495b5cSArtur Paszkiewicz struct spdk_bdev_channel {
2311495b5cSArtur Paszkiewicz 	struct spdk_io_channel *channel;
2411495b5cSArtur Paszkiewicz };
2511495b5cSArtur Paszkiewicz 
26d8a18924SShuhei Matsumoto struct spdk_bdev_desc {
27d8a18924SShuhei Matsumoto 	struct spdk_bdev *bdev;
28d8a18924SShuhei Matsumoto };
29d8a18924SShuhei Matsumoto 
3011495b5cSArtur Paszkiewicz /* Data structure to capture the output of IO for verification */
3111495b5cSArtur Paszkiewicz struct io_output {
3211495b5cSArtur Paszkiewicz 	struct spdk_bdev_desc       *desc;
3311495b5cSArtur Paszkiewicz 	struct spdk_io_channel      *ch;
3411495b5cSArtur Paszkiewicz 	enum spdk_bdev_io_type      iotype;
3511495b5cSArtur Paszkiewicz };
3611495b5cSArtur Paszkiewicz 
3711495b5cSArtur Paszkiewicz /* Globals */
3811495b5cSArtur Paszkiewicz struct io_output *g_io_output = NULL;
3911495b5cSArtur Paszkiewicz uint32_t g_io_output_index;
4011495b5cSArtur Paszkiewicz uint32_t g_io_comp_status;
4111495b5cSArtur Paszkiewicz bool g_child_io_status_flag;
4211495b5cSArtur Paszkiewicz void *g_rpc_req;
4311495b5cSArtur Paszkiewicz uint32_t g_rpc_req_size;
4411495b5cSArtur Paszkiewicz TAILQ_HEAD(bdev, spdk_bdev);
4511495b5cSArtur Paszkiewicz struct bdev g_bdev_list;
4611495b5cSArtur Paszkiewicz uint32_t g_block_len;
4711495b5cSArtur Paszkiewicz uint32_t g_strip_size;
4811495b5cSArtur Paszkiewicz uint32_t g_max_io_size;
4911495b5cSArtur Paszkiewicz uint8_t g_max_base_drives;
5011495b5cSArtur Paszkiewicz uint8_t g_max_raids;
5111495b5cSArtur Paszkiewicz uint8_t g_rpc_err;
5211495b5cSArtur Paszkiewicz char *g_get_raids_output[MAX_RAIDS];
5311495b5cSArtur Paszkiewicz uint32_t g_get_raids_count;
5411495b5cSArtur Paszkiewicz uint8_t g_json_decode_obj_err;
5511495b5cSArtur Paszkiewicz uint8_t g_json_decode_obj_create;
5611495b5cSArtur Paszkiewicz uint8_t g_test_multi_raids;
5750d58ff3SArtur Paszkiewicz uint64_t g_bdev_ch_io_device;
58aae5e04fSArtur Paszkiewicz bool g_bdev_io_defer_completion;
59aae5e04fSArtur Paszkiewicz TAILQ_HEAD(, spdk_bdev_io) g_deferred_ios = TAILQ_HEAD_INITIALIZER(g_deferred_ios);
60fff473bbSArtur Paszkiewicz struct spdk_thread *g_app_thread;
6179f76d9fSArtur Paszkiewicz struct spdk_thread *g_latest_thread;
6211495b5cSArtur Paszkiewicz 
63698da718SArtur Paszkiewicz static int
64698da718SArtur Paszkiewicz ut_raid_start(struct raid_bdev *raid_bdev)
65698da718SArtur Paszkiewicz {
66698da718SArtur Paszkiewicz 	uint64_t min_blockcnt = UINT64_MAX;
67698da718SArtur Paszkiewicz 	struct raid_base_bdev_info *base_info;
68698da718SArtur Paszkiewicz 
69698da718SArtur Paszkiewicz 	RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
70698da718SArtur Paszkiewicz 		min_blockcnt = spdk_min(min_blockcnt, base_info->data_size);
71698da718SArtur Paszkiewicz 	}
72698da718SArtur Paszkiewicz 	raid_bdev->bdev.blockcnt = min_blockcnt;
73698da718SArtur Paszkiewicz 
74698da718SArtur Paszkiewicz 	return 0;
75698da718SArtur Paszkiewicz }
76698da718SArtur Paszkiewicz 
77698da718SArtur Paszkiewicz static void
78698da718SArtur Paszkiewicz ut_raid_submit_rw_request_defered_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
79698da718SArtur Paszkiewicz {
80698da718SArtur Paszkiewicz 	struct raid_bdev_io *raid_io = cb_arg;
81698da718SArtur Paszkiewicz 
82698da718SArtur Paszkiewicz 	raid_bdev_io_complete(raid_io, success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED);
83698da718SArtur Paszkiewicz }
84698da718SArtur Paszkiewicz 
85698da718SArtur Paszkiewicz static void
86698da718SArtur Paszkiewicz ut_raid_submit_rw_request(struct raid_bdev_io *raid_io)
87698da718SArtur Paszkiewicz {
88698da718SArtur Paszkiewicz 	if (g_bdev_io_defer_completion) {
89698da718SArtur Paszkiewicz 		struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(raid_io);
90698da718SArtur Paszkiewicz 
91698da718SArtur Paszkiewicz 		bdev_io->internal.cb = ut_raid_submit_rw_request_defered_cb;
92698da718SArtur Paszkiewicz 		bdev_io->internal.caller_ctx = raid_io;
93698da718SArtur Paszkiewicz 		TAILQ_INSERT_TAIL(&g_deferred_ios, bdev_io, internal.link);
94698da718SArtur Paszkiewicz 		return;
95698da718SArtur Paszkiewicz 	}
96698da718SArtur Paszkiewicz 	raid_bdev_io_complete(raid_io,
97698da718SArtur Paszkiewicz 			      g_child_io_status_flag ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED);
98698da718SArtur Paszkiewicz }
99698da718SArtur Paszkiewicz 
100698da718SArtur Paszkiewicz static void
101698da718SArtur Paszkiewicz ut_raid_submit_null_payload_request(struct raid_bdev_io *raid_io)
102698da718SArtur Paszkiewicz {
103698da718SArtur Paszkiewicz 	raid_bdev_io_complete(raid_io,
104698da718SArtur Paszkiewicz 			      g_child_io_status_flag ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED);
105698da718SArtur Paszkiewicz }
106698da718SArtur Paszkiewicz 
107698da718SArtur Paszkiewicz static void
108698da718SArtur Paszkiewicz ut_raid_complete_process_request(void *ctx)
109698da718SArtur Paszkiewicz {
110698da718SArtur Paszkiewicz 	struct raid_bdev_process_request *process_req = ctx;
111698da718SArtur Paszkiewicz 
112698da718SArtur Paszkiewicz 	raid_bdev_process_request_complete(process_req, 0);
113698da718SArtur Paszkiewicz }
114698da718SArtur Paszkiewicz 
115698da718SArtur Paszkiewicz static int
116698da718SArtur Paszkiewicz ut_raid_submit_process_request(struct raid_bdev_process_request *process_req,
117698da718SArtur Paszkiewicz 			       struct raid_bdev_io_channel *raid_ch)
118698da718SArtur Paszkiewicz {
119698da718SArtur Paszkiewicz 	struct raid_bdev *raid_bdev = spdk_io_channel_get_io_device(spdk_io_channel_from_ctx(raid_ch));
120698da718SArtur Paszkiewicz 
121698da718SArtur Paszkiewicz 	*(uint64_t *)raid_bdev->module_private += process_req->num_blocks;
122698da718SArtur Paszkiewicz 
123698da718SArtur Paszkiewicz 	spdk_thread_send_msg(spdk_get_thread(), ut_raid_complete_process_request, process_req);
124698da718SArtur Paszkiewicz 
125698da718SArtur Paszkiewicz 	return process_req->num_blocks;
126698da718SArtur Paszkiewicz }
127698da718SArtur Paszkiewicz 
128698da718SArtur Paszkiewicz static struct raid_bdev_module g_ut_raid_module = {
129698da718SArtur Paszkiewicz 	.level = 123,
130698da718SArtur Paszkiewicz 	.base_bdevs_min = 1,
131698da718SArtur Paszkiewicz 	.start = ut_raid_start,
132698da718SArtur Paszkiewicz 	.submit_rw_request = ut_raid_submit_rw_request,
133698da718SArtur Paszkiewicz 	.submit_null_payload_request = ut_raid_submit_null_payload_request,
134698da718SArtur Paszkiewicz 	.submit_process_request = ut_raid_submit_process_request,
135698da718SArtur Paszkiewicz };
136698da718SArtur Paszkiewicz RAID_MODULE_REGISTER(&g_ut_raid_module)
137698da718SArtur Paszkiewicz 
13811495b5cSArtur Paszkiewicz DEFINE_STUB_V(spdk_bdev_module_examine_done, (struct spdk_bdev_module *module));
13911495b5cSArtur Paszkiewicz DEFINE_STUB_V(spdk_bdev_module_list_add, (struct spdk_bdev_module *bdev_module));
14011495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev,
14111495b5cSArtur Paszkiewicz 		enum spdk_bdev_io_type io_type), true);
14211495b5cSArtur Paszkiewicz DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
14311495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_bdev_flush_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
14411495b5cSArtur Paszkiewicz 		uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
14511495b5cSArtur Paszkiewicz 		void *cb_arg), 0);
14611495b5cSArtur Paszkiewicz DEFINE_STUB_V(spdk_rpc_register_method, (const char *method, spdk_rpc_method_handler func,
14711495b5cSArtur Paszkiewicz 		uint32_t state_mask));
14811495b5cSArtur Paszkiewicz DEFINE_STUB_V(spdk_jsonrpc_end_result, (struct spdk_jsonrpc_request *request,
14911495b5cSArtur Paszkiewicz 					struct spdk_json_write_ctx *w));
150d73077b8Syidong0635 DEFINE_STUB_V(spdk_jsonrpc_send_bool_response, (struct spdk_jsonrpc_request *request,
151d73077b8Syidong0635 		bool value));
15211495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_decode_string, int, (const struct spdk_json_val *val, void *out), 0);
15311495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_decode_uint32, int, (const struct spdk_json_val *val, void *out), 0);
154e85f1f11SKonrad Sztyber DEFINE_STUB(spdk_json_decode_uuid, int, (const struct spdk_json_val *val, void *out), 0);
15511495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_decode_array, int, (const struct spdk_json_val *values,
15611495b5cSArtur Paszkiewicz 		spdk_json_decode_fn decode_func,
15711495b5cSArtur Paszkiewicz 		void *out, size_t max_size, size_t *out_size, size_t stride), 0);
158e39760fdSKrzysztof Smolinski DEFINE_STUB(spdk_json_decode_bool, int, (const struct spdk_json_val *val, void *out), 0);
15911495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_name, int, (struct spdk_json_write_ctx *w, const char *name), 0);
16011495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_object_begin, int, (struct spdk_json_write_ctx *w), 0);
16111495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_named_object_begin, int, (struct spdk_json_write_ctx *w,
16211495b5cSArtur Paszkiewicz 		const char *name), 0);
163ec6d94b6SArtur Paszkiewicz DEFINE_STUB(spdk_json_write_string, int, (struct spdk_json_write_ctx *w, const char *val), 0);
16411495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_object_end, int, (struct spdk_json_write_ctx *w), 0);
16511495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_array_begin, int, (struct spdk_json_write_ctx *w), 0);
16611495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_array_end, int, (struct spdk_json_write_ctx *w), 0);
16711495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_named_array_begin, int, (struct spdk_json_write_ctx *w,
16811495b5cSArtur Paszkiewicz 		const char *name), 0);
16911495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_json_write_null, int, (struct spdk_json_write_ctx *w), 0);
170c51db566SArtur Paszkiewicz DEFINE_STUB(spdk_json_write_named_uint64, int, (struct spdk_json_write_ctx *w, const char *name,
171c51db566SArtur Paszkiewicz 		uint64_t val), 0);
17211495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_strerror, const char *, (int errnum), NULL);
17311495b5cSArtur Paszkiewicz DEFINE_STUB(spdk_bdev_queue_io_wait, int, (struct spdk_bdev *bdev, struct spdk_io_channel *ch,
17411495b5cSArtur Paszkiewicz 		struct spdk_bdev_io_wait_entry *entry), 0);
175be440c01SAlexey Marchuk DEFINE_STUB(spdk_bdev_get_memory_domains, int, (struct spdk_bdev *bdev,
176be440c01SAlexey Marchuk 		struct spdk_memory_domain **domains,	int array_size), 0);
177be440c01SAlexey Marchuk DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test_bdev");
178698da718SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, (const struct spdk_bdev *bdev), MD_SIZE);
179698da718SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), false);
180698da718SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_is_md_separate, bool, (const struct spdk_bdev *bdev), true);
181698da718SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev),
182698da718SArtur Paszkiewicz 	    SPDK_DIF_DISABLE);
183357c038cSKrzysztof Smolinski DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false);
184c22b052bSShuhei Matsumoto DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0);
18556317f62SEugene Kobyak DEFINE_STUB(spdk_json_write_named_uuid, int, (struct spdk_json_write_ctx *w, const char *name,
18656317f62SEugene Kobyak 		const struct spdk_uuid *val), 0);
18777b8f7b6SArtur Paszkiewicz DEFINE_STUB_V(raid_bdev_init_superblock, (struct raid_bdev *raid_bdev));
188c25b80e2SArtur Paszkiewicz DEFINE_STUB(raid_bdev_alloc_superblock, int, (struct raid_bdev *raid_bdev, uint32_t block_size), 0);
189c25b80e2SArtur Paszkiewicz DEFINE_STUB_V(raid_bdev_free_superblock, (struct raid_bdev *raid_bdev));
190698da718SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_readv_blocks_ext, int, (struct spdk_bdev_desc *desc,
191698da718SArtur Paszkiewicz 		struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, uint64_t offset_blocks,
192698da718SArtur Paszkiewicz 		uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
193698da718SArtur Paszkiewicz 		struct spdk_bdev_ext_io_opts *opts), 0);
194698da718SArtur Paszkiewicz DEFINE_STUB(spdk_bdev_writev_blocks_ext, int, (struct spdk_bdev_desc *desc,
195698da718SArtur Paszkiewicz 		struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, uint64_t offset_blocks,
196698da718SArtur Paszkiewicz 		uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
197698da718SArtur Paszkiewicz 		struct spdk_bdev_ext_io_opts *opts), 0);
198192db8deSSlawomir Ptak 
199bb374988SArtur Paszkiewicz uint32_t
200bb374988SArtur Paszkiewicz spdk_bdev_get_data_block_size(const struct spdk_bdev *bdev)
201bb374988SArtur Paszkiewicz {
202bb374988SArtur Paszkiewicz 	return g_block_len;
203bb374988SArtur Paszkiewicz }
204bb374988SArtur Paszkiewicz 
2058a6bb6a8SArtur Paszkiewicz int
2068a6bb6a8SArtur Paszkiewicz raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2078a6bb6a8SArtur Paszkiewicz 				    raid_bdev_load_sb_cb cb, void *cb_ctx)
2088a6bb6a8SArtur Paszkiewicz {
2098a6bb6a8SArtur Paszkiewicz 	cb(NULL, -EINVAL, cb_ctx);
2108a6bb6a8SArtur Paszkiewicz 
2118a6bb6a8SArtur Paszkiewicz 	return 0;
2128a6bb6a8SArtur Paszkiewicz }
2138a6bb6a8SArtur Paszkiewicz 
21477b8f7b6SArtur Paszkiewicz void
21577b8f7b6SArtur Paszkiewicz raid_bdev_write_superblock(struct raid_bdev *raid_bdev, raid_bdev_write_sb_cb cb, void *cb_ctx)
21677b8f7b6SArtur Paszkiewicz {
21777b8f7b6SArtur Paszkiewicz 	cb(0, raid_bdev, cb_ctx);
21877b8f7b6SArtur Paszkiewicz }
21977b8f7b6SArtur Paszkiewicz 
22077b8f7b6SArtur Paszkiewicz const struct spdk_uuid *
22177b8f7b6SArtur Paszkiewicz spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
22277b8f7b6SArtur Paszkiewicz {
22377b8f7b6SArtur Paszkiewicz 	return &bdev->uuid;
22477b8f7b6SArtur Paszkiewicz }
22511495b5cSArtur Paszkiewicz 
226c65d64a6SGangCao struct spdk_io_channel *
227c65d64a6SGangCao spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
228c65d64a6SGangCao {
22950d58ff3SArtur Paszkiewicz 	return spdk_get_io_channel(&g_bdev_ch_io_device);
230c65d64a6SGangCao }
231c65d64a6SGangCao 
232192db8deSSlawomir Ptak static int
23311495b5cSArtur Paszkiewicz set_test_opts(void)
23411495b5cSArtur Paszkiewicz {
23511495b5cSArtur Paszkiewicz 	g_max_base_drives = MAX_BASE_DRIVES;
23611495b5cSArtur Paszkiewicz 	g_max_raids = MAX_RAIDS;
23711495b5cSArtur Paszkiewicz 	g_block_len = 4096;
23811495b5cSArtur Paszkiewicz 	g_strip_size = 64;
23911495b5cSArtur Paszkiewicz 	g_max_io_size = 1024;
24011495b5cSArtur Paszkiewicz 
24111495b5cSArtur Paszkiewicz 	printf("Test Options\n");
24211495b5cSArtur Paszkiewicz 	printf("blocklen = %u, strip_size = %u, max_io_size = %u, g_max_base_drives = %u, "
243698da718SArtur Paszkiewicz 	       "g_max_raids = %u\n",
244698da718SArtur Paszkiewicz 	       g_block_len, g_strip_size, g_max_io_size, g_max_base_drives, g_max_raids);
245192db8deSSlawomir Ptak 
246192db8deSSlawomir Ptak 	return 0;
24711495b5cSArtur Paszkiewicz }
24811495b5cSArtur Paszkiewicz 
24911495b5cSArtur Paszkiewicz /* Set globals before every test run */
25011495b5cSArtur Paszkiewicz static void
25111495b5cSArtur Paszkiewicz set_globals(void)
25211495b5cSArtur Paszkiewicz {
25311495b5cSArtur Paszkiewicz 	uint32_t max_splits;
25411495b5cSArtur Paszkiewicz 
25511495b5cSArtur Paszkiewicz 	if (g_max_io_size < g_strip_size) {
25611495b5cSArtur Paszkiewicz 		max_splits = 2;
25711495b5cSArtur Paszkiewicz 	} else {
25811495b5cSArtur Paszkiewicz 		max_splits = (g_max_io_size / g_strip_size) + 1;
25911495b5cSArtur Paszkiewicz 	}
26011495b5cSArtur Paszkiewicz 	if (max_splits < g_max_base_drives) {
26111495b5cSArtur Paszkiewicz 		max_splits = g_max_base_drives;
26211495b5cSArtur Paszkiewicz 	}
26311495b5cSArtur Paszkiewicz 
26411495b5cSArtur Paszkiewicz 	g_io_output = calloc(max_splits, sizeof(struct io_output));
26511495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(g_io_output != NULL);
26611495b5cSArtur Paszkiewicz 	g_io_output_index = 0;
26711495b5cSArtur Paszkiewicz 	memset(g_get_raids_output, 0, sizeof(g_get_raids_output));
26811495b5cSArtur Paszkiewicz 	g_get_raids_count = 0;
26911495b5cSArtur Paszkiewicz 	g_io_comp_status = 0;
27011495b5cSArtur Paszkiewicz 	g_rpc_err = 0;
27111495b5cSArtur Paszkiewicz 	g_test_multi_raids = 0;
27211495b5cSArtur Paszkiewicz 	g_child_io_status_flag = true;
27311495b5cSArtur Paszkiewicz 	TAILQ_INIT(&g_bdev_list);
27411495b5cSArtur Paszkiewicz 	g_rpc_req = NULL;
27511495b5cSArtur Paszkiewicz 	g_rpc_req_size = 0;
27611495b5cSArtur Paszkiewicz 	g_json_decode_obj_err = 0;
27711495b5cSArtur Paszkiewicz 	g_json_decode_obj_create = 0;
278aae5e04fSArtur Paszkiewicz 	g_bdev_io_defer_completion = false;
27911495b5cSArtur Paszkiewicz }
28011495b5cSArtur Paszkiewicz 
28111495b5cSArtur Paszkiewicz static void
28211495b5cSArtur Paszkiewicz base_bdevs_cleanup(void)
28311495b5cSArtur Paszkiewicz {
28411495b5cSArtur Paszkiewicz 	struct spdk_bdev *bdev;
28511495b5cSArtur Paszkiewicz 	struct spdk_bdev *bdev_next;
28611495b5cSArtur Paszkiewicz 
28711495b5cSArtur Paszkiewicz 	if (!TAILQ_EMPTY(&g_bdev_list)) {
28811495b5cSArtur Paszkiewicz 		TAILQ_FOREACH_SAFE(bdev, &g_bdev_list, internal.link, bdev_next) {
28911495b5cSArtur Paszkiewicz 			free(bdev->name);
29011495b5cSArtur Paszkiewicz 			TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
29111495b5cSArtur Paszkiewicz 			free(bdev);
29211495b5cSArtur Paszkiewicz 		}
29311495b5cSArtur Paszkiewicz 	}
29411495b5cSArtur Paszkiewicz }
29511495b5cSArtur Paszkiewicz 
29611495b5cSArtur Paszkiewicz static void
297dccdd1e5SArtur Paszkiewicz check_and_remove_raid_bdev(struct raid_bdev *raid_bdev)
29811495b5cSArtur Paszkiewicz {
29911495b5cSArtur Paszkiewicz 	struct raid_base_bdev_info *base_info;
30011495b5cSArtur Paszkiewicz 
301dccdd1e5SArtur Paszkiewicz 	assert(raid_bdev != NULL);
30211495b5cSArtur Paszkiewicz 	assert(raid_bdev->base_bdev_info != NULL);
30311495b5cSArtur Paszkiewicz 
30411495b5cSArtur Paszkiewicz 	RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
3058d1993a5SArtur Paszkiewicz 		if (base_info->desc) {
30626861b70SArtur Paszkiewicz 			raid_bdev_free_base_bdev_resource(base_info);
30711495b5cSArtur Paszkiewicz 		}
30811495b5cSArtur Paszkiewicz 	}
30911495b5cSArtur Paszkiewicz 	assert(raid_bdev->num_base_bdevs_discovered == 0);
31095a04949SArtur Paszkiewicz 	raid_bdev_cleanup_and_free(raid_bdev);
31111495b5cSArtur Paszkiewicz }
31211495b5cSArtur Paszkiewicz 
31311495b5cSArtur Paszkiewicz /* Reset globals */
31411495b5cSArtur Paszkiewicz static void
31511495b5cSArtur Paszkiewicz reset_globals(void)
31611495b5cSArtur Paszkiewicz {
31711495b5cSArtur Paszkiewicz 	if (g_io_output) {
31811495b5cSArtur Paszkiewicz 		free(g_io_output);
31911495b5cSArtur Paszkiewicz 		g_io_output = NULL;
32011495b5cSArtur Paszkiewicz 	}
32111495b5cSArtur Paszkiewicz 	g_rpc_req = NULL;
32211495b5cSArtur Paszkiewicz 	g_rpc_req_size = 0;
32311495b5cSArtur Paszkiewicz }
32411495b5cSArtur Paszkiewicz 
32511495b5cSArtur Paszkiewicz void
32611495b5cSArtur Paszkiewicz spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb,
32711495b5cSArtur Paszkiewicz 		     uint64_t len)
32811495b5cSArtur Paszkiewicz {
32911495b5cSArtur Paszkiewicz 	cb(bdev_io->internal.ch->channel, bdev_io, true);
33011495b5cSArtur Paszkiewicz }
33111495b5cSArtur Paszkiewicz 
33211495b5cSArtur Paszkiewicz /* Store the IO completion status in global variable to verify by various tests */
33311495b5cSArtur Paszkiewicz void
33411495b5cSArtur Paszkiewicz spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
33511495b5cSArtur Paszkiewicz {
33611495b5cSArtur Paszkiewicz 	g_io_comp_status = ((status == SPDK_BDEV_IO_STATUS_SUCCESS) ? true : false);
337aae5e04fSArtur Paszkiewicz }
338aae5e04fSArtur Paszkiewicz 
339aae5e04fSArtur Paszkiewicz static void
340aae5e04fSArtur Paszkiewicz complete_deferred_ios(void)
341aae5e04fSArtur Paszkiewicz {
342aae5e04fSArtur Paszkiewicz 	struct spdk_bdev_io *child_io, *tmp;
343aae5e04fSArtur Paszkiewicz 
344aae5e04fSArtur Paszkiewicz 	TAILQ_FOREACH_SAFE(child_io, &g_deferred_ios, internal.link, tmp) {
345aae5e04fSArtur Paszkiewicz 		TAILQ_REMOVE(&g_deferred_ios, child_io, internal.link);
346aae5e04fSArtur Paszkiewicz 		child_io->internal.cb(child_io, g_child_io_status_flag, child_io->internal.caller_ctx);
347aae5e04fSArtur Paszkiewicz 	}
348aae5e04fSArtur Paszkiewicz }
349aae5e04fSArtur Paszkiewicz 
350192db8deSSlawomir Ptak int
35111495b5cSArtur Paszkiewicz spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
35211495b5cSArtur Paszkiewicz 		spdk_bdev_io_completion_cb cb, void *cb_arg)
35311495b5cSArtur Paszkiewicz {
35411495b5cSArtur Paszkiewicz 	struct io_output *output = &g_io_output[g_io_output_index];
35511495b5cSArtur Paszkiewicz 	struct spdk_bdev_io *child_io;
35611495b5cSArtur Paszkiewicz 
357698da718SArtur Paszkiewicz 	output->desc = desc;
358698da718SArtur Paszkiewicz 	output->ch = ch;
359698da718SArtur Paszkiewicz 	output->iotype = SPDK_BDEV_IO_TYPE_RESET;
360698da718SArtur Paszkiewicz 
36111495b5cSArtur Paszkiewicz 	g_io_output_index++;
36211495b5cSArtur Paszkiewicz 
36311495b5cSArtur Paszkiewicz 	child_io = calloc(1, sizeof(struct spdk_bdev_io));
36411495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(child_io != NULL);
365698da718SArtur Paszkiewicz 	cb(child_io, g_child_io_status_flag, cb_arg);
36611495b5cSArtur Paszkiewicz 
367698da718SArtur Paszkiewicz 	return 0;
36811495b5cSArtur Paszkiewicz }
36911495b5cSArtur Paszkiewicz 
37011495b5cSArtur Paszkiewicz void
37195a04949SArtur Paszkiewicz spdk_bdev_destruct_done(struct spdk_bdev *bdev, int bdeverrno)
37295a04949SArtur Paszkiewicz {
37395a04949SArtur Paszkiewicz 	CU_ASSERT(bdeverrno == 0);
37495a04949SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(bdev->internal.unregister_cb != NULL);
37595a04949SArtur Paszkiewicz 	bdev->internal.unregister_cb(bdev->internal.unregister_ctx, bdeverrno);
37695a04949SArtur Paszkiewicz }
37795a04949SArtur Paszkiewicz 
3789d2b7b41SArtur Paszkiewicz int
3799d2b7b41SArtur Paszkiewicz spdk_bdev_register(struct spdk_bdev *bdev)
3809d2b7b41SArtur Paszkiewicz {
3819d2b7b41SArtur Paszkiewicz 	TAILQ_INSERT_TAIL(&g_bdev_list, bdev, internal.link);
3829d2b7b41SArtur Paszkiewicz 	return 0;
3839d2b7b41SArtur Paszkiewicz }
3849d2b7b41SArtur Paszkiewicz 
385fff473bbSArtur Paszkiewicz static void
386fff473bbSArtur Paszkiewicz poll_app_thread(void)
387fff473bbSArtur Paszkiewicz {
388fff473bbSArtur Paszkiewicz 	while (spdk_thread_poll(g_app_thread, 0, 0) > 0) {
389fff473bbSArtur Paszkiewicz 	}
390fff473bbSArtur Paszkiewicz }
391fff473bbSArtur Paszkiewicz 
39295a04949SArtur Paszkiewicz void
39311495b5cSArtur Paszkiewicz spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
39411495b5cSArtur Paszkiewicz {
39595a04949SArtur Paszkiewicz 	int ret;
39611495b5cSArtur Paszkiewicz 
3979d2b7b41SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(spdk_bdev_get_by_name(bdev->name) == bdev);
3989d2b7b41SArtur Paszkiewicz 	TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
3999d2b7b41SArtur Paszkiewicz 
40095a04949SArtur Paszkiewicz 	bdev->internal.unregister_cb = cb_fn;
40195a04949SArtur Paszkiewicz 	bdev->internal.unregister_ctx = cb_arg;
40295a04949SArtur Paszkiewicz 
40395a04949SArtur Paszkiewicz 	ret = bdev->fn_table->destruct(bdev->ctxt);
40495a04949SArtur Paszkiewicz 	CU_ASSERT(ret == 1);
40595a04949SArtur Paszkiewicz 
406fff473bbSArtur Paszkiewicz 	poll_app_thread();
40711495b5cSArtur Paszkiewicz }
40811495b5cSArtur Paszkiewicz 
40911495b5cSArtur Paszkiewicz int
410d8a18924SShuhei Matsumoto spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb,
411d8a18924SShuhei Matsumoto 		   void *event_ctx, struct spdk_bdev_desc **_desc)
41211495b5cSArtur Paszkiewicz {
413d8a18924SShuhei Matsumoto 	struct spdk_bdev *bdev;
414d8a18924SShuhei Matsumoto 
415d8a18924SShuhei Matsumoto 	bdev = spdk_bdev_get_by_name(bdev_name);
416d8a18924SShuhei Matsumoto 	if (bdev == NULL) {
417d8a18924SShuhei Matsumoto 		return -ENODEV;
418d8a18924SShuhei Matsumoto 	}
419d8a18924SShuhei Matsumoto 
420d8a18924SShuhei Matsumoto 	*_desc = (void *)bdev;
42111495b5cSArtur Paszkiewicz 	return 0;
42211495b5cSArtur Paszkiewicz }
42311495b5cSArtur Paszkiewicz 
424d8a18924SShuhei Matsumoto struct spdk_bdev *
425d8a18924SShuhei Matsumoto spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
426d8a18924SShuhei Matsumoto {
427d8a18924SShuhei Matsumoto 	return (void *)desc;
428d8a18924SShuhei Matsumoto }
429d8a18924SShuhei Matsumoto 
4308dd1cd21SBen Walker int
4318dd1cd21SBen Walker spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
43211495b5cSArtur Paszkiewicz {
433ec6d94b6SArtur Paszkiewicz 	if (!g_test_multi_raids) {
43411495b5cSArtur Paszkiewicz 		struct rpc_bdev_raid_create *req = g_rpc_req;
43511495b5cSArtur Paszkiewicz 		if (strcmp(name, "strip_size_kb") == 0) {
43611495b5cSArtur Paszkiewicz 			CU_ASSERT(req->strip_size_kb == val);
43711495b5cSArtur Paszkiewicz 		} else if (strcmp(name, "blocklen_shift") == 0) {
43811495b5cSArtur Paszkiewicz 			CU_ASSERT(spdk_u32log2(g_block_len) == val);
43911495b5cSArtur Paszkiewicz 		} else if (strcmp(name, "num_base_bdevs") == 0) {
44011495b5cSArtur Paszkiewicz 			CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
44111495b5cSArtur Paszkiewicz 		} else if (strcmp(name, "state") == 0) {
44211495b5cSArtur Paszkiewicz 			CU_ASSERT(val == RAID_BDEV_STATE_ONLINE);
44311495b5cSArtur Paszkiewicz 		} else if (strcmp(name, "destruct_called") == 0) {
44411495b5cSArtur Paszkiewicz 			CU_ASSERT(val == 0);
44511495b5cSArtur Paszkiewicz 		} else if (strcmp(name, "num_base_bdevs_discovered") == 0) {
44611495b5cSArtur Paszkiewicz 			CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
44711495b5cSArtur Paszkiewicz 		}
448ec6d94b6SArtur Paszkiewicz 	}
44911495b5cSArtur Paszkiewicz 	return 0;
45011495b5cSArtur Paszkiewicz }
45111495b5cSArtur Paszkiewicz 
4528dd1cd21SBen Walker int
4538dd1cd21SBen Walker spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
45411495b5cSArtur Paszkiewicz {
455ec6d94b6SArtur Paszkiewicz 	if (g_test_multi_raids) {
456ec6d94b6SArtur Paszkiewicz 		if (strcmp(name, "name") == 0) {
457ec6d94b6SArtur Paszkiewicz 			g_get_raids_output[g_get_raids_count] = strdup(val);
458ec6d94b6SArtur Paszkiewicz 			SPDK_CU_ASSERT_FATAL(g_get_raids_output[g_get_raids_count] != NULL);
459ec6d94b6SArtur Paszkiewicz 			g_get_raids_count++;
460ec6d94b6SArtur Paszkiewicz 		}
461ec6d94b6SArtur Paszkiewicz 	} else {
46211495b5cSArtur Paszkiewicz 		struct rpc_bdev_raid_create *req = g_rpc_req;
46311495b5cSArtur Paszkiewicz 		if (strcmp(name, "raid_level") == 0) {
46411495b5cSArtur Paszkiewicz 			CU_ASSERT(strcmp(val, raid_bdev_level_to_str(req->level)) == 0);
46511495b5cSArtur Paszkiewicz 		}
466ec6d94b6SArtur Paszkiewicz 	}
46711495b5cSArtur Paszkiewicz 	return 0;
46811495b5cSArtur Paszkiewicz }
46911495b5cSArtur Paszkiewicz 
470deed7d2fSArtur Paszkiewicz int
471deed7d2fSArtur Paszkiewicz spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
472deed7d2fSArtur Paszkiewicz {
473deed7d2fSArtur Paszkiewicz 	if (!g_test_multi_raids) {
474deed7d2fSArtur Paszkiewicz 		struct rpc_bdev_raid_create *req = g_rpc_req;
475deed7d2fSArtur Paszkiewicz 		if (strcmp(name, "superblock") == 0) {
476deed7d2fSArtur Paszkiewicz 			CU_ASSERT(val == req->superblock_enabled);
477deed7d2fSArtur Paszkiewicz 		}
478deed7d2fSArtur Paszkiewicz 	}
479deed7d2fSArtur Paszkiewicz 	return 0;
480deed7d2fSArtur Paszkiewicz }
481deed7d2fSArtur Paszkiewicz 
48211495b5cSArtur Paszkiewicz void
48311495b5cSArtur Paszkiewicz spdk_bdev_free_io(struct spdk_bdev_io *bdev_io)
48411495b5cSArtur Paszkiewicz {
48511495b5cSArtur Paszkiewicz 	if (bdev_io) {
48611495b5cSArtur Paszkiewicz 		free(bdev_io);
48711495b5cSArtur Paszkiewicz 	}
48811495b5cSArtur Paszkiewicz }
48911495b5cSArtur Paszkiewicz 
49011495b5cSArtur Paszkiewicz void
49111495b5cSArtur Paszkiewicz spdk_bdev_module_release_bdev(struct spdk_bdev *bdev)
49211495b5cSArtur Paszkiewicz {
4934bb902a6SMike Gerdts 	CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE);
4949fd2f931SMike Gerdts 	CU_ASSERT(bdev->internal.claim.v1.module != NULL);
4954bb902a6SMike Gerdts 	bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE;
4969fd2f931SMike Gerdts 	bdev->internal.claim.v1.module = NULL;
49711495b5cSArtur Paszkiewicz }
49811495b5cSArtur Paszkiewicz 
49911495b5cSArtur Paszkiewicz int
50011495b5cSArtur Paszkiewicz spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
50111495b5cSArtur Paszkiewicz 			    struct spdk_bdev_module *module)
50211495b5cSArtur Paszkiewicz {
5034bb902a6SMike Gerdts 	if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) {
5044bb902a6SMike Gerdts 		CU_ASSERT(bdev->internal.claim.v1.module != NULL);
50511495b5cSArtur Paszkiewicz 		return -1;
50611495b5cSArtur Paszkiewicz 	}
5074bb902a6SMike Gerdts 	CU_ASSERT(bdev->internal.claim.v1.module == NULL);
5084bb902a6SMike Gerdts 	bdev->internal.claim_type = SPDK_BDEV_CLAIM_EXCL_WRITE;
5099fd2f931SMike Gerdts 	bdev->internal.claim.v1.module = module;
51011495b5cSArtur Paszkiewicz 	return 0;
51111495b5cSArtur Paszkiewicz }
51211495b5cSArtur Paszkiewicz 
51311495b5cSArtur Paszkiewicz int
51411495b5cSArtur Paszkiewicz spdk_json_decode_object(const struct spdk_json_val *values,
51511495b5cSArtur Paszkiewicz 			const struct spdk_json_object_decoder *decoders, size_t num_decoders,
51611495b5cSArtur Paszkiewicz 			void *out)
51711495b5cSArtur Paszkiewicz {
51811495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create *req, *_out;
51911495b5cSArtur Paszkiewicz 	size_t i;
52011495b5cSArtur Paszkiewicz 
52111495b5cSArtur Paszkiewicz 	if (g_json_decode_obj_err) {
52211495b5cSArtur Paszkiewicz 		return -1;
52311495b5cSArtur Paszkiewicz 	} else if (g_json_decode_obj_create) {
52411495b5cSArtur Paszkiewicz 		req = g_rpc_req;
52511495b5cSArtur Paszkiewicz 		_out = out;
52611495b5cSArtur Paszkiewicz 
52711495b5cSArtur Paszkiewicz 		_out->name = strdup(req->name);
52811495b5cSArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(_out->name != NULL);
52911495b5cSArtur Paszkiewicz 		_out->strip_size_kb = req->strip_size_kb;
53011495b5cSArtur Paszkiewicz 		_out->level = req->level;
531deed7d2fSArtur Paszkiewicz 		_out->superblock_enabled = req->superblock_enabled;
53211495b5cSArtur Paszkiewicz 		_out->base_bdevs.num_base_bdevs = req->base_bdevs.num_base_bdevs;
53311495b5cSArtur Paszkiewicz 		for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) {
53411495b5cSArtur Paszkiewicz 			_out->base_bdevs.base_bdevs[i] = strdup(req->base_bdevs.base_bdevs[i]);
53511495b5cSArtur Paszkiewicz 			SPDK_CU_ASSERT_FATAL(_out->base_bdevs.base_bdevs[i]);
53611495b5cSArtur Paszkiewicz 		}
53711495b5cSArtur Paszkiewicz 	} else {
53811495b5cSArtur Paszkiewicz 		memcpy(out, g_rpc_req, g_rpc_req_size);
53911495b5cSArtur Paszkiewicz 	}
54011495b5cSArtur Paszkiewicz 
54111495b5cSArtur Paszkiewicz 	return 0;
54211495b5cSArtur Paszkiewicz }
54311495b5cSArtur Paszkiewicz 
54411495b5cSArtur Paszkiewicz struct spdk_json_write_ctx *
54511495b5cSArtur Paszkiewicz spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
54611495b5cSArtur Paszkiewicz {
54711495b5cSArtur Paszkiewicz 	return (void *)1;
54811495b5cSArtur Paszkiewicz }
54911495b5cSArtur Paszkiewicz 
55011495b5cSArtur Paszkiewicz void
55111495b5cSArtur Paszkiewicz spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
55211495b5cSArtur Paszkiewicz 				 int error_code, const char *msg)
55311495b5cSArtur Paszkiewicz {
55411495b5cSArtur Paszkiewicz 	g_rpc_err = 1;
55511495b5cSArtur Paszkiewicz }
55611495b5cSArtur Paszkiewicz 
55711495b5cSArtur Paszkiewicz void
55811495b5cSArtur Paszkiewicz spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
55911495b5cSArtur Paszkiewicz 				     int error_code, const char *fmt, ...)
56011495b5cSArtur Paszkiewicz {
56111495b5cSArtur Paszkiewicz 	g_rpc_err = 1;
56211495b5cSArtur Paszkiewicz }
56311495b5cSArtur Paszkiewicz 
56411495b5cSArtur Paszkiewicz struct spdk_bdev *
56511495b5cSArtur Paszkiewicz spdk_bdev_get_by_name(const char *bdev_name)
56611495b5cSArtur Paszkiewicz {
56711495b5cSArtur Paszkiewicz 	struct spdk_bdev *bdev;
56811495b5cSArtur Paszkiewicz 
56911495b5cSArtur Paszkiewicz 	if (!TAILQ_EMPTY(&g_bdev_list)) {
57011495b5cSArtur Paszkiewicz 		TAILQ_FOREACH(bdev, &g_bdev_list, internal.link) {
57111495b5cSArtur Paszkiewicz 			if (strcmp(bdev_name, bdev->name) == 0) {
57211495b5cSArtur Paszkiewicz 				return bdev;
57311495b5cSArtur Paszkiewicz 			}
57411495b5cSArtur Paszkiewicz 		}
57511495b5cSArtur Paszkiewicz 	}
57611495b5cSArtur Paszkiewicz 
57711495b5cSArtur Paszkiewicz 	return NULL;
57811495b5cSArtur Paszkiewicz }
57911495b5cSArtur Paszkiewicz 
580b42cb0e5SArtur Paszkiewicz int
581b42cb0e5SArtur Paszkiewicz spdk_bdev_quiesce(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
582b42cb0e5SArtur Paszkiewicz 		  spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
583b42cb0e5SArtur Paszkiewicz {
584b42cb0e5SArtur Paszkiewicz 	if (cb_fn) {
585b42cb0e5SArtur Paszkiewicz 		cb_fn(cb_arg, 0);
586b42cb0e5SArtur Paszkiewicz 	}
587b42cb0e5SArtur Paszkiewicz 
588b42cb0e5SArtur Paszkiewicz 	return 0;
589b42cb0e5SArtur Paszkiewicz }
590b42cb0e5SArtur Paszkiewicz 
591b42cb0e5SArtur Paszkiewicz int
592b42cb0e5SArtur Paszkiewicz spdk_bdev_unquiesce(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
593b42cb0e5SArtur Paszkiewicz 		    spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
594b42cb0e5SArtur Paszkiewicz {
595b42cb0e5SArtur Paszkiewicz 	if (cb_fn) {
596b42cb0e5SArtur Paszkiewicz 		cb_fn(cb_arg, 0);
597b42cb0e5SArtur Paszkiewicz 	}
598b42cb0e5SArtur Paszkiewicz 
599b42cb0e5SArtur Paszkiewicz 	return 0;
600b42cb0e5SArtur Paszkiewicz }
601b42cb0e5SArtur Paszkiewicz 
60250d58ff3SArtur Paszkiewicz int
60350d58ff3SArtur Paszkiewicz spdk_bdev_quiesce_range(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
60450d58ff3SArtur Paszkiewicz 			uint64_t offset, uint64_t length,
60550d58ff3SArtur Paszkiewicz 			spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
60650d58ff3SArtur Paszkiewicz {
60750d58ff3SArtur Paszkiewicz 	if (cb_fn) {
60850d58ff3SArtur Paszkiewicz 		cb_fn(cb_arg, 0);
60950d58ff3SArtur Paszkiewicz 	}
61050d58ff3SArtur Paszkiewicz 
61150d58ff3SArtur Paszkiewicz 	return 0;
61250d58ff3SArtur Paszkiewicz }
61350d58ff3SArtur Paszkiewicz 
61450d58ff3SArtur Paszkiewicz int
61550d58ff3SArtur Paszkiewicz spdk_bdev_unquiesce_range(struct spdk_bdev *bdev, struct spdk_bdev_module *module,
61650d58ff3SArtur Paszkiewicz 			  uint64_t offset, uint64_t length,
61750d58ff3SArtur Paszkiewicz 			  spdk_bdev_quiesce_cb cb_fn, void *cb_arg)
61850d58ff3SArtur Paszkiewicz {
61950d58ff3SArtur Paszkiewicz 	if (cb_fn) {
62050d58ff3SArtur Paszkiewicz 		cb_fn(cb_arg, 0);
62150d58ff3SArtur Paszkiewicz 	}
62250d58ff3SArtur Paszkiewicz 
62350d58ff3SArtur Paszkiewicz 	return 0;
62450d58ff3SArtur Paszkiewicz }
62550d58ff3SArtur Paszkiewicz 
62611495b5cSArtur Paszkiewicz static void
62711495b5cSArtur Paszkiewicz bdev_io_cleanup(struct spdk_bdev_io *bdev_io)
62811495b5cSArtur Paszkiewicz {
62911495b5cSArtur Paszkiewicz 	if (bdev_io->u.bdev.iovs) {
630aae5e04fSArtur Paszkiewicz 		int i;
631aae5e04fSArtur Paszkiewicz 
632aae5e04fSArtur Paszkiewicz 		for (i = 0; i < bdev_io->u.bdev.iovcnt; i++) {
633aae5e04fSArtur Paszkiewicz 			free(bdev_io->u.bdev.iovs[i].iov_base);
63411495b5cSArtur Paszkiewicz 		}
63511495b5cSArtur Paszkiewicz 		free(bdev_io->u.bdev.iovs);
63611495b5cSArtur Paszkiewicz 	}
637192db8deSSlawomir Ptak 
63811495b5cSArtur Paszkiewicz 	free(bdev_io);
63911495b5cSArtur Paszkiewicz }
64011495b5cSArtur Paszkiewicz 
64111495b5cSArtur Paszkiewicz static void
642aae5e04fSArtur Paszkiewicz _bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch,
643aae5e04fSArtur Paszkiewicz 		    struct spdk_bdev *bdev, uint64_t lba, uint64_t blocks, int16_t iotype,
644aae5e04fSArtur Paszkiewicz 		    int iovcnt, size_t iov_len)
64511495b5cSArtur Paszkiewicz {
64611495b5cSArtur Paszkiewicz 	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
647aae5e04fSArtur Paszkiewicz 	int i;
64811495b5cSArtur Paszkiewicz 
64911495b5cSArtur Paszkiewicz 	bdev_io->bdev = bdev;
65011495b5cSArtur Paszkiewicz 	bdev_io->u.bdev.offset_blocks = lba;
65111495b5cSArtur Paszkiewicz 	bdev_io->u.bdev.num_blocks = blocks;
65211495b5cSArtur Paszkiewicz 	bdev_io->type = iotype;
653aae5e04fSArtur Paszkiewicz 	bdev_io->internal.ch = channel;
654aae5e04fSArtur Paszkiewicz 	bdev_io->u.bdev.iovcnt = iovcnt;
65511495b5cSArtur Paszkiewicz 
656aae5e04fSArtur Paszkiewicz 	if (iovcnt == 0) {
657aae5e04fSArtur Paszkiewicz 		bdev_io->u.bdev.iovs = NULL;
65811495b5cSArtur Paszkiewicz 		return;
65911495b5cSArtur Paszkiewicz 	}
66011495b5cSArtur Paszkiewicz 
661aae5e04fSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(iov_len * iovcnt == blocks * g_block_len);
662aae5e04fSArtur Paszkiewicz 
663aae5e04fSArtur Paszkiewicz 	bdev_io->u.bdev.iovs = calloc(iovcnt, sizeof(struct iovec));
66411495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs != NULL);
665aae5e04fSArtur Paszkiewicz 
666aae5e04fSArtur Paszkiewicz 	for (i = 0; i < iovcnt; i++) {
667aae5e04fSArtur Paszkiewicz 		struct iovec *iov = &bdev_io->u.bdev.iovs[i];
668aae5e04fSArtur Paszkiewicz 
669aae5e04fSArtur Paszkiewicz 		iov->iov_base = calloc(1, iov_len);
670aae5e04fSArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(iov->iov_base != NULL);
671aae5e04fSArtur Paszkiewicz 		iov->iov_len = iov_len;
672aae5e04fSArtur Paszkiewicz 	}
673192db8deSSlawomir Ptak 
674698da718SArtur Paszkiewicz 	bdev_io->u.bdev.md_buf = (void *)0x10000000;
675aae5e04fSArtur Paszkiewicz }
676aae5e04fSArtur Paszkiewicz 
677aae5e04fSArtur Paszkiewicz static void
678aae5e04fSArtur Paszkiewicz bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch, struct spdk_bdev *bdev,
679aae5e04fSArtur Paszkiewicz 		   uint64_t lba, uint64_t blocks, int16_t iotype)
680aae5e04fSArtur Paszkiewicz {
681698da718SArtur Paszkiewicz 	_bdev_io_initialize(bdev_io, ch, bdev, lba, blocks, iotype, 0, 0);
68211495b5cSArtur Paszkiewicz }
68311495b5cSArtur Paszkiewicz 
68411495b5cSArtur Paszkiewicz static void
68511495b5cSArtur Paszkiewicz verify_reset_io(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
68611495b5cSArtur Paszkiewicz 		struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
68711495b5cSArtur Paszkiewicz {
68811495b5cSArtur Paszkiewicz 	uint8_t index = 0;
68911495b5cSArtur Paszkiewicz 	struct io_output *output;
69011495b5cSArtur Paszkiewicz 
69111495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
69211495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
69311495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(ch_ctx->base_channel != NULL);
69411495b5cSArtur Paszkiewicz 
69511495b5cSArtur Paszkiewicz 	CU_ASSERT(g_io_output_index == num_base_drives);
69611495b5cSArtur Paszkiewicz 	for (index = 0; index < g_io_output_index; index++) {
69711495b5cSArtur Paszkiewicz 		output = &g_io_output[index];
69811495b5cSArtur Paszkiewicz 		CU_ASSERT(ch_ctx->base_channel[index] == output->ch);
69911495b5cSArtur Paszkiewicz 		CU_ASSERT(raid_bdev->base_bdev_info[index].desc == output->desc);
70011495b5cSArtur Paszkiewicz 		CU_ASSERT(bdev_io->type == output->iotype);
70111495b5cSArtur Paszkiewicz 	}
70211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_io_comp_status == io_status);
70311495b5cSArtur Paszkiewicz }
70411495b5cSArtur Paszkiewicz 
70511495b5cSArtur Paszkiewicz static void
70611495b5cSArtur Paszkiewicz verify_raid_bdev_present(const char *name, bool presence)
70711495b5cSArtur Paszkiewicz {
70811495b5cSArtur Paszkiewicz 	struct raid_bdev *pbdev;
70911495b5cSArtur Paszkiewicz 	bool   pbdev_found;
71011495b5cSArtur Paszkiewicz 
71111495b5cSArtur Paszkiewicz 	pbdev_found = false;
71211495b5cSArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
71311495b5cSArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, name) == 0) {
71411495b5cSArtur Paszkiewicz 			pbdev_found = true;
71511495b5cSArtur Paszkiewicz 			break;
71611495b5cSArtur Paszkiewicz 		}
71711495b5cSArtur Paszkiewicz 	}
71811495b5cSArtur Paszkiewicz 	if (presence == true) {
71911495b5cSArtur Paszkiewicz 		CU_ASSERT(pbdev_found == true);
72011495b5cSArtur Paszkiewicz 	} else {
72111495b5cSArtur Paszkiewicz 		CU_ASSERT(pbdev_found == false);
72211495b5cSArtur Paszkiewicz 	}
72311495b5cSArtur Paszkiewicz }
72411495b5cSArtur Paszkiewicz 
72511495b5cSArtur Paszkiewicz static void
72611495b5cSArtur Paszkiewicz verify_raid_bdev(struct rpc_bdev_raid_create *r, bool presence, uint32_t raid_state)
72711495b5cSArtur Paszkiewicz {
72811495b5cSArtur Paszkiewicz 	struct raid_bdev *pbdev;
72911495b5cSArtur Paszkiewicz 	struct raid_base_bdev_info *base_info;
73011495b5cSArtur Paszkiewicz 	struct spdk_bdev *bdev = NULL;
73111495b5cSArtur Paszkiewicz 	bool   pbdev_found;
73211495b5cSArtur Paszkiewicz 	uint64_t min_blockcnt = 0xFFFFFFFFFFFFFFFF;
73311495b5cSArtur Paszkiewicz 
73411495b5cSArtur Paszkiewicz 	pbdev_found = false;
73511495b5cSArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
73611495b5cSArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, r->name) == 0) {
73711495b5cSArtur Paszkiewicz 			pbdev_found = true;
73811495b5cSArtur Paszkiewicz 			if (presence == false) {
73911495b5cSArtur Paszkiewicz 				break;
74011495b5cSArtur Paszkiewicz 			}
74111495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->base_bdev_info != NULL);
74211495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->strip_size == ((r->strip_size_kb * 1024) / g_block_len));
74311495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->strip_size_shift == spdk_u32log2(((r->strip_size_kb * 1024) /
74411495b5cSArtur Paszkiewicz 					g_block_len)));
7455c5a44f0SNick Connolly 			CU_ASSERT((uint32_t)pbdev->state == raid_state);
74611495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->num_base_bdevs == r->base_bdevs.num_base_bdevs);
74711495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->num_base_bdevs_discovered == r->base_bdevs.num_base_bdevs);
74811495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->level == r->level);
74911495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->base_bdev_info != NULL);
75011495b5cSArtur Paszkiewicz 			RAID_FOR_EACH_BASE_BDEV(pbdev, base_info) {
7518d1993a5SArtur Paszkiewicz 				CU_ASSERT(base_info->desc != NULL);
7528d1993a5SArtur Paszkiewicz 				bdev = spdk_bdev_desc_get_bdev(base_info->desc);
75311495b5cSArtur Paszkiewicz 				CU_ASSERT(bdev != NULL);
75411495b5cSArtur Paszkiewicz 				CU_ASSERT(base_info->remove_scheduled == false);
7553bb8256aSArtur Paszkiewicz 				CU_ASSERT((pbdev->superblock_enabled && base_info->data_offset != 0) ||
7563bb8256aSArtur Paszkiewicz 					  (!pbdev->superblock_enabled && base_info->data_offset == 0));
757deed7d2fSArtur Paszkiewicz 				CU_ASSERT(base_info->data_offset + base_info->data_size == bdev->blockcnt);
75811495b5cSArtur Paszkiewicz 
759deed7d2fSArtur Paszkiewicz 				if (bdev && base_info->data_size < min_blockcnt) {
760deed7d2fSArtur Paszkiewicz 					min_blockcnt = base_info->data_size;
76111495b5cSArtur Paszkiewicz 				}
76211495b5cSArtur Paszkiewicz 			}
76311495b5cSArtur Paszkiewicz 			CU_ASSERT(strcmp(pbdev->bdev.product_name, "Raid Volume") == 0);
76411495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->bdev.write_cache == 0);
76511495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->bdev.blocklen == g_block_len);
76611495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->bdev.ctxt == pbdev);
76711495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->bdev.fn_table == &g_raid_bdev_fn_table);
76811495b5cSArtur Paszkiewicz 			CU_ASSERT(pbdev->bdev.module == &g_raid_if);
76911495b5cSArtur Paszkiewicz 			break;
77011495b5cSArtur Paszkiewicz 		}
77111495b5cSArtur Paszkiewicz 	}
77211495b5cSArtur Paszkiewicz 	if (presence == true) {
77311495b5cSArtur Paszkiewicz 		CU_ASSERT(pbdev_found == true);
77411495b5cSArtur Paszkiewicz 	} else {
77511495b5cSArtur Paszkiewicz 		CU_ASSERT(pbdev_found == false);
77611495b5cSArtur Paszkiewicz 	}
77711495b5cSArtur Paszkiewicz }
77811495b5cSArtur Paszkiewicz 
77911495b5cSArtur Paszkiewicz static void
78011495b5cSArtur Paszkiewicz verify_get_raids(struct rpc_bdev_raid_create *construct_req,
78111495b5cSArtur Paszkiewicz 		 uint8_t g_max_raids,
78211495b5cSArtur Paszkiewicz 		 char **g_get_raids_output, uint32_t g_get_raids_count)
78311495b5cSArtur Paszkiewicz {
78411495b5cSArtur Paszkiewicz 	uint8_t i, j;
78511495b5cSArtur Paszkiewicz 	bool found;
78611495b5cSArtur Paszkiewicz 
78711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_max_raids == g_get_raids_count);
78811495b5cSArtur Paszkiewicz 	if (g_max_raids == g_get_raids_count) {
78911495b5cSArtur Paszkiewicz 		for (i = 0; i < g_max_raids; i++) {
79011495b5cSArtur Paszkiewicz 			found = false;
79111495b5cSArtur Paszkiewicz 			for (j = 0; j < g_max_raids; j++) {
79211495b5cSArtur Paszkiewicz 				if (construct_req[i].name &&
79311495b5cSArtur Paszkiewicz 				    strcmp(construct_req[i].name, g_get_raids_output[i]) == 0) {
79411495b5cSArtur Paszkiewicz 					found = true;
79511495b5cSArtur Paszkiewicz 					break;
79611495b5cSArtur Paszkiewicz 				}
79711495b5cSArtur Paszkiewicz 			}
79811495b5cSArtur Paszkiewicz 			CU_ASSERT(found == true);
79911495b5cSArtur Paszkiewicz 		}
80011495b5cSArtur Paszkiewicz 	}
80111495b5cSArtur Paszkiewicz }
80211495b5cSArtur Paszkiewicz 
80311495b5cSArtur Paszkiewicz static void
80411495b5cSArtur Paszkiewicz create_base_bdevs(uint32_t bbdev_start_idx)
80511495b5cSArtur Paszkiewicz {
80611495b5cSArtur Paszkiewicz 	uint8_t i;
80711495b5cSArtur Paszkiewicz 	struct spdk_bdev *base_bdev;
80811495b5cSArtur Paszkiewicz 	char name[16];
80911495b5cSArtur Paszkiewicz 
81011495b5cSArtur Paszkiewicz 	for (i = 0; i < g_max_base_drives; i++, bbdev_start_idx++) {
81111495b5cSArtur Paszkiewicz 		snprintf(name, 16, "%s%u%s", "Nvme", bbdev_start_idx, "n1");
81211495b5cSArtur Paszkiewicz 		base_bdev = calloc(1, sizeof(struct spdk_bdev));
81311495b5cSArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(base_bdev != NULL);
81411495b5cSArtur Paszkiewicz 		base_bdev->name = strdup(name);
81577b8f7b6SArtur Paszkiewicz 		spdk_uuid_generate(&base_bdev->uuid);
81611495b5cSArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(base_bdev->name != NULL);
81711495b5cSArtur Paszkiewicz 		base_bdev->blocklen = g_block_len;
81811495b5cSArtur Paszkiewicz 		base_bdev->blockcnt = BLOCK_CNT;
81911495b5cSArtur Paszkiewicz 		TAILQ_INSERT_TAIL(&g_bdev_list, base_bdev, internal.link);
82011495b5cSArtur Paszkiewicz 	}
82111495b5cSArtur Paszkiewicz }
82211495b5cSArtur Paszkiewicz 
82311495b5cSArtur Paszkiewicz static void
82411495b5cSArtur Paszkiewicz create_test_req(struct rpc_bdev_raid_create *r, const char *raid_name,
825deed7d2fSArtur Paszkiewicz 		uint8_t bbdev_start_idx, bool create_base_bdev, bool superblock_enabled)
82611495b5cSArtur Paszkiewicz {
82711495b5cSArtur Paszkiewicz 	uint8_t i;
82811495b5cSArtur Paszkiewicz 	char name[16];
82911495b5cSArtur Paszkiewicz 	uint8_t bbdev_idx = bbdev_start_idx;
83011495b5cSArtur Paszkiewicz 
83111495b5cSArtur Paszkiewicz 	r->name = strdup(raid_name);
83211495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(r->name != NULL);
83311495b5cSArtur Paszkiewicz 	r->strip_size_kb = (g_strip_size * g_block_len) / 1024;
834698da718SArtur Paszkiewicz 	r->level = 123;
835deed7d2fSArtur Paszkiewicz 	r->superblock_enabled = superblock_enabled;
83611495b5cSArtur Paszkiewicz 	r->base_bdevs.num_base_bdevs = g_max_base_drives;
83711495b5cSArtur Paszkiewicz 	for (i = 0; i < g_max_base_drives; i++, bbdev_idx++) {
83811495b5cSArtur Paszkiewicz 		snprintf(name, 16, "%s%u%s", "Nvme", bbdev_idx, "n1");
83911495b5cSArtur Paszkiewicz 		r->base_bdevs.base_bdevs[i] = strdup(name);
84011495b5cSArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(r->base_bdevs.base_bdevs[i] != NULL);
84111495b5cSArtur Paszkiewicz 	}
84211495b5cSArtur Paszkiewicz 	if (create_base_bdev == true) {
84311495b5cSArtur Paszkiewicz 		create_base_bdevs(bbdev_start_idx);
84411495b5cSArtur Paszkiewicz 	}
84511495b5cSArtur Paszkiewicz 	g_rpc_req = r;
84611495b5cSArtur Paszkiewicz 	g_rpc_req_size = sizeof(*r);
84711495b5cSArtur Paszkiewicz }
84811495b5cSArtur Paszkiewicz 
84911495b5cSArtur Paszkiewicz static void
85011495b5cSArtur Paszkiewicz create_raid_bdev_create_req(struct rpc_bdev_raid_create *r, const char *raid_name,
85111495b5cSArtur Paszkiewicz 			    uint8_t bbdev_start_idx, bool create_base_bdev,
85277b8f7b6SArtur Paszkiewicz 			    uint8_t json_decode_obj_err, bool superblock_enabled)
85311495b5cSArtur Paszkiewicz {
85477b8f7b6SArtur Paszkiewicz 	create_test_req(r, raid_name, bbdev_start_idx, create_base_bdev, superblock_enabled);
85511495b5cSArtur Paszkiewicz 
85611495b5cSArtur Paszkiewicz 	g_rpc_err = 0;
85711495b5cSArtur Paszkiewicz 	g_json_decode_obj_create = 1;
85811495b5cSArtur Paszkiewicz 	g_json_decode_obj_err = json_decode_obj_err;
85911495b5cSArtur Paszkiewicz 	g_test_multi_raids = 0;
86011495b5cSArtur Paszkiewicz }
86111495b5cSArtur Paszkiewicz 
86211495b5cSArtur Paszkiewicz static void
86311495b5cSArtur Paszkiewicz free_test_req(struct rpc_bdev_raid_create *r)
86411495b5cSArtur Paszkiewicz {
86511495b5cSArtur Paszkiewicz 	uint8_t i;
86611495b5cSArtur Paszkiewicz 
86711495b5cSArtur Paszkiewicz 	free(r->name);
86811495b5cSArtur Paszkiewicz 	for (i = 0; i < r->base_bdevs.num_base_bdevs; i++) {
86911495b5cSArtur Paszkiewicz 		free(r->base_bdevs.base_bdevs[i]);
87011495b5cSArtur Paszkiewicz 	}
87111495b5cSArtur Paszkiewicz }
87211495b5cSArtur Paszkiewicz 
87311495b5cSArtur Paszkiewicz static void
87411495b5cSArtur Paszkiewicz create_raid_bdev_delete_req(struct rpc_bdev_raid_delete *r, const char *raid_name,
87511495b5cSArtur Paszkiewicz 			    uint8_t json_decode_obj_err)
87611495b5cSArtur Paszkiewicz {
87711495b5cSArtur Paszkiewicz 	r->name = strdup(raid_name);
87811495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(r->name != NULL);
87911495b5cSArtur Paszkiewicz 
88011495b5cSArtur Paszkiewicz 	g_rpc_req = r;
88111495b5cSArtur Paszkiewicz 	g_rpc_req_size = sizeof(*r);
88211495b5cSArtur Paszkiewicz 	g_rpc_err = 0;
88311495b5cSArtur Paszkiewicz 	g_json_decode_obj_create = 0;
88411495b5cSArtur Paszkiewicz 	g_json_decode_obj_err = json_decode_obj_err;
88511495b5cSArtur Paszkiewicz 	g_test_multi_raids = 0;
88611495b5cSArtur Paszkiewicz }
88711495b5cSArtur Paszkiewicz 
88811495b5cSArtur Paszkiewicz static void
88911495b5cSArtur Paszkiewicz create_get_raids_req(struct rpc_bdev_raid_get_bdevs *r, const char *category,
89011495b5cSArtur Paszkiewicz 		     uint8_t json_decode_obj_err)
89111495b5cSArtur Paszkiewicz {
89211495b5cSArtur Paszkiewicz 	r->category = strdup(category);
89311495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(r->category != NULL);
89411495b5cSArtur Paszkiewicz 
89511495b5cSArtur Paszkiewicz 	g_rpc_req = r;
89611495b5cSArtur Paszkiewicz 	g_rpc_req_size = sizeof(*r);
89711495b5cSArtur Paszkiewicz 	g_rpc_err = 0;
89811495b5cSArtur Paszkiewicz 	g_json_decode_obj_create = 0;
89911495b5cSArtur Paszkiewicz 	g_json_decode_obj_err = json_decode_obj_err;
90011495b5cSArtur Paszkiewicz 	g_test_multi_raids = 1;
90111495b5cSArtur Paszkiewicz 	g_get_raids_count = 0;
90211495b5cSArtur Paszkiewicz }
90311495b5cSArtur Paszkiewicz 
90411495b5cSArtur Paszkiewicz static void
90511495b5cSArtur Paszkiewicz test_create_raid(void)
90611495b5cSArtur Paszkiewicz {
90711495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
90811495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete delete_req;
90911495b5cSArtur Paszkiewicz 
91011495b5cSArtur Paszkiewicz 	set_globals();
91111495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
91211495b5cSArtur Paszkiewicz 
91311495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
914deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
915fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
91611495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
91711495b5cSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
91811495b5cSArtur Paszkiewicz 	free_test_req(&req);
91911495b5cSArtur Paszkiewicz 
92011495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&delete_req, "raid1", 0);
921fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
92211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
92311495b5cSArtur Paszkiewicz 	raid_bdev_exit();
92411495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
92511495b5cSArtur Paszkiewicz 	reset_globals();
92611495b5cSArtur Paszkiewicz }
92711495b5cSArtur Paszkiewicz 
92811495b5cSArtur Paszkiewicz static void
92911495b5cSArtur Paszkiewicz test_delete_raid(void)
93011495b5cSArtur Paszkiewicz {
93111495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create construct_req;
93211495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete delete_req;
93311495b5cSArtur Paszkiewicz 
93411495b5cSArtur Paszkiewicz 	set_globals();
93511495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
93611495b5cSArtur Paszkiewicz 
93711495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
938deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
939fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
94011495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
94111495b5cSArtur Paszkiewicz 	verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
94211495b5cSArtur Paszkiewicz 	free_test_req(&construct_req);
94311495b5cSArtur Paszkiewicz 
94411495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&delete_req, "raid1", 0);
945fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
94611495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
94711495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
94811495b5cSArtur Paszkiewicz 
94911495b5cSArtur Paszkiewicz 	raid_bdev_exit();
95011495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
95111495b5cSArtur Paszkiewicz 	reset_globals();
95211495b5cSArtur Paszkiewicz }
95311495b5cSArtur Paszkiewicz 
95411495b5cSArtur Paszkiewicz static void
95511495b5cSArtur Paszkiewicz test_create_raid_invalid_args(void)
95611495b5cSArtur Paszkiewicz {
95711495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
95811495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
959dccdd1e5SArtur Paszkiewicz 	struct raid_bdev *raid_bdev;
96011495b5cSArtur Paszkiewicz 
96111495b5cSArtur Paszkiewicz 	set_globals();
96211495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
96311495b5cSArtur Paszkiewicz 
96411495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
965deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
96611495b5cSArtur Paszkiewicz 	req.level = INVALID_RAID_LEVEL;
967fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
96811495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
96911495b5cSArtur Paszkiewicz 	free_test_req(&req);
97011495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
97111495b5cSArtur Paszkiewicz 
972deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, false, 1, false);
973fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
97411495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
97511495b5cSArtur Paszkiewicz 	free_test_req(&req);
97611495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
97711495b5cSArtur Paszkiewicz 
978deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
97911495b5cSArtur Paszkiewicz 	req.strip_size_kb = 1231;
980fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
98111495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
98211495b5cSArtur Paszkiewicz 	free_test_req(&req);
98311495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
98411495b5cSArtur Paszkiewicz 
985deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
986fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
98711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
98811495b5cSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
98911495b5cSArtur Paszkiewicz 	free_test_req(&req);
99011495b5cSArtur Paszkiewicz 
991deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
992fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
99311495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
99411495b5cSArtur Paszkiewicz 	free_test_req(&req);
99511495b5cSArtur Paszkiewicz 
996deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid2", 0, false, 0, false);
997fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
99811495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
99911495b5cSArtur Paszkiewicz 	free_test_req(&req);
100011495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid2", false);
100111495b5cSArtur Paszkiewicz 
1002deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
100311495b5cSArtur Paszkiewicz 	free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
100411495b5cSArtur Paszkiewicz 	req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme0n1");
100511495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
1006fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
100711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
100811495b5cSArtur Paszkiewicz 	free_test_req(&req);
100911495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid2", false);
101011495b5cSArtur Paszkiewicz 
1011deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
101211495b5cSArtur Paszkiewicz 	free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
101311495b5cSArtur Paszkiewicz 	req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme100000n1");
101411495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
1015fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
101611495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
101711495b5cSArtur Paszkiewicz 	free_test_req(&req);
101811495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid2", true);
1019dccdd1e5SArtur Paszkiewicz 	raid_bdev = raid_bdev_find_by_name("raid2");
1020dccdd1e5SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
1021dccdd1e5SArtur Paszkiewicz 	check_and_remove_raid_bdev(raid_bdev);
102211495b5cSArtur Paszkiewicz 
1023deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, false, 0, false);
1024fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
102511495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
102611495b5cSArtur Paszkiewicz 	free_test_req(&req);
102711495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid2", true);
102811495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", true);
102911495b5cSArtur Paszkiewicz 
103011495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1031fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
103211495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid2", 0);
1033fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
103411495b5cSArtur Paszkiewicz 	raid_bdev_exit();
103511495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
103611495b5cSArtur Paszkiewicz 	reset_globals();
103711495b5cSArtur Paszkiewicz }
103811495b5cSArtur Paszkiewicz 
103911495b5cSArtur Paszkiewicz static void
104011495b5cSArtur Paszkiewicz test_delete_raid_invalid_args(void)
104111495b5cSArtur Paszkiewicz {
104211495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create construct_req;
104311495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
104411495b5cSArtur Paszkiewicz 
104511495b5cSArtur Paszkiewicz 	set_globals();
104611495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
104711495b5cSArtur Paszkiewicz 
104811495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1049deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
1050fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
105111495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
105211495b5cSArtur Paszkiewicz 	verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
105311495b5cSArtur Paszkiewicz 	free_test_req(&construct_req);
105411495b5cSArtur Paszkiewicz 
105511495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid2", 0);
1056fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
105711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
105811495b5cSArtur Paszkiewicz 
105911495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 1);
1060fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
106111495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
106211495b5cSArtur Paszkiewicz 	free(destroy_req.name);
106311495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", true);
106411495b5cSArtur Paszkiewicz 
106511495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1066fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
106711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
106811495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
106911495b5cSArtur Paszkiewicz 
107011495b5cSArtur Paszkiewicz 	raid_bdev_exit();
107111495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
107211495b5cSArtur Paszkiewicz 	reset_globals();
107311495b5cSArtur Paszkiewicz }
107411495b5cSArtur Paszkiewicz 
107511495b5cSArtur Paszkiewicz static void
107611495b5cSArtur Paszkiewicz test_io_channel(void)
107711495b5cSArtur Paszkiewicz {
107811495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
107911495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
108011495b5cSArtur Paszkiewicz 	struct raid_bdev *pbdev;
108140fd936fSArtur Paszkiewicz 	struct spdk_io_channel *ch;
108211495b5cSArtur Paszkiewicz 	struct raid_bdev_io_channel *ch_ctx;
108311495b5cSArtur Paszkiewicz 
108411495b5cSArtur Paszkiewicz 	set_globals();
108511495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
108611495b5cSArtur Paszkiewicz 
1087deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
108811495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1089fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
109011495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
109111495b5cSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
109211495b5cSArtur Paszkiewicz 
109311495b5cSArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
109411495b5cSArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, "raid1") == 0) {
109511495b5cSArtur Paszkiewicz 			break;
109611495b5cSArtur Paszkiewicz 		}
109711495b5cSArtur Paszkiewicz 	}
109811495b5cSArtur Paszkiewicz 	CU_ASSERT(pbdev != NULL);
109940fd936fSArtur Paszkiewicz 
110040fd936fSArtur Paszkiewicz 	ch = spdk_get_io_channel(pbdev);
110140fd936fSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(ch != NULL);
110240fd936fSArtur Paszkiewicz 
110340fd936fSArtur Paszkiewicz 	ch_ctx = spdk_io_channel_get_ctx(ch);
110411495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
110511495b5cSArtur Paszkiewicz 
110611495b5cSArtur Paszkiewicz 	free_test_req(&req);
110711495b5cSArtur Paszkiewicz 
110840fd936fSArtur Paszkiewicz 	spdk_put_io_channel(ch);
110940fd936fSArtur Paszkiewicz 
111011495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1111fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
111211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
111311495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
111411495b5cSArtur Paszkiewicz 
111511495b5cSArtur Paszkiewicz 	raid_bdev_exit();
111611495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
111711495b5cSArtur Paszkiewicz 	reset_globals();
111811495b5cSArtur Paszkiewicz }
111911495b5cSArtur Paszkiewicz 
112011495b5cSArtur Paszkiewicz /* Test reset IO */
112111495b5cSArtur Paszkiewicz static void
112211495b5cSArtur Paszkiewicz test_reset_io(void)
112311495b5cSArtur Paszkiewicz {
112411495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
112511495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
112611495b5cSArtur Paszkiewicz 	struct raid_bdev *pbdev;
112711495b5cSArtur Paszkiewicz 	struct spdk_io_channel *ch;
112811495b5cSArtur Paszkiewicz 	struct raid_bdev_io_channel *ch_ctx;
112911495b5cSArtur Paszkiewicz 	struct spdk_bdev_io *bdev_io;
113011495b5cSArtur Paszkiewicz 
113111495b5cSArtur Paszkiewicz 	set_globals();
113211495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
113311495b5cSArtur Paszkiewicz 
113411495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1135deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1136fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
113711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
113811495b5cSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
113911495b5cSArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
114011495b5cSArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, "raid1") == 0) {
114111495b5cSArtur Paszkiewicz 			break;
114211495b5cSArtur Paszkiewicz 		}
114311495b5cSArtur Paszkiewicz 	}
114411495b5cSArtur Paszkiewicz 	CU_ASSERT(pbdev != NULL);
114540fd936fSArtur Paszkiewicz 
114640fd936fSArtur Paszkiewicz 	ch = spdk_get_io_channel(pbdev);
114711495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(ch != NULL);
114840fd936fSArtur Paszkiewicz 
114911495b5cSArtur Paszkiewicz 	ch_ctx = spdk_io_channel_get_ctx(ch);
115011495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
115111495b5cSArtur Paszkiewicz 
115211495b5cSArtur Paszkiewicz 	g_child_io_status_flag = true;
115311495b5cSArtur Paszkiewicz 
115411495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_RESET) == true);
115511495b5cSArtur Paszkiewicz 
115611495b5cSArtur Paszkiewicz 	bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
115711495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
115811495b5cSArtur Paszkiewicz 	bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, 1, SPDK_BDEV_IO_TYPE_RESET);
115911495b5cSArtur Paszkiewicz 	memset(g_io_output, 0, g_max_base_drives * sizeof(struct io_output));
116011495b5cSArtur Paszkiewicz 	g_io_output_index = 0;
116111495b5cSArtur Paszkiewicz 	raid_bdev_submit_request(ch, bdev_io);
116211495b5cSArtur Paszkiewicz 	verify_reset_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
116311495b5cSArtur Paszkiewicz 			true);
116411495b5cSArtur Paszkiewicz 	bdev_io_cleanup(bdev_io);
116511495b5cSArtur Paszkiewicz 
116640fd936fSArtur Paszkiewicz 	free_test_req(&req);
116740fd936fSArtur Paszkiewicz 	spdk_put_io_channel(ch);
116811495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1169fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
117011495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
117111495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
117211495b5cSArtur Paszkiewicz 
117311495b5cSArtur Paszkiewicz 	raid_bdev_exit();
117411495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
117511495b5cSArtur Paszkiewicz 	reset_globals();
117611495b5cSArtur Paszkiewicz }
117711495b5cSArtur Paszkiewicz 
117811495b5cSArtur Paszkiewicz /* Create multiple raids, destroy raids without IO, get_raids related tests */
117911495b5cSArtur Paszkiewicz static void
1180698da718SArtur Paszkiewicz test_multi_raid(void)
118111495b5cSArtur Paszkiewicz {
118211495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create *construct_req;
118311495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
118411495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_get_bdevs get_raids_req;
118511495b5cSArtur Paszkiewicz 	uint8_t i;
118611495b5cSArtur Paszkiewicz 	char name[16];
118711495b5cSArtur Paszkiewicz 	uint8_t bbdev_idx = 0;
118811495b5cSArtur Paszkiewicz 
118911495b5cSArtur Paszkiewicz 	set_globals();
119011495b5cSArtur Paszkiewicz 	construct_req = calloc(MAX_RAIDS, sizeof(struct rpc_bdev_raid_create));
119111495b5cSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(construct_req != NULL);
119211495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
119311495b5cSArtur Paszkiewicz 	for (i = 0; i < g_max_raids; i++) {
119411495b5cSArtur Paszkiewicz 		snprintf(name, 16, "%s%u", "raid", i);
119511495b5cSArtur Paszkiewicz 		verify_raid_bdev_present(name, false);
1196deed7d2fSArtur Paszkiewicz 		create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0, false);
119711495b5cSArtur Paszkiewicz 		bbdev_idx += g_max_base_drives;
1198fe5ba303SSeth Howell 		rpc_bdev_raid_create(NULL, NULL);
119911495b5cSArtur Paszkiewicz 		CU_ASSERT(g_rpc_err == 0);
120011495b5cSArtur Paszkiewicz 		verify_raid_bdev(&construct_req[i], true, RAID_BDEV_STATE_ONLINE);
120111495b5cSArtur Paszkiewicz 	}
120211495b5cSArtur Paszkiewicz 
120311495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "all", 0);
1204fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
120511495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
120611495b5cSArtur Paszkiewicz 	verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
120711495b5cSArtur Paszkiewicz 	for (i = 0; i < g_get_raids_count; i++) {
120811495b5cSArtur Paszkiewicz 		free(g_get_raids_output[i]);
120911495b5cSArtur Paszkiewicz 	}
121011495b5cSArtur Paszkiewicz 
121111495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "online", 0);
1212fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
121311495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
121411495b5cSArtur Paszkiewicz 	verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
121511495b5cSArtur Paszkiewicz 	for (i = 0; i < g_get_raids_count; i++) {
121611495b5cSArtur Paszkiewicz 		free(g_get_raids_output[i]);
121711495b5cSArtur Paszkiewicz 	}
121811495b5cSArtur Paszkiewicz 
121911495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "configuring", 0);
1220fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
122111495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
122211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_get_raids_count == 0);
122311495b5cSArtur Paszkiewicz 
122411495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "offline", 0);
1225fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
122611495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
122711495b5cSArtur Paszkiewicz 	CU_ASSERT(g_get_raids_count == 0);
122811495b5cSArtur Paszkiewicz 
122911495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "invalid_category", 0);
1230fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
123111495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
123211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_get_raids_count == 0);
123311495b5cSArtur Paszkiewicz 
123411495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "all", 1);
1235fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
123611495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 1);
123711495b5cSArtur Paszkiewicz 	free(get_raids_req.category);
123811495b5cSArtur Paszkiewicz 	CU_ASSERT(g_get_raids_count == 0);
123911495b5cSArtur Paszkiewicz 
124011495b5cSArtur Paszkiewicz 	create_get_raids_req(&get_raids_req, "all", 0);
1241fe5ba303SSeth Howell 	rpc_bdev_raid_get_bdevs(NULL, NULL);
124211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
124311495b5cSArtur Paszkiewicz 	CU_ASSERT(g_get_raids_count == g_max_raids);
124411495b5cSArtur Paszkiewicz 	for (i = 0; i < g_get_raids_count; i++) {
124511495b5cSArtur Paszkiewicz 		free(g_get_raids_output[i]);
124611495b5cSArtur Paszkiewicz 	}
124711495b5cSArtur Paszkiewicz 
124811495b5cSArtur Paszkiewicz 	for (i = 0; i < g_max_raids; i++) {
124911495b5cSArtur Paszkiewicz 		SPDK_CU_ASSERT_FATAL(construct_req[i].name != NULL);
125011495b5cSArtur Paszkiewicz 		snprintf(name, 16, "%s", construct_req[i].name);
125111495b5cSArtur Paszkiewicz 		create_raid_bdev_delete_req(&destroy_req, name, 0);
1252fe5ba303SSeth Howell 		rpc_bdev_raid_delete(NULL, NULL);
125311495b5cSArtur Paszkiewicz 		CU_ASSERT(g_rpc_err == 0);
125411495b5cSArtur Paszkiewicz 		verify_raid_bdev_present(name, false);
125511495b5cSArtur Paszkiewicz 	}
125611495b5cSArtur Paszkiewicz 	raid_bdev_exit();
125711495b5cSArtur Paszkiewicz 	for (i = 0; i < g_max_raids; i++) {
125811495b5cSArtur Paszkiewicz 		free_test_req(&construct_req[i]);
125911495b5cSArtur Paszkiewicz 	}
126011495b5cSArtur Paszkiewicz 	free(construct_req);
126111495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
126211495b5cSArtur Paszkiewicz 	reset_globals();
126311495b5cSArtur Paszkiewicz }
126411495b5cSArtur Paszkiewicz 
126511495b5cSArtur Paszkiewicz static void
126611495b5cSArtur Paszkiewicz test_io_type_supported(void)
126711495b5cSArtur Paszkiewicz {
126811495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_READ) == true);
126911495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_WRITE) == true);
127011495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_INVALID) == false);
127111495b5cSArtur Paszkiewicz }
127211495b5cSArtur Paszkiewicz 
127311495b5cSArtur Paszkiewicz static void
127411495b5cSArtur Paszkiewicz test_raid_json_dump_info(void)
127511495b5cSArtur Paszkiewicz {
127611495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
127711495b5cSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
127811495b5cSArtur Paszkiewicz 	struct raid_bdev *pbdev;
127911495b5cSArtur Paszkiewicz 
128011495b5cSArtur Paszkiewicz 	set_globals();
128111495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
128211495b5cSArtur Paszkiewicz 
128311495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1284deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1285fe5ba303SSeth Howell 	rpc_bdev_raid_create(NULL, NULL);
128611495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
128711495b5cSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
128811495b5cSArtur Paszkiewicz 
128911495b5cSArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
129011495b5cSArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, "raid1") == 0) {
129111495b5cSArtur Paszkiewicz 			break;
129211495b5cSArtur Paszkiewicz 		}
129311495b5cSArtur Paszkiewicz 	}
129411495b5cSArtur Paszkiewicz 	CU_ASSERT(pbdev != NULL);
129511495b5cSArtur Paszkiewicz 
129611495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_dump_info_json(pbdev, NULL) == 0);
129711495b5cSArtur Paszkiewicz 
129811495b5cSArtur Paszkiewicz 	free_test_req(&req);
129911495b5cSArtur Paszkiewicz 
130011495b5cSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1301fe5ba303SSeth Howell 	rpc_bdev_raid_delete(NULL, NULL);
130211495b5cSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
130311495b5cSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
130411495b5cSArtur Paszkiewicz 
130511495b5cSArtur Paszkiewicz 	raid_bdev_exit();
130611495b5cSArtur Paszkiewicz 	base_bdevs_cleanup();
130711495b5cSArtur Paszkiewicz 	reset_globals();
130811495b5cSArtur Paszkiewicz }
130911495b5cSArtur Paszkiewicz 
131011495b5cSArtur Paszkiewicz static void
131111495b5cSArtur Paszkiewicz test_context_size(void)
131211495b5cSArtur Paszkiewicz {
131311495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_get_ctx_size() == sizeof(struct raid_bdev_io));
131411495b5cSArtur Paszkiewicz }
131511495b5cSArtur Paszkiewicz 
131611495b5cSArtur Paszkiewicz static void
131711495b5cSArtur Paszkiewicz test_raid_level_conversions(void)
131811495b5cSArtur Paszkiewicz {
131911495b5cSArtur Paszkiewicz 	const char *raid_str;
132011495b5cSArtur Paszkiewicz 
132146ff15a6SArtur Paszkiewicz 	CU_ASSERT(raid_bdev_str_to_level("abcd123") == INVALID_RAID_LEVEL);
132246ff15a6SArtur Paszkiewicz 	CU_ASSERT(raid_bdev_str_to_level("0") == RAID0);
132346ff15a6SArtur Paszkiewicz 	CU_ASSERT(raid_bdev_str_to_level("raid0") == RAID0);
132446ff15a6SArtur Paszkiewicz 	CU_ASSERT(raid_bdev_str_to_level("RAID0") == RAID0);
132511495b5cSArtur Paszkiewicz 
132611495b5cSArtur Paszkiewicz 	raid_str = raid_bdev_level_to_str(INVALID_RAID_LEVEL);
132711495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_str != NULL && strlen(raid_str) == 0);
132811495b5cSArtur Paszkiewicz 	raid_str = raid_bdev_level_to_str(1234);
132911495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_str != NULL && strlen(raid_str) == 0);
133011495b5cSArtur Paszkiewicz 	raid_str = raid_bdev_level_to_str(RAID0);
133111495b5cSArtur Paszkiewicz 	CU_ASSERT(raid_str != NULL && strcmp(raid_str, "raid0") == 0);
133211495b5cSArtur Paszkiewicz }
133311495b5cSArtur Paszkiewicz 
1334deed7d2fSArtur Paszkiewicz static void
1335deed7d2fSArtur Paszkiewicz test_create_raid_superblock(void)
1336deed7d2fSArtur Paszkiewicz {
1337deed7d2fSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
1338deed7d2fSArtur Paszkiewicz 	struct rpc_bdev_raid_delete delete_req;
1339deed7d2fSArtur Paszkiewicz 
1340deed7d2fSArtur Paszkiewicz 	set_globals();
1341deed7d2fSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
1342deed7d2fSArtur Paszkiewicz 
1343deed7d2fSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1344deed7d2fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, true);
1345deed7d2fSArtur Paszkiewicz 	rpc_bdev_raid_create(NULL, NULL);
1346deed7d2fSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
1347deed7d2fSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1348deed7d2fSArtur Paszkiewicz 	free_test_req(&req);
1349deed7d2fSArtur Paszkiewicz 
1350deed7d2fSArtur Paszkiewicz 	create_raid_bdev_delete_req(&delete_req, "raid1", 0);
1351deed7d2fSArtur Paszkiewicz 	rpc_bdev_raid_delete(NULL, NULL);
1352deed7d2fSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
1353deed7d2fSArtur Paszkiewicz 	raid_bdev_exit();
1354deed7d2fSArtur Paszkiewicz 	base_bdevs_cleanup();
1355deed7d2fSArtur Paszkiewicz 	reset_globals();
135650d58ff3SArtur Paszkiewicz }
1357deed7d2fSArtur Paszkiewicz 
135850d58ff3SArtur Paszkiewicz static void
135950d58ff3SArtur Paszkiewicz test_raid_process(void)
136050d58ff3SArtur Paszkiewicz {
136150d58ff3SArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
136250d58ff3SArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
136350d58ff3SArtur Paszkiewicz 	struct raid_bdev *pbdev;
136450d58ff3SArtur Paszkiewicz 	struct spdk_bdev *base_bdev;
136550d58ff3SArtur Paszkiewicz 	struct spdk_thread *process_thread;
136650d58ff3SArtur Paszkiewicz 	uint64_t num_blocks_processed = 0;
136750d58ff3SArtur Paszkiewicz 
136850d58ff3SArtur Paszkiewicz 	set_globals();
136950d58ff3SArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
137050d58ff3SArtur Paszkiewicz 
137150d58ff3SArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
137250d58ff3SArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
137350d58ff3SArtur Paszkiewicz 	TAILQ_FOREACH(base_bdev, &g_bdev_list, internal.link) {
137450d58ff3SArtur Paszkiewicz 		base_bdev->blockcnt = 128;
137550d58ff3SArtur Paszkiewicz 	}
137650d58ff3SArtur Paszkiewicz 	rpc_bdev_raid_create(NULL, NULL);
137750d58ff3SArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
137850d58ff3SArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
137950d58ff3SArtur Paszkiewicz 	free_test_req(&req);
138050d58ff3SArtur Paszkiewicz 
138150d58ff3SArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
138250d58ff3SArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, "raid1") == 0) {
138350d58ff3SArtur Paszkiewicz 			break;
138450d58ff3SArtur Paszkiewicz 		}
138550d58ff3SArtur Paszkiewicz 	}
138650d58ff3SArtur Paszkiewicz 	CU_ASSERT(pbdev != NULL);
138750d58ff3SArtur Paszkiewicz 
138850d58ff3SArtur Paszkiewicz 	pbdev->module_private = &num_blocks_processed;
13891a587504SArtur Paszkiewicz 	pbdev->min_base_bdevs_operational = 0;
139050d58ff3SArtur Paszkiewicz 
139150d58ff3SArtur Paszkiewicz 	CU_ASSERT(raid_bdev_start_rebuild(&pbdev->base_bdev_info[0]) == 0);
1392fff473bbSArtur Paszkiewicz 	poll_app_thread();
139350d58ff3SArtur Paszkiewicz 
139450d58ff3SArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(pbdev->process != NULL);
139550d58ff3SArtur Paszkiewicz 
139679f76d9fSArtur Paszkiewicz 	process_thread = g_latest_thread;
139779f76d9fSArtur Paszkiewicz 	spdk_thread_poll(process_thread, 0, 0);
139879f76d9fSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(pbdev->process->thread == process_thread);
139950d58ff3SArtur Paszkiewicz 
140050d58ff3SArtur Paszkiewicz 	while (spdk_thread_poll(process_thread, 0, 0) > 0) {
1401fff473bbSArtur Paszkiewicz 		poll_app_thread();
140250d58ff3SArtur Paszkiewicz 	}
140350d58ff3SArtur Paszkiewicz 
140450d58ff3SArtur Paszkiewicz 	CU_ASSERT(pbdev->process == NULL);
140550d58ff3SArtur Paszkiewicz 	CU_ASSERT(num_blocks_processed == pbdev->bdev.blockcnt);
140650d58ff3SArtur Paszkiewicz 
1407fff473bbSArtur Paszkiewicz 	poll_app_thread();
140850d58ff3SArtur Paszkiewicz 
140950d58ff3SArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
141050d58ff3SArtur Paszkiewicz 	rpc_bdev_raid_delete(NULL, NULL);
141150d58ff3SArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
141250d58ff3SArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
141350d58ff3SArtur Paszkiewicz 
141450d58ff3SArtur Paszkiewicz 	raid_bdev_exit();
141550d58ff3SArtur Paszkiewicz 	base_bdevs_cleanup();
141650d58ff3SArtur Paszkiewicz 	reset_globals();
141750d58ff3SArtur Paszkiewicz }
141850d58ff3SArtur Paszkiewicz 
1419aae5e04fSArtur Paszkiewicz static void
1420*89fd1730Sxupeng9 test_raid_process_with_qos(void)
1421*89fd1730Sxupeng9 {
1422*89fd1730Sxupeng9 	struct rpc_bdev_raid_create req;
1423*89fd1730Sxupeng9 	struct rpc_bdev_raid_delete destroy_req;
1424*89fd1730Sxupeng9 	struct raid_bdev *pbdev;
1425*89fd1730Sxupeng9 	struct spdk_bdev *base_bdev;
1426*89fd1730Sxupeng9 	struct spdk_thread *process_thread;
1427*89fd1730Sxupeng9 	uint64_t num_blocks_processed = 0;
1428*89fd1730Sxupeng9 	struct spdk_raid_bdev_opts opts;
1429*89fd1730Sxupeng9 	int i = 0;
1430*89fd1730Sxupeng9 
1431*89fd1730Sxupeng9 	set_globals();
1432*89fd1730Sxupeng9 	CU_ASSERT(raid_bdev_init() == 0);
1433*89fd1730Sxupeng9 
1434*89fd1730Sxupeng9 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1435*89fd1730Sxupeng9 	verify_raid_bdev_present("raid1", false);
1436*89fd1730Sxupeng9 	TAILQ_FOREACH(base_bdev, &g_bdev_list, internal.link) {
1437*89fd1730Sxupeng9 		base_bdev->blockcnt = 128;
1438*89fd1730Sxupeng9 	}
1439*89fd1730Sxupeng9 	rpc_bdev_raid_create(NULL, NULL);
1440*89fd1730Sxupeng9 	CU_ASSERT(g_rpc_err == 0);
1441*89fd1730Sxupeng9 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1442*89fd1730Sxupeng9 	free_test_req(&req);
1443*89fd1730Sxupeng9 
1444*89fd1730Sxupeng9 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1445*89fd1730Sxupeng9 		if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1446*89fd1730Sxupeng9 			break;
1447*89fd1730Sxupeng9 		}
1448*89fd1730Sxupeng9 	}
1449*89fd1730Sxupeng9 	CU_ASSERT(pbdev != NULL);
1450*89fd1730Sxupeng9 
1451*89fd1730Sxupeng9 	pbdev->module_private = &num_blocks_processed;
1452*89fd1730Sxupeng9 	pbdev->min_base_bdevs_operational = 0;
1453*89fd1730Sxupeng9 
1454*89fd1730Sxupeng9 	opts.process_window_size_kb = 1024;
1455*89fd1730Sxupeng9 	opts.process_max_bandwidth_mb_sec = 1;
1456*89fd1730Sxupeng9 	CU_ASSERT(raid_bdev_set_opts(&opts) == 0);
1457*89fd1730Sxupeng9 	CU_ASSERT(raid_bdev_start_rebuild(&pbdev->base_bdev_info[0]) == 0);
1458*89fd1730Sxupeng9 	poll_app_thread();
1459*89fd1730Sxupeng9 
1460*89fd1730Sxupeng9 	SPDK_CU_ASSERT_FATAL(pbdev->process != NULL);
1461*89fd1730Sxupeng9 
1462*89fd1730Sxupeng9 	process_thread = g_latest_thread;
1463*89fd1730Sxupeng9 
1464*89fd1730Sxupeng9 	for (i = 0; i < 10; i++) {
1465*89fd1730Sxupeng9 		spdk_thread_poll(process_thread, 0, 0);
1466*89fd1730Sxupeng9 		poll_app_thread();
1467*89fd1730Sxupeng9 	}
1468*89fd1730Sxupeng9 	CU_ASSERT(pbdev->process->window_offset == 0);
1469*89fd1730Sxupeng9 
1470*89fd1730Sxupeng9 	spdk_delay_us(SPDK_SEC_TO_USEC);
1471*89fd1730Sxupeng9 	while (spdk_thread_poll(process_thread, 0, 0) > 0) {
1472*89fd1730Sxupeng9 		spdk_delay_us(SPDK_SEC_TO_USEC);
1473*89fd1730Sxupeng9 		poll_app_thread();
1474*89fd1730Sxupeng9 	}
1475*89fd1730Sxupeng9 
1476*89fd1730Sxupeng9 	CU_ASSERT(pbdev->process == NULL);
1477*89fd1730Sxupeng9 	CU_ASSERT(num_blocks_processed == pbdev->bdev.blockcnt);
1478*89fd1730Sxupeng9 
1479*89fd1730Sxupeng9 	poll_app_thread();
1480*89fd1730Sxupeng9 
1481*89fd1730Sxupeng9 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1482*89fd1730Sxupeng9 	rpc_bdev_raid_delete(NULL, NULL);
1483*89fd1730Sxupeng9 	CU_ASSERT(g_rpc_err == 0);
1484*89fd1730Sxupeng9 	verify_raid_bdev_present("raid1", false);
1485*89fd1730Sxupeng9 
1486*89fd1730Sxupeng9 	raid_bdev_exit();
1487*89fd1730Sxupeng9 	base_bdevs_cleanup();
1488*89fd1730Sxupeng9 	reset_globals();
1489*89fd1730Sxupeng9 }
1490*89fd1730Sxupeng9 
1491*89fd1730Sxupeng9 static void
1492aae5e04fSArtur Paszkiewicz test_raid_io_split(void)
1493aae5e04fSArtur Paszkiewicz {
1494aae5e04fSArtur Paszkiewicz 	struct rpc_bdev_raid_create req;
1495aae5e04fSArtur Paszkiewicz 	struct rpc_bdev_raid_delete destroy_req;
1496aae5e04fSArtur Paszkiewicz 	struct raid_bdev *pbdev;
1497aae5e04fSArtur Paszkiewicz 	struct spdk_io_channel *ch;
1498aae5e04fSArtur Paszkiewicz 	struct raid_bdev_io_channel *raid_ch;
1499aae5e04fSArtur Paszkiewicz 	struct spdk_bdev_io *bdev_io;
1500aae5e04fSArtur Paszkiewicz 	struct raid_bdev_io *raid_io;
1501aae5e04fSArtur Paszkiewicz 	uint64_t split_offset;
1502aae5e04fSArtur Paszkiewicz 	struct iovec iovs_orig[4];
1503aae5e04fSArtur Paszkiewicz 	struct raid_bdev_process process = { };
1504aae5e04fSArtur Paszkiewicz 
1505aae5e04fSArtur Paszkiewicz 	set_globals();
1506aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_bdev_init() == 0);
1507aae5e04fSArtur Paszkiewicz 
1508aae5e04fSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1509aae5e04fSArtur Paszkiewicz 	create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
1510aae5e04fSArtur Paszkiewicz 	rpc_bdev_raid_create(NULL, NULL);
1511aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
1512aae5e04fSArtur Paszkiewicz 	verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
1513aae5e04fSArtur Paszkiewicz 
1514aae5e04fSArtur Paszkiewicz 	TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
1515aae5e04fSArtur Paszkiewicz 		if (strcmp(pbdev->bdev.name, "raid1") == 0) {
1516aae5e04fSArtur Paszkiewicz 			break;
1517aae5e04fSArtur Paszkiewicz 		}
1518aae5e04fSArtur Paszkiewicz 	}
1519aae5e04fSArtur Paszkiewicz 	CU_ASSERT(pbdev != NULL);
1520aae5e04fSArtur Paszkiewicz 	pbdev->bdev.md_len = 8;
1521aae5e04fSArtur Paszkiewicz 
1522aae5e04fSArtur Paszkiewicz 	process.raid_bdev = pbdev;
1523aae5e04fSArtur Paszkiewicz 	process.target = &pbdev->base_bdev_info[0];
1524aae5e04fSArtur Paszkiewicz 	pbdev->process = &process;
1525aae5e04fSArtur Paszkiewicz 	ch = spdk_get_io_channel(pbdev);
1526aae5e04fSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(ch != NULL);
1527aae5e04fSArtur Paszkiewicz 	raid_ch = spdk_io_channel_get_ctx(ch);
1528aae5e04fSArtur Paszkiewicz 	g_bdev_io_defer_completion = true;
1529aae5e04fSArtur Paszkiewicz 
1530aae5e04fSArtur Paszkiewicz 	/* test split of bdev_io with 1 iovec */
1531aae5e04fSArtur Paszkiewicz 	bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1532aae5e04fSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1533aae5e04fSArtur Paszkiewicz 	raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
1534698da718SArtur Paszkiewicz 	_bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, g_strip_size, SPDK_BDEV_IO_TYPE_WRITE, 1,
1535698da718SArtur Paszkiewicz 			    g_strip_size * g_block_len);
1536aae5e04fSArtur Paszkiewicz 	memcpy(iovs_orig, bdev_io->u.bdev.iovs, sizeof(*iovs_orig) * bdev_io->u.bdev.iovcnt);
1537aae5e04fSArtur Paszkiewicz 
1538aae5e04fSArtur Paszkiewicz 	split_offset = 1;
1539aae5e04fSArtur Paszkiewicz 	raid_ch->process.offset = split_offset;
1540aae5e04fSArtur Paszkiewicz 	raid_bdev_submit_request(ch, bdev_io);
1541aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1542aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == split_offset);
1543aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 1);
1544aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1545aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == raid_io->split.iov);
1546aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base + split_offset * g_block_len);
1547aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig->iov_len - split_offset * g_block_len);
1548192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1549192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1550aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1551192db8deSSlawomir Ptak 	}
1552aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1553aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == split_offset);
1554aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1555aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 1);
1556aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base);
1557aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == split_offset * g_block_len);
1558192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1559192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1560aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1561192db8deSSlawomir Ptak 	}
1562aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1563aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size);
1564aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1565aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 1);
1566aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig->iov_base);
1567aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig->iov_len);
1568192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1569192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1570aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1571192db8deSSlawomir Ptak 	}
1572aae5e04fSArtur Paszkiewicz 
1573aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1574698da718SArtur Paszkiewicz 
1575aae5e04fSArtur Paszkiewicz 	bdev_io_cleanup(bdev_io);
1576aae5e04fSArtur Paszkiewicz 
1577aae5e04fSArtur Paszkiewicz 	/* test split of bdev_io with 4 iovecs */
1578aae5e04fSArtur Paszkiewicz 	bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
1579aae5e04fSArtur Paszkiewicz 	SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
1580aae5e04fSArtur Paszkiewicz 	raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
1581aae5e04fSArtur Paszkiewicz 	_bdev_io_initialize(bdev_io, ch, &pbdev->bdev, 0, g_strip_size, SPDK_BDEV_IO_TYPE_WRITE,
1582aae5e04fSArtur Paszkiewicz 			    4, g_strip_size / 4 * g_block_len);
1583aae5e04fSArtur Paszkiewicz 	memcpy(iovs_orig, bdev_io->u.bdev.iovs, sizeof(*iovs_orig) * bdev_io->u.bdev.iovcnt);
1584aae5e04fSArtur Paszkiewicz 
1585aae5e04fSArtur Paszkiewicz 	split_offset = 1; /* split at the first iovec */
1586aae5e04fSArtur Paszkiewicz 	raid_ch->process.offset = split_offset;
1587aae5e04fSArtur Paszkiewicz 	raid_bdev_submit_request(ch, bdev_io);
1588aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1589aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == split_offset);
1590aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 4);
1591aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[0]);
1592aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[0]);
1593aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[0].iov_base + g_block_len);
1594aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig[0].iov_len -  g_block_len);
1595aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs + 1, iovs_orig + 1, sizeof(*iovs_orig) * 3) == 0);
1596192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1597192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1598aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1599192db8deSSlawomir Ptak 	}
1600aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1601aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == split_offset);
1602aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1603aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 1);
1604aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1605aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[0].iov_base);
1606aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == g_block_len);
1607192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1608192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1609aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1610192db8deSSlawomir Ptak 	}
1611aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1612aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size);
1613aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1614aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 4);
1615aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1616aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1617192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1618192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1619aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1620192db8deSSlawomir Ptak 	}
1621aae5e04fSArtur Paszkiewicz 
1622aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1623aae5e04fSArtur Paszkiewicz 
1624aae5e04fSArtur Paszkiewicz 	split_offset = g_strip_size / 2; /* split exactly between second and third iovec */
1625aae5e04fSArtur Paszkiewicz 	raid_ch->process.offset = split_offset;
1626aae5e04fSArtur Paszkiewicz 	raid_bdev_submit_request(ch, bdev_io);
1627aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1628aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == split_offset);
1629aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 2);
1630aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->split.iov == NULL);
1631aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[2]);
1632aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig + 2, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1633192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1634192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1635aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1636192db8deSSlawomir Ptak 	}
1637aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1638aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == split_offset);
1639aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1640aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 2);
1641aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1642aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1643192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1644192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1645aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1646192db8deSSlawomir Ptak 	}
1647aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1648aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size);
1649aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1650aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 4);
1651aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1652aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1653192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1654192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1655aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1656192db8deSSlawomir Ptak 	}
1657aae5e04fSArtur Paszkiewicz 
1658aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1659aae5e04fSArtur Paszkiewicz 
1660aae5e04fSArtur Paszkiewicz 	split_offset = g_strip_size / 2 + 1; /* split at the third iovec */
1661aae5e04fSArtur Paszkiewicz 	raid_ch->process.offset = split_offset;
1662aae5e04fSArtur Paszkiewicz 	raid_bdev_submit_request(ch, bdev_io);
1663aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1664aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == split_offset);
1665aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 2);
1666aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[2]);
1667aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[2]);
1668aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[2].iov_base + g_block_len);
1669aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == iovs_orig[2].iov_len - g_block_len);
1670aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[1].iov_base == iovs_orig[3].iov_base);
1671aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[1].iov_len == iovs_orig[3].iov_len);
1672192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1673192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1674aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1675192db8deSSlawomir Ptak 	}
1676aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1677aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == split_offset);
1678aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1679aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 3);
1680aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1681aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * 2) == 0);
1682aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[2].iov_base == iovs_orig[2].iov_base);
1683aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[2].iov_len == g_block_len);
1684192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1685192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1686aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1687192db8deSSlawomir Ptak 	}
1688aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1689aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size);
1690aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1691aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 4);
1692aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1693aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1694192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1695192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1696aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1697192db8deSSlawomir Ptak 	}
1698aae5e04fSArtur Paszkiewicz 
1699aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1700aae5e04fSArtur Paszkiewicz 
1701aae5e04fSArtur Paszkiewicz 	split_offset = g_strip_size - 1; /* split at the last iovec */
1702aae5e04fSArtur Paszkiewicz 	raid_ch->process.offset = split_offset;
1703aae5e04fSArtur Paszkiewicz 	raid_bdev_submit_request(ch, bdev_io);
1704aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size - split_offset);
1705aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == split_offset);
1706aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 1);
1707aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->split.iov == &bdev_io->u.bdev.iovs[3]);
1708aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == &bdev_io->u.bdev.iovs[3]);
1709aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_base == iovs_orig[3].iov_base + iovs_orig[3].iov_len - g_block_len);
1710aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[0].iov_len == g_block_len);
1711192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1712192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1713aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf + split_offset * pbdev->bdev.md_len);
1714192db8deSSlawomir Ptak 	}
1715aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1716aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == split_offset);
1717aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1718aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 4);
1719aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1720aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * 3) == 0);
1721aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[3].iov_base == iovs_orig[3].iov_base);
1722aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs[3].iov_len == iovs_orig[3].iov_len - g_block_len);
1723192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1724192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1725aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1726192db8deSSlawomir Ptak 	}
1727aae5e04fSArtur Paszkiewicz 	complete_deferred_ios();
1728aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->num_blocks == g_strip_size);
1729aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->offset_blocks == 0);
1730aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovcnt == 4);
1731aae5e04fSArtur Paszkiewicz 	CU_ASSERT(raid_io->iovs == bdev_io->u.bdev.iovs);
1732aae5e04fSArtur Paszkiewicz 	CU_ASSERT(memcmp(raid_io->iovs, iovs_orig, sizeof(*iovs_orig) * raid_io->iovcnt) == 0);
1733192db8deSSlawomir Ptak 	if (spdk_bdev_get_dif_type(&pbdev->bdev) != SPDK_DIF_DISABLE &&
1734192db8deSSlawomir Ptak 	    !spdk_bdev_is_md_interleaved(&pbdev->bdev)) {
1735aae5e04fSArtur Paszkiewicz 		CU_ASSERT(raid_io->md_buf == bdev_io->u.bdev.md_buf);
1736192db8deSSlawomir Ptak 	}
1737aae5e04fSArtur Paszkiewicz 
1738aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_io_comp_status == g_child_io_status_flag);
1739698da718SArtur Paszkiewicz 
1740aae5e04fSArtur Paszkiewicz 	bdev_io_cleanup(bdev_io);
1741aae5e04fSArtur Paszkiewicz 
1742aae5e04fSArtur Paszkiewicz 	spdk_put_io_channel(ch);
1743aae5e04fSArtur Paszkiewicz 	free_test_req(&req);
17449d2b7b41SArtur Paszkiewicz 	pbdev->process = NULL;
1745aae5e04fSArtur Paszkiewicz 
1746aae5e04fSArtur Paszkiewicz 	create_raid_bdev_delete_req(&destroy_req, "raid1", 0);
1747aae5e04fSArtur Paszkiewicz 	rpc_bdev_raid_delete(NULL, NULL);
1748aae5e04fSArtur Paszkiewicz 	CU_ASSERT(g_rpc_err == 0);
1749aae5e04fSArtur Paszkiewicz 	verify_raid_bdev_present("raid1", false);
1750aae5e04fSArtur Paszkiewicz 
1751aae5e04fSArtur Paszkiewicz 	raid_bdev_exit();
1752aae5e04fSArtur Paszkiewicz 	base_bdevs_cleanup();
1753aae5e04fSArtur Paszkiewicz 	reset_globals();
1754aae5e04fSArtur Paszkiewicz }
1755aae5e04fSArtur Paszkiewicz 
175650d58ff3SArtur Paszkiewicz static int
175779f76d9fSArtur Paszkiewicz test_new_thread_fn(struct spdk_thread *thread)
175879f76d9fSArtur Paszkiewicz {
175979f76d9fSArtur Paszkiewicz 	g_latest_thread = thread;
176079f76d9fSArtur Paszkiewicz 
176179f76d9fSArtur Paszkiewicz 	return 0;
176279f76d9fSArtur Paszkiewicz }
176379f76d9fSArtur Paszkiewicz 
176479f76d9fSArtur Paszkiewicz static int
176550d58ff3SArtur Paszkiewicz test_bdev_ioch_create(void *io_device, void *ctx_buf)
176650d58ff3SArtur Paszkiewicz {
176750d58ff3SArtur Paszkiewicz 	return 0;
176850d58ff3SArtur Paszkiewicz }
176950d58ff3SArtur Paszkiewicz 
177050d58ff3SArtur Paszkiewicz static void
177150d58ff3SArtur Paszkiewicz test_bdev_ioch_destroy(void *io_device, void *ctx_buf)
177250d58ff3SArtur Paszkiewicz {
1773deed7d2fSArtur Paszkiewicz }
1774deed7d2fSArtur Paszkiewicz 
17758dd1cd21SBen Walker int
17768dd1cd21SBen Walker main(int argc, char **argv)
177711495b5cSArtur Paszkiewicz {
1778698da718SArtur Paszkiewicz 	CU_pSuite suite = NULL;
177911495b5cSArtur Paszkiewicz 	unsigned int num_failures;
178011495b5cSArtur Paszkiewicz 
178178b696bcSVitaliy Mysak 	CU_initialize_registry();
1782698da718SArtur Paszkiewicz 
1783698da718SArtur Paszkiewicz 	suite = CU_add_suite("raid", set_test_opts, NULL);
1784698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_create_raid);
1785698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_create_raid_superblock);
1786698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_delete_raid);
1787698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_create_raid_invalid_args);
1788698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_delete_raid_invalid_args);
1789698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_io_channel);
1790698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_reset_io);
1791698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_multi_raid);
1792698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_io_type_supported);
1793698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_raid_json_dump_info);
1794698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_context_size);
1795698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_raid_level_conversions);
1796698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_raid_io_split);
1797698da718SArtur Paszkiewicz 	CU_ADD_TEST(suite, test_raid_process);
1798*89fd1730Sxupeng9 	CU_ADD_TEST(suite, test_raid_process_with_qos);
179911495b5cSArtur Paszkiewicz 
180079f76d9fSArtur Paszkiewicz 	spdk_thread_lib_init(test_new_thread_fn, 0);
1801fff473bbSArtur Paszkiewicz 	g_app_thread = spdk_thread_create("app_thread", NULL);
1802fff473bbSArtur Paszkiewicz 	spdk_set_thread(g_app_thread);
180350d58ff3SArtur Paszkiewicz 	spdk_io_device_register(&g_bdev_ch_io_device, test_bdev_ioch_create, test_bdev_ioch_destroy, 0,
180450d58ff3SArtur Paszkiewicz 				NULL);
1805c65d64a6SGangCao 
1806ea941caeSKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
180711495b5cSArtur Paszkiewicz 	CU_cleanup_registry();
1808c65d64a6SGangCao 
180950d58ff3SArtur Paszkiewicz 	spdk_io_device_unregister(&g_bdev_ch_io_device, NULL);
1810fff473bbSArtur Paszkiewicz 	spdk_thread_exit(g_app_thread);
1811fff473bbSArtur Paszkiewicz 	spdk_thread_poll(g_app_thread, 0, 0);
1812fff473bbSArtur Paszkiewicz 	spdk_thread_destroy(g_app_thread);
1813fff473bbSArtur Paszkiewicz 	spdk_thread_lib_fini();
1814c65d64a6SGangCao 
181511495b5cSArtur Paszkiewicz 	return num_failures;
181611495b5cSArtur Paszkiewicz }
1817