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: 1010 1070 94.4 %
Date: 2024-07-12 06:37:40 Functions: 95 143 66.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 309 546 56.6 %

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

Generated by: LCOV version 1.14