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