LCOV - code coverage report
Current view: top level - spdk/test/unit/lib/bdev/raid/bdev_raid.c - bdev_raid_ut.c (source / functions) Hit Total Coverage
Test: Combined Lines: 1430 1477 96.8 %
Date: 2024-07-13 02:54:37 Functions: 101 120 84.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 443 704 62.9 %

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

Generated by: LCOV version 1.14