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: 1059 1119 94.6 %
Date: 2024-08-14 00:43:33 Functions: 96 144 66.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 320 560 57.1 %

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

Generated by: LCOV version 1.14