2018-05-08 11:30:29 +00:00
|
|
|
/*-
|
|
|
|
* BSD LICENSE
|
|
|
|
*
|
|
|
|
* Copyright (c) Intel Corporation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* * Neither the name of Intel Corporation nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "spdk/stdinc.h"
|
|
|
|
#include "spdk_cunit.h"
|
|
|
|
#include "spdk/env.h"
|
|
|
|
#include "spdk_internal/mock.h"
|
2018-08-02 21:30:47 +00:00
|
|
|
#include "bdev/raid/bdev_raid.c"
|
|
|
|
#include "bdev/raid/bdev_raid_rpc.c"
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
#define MAX_BASE_DRIVES 255
|
|
|
|
#define MAX_RAIDS 31
|
|
|
|
#define INVALID_IO_SUBMIT 0xFFFF
|
2019-01-21 13:34:21 +00:00
|
|
|
#define MAX_TEST_IO_RANGE (3 * 3 * 3 * (MAX_BASE_DRIVES + 5))
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* Data structure to capture the output of IO for verification */
|
|
|
|
struct io_output {
|
|
|
|
struct spdk_bdev_desc *desc;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
uint64_t offset_blocks;
|
|
|
|
uint64_t num_blocks;
|
|
|
|
spdk_bdev_io_completion_cb cb;
|
|
|
|
void *cb_arg;
|
|
|
|
enum spdk_bdev_io_type iotype;
|
|
|
|
};
|
|
|
|
|
2019-01-21 13:34:21 +00:00
|
|
|
struct raid_io_ranges {
|
|
|
|
uint64_t lba;
|
|
|
|
uint64_t nblocks;
|
|
|
|
};
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* Different test options, more options to test can be added here */
|
|
|
|
uint32_t g_blklen_opts[] = {512, 4096};
|
|
|
|
uint32_t g_strip_opts[] = {64, 128, 256, 512, 1024, 2048};
|
|
|
|
uint32_t g_iosize_opts[] = {256, 512, 1024};
|
|
|
|
uint32_t g_max_qd_opts[] = {64, 128, 256, 512, 1024, 2048};
|
|
|
|
|
|
|
|
/* Globals */
|
|
|
|
int g_bdev_io_submit_status;
|
|
|
|
struct io_output *g_io_output = NULL;
|
|
|
|
uint32_t g_io_output_index;
|
|
|
|
uint32_t g_io_comp_status;
|
|
|
|
bool g_child_io_status_flag;
|
|
|
|
void *rpc_req;
|
|
|
|
uint32_t rpc_req_size;
|
|
|
|
TAILQ_HEAD(bdev, spdk_bdev);
|
|
|
|
struct bdev g_bdev_list;
|
|
|
|
TAILQ_HEAD(waitq, spdk_bdev_io_wait_entry);
|
|
|
|
struct waitq g_io_waitq;
|
|
|
|
uint32_t g_block_len;
|
|
|
|
uint32_t g_strip_size;
|
|
|
|
uint32_t g_max_io_size;
|
|
|
|
uint32_t g_max_qd;
|
|
|
|
uint8_t g_max_base_drives;
|
|
|
|
uint8_t g_max_raids;
|
|
|
|
uint8_t g_ignore_io_output;
|
|
|
|
uint8_t g_rpc_err;
|
|
|
|
char *g_get_raids_output[MAX_RAIDS];
|
|
|
|
uint32_t g_get_raids_count;
|
|
|
|
uint8_t g_json_beg_res_ret_err;
|
|
|
|
uint8_t g_json_decode_obj_err;
|
2018-07-24 23:49:05 +00:00
|
|
|
uint8_t g_json_decode_obj_construct;
|
2018-05-08 11:30:29 +00:00
|
|
|
uint8_t g_config_level_create = 0;
|
|
|
|
uint8_t g_test_multi_raids;
|
2019-01-21 13:34:21 +00:00
|
|
|
struct raid_io_ranges g_io_ranges[MAX_TEST_IO_RANGE];
|
|
|
|
uint32_t g_io_range_idx;
|
|
|
|
uint64_t g_lba_offset;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* Set randomly test options, in every run it is different */
|
|
|
|
static void
|
|
|
|
set_test_opts(void)
|
|
|
|
{
|
|
|
|
uint32_t seed = time(0);
|
|
|
|
|
|
|
|
/* Generate random test options */
|
|
|
|
srand(seed);
|
|
|
|
g_max_base_drives = (rand() % MAX_BASE_DRIVES) + 1;
|
|
|
|
g_max_raids = (rand() % MAX_RAIDS) + 1;
|
|
|
|
g_block_len = g_blklen_opts[rand() % SPDK_COUNTOF(g_blklen_opts)];
|
|
|
|
g_strip_size = g_strip_opts[rand() % SPDK_COUNTOF(g_strip_opts)];
|
|
|
|
g_max_io_size = g_iosize_opts[rand() % SPDK_COUNTOF(g_iosize_opts)];
|
|
|
|
g_max_qd = g_max_qd_opts[rand() % SPDK_COUNTOF(g_max_qd_opts)];
|
|
|
|
|
|
|
|
printf("Test Options, seed = %u\n", seed);
|
|
|
|
printf("blocklen = %u, strip_size = %u, max_io_size = %u, max_qd = %u, g_max_base_drives = %u, g_max_raids = %u\n",
|
|
|
|
g_block_len, g_strip_size, g_max_io_size, g_max_qd, g_max_base_drives, g_max_raids);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set globals before every test run */
|
|
|
|
static void
|
|
|
|
set_globals(void)
|
|
|
|
{
|
|
|
|
uint32_t max_splits;
|
|
|
|
|
|
|
|
g_bdev_io_submit_status = 0;
|
|
|
|
if (g_max_io_size < g_strip_size) {
|
|
|
|
max_splits = 2;
|
|
|
|
} else {
|
|
|
|
max_splits = (g_max_io_size / g_strip_size) + 1;
|
|
|
|
}
|
2019-01-21 13:09:15 +00:00
|
|
|
if (max_splits < g_max_base_drives) {
|
|
|
|
max_splits = g_max_base_drives;
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
g_io_output = calloc(max_splits, sizeof(struct io_output));
|
|
|
|
SPDK_CU_ASSERT_FATAL(g_io_output != NULL);
|
|
|
|
g_io_output_index = 0;
|
|
|
|
memset(g_get_raids_output, 0, sizeof(g_get_raids_output));
|
|
|
|
g_get_raids_count = 0;
|
|
|
|
g_io_comp_status = 0;
|
|
|
|
g_ignore_io_output = 0;
|
|
|
|
g_config_level_create = 0;
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_test_multi_raids = 0;
|
|
|
|
g_child_io_status_flag = true;
|
|
|
|
TAILQ_INIT(&g_bdev_list);
|
|
|
|
TAILQ_INIT(&g_io_waitq);
|
|
|
|
rpc_req = NULL;
|
|
|
|
rpc_req_size = 0;
|
|
|
|
g_json_beg_res_ret_err = 0;
|
|
|
|
g_json_decode_obj_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2019-01-21 13:34:21 +00:00
|
|
|
g_lba_offset = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
base_bdevs_cleanup(void)
|
|
|
|
{
|
|
|
|
struct spdk_bdev *bdev;
|
|
|
|
struct spdk_bdev *bdev_next;
|
|
|
|
|
|
|
|
if (!TAILQ_EMPTY(&g_bdev_list)) {
|
|
|
|
TAILQ_FOREACH_SAFE(bdev, &g_bdev_list, internal.link, bdev_next) {
|
|
|
|
free(bdev->name);
|
|
|
|
TAILQ_REMOVE(&g_bdev_list, bdev, internal.link);
|
|
|
|
free(bdev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
bdev/raid: Change construct_raid_bdev RPC to be consistent to other bdev modules
Change the behavior of construct_raid_bdev RPC to be consistent with
other bdev modules.
Create a config of raid bdev first. Then create a raid bdev based
on the config.
If both succeed, the config and the raid bdev are not removed even if
any failure occur later in construct_raid_bdev RPC. Otherwise, both
are removed and return failure.
During iteration of adding base bdevs in construct_raid_bdev RPC,
- skip any nonexistent bdev and move to the next base bdev.
- if adding any base bdev fails, move to the next bdev.
- if adding base bdevs don't fail but any base bdev doesn't exist,
the raid bdev is in the configuring state and return success.
- if adding base bdev fails, the raid bdev is in the configuring state
and return failure.
- if all adding base bdevs succeed, configure the raid bdev. If configuring
the raid bdev fails, move the raid bdev to the offline state and return
failure. If configuring the raid bdev succeed, return success.
check_and_remove_raid_bdev() becomes unused in raid_bdev_rpc.c but
is still necessary in UT. Hence move this function to UT.
In UT, finding a raid bdev config by name becomes necessary. Hence
factor out the iteration to a function and use the function in UT.
Change-Id: Ifa36967bdc987d97030e3a4e36684cb37b329d4e
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/423622
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Kunal Sablok <kunal.sablok@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2018-08-31 00:58:25 +00:00
|
|
|
static void
|
|
|
|
check_and_remove_raid_bdev(struct raid_bdev_config *raid_cfg)
|
|
|
|
{
|
|
|
|
struct raid_bdev *raid_bdev;
|
|
|
|
|
|
|
|
/* Get the raid structured allocated if exists */
|
|
|
|
raid_bdev = raid_cfg->raid_bdev;
|
|
|
|
if (raid_bdev == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < raid_bdev->num_base_bdevs; i++) {
|
|
|
|
assert(raid_bdev->base_bdev_info != NULL);
|
|
|
|
if (raid_bdev->base_bdev_info[i].bdev) {
|
|
|
|
raid_bdev_free_base_bdev_resource(raid_bdev, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(raid_bdev->num_base_bdevs_discovered == 0);
|
|
|
|
raid_bdev_cleanup(raid_bdev);
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* Reset globals */
|
|
|
|
static void
|
|
|
|
reset_globals(void)
|
|
|
|
{
|
|
|
|
if (g_io_output) {
|
|
|
|
free(g_io_output);
|
|
|
|
g_io_output = NULL;
|
|
|
|
}
|
|
|
|
rpc_req = NULL;
|
|
|
|
rpc_req_size = 0;
|
|
|
|
}
|
|
|
|
|
2018-07-27 19:23:26 +00:00
|
|
|
void
|
|
|
|
spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb,
|
|
|
|
uint64_t len)
|
|
|
|
{
|
|
|
|
CU_ASSERT(false);
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* Store the IO completion status in global variable to verify by various tests */
|
|
|
|
void
|
|
|
|
spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
|
|
|
|
{
|
|
|
|
g_io_comp_status = ((status == SPDK_BDEV_IO_STATUS_SUCCESS) ? true : false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* It will cache the split IOs for verification */
|
|
|
|
int
|
2018-08-23 21:18:42 +00:00
|
|
|
spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
|
|
struct iovec *iov, int iovcnt,
|
|
|
|
uint64_t offset_blocks, uint64_t num_blocks,
|
|
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
2018-05-08 11:30:29 +00:00
|
|
|
{
|
|
|
|
struct io_output *p = &g_io_output[g_io_output_index];
|
|
|
|
struct spdk_bdev_io *child_io;
|
|
|
|
|
|
|
|
if (g_ignore_io_output) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_max_io_size < g_strip_size) {
|
|
|
|
SPDK_CU_ASSERT_FATAL(g_io_output_index < 2);
|
|
|
|
} else {
|
|
|
|
SPDK_CU_ASSERT_FATAL(g_io_output_index < (g_max_io_size / g_strip_size) + 1);
|
|
|
|
}
|
|
|
|
if (g_bdev_io_submit_status == 0) {
|
|
|
|
p->desc = desc;
|
|
|
|
p->ch = ch;
|
|
|
|
p->offset_blocks = offset_blocks;
|
|
|
|
p->num_blocks = num_blocks;
|
|
|
|
p->cb = cb;
|
|
|
|
p->cb_arg = cb_arg;
|
|
|
|
p->iotype = SPDK_BDEV_IO_TYPE_WRITE;
|
|
|
|
g_io_output_index++;
|
|
|
|
child_io = calloc(1, sizeof(struct spdk_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(child_io != NULL);
|
|
|
|
cb(child_io, g_child_io_status_flag, cb_arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_bdev_io_submit_status;
|
|
|
|
}
|
|
|
|
|
2018-08-24 16:40:22 +00:00
|
|
|
int
|
|
|
|
spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
|
|
|
{
|
2019-01-21 13:09:15 +00:00
|
|
|
struct io_output *p = &g_io_output[g_io_output_index];
|
|
|
|
struct spdk_bdev_io *child_io;
|
|
|
|
|
|
|
|
if (g_ignore_io_output) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_bdev_io_submit_status == 0) {
|
|
|
|
p->desc = desc;
|
|
|
|
p->ch = ch;
|
|
|
|
p->cb = cb;
|
|
|
|
p->cb_arg = cb_arg;
|
|
|
|
p->iotype = SPDK_BDEV_IO_TYPE_RESET;
|
|
|
|
g_io_output_index++;
|
|
|
|
child_io = calloc(1, sizeof(struct spdk_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(child_io != NULL);
|
|
|
|
cb(child_io, g_child_io_status_flag, cb_arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_bdev_io_submit_status;
|
2018-08-24 16:40:22 +00:00
|
|
|
}
|
|
|
|
|
2019-01-21 13:34:21 +00:00
|
|
|
int
|
|
|
|
spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
|
|
uint64_t offset_blocks, uint64_t num_blocks,
|
|
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
|
|
|
{
|
|
|
|
struct io_output *p = &g_io_output[g_io_output_index];
|
|
|
|
struct spdk_bdev_io *child_io;
|
|
|
|
|
|
|
|
if (g_ignore_io_output) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_bdev_io_submit_status == 0) {
|
|
|
|
p->desc = desc;
|
|
|
|
p->ch = ch;
|
|
|
|
p->offset_blocks = offset_blocks;
|
|
|
|
p->num_blocks = num_blocks;
|
|
|
|
p->cb = cb;
|
|
|
|
p->cb_arg = cb_arg;
|
|
|
|
p->iotype = SPDK_BDEV_IO_TYPE_UNMAP;
|
|
|
|
g_io_output_index++;
|
|
|
|
child_io = calloc(1, sizeof(struct spdk_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(child_io != NULL);
|
|
|
|
cb(child_io, g_child_io_status_flag, cb_arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_bdev_io_submit_status;
|
|
|
|
}
|
|
|
|
|
2019-02-28 13:00:11 +00:00
|
|
|
int
|
|
|
|
spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
|
|
uint64_t offset_blocks, uint64_t num_blocks,
|
|
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-01-21 13:34:21 +00:00
|
|
|
bool
|
|
|
|
spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
void
|
|
|
|
spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
|
|
|
|
{
|
|
|
|
bdev->fn_table->destruct(bdev->ctxt);
|
2019-04-09 00:40:54 +00:00
|
|
|
|
|
|
|
if (cb_fn) {
|
|
|
|
cb_fn(cb_arg, 0);
|
|
|
|
}
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb,
|
|
|
|
void *remove_ctx, struct spdk_bdev_desc **_desc)
|
|
|
|
{
|
|
|
|
*_desc = (void *)0x1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_put_io_channel(struct spdk_io_channel *ch)
|
|
|
|
{
|
|
|
|
CU_ASSERT(ch == (void *)1);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_io_channel *
|
|
|
|
spdk_get_io_channel(void *io_device)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_poller_unregister(struct spdk_poller **ppoller)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_poller *
|
|
|
|
spdk_poller_register(spdk_poller_fn fn,
|
|
|
|
void *arg,
|
|
|
|
uint64_t period_microseconds)
|
|
|
|
{
|
|
|
|
return (void *)1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_io_device_unregister(void *io_device, spdk_io_device_unregister_cb unregister_cb)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
spdk_sprintf_alloc(const char *format, ...)
|
|
|
|
{
|
|
|
|
return strdup(format);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_io_device_register(void *io_device, spdk_io_channel_create_cb create_cb,
|
2018-08-30 20:26:50 +00:00
|
|
|
spdk_io_channel_destroy_cb destroy_cb, uint32_t ctx_size,
|
|
|
|
const char *name)
|
2018-05-08 11:30:29 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
|
|
|
|
{
|
2018-07-24 23:49:05 +00:00
|
|
|
struct rpc_construct_raid_bdev *req = rpc_req;
|
2019-02-27 21:01:18 +00:00
|
|
|
if (strcmp(name, "strip_size_kb") == 0) {
|
|
|
|
CU_ASSERT(req->strip_size_kb == val);
|
2018-05-08 11:30:29 +00:00
|
|
|
} else if (strcmp(name, "blocklen_shift") == 0) {
|
|
|
|
CU_ASSERT(spdk_u32log2(g_block_len) == val);
|
|
|
|
} else if (strcmp(name, "raid_level") == 0) {
|
|
|
|
CU_ASSERT(req->raid_level == val);
|
|
|
|
} else if (strcmp(name, "num_base_bdevs") == 0) {
|
|
|
|
CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
|
|
|
|
} else if (strcmp(name, "state") == 0) {
|
|
|
|
CU_ASSERT(val == RAID_BDEV_STATE_ONLINE);
|
|
|
|
} else if (strcmp(name, "destruct_called") == 0) {
|
|
|
|
CU_ASSERT(val == 0);
|
|
|
|
} else if (strcmp(name, "num_base_bdevs_discovered") == 0) {
|
|
|
|
CU_ASSERT(req->base_bdevs.num_base_bdevs == val);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-20 23:33:32 +00:00
|
|
|
int
|
|
|
|
spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
int
|
|
|
|
spdk_json_write_array_end(struct spdk_json_write_ctx *w)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_object_end(struct spdk_json_write_ctx *w)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int spdk_json_write_null(struct spdk_json_write_ctx *w)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_io_channel *
|
|
|
|
spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
|
|
|
|
{
|
|
|
|
return (void *)1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-10-10 21:05:04 +00:00
|
|
|
spdk_for_each_thread(spdk_msg_fn fn, void *ctx, spdk_msg_fn cpl)
|
2018-05-08 11:30:29 +00:00
|
|
|
{
|
|
|
|
fn(ctx);
|
|
|
|
cpl(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_thread *
|
|
|
|
spdk_get_thread(void)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-10-10 21:05:04 +00:00
|
|
|
spdk_thread_send_msg(const struct spdk_thread *thread, spdk_msg_fn fn, void *ctx)
|
2018-05-08 11:30:29 +00:00
|
|
|
{
|
|
|
|
fn(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
spdk_env_get_current_core(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_bdev_free_io(struct spdk_bdev_io *bdev_io)
|
|
|
|
{
|
|
|
|
if (bdev_io) {
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* It will cache split IOs for verification */
|
|
|
|
int
|
2018-08-23 21:18:42 +00:00
|
|
|
spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
|
|
struct iovec *iov, int iovcnt,
|
|
|
|
uint64_t offset_blocks, uint64_t num_blocks,
|
|
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
2018-05-08 11:30:29 +00:00
|
|
|
{
|
|
|
|
struct io_output *p = &g_io_output[g_io_output_index];
|
|
|
|
struct spdk_bdev_io *child_io;
|
|
|
|
|
|
|
|
if (g_ignore_io_output) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(g_io_output_index <= (g_max_io_size / g_strip_size) + 1);
|
|
|
|
if (g_bdev_io_submit_status == 0) {
|
|
|
|
p->desc = desc;
|
|
|
|
p->ch = ch;
|
|
|
|
p->offset_blocks = offset_blocks;
|
|
|
|
p->num_blocks = num_blocks;
|
|
|
|
p->cb = cb;
|
|
|
|
p->cb_arg = cb_arg;
|
|
|
|
p->iotype = SPDK_BDEV_IO_TYPE_READ;
|
|
|
|
g_io_output_index++;
|
|
|
|
child_io = calloc(1, sizeof(struct spdk_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(child_io != NULL);
|
|
|
|
cb(child_io, g_child_io_status_flag, cb_arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_bdev_io_submit_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_bdev_module_release_bdev(struct spdk_bdev *bdev)
|
|
|
|
{
|
|
|
|
CU_ASSERT(bdev->internal.claim_module != NULL);
|
|
|
|
bdev->internal.claim_module = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_bdev_module_examine_done(struct spdk_bdev_module *module)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_conf_section *
|
|
|
|
spdk_conf_first_section(struct spdk_conf *cp)
|
|
|
|
{
|
|
|
|
if (g_config_level_create) {
|
|
|
|
return (void *) 0x1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
spdk_conf_section_match_prefix(const struct spdk_conf_section *sp, const char *name_prefix)
|
|
|
|
{
|
|
|
|
if (g_config_level_create) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
spdk_conf_section_get_val(struct spdk_conf_section *sp, const char *key)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev *req = rpc_req;
|
|
|
|
|
|
|
|
if (g_config_level_create) {
|
|
|
|
if (strcmp(key, "Name") == 0) {
|
|
|
|
return req->name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_conf_section_get_intval(struct spdk_conf_section *sp, const char *key)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev *req = rpc_req;
|
|
|
|
|
|
|
|
if (g_config_level_create) {
|
|
|
|
if (strcmp(key, "StripSize") == 0) {
|
2019-02-27 21:01:18 +00:00
|
|
|
return req->strip_size_kb;
|
2018-05-08 11:30:29 +00:00
|
|
|
} else if (strcmp(key, "NumDevices") == 0) {
|
|
|
|
return req->base_bdevs.num_base_bdevs;
|
|
|
|
} else if (strcmp(key, "RaidLevel") == 0) {
|
|
|
|
return req->raid_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_conf_section *
|
|
|
|
spdk_conf_next_section(struct spdk_conf_section *sp)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
spdk_conf_section_get_nmval(struct spdk_conf_section *sp, const char *key, int idx1, int idx2)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev *req = rpc_req;
|
|
|
|
|
|
|
|
if (g_config_level_create) {
|
|
|
|
if (strcmp(key, "Devices") == 0) {
|
|
|
|
if (idx2 >= g_max_base_drives) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return req->base_bdevs.base_bdevs[idx2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_bdev_close(struct spdk_bdev_desc *desc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
|
|
|
|
struct spdk_bdev_module *module)
|
|
|
|
{
|
|
|
|
if (bdev->internal.claim_module != NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
bdev->internal.claim_module = module;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_bdev_register(struct spdk_bdev *bdev)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
spdk_env_get_last_core(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_decode_string(const struct spdk_json_val *val, void *out)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_decode_object(const struct spdk_json_val *values,
|
|
|
|
const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out)
|
|
|
|
{
|
2018-07-24 23:49:05 +00:00
|
|
|
struct rpc_construct_raid_bdev *req, *_out;
|
|
|
|
size_t i;
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
if (g_json_decode_obj_err) {
|
|
|
|
return -1;
|
2018-07-24 23:49:05 +00:00
|
|
|
} else if (g_json_decode_obj_construct) {
|
|
|
|
req = rpc_req;
|
|
|
|
_out = out;
|
|
|
|
|
|
|
|
_out->name = strdup(req->name);
|
|
|
|
SPDK_CU_ASSERT_FATAL(_out->name != NULL);
|
2019-02-27 21:01:18 +00:00
|
|
|
_out->strip_size_kb = req->strip_size_kb;
|
2018-07-24 23:49:05 +00:00
|
|
|
_out->raid_level = req->raid_level;
|
|
|
|
_out->base_bdevs.num_base_bdevs = req->base_bdevs.num_base_bdevs;
|
|
|
|
for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) {
|
|
|
|
_out->base_bdevs.base_bdevs[i] = strdup(req->base_bdevs.base_bdevs[i]);
|
|
|
|
SPDK_CU_ASSERT_FATAL(_out->base_bdevs.base_bdevs[i]);
|
|
|
|
}
|
2018-05-08 11:30:29 +00:00
|
|
|
} else {
|
|
|
|
memcpy(out, rpc_req, rpc_req_size);
|
|
|
|
}
|
2018-07-24 23:49:05 +00:00
|
|
|
|
|
|
|
return 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_json_write_ctx *
|
|
|
|
spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
|
|
|
|
{
|
|
|
|
if (g_json_beg_res_ret_err) {
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
return (void *)1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
|
|
|
|
{
|
|
|
|
if (g_test_multi_raids) {
|
|
|
|
g_get_raids_output[g_get_raids_count] = strdup(val);
|
|
|
|
SPDK_CU_ASSERT_FATAL(g_get_raids_output[g_get_raids_count] != NULL);
|
|
|
|
g_get_raids_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
|
|
|
|
int error_code, const char *msg)
|
|
|
|
{
|
|
|
|
g_rpc_err = 1;
|
|
|
|
}
|
|
|
|
|
2018-08-28 08:09:10 +00:00
|
|
|
void
|
|
|
|
spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
|
|
|
|
int error_code, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
g_rpc_err = 1;
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
void
|
|
|
|
spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
struct spdk_bdev *
|
|
|
|
spdk_bdev_get_by_name(const char *bdev_name)
|
|
|
|
{
|
|
|
|
struct spdk_bdev *bdev;
|
|
|
|
|
|
|
|
if (!TAILQ_EMPTY(&g_bdev_list)) {
|
|
|
|
TAILQ_FOREACH(bdev, &g_bdev_list, internal.link) {
|
|
|
|
if (strcmp(bdev_name, bdev->name) == 0) {
|
|
|
|
return bdev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
spdk_strerror(int errnum)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func,
|
|
|
|
void *out, size_t max_size, size_t *out_size, size_t stride)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_rpc_register_method(const char *method, spdk_rpc_method_handler func, uint32_t state_mask)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_json_decode_uint32(const struct spdk_json_val *val, void *out)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
spdk_bdev_module_list_add(struct spdk_bdev_module *bdev_module)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bdev_io_cleanup(struct spdk_bdev_io *bdev_io)
|
|
|
|
{
|
|
|
|
if (bdev_io->u.bdev.iovs) {
|
|
|
|
if (bdev_io->u.bdev.iovs->iov_base) {
|
|
|
|
free(bdev_io->u.bdev.iovs->iov_base);
|
|
|
|
bdev_io->u.bdev.iovs->iov_base = NULL;
|
|
|
|
}
|
|
|
|
free(bdev_io->u.bdev.iovs);
|
|
|
|
bdev_io->u.bdev.iovs = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_bdev *bdev,
|
|
|
|
uint64_t lba, uint64_t blocks, int16_t iotype)
|
2018-05-08 11:30:29 +00:00
|
|
|
{
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io->bdev = bdev;
|
2018-05-08 11:30:29 +00:00
|
|
|
bdev_io->u.bdev.offset_blocks = lba;
|
|
|
|
bdev_io->u.bdev.num_blocks = blocks;
|
|
|
|
bdev_io->type = iotype;
|
2019-01-21 13:34:21 +00:00
|
|
|
|
|
|
|
if (bdev_io->type == SPDK_BDEV_IO_TYPE_UNMAP || bdev_io->type == SPDK_BDEV_IO_TYPE_FLUSH) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
bdev_io->u.bdev.iovcnt = 1;
|
|
|
|
bdev_io->u.bdev.iovs = calloc(1, sizeof(struct iovec));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs != NULL);
|
|
|
|
bdev_io->u.bdev.iovs->iov_base = calloc(1, bdev_io->u.bdev.num_blocks * g_block_len);
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs->iov_base != NULL);
|
|
|
|
bdev_io->u.bdev.iovs->iov_len = bdev_io->u.bdev.num_blocks * g_block_len;
|
|
|
|
bdev_io->u.bdev.iovs = bdev_io->u.bdev.iovs;
|
|
|
|
}
|
|
|
|
|
2019-01-21 13:09:15 +00:00
|
|
|
static void
|
|
|
|
verify_reset_io(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
|
|
|
|
struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
|
|
|
|
{
|
|
|
|
uint32_t index = 0;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(io_status != INVALID_IO_SUBMIT);
|
|
|
|
|
|
|
|
CU_ASSERT(g_io_output_index == num_base_drives);
|
|
|
|
for (index = 0; index < g_io_output_index; index++) {
|
|
|
|
CU_ASSERT(ch_ctx->base_channel[index] == g_io_output[index].ch);
|
|
|
|
CU_ASSERT(raid_bdev->base_bdev_info[index].desc == g_io_output[index].desc);
|
|
|
|
CU_ASSERT(bdev_io->type == g_io_output[index].iotype);
|
|
|
|
}
|
|
|
|
CU_ASSERT(g_io_comp_status == io_status);
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
static void
|
|
|
|
verify_io(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
|
|
|
|
struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
|
|
|
|
{
|
|
|
|
uint32_t strip_shift = spdk_u32log2(g_strip_size);
|
|
|
|
uint64_t start_strip = bdev_io->u.bdev.offset_blocks >> strip_shift;
|
|
|
|
uint64_t end_strip = (bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) >>
|
|
|
|
strip_shift;
|
|
|
|
uint32_t splits_reqd = (end_strip - start_strip + 1);
|
|
|
|
uint32_t strip;
|
|
|
|
uint64_t pd_strip;
|
|
|
|
uint64_t pd_idx;
|
|
|
|
uint32_t offset_in_strip;
|
|
|
|
uint64_t pd_lba;
|
|
|
|
uint64_t pd_blocks;
|
|
|
|
uint32_t index = 0;
|
|
|
|
uint8_t *buf = bdev_io->u.bdev.iovs->iov_base;
|
|
|
|
|
|
|
|
if (io_status == INVALID_IO_SUBMIT) {
|
|
|
|
CU_ASSERT(g_io_comp_status == false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
|
|
|
|
|
2018-08-31 04:20:45 +00:00
|
|
|
CU_ASSERT(splits_reqd == g_io_output_index);
|
|
|
|
for (strip = start_strip; strip <= end_strip; strip++, index++) {
|
|
|
|
pd_strip = strip / num_base_drives;
|
|
|
|
pd_idx = strip % num_base_drives;
|
|
|
|
if (strip == start_strip) {
|
|
|
|
offset_in_strip = bdev_io->u.bdev.offset_blocks & (g_strip_size - 1);
|
|
|
|
pd_lba = (pd_strip << strip_shift) + offset_in_strip;
|
|
|
|
if (strip == end_strip) {
|
|
|
|
pd_blocks = bdev_io->u.bdev.num_blocks;
|
2018-05-08 11:30:29 +00:00
|
|
|
} else {
|
2018-08-31 04:20:45 +00:00
|
|
|
pd_blocks = g_strip_size - offset_in_strip;
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
2018-08-31 04:20:45 +00:00
|
|
|
} else if (strip == end_strip) {
|
|
|
|
pd_lba = pd_strip << strip_shift;
|
|
|
|
pd_blocks = ((bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) &
|
|
|
|
(g_strip_size - 1)) + 1;
|
|
|
|
} else {
|
|
|
|
pd_lba = pd_strip << raid_bdev->strip_size_shift;
|
|
|
|
pd_blocks = raid_bdev->strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
2018-08-31 04:20:45 +00:00
|
|
|
CU_ASSERT(pd_lba == g_io_output[index].offset_blocks);
|
|
|
|
CU_ASSERT(pd_blocks == g_io_output[index].num_blocks);
|
|
|
|
CU_ASSERT(ch_ctx->base_channel[pd_idx] == g_io_output[index].ch);
|
|
|
|
CU_ASSERT(raid_bdev->base_bdev_info[pd_idx].desc == g_io_output[index].desc);
|
|
|
|
CU_ASSERT(bdev_io->type == g_io_output[index].iotype);
|
|
|
|
buf += (pd_blocks << spdk_u32log2(g_block_len));
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
CU_ASSERT(g_io_comp_status == io_status);
|
|
|
|
}
|
|
|
|
|
2019-01-21 13:34:21 +00:00
|
|
|
static void
|
|
|
|
verify_io_without_payload(struct spdk_bdev_io *bdev_io, uint8_t num_base_drives,
|
|
|
|
struct raid_bdev_io_channel *ch_ctx, struct raid_bdev *raid_bdev, uint32_t io_status)
|
|
|
|
{
|
|
|
|
uint32_t strip_shift = spdk_u32log2(g_strip_size);
|
|
|
|
uint64_t start_offset_in_strip = bdev_io->u.bdev.offset_blocks % g_strip_size;
|
|
|
|
uint64_t end_offset_in_strip = (bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) %
|
|
|
|
g_strip_size;
|
|
|
|
uint64_t start_strip = bdev_io->u.bdev.offset_blocks >> strip_shift;
|
|
|
|
uint64_t end_strip = (bdev_io->u.bdev.offset_blocks + bdev_io->u.bdev.num_blocks - 1) >>
|
|
|
|
strip_shift;
|
|
|
|
uint32_t n_disks_involved;
|
|
|
|
uint64_t start_strip_disk_idx;
|
|
|
|
uint64_t end_strip_disk_idx;
|
|
|
|
uint64_t nblocks_in_start_disk;
|
|
|
|
uint64_t offset_in_start_disk;
|
|
|
|
uint32_t disk_idx;
|
|
|
|
uint64_t base_io_idx;
|
|
|
|
uint64_t sum_nblocks = 0;
|
|
|
|
|
|
|
|
if (io_status == INVALID_IO_SUBMIT) {
|
|
|
|
CU_ASSERT(g_io_comp_status == false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(num_base_drives != 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->type != SPDK_BDEV_IO_TYPE_READ);
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->type != SPDK_BDEV_IO_TYPE_WRITE);
|
|
|
|
|
|
|
|
n_disks_involved = spdk_min(end_strip - start_strip + 1, num_base_drives);
|
|
|
|
CU_ASSERT(n_disks_involved == g_io_output_index);
|
|
|
|
|
|
|
|
start_strip_disk_idx = start_strip % num_base_drives;
|
|
|
|
end_strip_disk_idx = end_strip % num_base_drives;
|
|
|
|
offset_in_start_disk = g_io_output[0].offset_blocks;
|
|
|
|
nblocks_in_start_disk = g_io_output[0].num_blocks;
|
|
|
|
|
|
|
|
for (base_io_idx = 0, disk_idx = start_strip_disk_idx; base_io_idx < n_disks_involved;
|
|
|
|
base_io_idx++, disk_idx++) {
|
|
|
|
uint64_t start_offset_in_disk;
|
|
|
|
uint64_t end_offset_in_disk;
|
|
|
|
|
|
|
|
/* round disk_idx */
|
|
|
|
if (disk_idx >= num_base_drives) {
|
|
|
|
disk_idx %= num_base_drives;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* start_offset_in_disk aligned in strip check:
|
|
|
|
* The first base io has a same start_offset_in_strip with the whole raid io.
|
|
|
|
* Other base io should have aligned start_offset_in_strip which is 0.
|
|
|
|
*/
|
|
|
|
start_offset_in_disk = g_io_output[base_io_idx].offset_blocks;
|
|
|
|
if (base_io_idx == 0) {
|
|
|
|
CU_ASSERT(start_offset_in_disk % g_strip_size == start_offset_in_strip);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(start_offset_in_disk % g_strip_size == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* end_offset_in_disk aligned in strip check:
|
|
|
|
* Base io on disk at which end_strip is located, has a same end_offset_in_strip with the whole raid io.
|
|
|
|
* Other base io should have aligned end_offset_in_strip.
|
|
|
|
*/
|
|
|
|
end_offset_in_disk = g_io_output[base_io_idx].offset_blocks +
|
|
|
|
g_io_output[base_io_idx].num_blocks - 1;
|
|
|
|
if (disk_idx == end_strip_disk_idx) {
|
|
|
|
CU_ASSERT(end_offset_in_disk % g_strip_size == end_offset_in_strip);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(end_offset_in_disk % g_strip_size == g_strip_size - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* start_offset_in_disk compared with start_disk.
|
|
|
|
* 1. For disk_idx which is larger than start_strip_disk_idx: Its start_offset_in_disk mustn't be
|
|
|
|
* larger than the start offset of start_offset_in_disk; And the gap must be less than strip size.
|
|
|
|
* 2. For disk_idx which is less than start_strip_disk_idx, Its start_offset_in_disk must be
|
|
|
|
* larger than the start offset of start_offset_in_disk; And the gap mustn't be less than strip size.
|
|
|
|
*/
|
|
|
|
if (disk_idx > start_strip_disk_idx) {
|
|
|
|
CU_ASSERT(start_offset_in_disk <= offset_in_start_disk);
|
|
|
|
CU_ASSERT(offset_in_start_disk - start_offset_in_disk < g_strip_size);
|
|
|
|
} else if (disk_idx < start_strip_disk_idx) {
|
|
|
|
CU_ASSERT(start_offset_in_disk > offset_in_start_disk);
|
|
|
|
CU_ASSERT(g_io_output[base_io_idx].offset_blocks - offset_in_start_disk <= g_strip_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* nblocks compared with start_disk:
|
|
|
|
* The gap between them must be within a strip size.
|
|
|
|
*/
|
|
|
|
if (g_io_output[base_io_idx].num_blocks <= nblocks_in_start_disk) {
|
|
|
|
CU_ASSERT(nblocks_in_start_disk - g_io_output[base_io_idx].num_blocks <= g_strip_size);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(g_io_output[base_io_idx].num_blocks - nblocks_in_start_disk < g_strip_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
sum_nblocks += g_io_output[base_io_idx].num_blocks;
|
|
|
|
|
|
|
|
CU_ASSERT(ch_ctx->base_channel[disk_idx] == g_io_output[base_io_idx].ch);
|
|
|
|
CU_ASSERT(raid_bdev->base_bdev_info[disk_idx].desc == g_io_output[base_io_idx].desc);
|
|
|
|
CU_ASSERT(bdev_io->type == g_io_output[base_io_idx].iotype);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sum of each nblocks should be same with raid bdev_io */
|
|
|
|
CU_ASSERT(bdev_io->u.bdev.num_blocks == sum_nblocks);
|
|
|
|
|
|
|
|
CU_ASSERT(g_io_comp_status == io_status);
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
static void
|
|
|
|
verify_raid_config_present(const char *name, bool presence)
|
|
|
|
{
|
2018-07-23 07:54:33 +00:00
|
|
|
struct raid_bdev_config *raid_cfg;
|
2018-05-08 11:30:29 +00:00
|
|
|
bool cfg_found;
|
|
|
|
|
|
|
|
cfg_found = false;
|
2018-07-23 07:54:33 +00:00
|
|
|
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(raid_cfg, &g_raid_config.raid_bdev_config_head, link) {
|
2018-07-24 23:49:05 +00:00
|
|
|
if (raid_cfg->name != NULL) {
|
|
|
|
if (strcmp(name, raid_cfg->name) == 0) {
|
|
|
|
cfg_found = true;
|
|
|
|
break;
|
|
|
|
}
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (presence == true) {
|
|
|
|
CU_ASSERT(cfg_found == true);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(cfg_found == false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
verify_raid_bdev_present(const char *name, bool presence)
|
|
|
|
{
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
bool pbdev_found;
|
|
|
|
|
|
|
|
pbdev_found = false;
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
pbdev_found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (presence == true) {
|
|
|
|
CU_ASSERT(pbdev_found == true);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(pbdev_found == false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
verify_raid_config(struct rpc_construct_raid_bdev *r, bool presence)
|
|
|
|
{
|
|
|
|
struct raid_bdev_config *raid_cfg = NULL;
|
2018-07-23 07:54:33 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
int val;
|
|
|
|
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(raid_cfg, &g_raid_config.raid_bdev_config_head, link) {
|
2018-07-23 07:54:33 +00:00
|
|
|
if (strcmp(r->name, raid_cfg->name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
if (presence == false) {
|
|
|
|
break;
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_cfg->raid_bdev != NULL);
|
2019-02-27 21:01:18 +00:00
|
|
|
CU_ASSERT(raid_cfg->strip_size == r->strip_size_kb);
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_ASSERT(raid_cfg->num_base_bdevs == r->base_bdevs.num_base_bdevs);
|
|
|
|
CU_ASSERT(raid_cfg->raid_level == r->raid_level);
|
2018-07-24 23:49:05 +00:00
|
|
|
if (raid_cfg->base_bdev != NULL) {
|
|
|
|
for (i = 0; i < raid_cfg->num_base_bdevs; i++) {
|
2018-08-27 04:43:27 +00:00
|
|
|
val = strcmp(raid_cfg->base_bdev[i].name, r->base_bdevs.base_bdevs[i]);
|
2018-07-24 23:49:05 +00:00
|
|
|
CU_ASSERT(val == 0);
|
|
|
|
}
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (presence == true) {
|
|
|
|
CU_ASSERT(raid_cfg != NULL);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(raid_cfg == NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
verify_raid_bdev(struct rpc_construct_raid_bdev *r, bool presence, uint32_t raid_state)
|
|
|
|
{
|
|
|
|
struct raid_bdev *pbdev;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
struct spdk_bdev *bdev = NULL;
|
|
|
|
bool pbdev_found;
|
|
|
|
uint64_t min_blockcnt = 0xFFFFFFFFFFFFFFFF;
|
|
|
|
|
|
|
|
pbdev_found = false;
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, r->name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
pbdev_found = true;
|
|
|
|
if (presence == false) {
|
|
|
|
break;
|
|
|
|
}
|
2018-08-21 00:13:44 +00:00
|
|
|
CU_ASSERT(pbdev->config->raid_bdev == pbdev);
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_ASSERT(pbdev->base_bdev_info != NULL);
|
2019-02-27 21:01:18 +00:00
|
|
|
CU_ASSERT(pbdev->strip_size == ((r->strip_size_kb * 1024) / g_block_len));
|
|
|
|
CU_ASSERT(pbdev->strip_size_shift == spdk_u32log2(((r->strip_size_kb * 1024) / g_block_len)));
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_ASSERT(pbdev->blocklen_shift == spdk_u32log2(g_block_len));
|
|
|
|
CU_ASSERT(pbdev->state == raid_state);
|
|
|
|
CU_ASSERT(pbdev->num_base_bdevs == r->base_bdevs.num_base_bdevs);
|
|
|
|
CU_ASSERT(pbdev->num_base_bdevs_discovered == r->base_bdevs.num_base_bdevs);
|
|
|
|
CU_ASSERT(pbdev->raid_level == r->raid_level);
|
|
|
|
CU_ASSERT(pbdev->destruct_called == false);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < pbdev->num_base_bdevs; i++) {
|
2018-08-20 23:01:56 +00:00
|
|
|
if (pbdev->base_bdev_info && pbdev->base_bdev_info[i].bdev) {
|
|
|
|
bdev = spdk_bdev_get_by_name(pbdev->base_bdev_info[i].bdev->name);
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_ASSERT(bdev != NULL);
|
2018-08-20 23:01:56 +00:00
|
|
|
CU_ASSERT(pbdev->base_bdev_info[i].remove_scheduled == false);
|
2018-05-08 11:30:29 +00:00
|
|
|
} else {
|
|
|
|
CU_ASSERT(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bdev && bdev->blockcnt < min_blockcnt) {
|
|
|
|
min_blockcnt = bdev->blockcnt;
|
|
|
|
}
|
|
|
|
}
|
2019-02-27 21:01:18 +00:00
|
|
|
CU_ASSERT((((min_blockcnt / (r->strip_size_kb * 1024 / g_block_len)) * (r->strip_size_kb * 1024 /
|
2018-07-31 00:14:18 +00:00
|
|
|
g_block_len)) * r->base_bdevs.num_base_bdevs) == pbdev->bdev.blockcnt);
|
|
|
|
CU_ASSERT(strcmp(pbdev->bdev.product_name, "Pooled Device") == 0);
|
|
|
|
CU_ASSERT(pbdev->bdev.write_cache == 0);
|
|
|
|
CU_ASSERT(pbdev->bdev.blocklen == g_block_len);
|
2018-09-14 02:32:30 +00:00
|
|
|
if (pbdev->num_base_bdevs > 1) {
|
|
|
|
CU_ASSERT(pbdev->bdev.optimal_io_boundary == pbdev->strip_size);
|
|
|
|
CU_ASSERT(pbdev->bdev.split_on_optimal_io_boundary == true);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(pbdev->bdev.optimal_io_boundary == 0);
|
|
|
|
CU_ASSERT(pbdev->bdev.split_on_optimal_io_boundary == false);
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev->bdev.ctxt == pbdev);
|
|
|
|
CU_ASSERT(pbdev->bdev.fn_table == &g_raid_bdev_fn_table);
|
|
|
|
CU_ASSERT(pbdev->bdev.module == &g_raid_if);
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (presence == true) {
|
|
|
|
CU_ASSERT(pbdev_found == true);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(pbdev_found == false);
|
|
|
|
}
|
|
|
|
pbdev_found = false;
|
|
|
|
if (raid_state == RAID_BDEV_STATE_ONLINE) {
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_configured_list, state_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, r->name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
pbdev_found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (raid_state == RAID_BDEV_STATE_CONFIGURING) {
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_configuring_list, state_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, r->name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
pbdev_found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (raid_state == RAID_BDEV_STATE_OFFLINE) {
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_offline_list, state_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, r->name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
pbdev_found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (presence == true) {
|
|
|
|
CU_ASSERT(pbdev_found == true);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(pbdev_found == false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
|
|
|
|
struct spdk_bdev_io_wait_entry *entry)
|
|
|
|
{
|
|
|
|
CU_ASSERT(bdev == entry->bdev);
|
|
|
|
CU_ASSERT(entry->cb_fn != NULL);
|
|
|
|
CU_ASSERT(entry->cb_arg != NULL);
|
|
|
|
TAILQ_INSERT_TAIL(&g_io_waitq, entry, link);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t
|
|
|
|
get_num_elts_in_waitq(void)
|
|
|
|
{
|
|
|
|
struct spdk_bdev_io_wait_entry *ele;
|
|
|
|
uint32_t count = 0;
|
|
|
|
|
|
|
|
TAILQ_FOREACH(ele, &g_io_waitq, link) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
process_io_waitq(void)
|
|
|
|
{
|
|
|
|
struct spdk_bdev_io_wait_entry *ele;
|
|
|
|
struct spdk_bdev_io_wait_entry *next_ele;
|
|
|
|
|
|
|
|
TAILQ_FOREACH_SAFE(ele, &g_io_waitq, link, next_ele) {
|
|
|
|
TAILQ_REMOVE(&g_io_waitq, ele, link);
|
|
|
|
ele->cb_fn(ele->cb_arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
verify_get_raids(struct rpc_construct_raid_bdev *construct_req,
|
|
|
|
uint8_t g_max_raids,
|
|
|
|
char **g_get_raids_output, uint32_t g_get_raids_count)
|
|
|
|
{
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i, j;
|
2018-05-08 11:30:29 +00:00
|
|
|
bool found;
|
|
|
|
|
|
|
|
CU_ASSERT(g_max_raids == g_get_raids_count);
|
|
|
|
if (g_max_raids == g_get_raids_count) {
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
2018-05-08 11:30:29 +00:00
|
|
|
found = false;
|
2018-07-23 06:03:28 +00:00
|
|
|
for (j = 0; j < g_max_raids; j++) {
|
|
|
|
if (construct_req[i].name && strcmp(construct_req[i].name, g_get_raids_output[i]) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CU_ASSERT(found == true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
create_base_bdevs(uint32_t bbdev_start_idx)
|
|
|
|
{
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
struct spdk_bdev *base_bdev;
|
|
|
|
char name[16];
|
|
|
|
uint16_t num_chars;
|
|
|
|
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_base_drives; i++, bbdev_start_idx++) {
|
2018-05-08 11:30:29 +00:00
|
|
|
num_chars = snprintf(name, 16, "%s%u%s", "Nvme", bbdev_start_idx, "n1");
|
|
|
|
name[num_chars] = '\0';
|
|
|
|
base_bdev = calloc(1, sizeof(struct spdk_bdev));
|
|
|
|
SPDK_CU_ASSERT_FATAL(base_bdev != NULL);
|
|
|
|
base_bdev->name = strdup(name);
|
|
|
|
SPDK_CU_ASSERT_FATAL(base_bdev->name != NULL);
|
|
|
|
base_bdev->blocklen = g_block_len;
|
|
|
|
base_bdev->blockcnt = (uint64_t)1024 * 1024 * 1024 * 1024;
|
|
|
|
TAILQ_INSERT_TAIL(&g_bdev_list, base_bdev, internal.link);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
create_test_req(struct rpc_construct_raid_bdev *r, const char *raid_name, uint32_t bbdev_start_idx,
|
|
|
|
bool create_base_bdev)
|
|
|
|
{
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
char name[16];
|
|
|
|
uint16_t num_chars;
|
|
|
|
uint32_t bbdev_idx = bbdev_start_idx;
|
|
|
|
|
|
|
|
r->name = strdup(raid_name);
|
|
|
|
SPDK_CU_ASSERT_FATAL(r->name != NULL);
|
2019-02-27 21:01:18 +00:00
|
|
|
r->strip_size_kb = (g_strip_size * g_block_len) / 1024;
|
2018-05-08 11:30:29 +00:00
|
|
|
r->raid_level = 0;
|
|
|
|
r->base_bdevs.num_base_bdevs = g_max_base_drives;
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_base_drives; i++, bbdev_idx++) {
|
2018-05-08 11:30:29 +00:00
|
|
|
num_chars = snprintf(name, 16, "%s%u%s", "Nvme", bbdev_idx, "n1");
|
|
|
|
name[num_chars] = '\0';
|
2018-07-23 06:03:28 +00:00
|
|
|
r->base_bdevs.base_bdevs[i] = strdup(name);
|
|
|
|
SPDK_CU_ASSERT_FATAL(r->base_bdevs.base_bdevs[i] != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
if (create_base_bdev == true) {
|
|
|
|
create_base_bdevs(bbdev_start_idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_test_req(struct rpc_construct_raid_bdev *r)
|
|
|
|
{
|
2018-07-23 06:03:28 +00:00
|
|
|
uint8_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
free(r->name);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < r->base_bdevs.num_base_bdevs; i++) {
|
|
|
|
free(r->base_bdevs.base_bdevs[i]);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_construct_raid(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_destroy_raid(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev construct_req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&construct_req, "raid1", 0, true);
|
|
|
|
rpc_req = &construct_req;
|
|
|
|
rpc_req_size = sizeof(construct_req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(construct_req.name, false);
|
|
|
|
verify_raid_bdev_present(construct_req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&construct_req, true);
|
|
|
|
verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&construct_req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_construct_raid_invalid_args(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
bdev/raid: Change construct_raid_bdev RPC to be consistent to other bdev modules
Change the behavior of construct_raid_bdev RPC to be consistent with
other bdev modules.
Create a config of raid bdev first. Then create a raid bdev based
on the config.
If both succeed, the config and the raid bdev are not removed even if
any failure occur later in construct_raid_bdev RPC. Otherwise, both
are removed and return failure.
During iteration of adding base bdevs in construct_raid_bdev RPC,
- skip any nonexistent bdev and move to the next base bdev.
- if adding any base bdev fails, move to the next bdev.
- if adding base bdevs don't fail but any base bdev doesn't exist,
the raid bdev is in the configuring state and return success.
- if adding base bdev fails, the raid bdev is in the configuring state
and return failure.
- if all adding base bdevs succeed, configure the raid bdev. If configuring
the raid bdev fails, move the raid bdev to the offline state and return
failure. If configuring the raid bdev succeed, return success.
check_and_remove_raid_bdev() becomes unused in raid_bdev_rpc.c but
is still necessary in UT. Hence move this function to UT.
In UT, finding a raid bdev config by name becomes necessary. Hence
factor out the iteration to a function and use the function in UT.
Change-Id: Ifa36967bdc987d97030e3a4e36684cb37b329d4e
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/423622
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Kunal Sablok <kunal.sablok@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2018-08-31 00:58:25 +00:00
|
|
|
struct raid_bdev_config *raid_cfg;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
set_globals();
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
req.raid_level = 1;
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_err = 1;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
|
|
|
g_json_decode_obj_err = 0;
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
2019-02-27 21:01:18 +00:00
|
|
|
req.strip_size_kb = 1231;
|
2018-05-08 11:30:29 +00:00
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
create_test_req(&req, "raid2", 0, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present("raid2", false);
|
|
|
|
verify_raid_bdev_present("raid2", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid2", g_max_base_drives, true);
|
|
|
|
free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
|
|
|
|
req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme0n1");
|
|
|
|
SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present("raid2", false);
|
|
|
|
verify_raid_bdev_present("raid2", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid2", g_max_base_drives, true);
|
|
|
|
free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
|
|
|
|
req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme100000n1");
|
|
|
|
SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
bdev/raid: Change construct_raid_bdev RPC to be consistent to other bdev modules
Change the behavior of construct_raid_bdev RPC to be consistent with
other bdev modules.
Create a config of raid bdev first. Then create a raid bdev based
on the config.
If both succeed, the config and the raid bdev are not removed even if
any failure occur later in construct_raid_bdev RPC. Otherwise, both
are removed and return failure.
During iteration of adding base bdevs in construct_raid_bdev RPC,
- skip any nonexistent bdev and move to the next base bdev.
- if adding any base bdev fails, move to the next bdev.
- if adding base bdevs don't fail but any base bdev doesn't exist,
the raid bdev is in the configuring state and return success.
- if adding base bdev fails, the raid bdev is in the configuring state
and return failure.
- if all adding base bdevs succeed, configure the raid bdev. If configuring
the raid bdev fails, move the raid bdev to the offline state and return
failure. If configuring the raid bdev succeed, return success.
check_and_remove_raid_bdev() becomes unused in raid_bdev_rpc.c but
is still necessary in UT. Hence move this function to UT.
In UT, finding a raid bdev config by name becomes necessary. Hence
factor out the iteration to a function and use the function in UT.
Change-Id: Ifa36967bdc987d97030e3a4e36684cb37b329d4e
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/423622
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Kunal Sablok <kunal.sablok@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2018-08-31 00:58:25 +00:00
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
bdev/raid: Change construct_raid_bdev RPC to be consistent to other bdev modules
Change the behavior of construct_raid_bdev RPC to be consistent with
other bdev modules.
Create a config of raid bdev first. Then create a raid bdev based
on the config.
If both succeed, the config and the raid bdev are not removed even if
any failure occur later in construct_raid_bdev RPC. Otherwise, both
are removed and return failure.
During iteration of adding base bdevs in construct_raid_bdev RPC,
- skip any nonexistent bdev and move to the next base bdev.
- if adding any base bdev fails, move to the next bdev.
- if adding base bdevs don't fail but any base bdev doesn't exist,
the raid bdev is in the configuring state and return success.
- if adding base bdev fails, the raid bdev is in the configuring state
and return failure.
- if all adding base bdevs succeed, configure the raid bdev. If configuring
the raid bdev fails, move the raid bdev to the offline state and return
failure. If configuring the raid bdev succeed, return success.
check_and_remove_raid_bdev() becomes unused in raid_bdev_rpc.c but
is still necessary in UT. Hence move this function to UT.
In UT, finding a raid bdev config by name becomes necessary. Hence
factor out the iteration to a function and use the function in UT.
Change-Id: Ifa36967bdc987d97030e3a4e36684cb37b329d4e
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/423622
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Kunal Sablok <kunal.sablok@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2018-08-31 00:58:25 +00:00
|
|
|
verify_raid_config_present("raid2", true);
|
|
|
|
verify_raid_bdev_present("raid2", true);
|
|
|
|
raid_cfg = raid_bdev_config_find_by_name("raid2");
|
|
|
|
SPDK_CU_ASSERT_FATAL(raid_cfg != NULL);
|
|
|
|
check_and_remove_raid_bdev(raid_cfg);
|
|
|
|
raid_bdev_config_cleanup(raid_cfg);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
create_test_req(&req, "raid2", g_max_base_drives, false);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_beg_res_ret_err = 1;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present("raid2", true);
|
|
|
|
verify_raid_bdev_present("raid2", true);
|
|
|
|
verify_raid_config_present("raid1", true);
|
|
|
|
verify_raid_bdev_present("raid1", true);
|
|
|
|
g_json_beg_res_ret_err = 0;
|
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
destroy_req.name = strdup("raid2");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_destroy_raid_invalid_args(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev construct_req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&construct_req, "raid1", 0, true);
|
|
|
|
rpc_req = &construct_req;
|
|
|
|
rpc_req_size = sizeof(construct_req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(construct_req.name, false);
|
|
|
|
verify_raid_bdev_present(construct_req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&construct_req, true);
|
|
|
|
verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&construct_req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
destroy_req.name = strdup("raid2");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_err = 1;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
|
|
|
g_json_decode_obj_err = 0;
|
|
|
|
g_rpc_err = 0;
|
|
|
|
free(destroy_req.name);
|
|
|
|
verify_raid_config_present("raid1", true);
|
|
|
|
verify_raid_bdev_present("raid1", true);
|
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_io_channel(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
|
|
|
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
ch_ctx = calloc(1, sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel && ch_ctx->base_channel[i] == (void *)0x1);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
free(ch_ctx);
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_write_io(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
uint32_t count;
|
|
|
|
uint64_t io_len;
|
|
|
|
uint64_t lba;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
ch_ctx = spdk_io_channel_get_ctx(ch);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel && ch_ctx->base_channel[i] == (void *)0x1);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
lba = 0;
|
|
|
|
for (count = 0; count < g_max_qd; count++) {
|
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
2018-08-23 19:50:53 +00:00
|
|
|
io_len = (rand() % g_strip_size) + 1;
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_WRITE);
|
2018-08-23 19:50:53 +00:00
|
|
|
lba += g_strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
memset(g_io_output, 0, (g_max_io_size / g_strip_size) + 1 * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
2018-07-31 00:14:18 +00:00
|
|
|
verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
|
2018-05-08 11:30:29 +00:00
|
|
|
g_child_io_status_flag);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
free(ch);
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_read_io(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
uint32_t count;
|
|
|
|
uint64_t io_len;
|
|
|
|
uint64_t lba;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
ch_ctx = spdk_io_channel_get_ctx(ch);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel && ch_ctx->base_channel[i] == (void *)0x1);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
lba = 0;
|
|
|
|
for (count = 0; count < g_max_qd; count++) {
|
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
2018-08-23 19:50:53 +00:00
|
|
|
io_len = (rand() % g_strip_size) + 1;
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_READ);
|
2018-08-23 19:50:53 +00:00
|
|
|
lba += g_strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
memset(g_io_output, 0, (g_max_io_size / g_strip_size) + 1 * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
2018-07-31 00:14:18 +00:00
|
|
|
verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
|
2018-05-08 11:30:29 +00:00
|
|
|
g_child_io_status_flag);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
free(ch);
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
2019-01-21 13:34:21 +00:00
|
|
|
static void
|
|
|
|
raid_bdev_io_generate_by_strips(uint64_t n_strips)
|
|
|
|
{
|
|
|
|
uint64_t lba;
|
|
|
|
uint64_t nblocks;
|
|
|
|
uint64_t start_offset;
|
|
|
|
uint64_t end_offset;
|
|
|
|
uint64_t offsets_in_strip[3];
|
|
|
|
uint64_t start_bdev_idx;
|
|
|
|
uint64_t start_bdev_offset;
|
|
|
|
uint64_t start_bdev_idxs[3];
|
|
|
|
int i, j, l;
|
|
|
|
|
|
|
|
/* 3 different situations of offset in strip */
|
|
|
|
offsets_in_strip[0] = 0;
|
|
|
|
offsets_in_strip[1] = g_strip_size >> 1;
|
|
|
|
offsets_in_strip[2] = g_strip_size - 1;
|
|
|
|
|
|
|
|
/* 3 different situations of start_bdev_idx */
|
|
|
|
start_bdev_idxs[0] = 0;
|
|
|
|
start_bdev_idxs[1] = g_max_base_drives >> 1;
|
|
|
|
start_bdev_idxs[2] = g_max_base_drives - 1;
|
|
|
|
|
|
|
|
/* consider different offset in strip */
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
start_offset = offsets_in_strip[i];
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
|
|
end_offset = offsets_in_strip[j];
|
|
|
|
if (n_strips == 1 && start_offset > end_offset) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* consider at which base_bdev lba is started. */
|
|
|
|
for (l = 0; l < 3; l++) {
|
|
|
|
start_bdev_idx = start_bdev_idxs[l];
|
|
|
|
start_bdev_offset = start_bdev_idx * g_strip_size;
|
|
|
|
lba = g_lba_offset + start_bdev_offset + start_offset;
|
|
|
|
nblocks = (n_strips - 1) * g_strip_size + end_offset - start_offset + 1;
|
|
|
|
|
|
|
|
g_io_ranges[g_io_range_idx].lba = lba;
|
|
|
|
g_io_ranges[g_io_range_idx].nblocks = nblocks;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(g_io_range_idx < MAX_TEST_IO_RANGE);
|
|
|
|
g_io_range_idx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
raid_bdev_io_generate(void)
|
|
|
|
{
|
|
|
|
uint64_t n_strips;
|
|
|
|
uint64_t n_strips_span = g_max_base_drives;
|
|
|
|
uint64_t n_strips_times[5] = {g_max_base_drives + 1, g_max_base_drives * 2 - 1, g_max_base_drives * 2,
|
|
|
|
g_max_base_drives * 3, g_max_base_drives * 4
|
|
|
|
};
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
g_io_range_idx = 0;
|
|
|
|
|
|
|
|
/* consider different number of strips from 1 to strips spanned base bdevs,
|
|
|
|
* and even to times of strips spanned base bdevs
|
|
|
|
*/
|
|
|
|
for (n_strips = 1; n_strips < n_strips_span; n_strips++) {
|
|
|
|
raid_bdev_io_generate_by_strips(n_strips);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < SPDK_COUNTOF(n_strips_times); i++) {
|
|
|
|
n_strips = n_strips_times[i];
|
|
|
|
raid_bdev_io_generate_by_strips(n_strips);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_unmap_io(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
|
|
|
uint32_t i;
|
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
uint32_t count;
|
|
|
|
uint64_t io_len;
|
|
|
|
uint64_t lba;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_construct = 1;
|
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2019-01-21 13:34:21 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CU_ASSERT(pbdev != NULL);
|
|
|
|
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
ch_ctx = spdk_io_channel_get_ctx(ch);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx->base_channel && ch_ctx->base_channel[i] == (void *)0x1);
|
|
|
|
}
|
|
|
|
|
|
|
|
CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_UNMAP) == true);
|
2019-02-28 12:16:30 +00:00
|
|
|
CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_FLUSH) == true);
|
2019-01-21 13:34:21 +00:00
|
|
|
|
|
|
|
raid_bdev_io_generate();
|
|
|
|
for (count = 0; count < g_io_range_idx; count++) {
|
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
|
|
|
io_len = g_io_ranges[count].nblocks;
|
|
|
|
lba = g_io_ranges[count].lba;
|
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_UNMAP);
|
|
|
|
memset(g_io_output, 0, g_max_base_drives * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
|
|
|
verify_io_without_payload(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
|
|
|
|
g_child_io_status_flag);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
free_test_req(&req);
|
|
|
|
|
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
|
|
|
free(ch);
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_construct = 0;
|
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* Test IO failures */
|
|
|
|
static void
|
|
|
|
test_io_failure(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
uint32_t count;
|
|
|
|
uint64_t io_len;
|
|
|
|
uint64_t lba;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
ch_ctx = spdk_io_channel_get_ctx(ch);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel && ch_ctx->base_channel[i] == (void *)0x1);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
lba = 0;
|
|
|
|
for (count = 0; count < 1; count++) {
|
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
2018-08-23 19:50:53 +00:00
|
|
|
io_len = (rand() % g_strip_size) + 1;
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_INVALID);
|
2018-08-23 19:50:53 +00:00
|
|
|
lba += g_strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
memset(g_io_output, 0, (g_max_io_size / g_strip_size) + 1 * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
2018-07-31 00:14:18 +00:00
|
|
|
verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
|
2018-05-08 11:30:29 +00:00
|
|
|
INVALID_IO_SUBMIT);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lba = 0;
|
|
|
|
g_child_io_status_flag = false;
|
|
|
|
for (count = 0; count < 1; count++) {
|
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
2018-08-23 19:50:53 +00:00
|
|
|
io_len = (rand() % g_strip_size) + 1;
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, io_len, SPDK_BDEV_IO_TYPE_WRITE);
|
2018-08-23 19:50:53 +00:00
|
|
|
lba += g_strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
memset(g_io_output, 0, (g_max_io_size / g_strip_size) + 1 * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
2018-07-31 00:14:18 +00:00
|
|
|
verify_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
|
2018-05-08 11:30:29 +00:00
|
|
|
g_child_io_status_flag);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
free(ch);
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
2019-01-21 13:09:15 +00:00
|
|
|
/* Test reset IO */
|
|
|
|
static void
|
|
|
|
test_reset_io(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
|
|
|
uint32_t i;
|
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_construct = 1;
|
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2019-01-21 13:09:15 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CU_ASSERT(pbdev != NULL);
|
|
|
|
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
ch_ctx = spdk_io_channel_get_ctx(ch);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
|
|
|
CU_ASSERT(ch_ctx->base_channel && ch_ctx->base_channel[i] == (void *)0x1);
|
|
|
|
}
|
|
|
|
free_test_req(&req);
|
|
|
|
|
|
|
|
g_bdev_io_submit_status = 0;
|
|
|
|
g_child_io_status_flag = true;
|
|
|
|
|
2019-02-28 12:16:30 +00:00
|
|
|
CU_ASSERT(raid_bdev_io_type_supported(pbdev, SPDK_BDEV_IO_TYPE_RESET) == true);
|
|
|
|
|
2019-01-21 13:09:15 +00:00
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, 0, 1, SPDK_BDEV_IO_TYPE_RESET);
|
|
|
|
memset(g_io_output, 0, g_max_base_drives * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
|
|
|
verify_reset_io(bdev_io, req.base_bdevs.num_base_bdevs, ch_ctx, pbdev,
|
|
|
|
true);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
|
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
|
|
|
free(ch);
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_construct = 0;
|
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* Test waitq logic */
|
|
|
|
static void
|
|
|
|
test_io_waitq(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
struct spdk_bdev_io *bdev_io_next;
|
|
|
|
uint32_t count;
|
|
|
|
uint64_t lba;
|
|
|
|
TAILQ_HEAD(, spdk_bdev_io) head_io;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
SPDK_CU_ASSERT_FATAL(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
ch_ctx = spdk_io_channel_get_ctx(ch);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
2018-08-21 03:57:26 +00:00
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx->base_channel != NULL);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < req.base_bdevs.num_base_bdevs; i++) {
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel[i] == (void *)0x1);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
lba = 0;
|
|
|
|
TAILQ_INIT(&head_io);
|
2019-03-15 14:49:24 +00:00
|
|
|
for (count = 0; count < 128; count++) {
|
2018-05-08 11:30:29 +00:00
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
|
|
|
TAILQ_INSERT_TAIL(&head_io, bdev_io, module_link);
|
2019-03-15 14:49:24 +00:00
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, 8, SPDK_BDEV_IO_TYPE_WRITE);
|
2018-05-08 11:30:29 +00:00
|
|
|
g_bdev_io_submit_status = -ENOMEM;
|
2018-08-23 19:50:53 +00:00
|
|
|
lba += g_strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
raid_bdev_submit_request(ch, bdev_io);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_ignore_io_output = 1;
|
|
|
|
|
|
|
|
count = get_num_elts_in_waitq();
|
2019-03-15 14:49:24 +00:00
|
|
|
CU_ASSERT(count == 128);
|
2018-05-08 11:30:29 +00:00
|
|
|
g_bdev_io_submit_status = 0;
|
|
|
|
process_io_waitq();
|
|
|
|
CU_ASSERT(TAILQ_EMPTY(&g_io_waitq));
|
|
|
|
|
|
|
|
TAILQ_FOREACH_SAFE(bdev_io, &head_io, module_link, bdev_io_next) {
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
g_ignore_io_output = 0;
|
|
|
|
free(ch);
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create multiple raids, destroy raids without IO, get_raids related tests */
|
|
|
|
static void
|
|
|
|
test_multi_raid_no_io(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev *construct_req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct rpc_get_raid_bdevs get_raids_req;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
char name[16];
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t bbdev_idx = 0;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
construct_req = calloc(MAX_RAIDS, sizeof(struct rpc_construct_raid_bdev));
|
|
|
|
SPDK_CU_ASSERT_FATAL(construct_req != NULL);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
|
|
|
count = snprintf(name, 16, "%s%u", "raid", i);
|
2018-05-08 11:30:29 +00:00
|
|
|
name[count] = '\0';
|
2018-07-23 06:03:28 +00:00
|
|
|
create_test_req(&construct_req[i], name, bbdev_idx, true);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present(name, false);
|
|
|
|
verify_raid_bdev_present(name, false);
|
|
|
|
bbdev_idx += g_max_base_drives;
|
2018-07-23 06:03:28 +00:00
|
|
|
rpc_req = &construct_req[i];
|
2018-05-08 11:30:29 +00:00
|
|
|
rpc_req_size = sizeof(construct_req[0]);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
verify_raid_config(&construct_req[i], true);
|
|
|
|
verify_raid_bdev(&construct_req[i], true, RAID_BDEV_STATE_ONLINE);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("all");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_test_multi_raids = 1;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_get_raids_count; i++) {
|
|
|
|
free(g_get_raids_output[i]);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
g_get_raids_count = 0;
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("online");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_get_raids(construct_req, g_max_raids, g_get_raids_output, g_get_raids_count);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_get_raids_count; i++) {
|
|
|
|
free(g_get_raids_output[i]);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
g_get_raids_count = 0;
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("configuring");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
CU_ASSERT(g_get_raids_count == 0);
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("offline");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
CU_ASSERT(g_get_raids_count == 0);
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("invalid_category");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
|
|
|
CU_ASSERT(g_get_raids_count == 0);
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("all");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_decode_obj_err = 1;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 1);
|
|
|
|
g_json_decode_obj_err = 0;
|
|
|
|
free(get_raids_req.category);
|
|
|
|
CU_ASSERT(g_get_raids_count == 0);
|
|
|
|
|
|
|
|
get_raids_req.category = strdup("all");
|
|
|
|
rpc_req = &get_raids_req;
|
|
|
|
rpc_req_size = sizeof(get_raids_req);
|
|
|
|
g_rpc_err = 0;
|
|
|
|
g_json_beg_res_ret_err = 1;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_get_raid_bdevs(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
g_json_beg_res_ret_err = 0;
|
|
|
|
CU_ASSERT(g_get_raids_count == 0);
|
|
|
|
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
|
|
|
SPDK_CU_ASSERT_FATAL(construct_req[i].name != NULL);
|
|
|
|
destroy_req.name = strdup(construct_req[i].name);
|
2018-05-08 11:30:29 +00:00
|
|
|
count = snprintf(name, 16, "%s", destroy_req.name);
|
|
|
|
name[count] = '\0';
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present(name, false);
|
|
|
|
verify_raid_bdev_present(name, false);
|
|
|
|
}
|
|
|
|
g_test_multi_raids = 0;
|
|
|
|
raid_bdev_exit();
|
2018-07-24 23:49:05 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
|
|
|
free_test_req(&construct_req[i]);
|
|
|
|
}
|
2018-05-08 11:30:29 +00:00
|
|
|
free(construct_req);
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create multiple raids, fire IOs randomly on various raids */
|
|
|
|
static void
|
|
|
|
test_multi_raid_with_io(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev *construct_req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i, j;
|
2018-05-08 11:30:29 +00:00
|
|
|
char name[16];
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t bbdev_idx = 0;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
struct spdk_io_channel *ch;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx;
|
|
|
|
struct spdk_bdev_io *bdev_io;
|
|
|
|
uint64_t io_len;
|
|
|
|
uint64_t lba;
|
|
|
|
struct spdk_io_channel *ch_random;
|
|
|
|
struct raid_bdev_io_channel *ch_ctx_random;
|
|
|
|
int16_t iotype;
|
|
|
|
uint32_t raid_random;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
construct_req = calloc(g_max_raids, sizeof(struct rpc_construct_raid_bdev));
|
|
|
|
SPDK_CU_ASSERT_FATAL(construct_req != NULL);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
ch = calloc(g_max_raids, sizeof(struct spdk_io_channel) + sizeof(struct raid_bdev_io_channel));
|
|
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
|
|
|
count = snprintf(name, 16, "%s%u", "raid", i);
|
2018-05-08 11:30:29 +00:00
|
|
|
name[count] = '\0';
|
2018-07-23 06:03:28 +00:00
|
|
|
create_test_req(&construct_req[i], name, bbdev_idx, true);
|
2018-05-08 11:30:29 +00:00
|
|
|
verify_raid_config_present(name, false);
|
|
|
|
verify_raid_bdev_present(name, false);
|
|
|
|
bbdev_idx += g_max_base_drives;
|
2018-07-23 06:03:28 +00:00
|
|
|
rpc_req = &construct_req[i];
|
2018-05-08 11:30:29 +00:00
|
|
|
rpc_req_size = sizeof(construct_req[0]);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
2018-07-23 06:03:28 +00:00
|
|
|
verify_raid_config(&construct_req[i], true);
|
|
|
|
verify_raid_bdev(&construct_req[i], true, RAID_BDEV_STATE_ONLINE);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, construct_req[i].name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-07-23 06:03:28 +00:00
|
|
|
ch_ctx = spdk_io_channel_get_ctx(&ch[i]);
|
2018-05-08 11:30:29 +00:00
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_create_cb(pbdev, ch_ctx) == 0);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel != NULL);
|
2018-07-23 06:03:28 +00:00
|
|
|
for (j = 0; j < construct_req[i].base_bdevs.num_base_bdevs; j++) {
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel[j] == (void *)0x1);
|
2018-05-08 11:30:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lba = 0;
|
|
|
|
for (count = 0; count < g_max_qd; count++) {
|
|
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
2018-08-23 19:50:53 +00:00
|
|
|
io_len = (rand() % g_strip_size) + 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
iotype = (rand() % 2) ? SPDK_BDEV_IO_TYPE_WRITE : SPDK_BDEV_IO_TYPE_READ;
|
|
|
|
memset(g_io_output, 0, (g_max_io_size / g_strip_size) + 1 * sizeof(struct io_output));
|
|
|
|
g_io_output_index = 0;
|
|
|
|
raid_random = rand() % g_max_raids;
|
|
|
|
ch_random = &ch[raid_random];
|
|
|
|
ch_ctx_random = spdk_io_channel_get_ctx(ch_random);
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, construct_req[raid_random].name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-08-03 04:06:29 +00:00
|
|
|
bdev_io_initialize(bdev_io, &pbdev->bdev, lba, io_len, iotype);
|
2018-08-23 19:50:53 +00:00
|
|
|
lba += g_strip_size;
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
raid_bdev_submit_request(ch_random, bdev_io);
|
2018-07-31 00:14:18 +00:00
|
|
|
verify_io(bdev_io, g_max_base_drives, ch_ctx_random, pbdev,
|
2018-05-08 11:30:29 +00:00
|
|
|
g_child_io_status_flag);
|
|
|
|
bdev_io_cleanup(bdev_io);
|
|
|
|
free(bdev_io);
|
|
|
|
}
|
|
|
|
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, construct_req[i].name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-07-23 06:03:28 +00:00
|
|
|
ch_ctx = spdk_io_channel_get_ctx(&ch[i]);
|
2018-05-08 11:30:29 +00:00
|
|
|
SPDK_CU_ASSERT_FATAL(ch_ctx != NULL);
|
2018-07-31 00:14:18 +00:00
|
|
|
raid_bdev_destroy_cb(pbdev, ch_ctx);
|
2018-08-21 03:57:26 +00:00
|
|
|
CU_ASSERT(ch_ctx->base_channel == NULL);
|
2018-07-23 06:03:28 +00:00
|
|
|
destroy_req.name = strdup(construct_req[i].name);
|
2018-05-08 11:30:29 +00:00
|
|
|
count = snprintf(name, 16, "%s", destroy_req.name);
|
|
|
|
name[count] = '\0';
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present(name, false);
|
|
|
|
verify_raid_bdev_present(name, false);
|
|
|
|
}
|
|
|
|
raid_bdev_exit();
|
2018-07-24 23:49:05 +00:00
|
|
|
for (i = 0; i < g_max_raids; i++) {
|
|
|
|
free_test_req(&construct_req[i]);
|
|
|
|
}
|
2018-05-08 11:30:29 +00:00
|
|
|
free(construct_req);
|
|
|
|
free(ch);
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_io_type_supported(void)
|
|
|
|
{
|
|
|
|
CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_READ) == true);
|
|
|
|
CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_WRITE) == true);
|
|
|
|
CU_ASSERT(raid_bdev_io_type_supported(NULL, SPDK_BDEV_IO_TYPE_INVALID) == false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_create_raid_from_config(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct spdk_bdev *bdev;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
2018-08-28 01:13:38 +00:00
|
|
|
bool can_claim;
|
|
|
|
struct raid_bdev_config *raid_cfg;
|
|
|
|
uint32_t base_bdev_slot;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
g_config_level_create = 1;
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
g_config_level_create = 0;
|
|
|
|
|
|
|
|
verify_raid_config_present("raid1", true);
|
2018-08-31 00:25:37 +00:00
|
|
|
verify_raid_bdev_present("raid1", true);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
TAILQ_FOREACH(bdev, &g_bdev_list, internal.link) {
|
|
|
|
raid_bdev_examine(bdev);
|
|
|
|
}
|
|
|
|
|
2018-08-28 01:13:38 +00:00
|
|
|
can_claim = raid_bdev_can_claim_bdev("Invalid", &raid_cfg, &base_bdev_slot);
|
|
|
|
CU_ASSERT(can_claim == false);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
verify_raid_config(&req, true);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
free_test_req(&req);
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_create_raid_from_config_invalid_params(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
uint8_t count;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
g_config_level_create = 1;
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
free(req.name);
|
|
|
|
req.name = NULL;
|
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
2019-02-27 21:01:18 +00:00
|
|
|
req.strip_size_kb = 1234;
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
req.raid_level = 1;
|
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
req.raid_level = 1;
|
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
req.base_bdevs.num_base_bdevs++;
|
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
req.base_bdevs.num_base_bdevs--;
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
req.base_bdevs.num_base_bdevs--;
|
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
req.base_bdevs.num_base_bdevs++;
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
if (g_max_base_drives > 1) {
|
|
|
|
create_test_req(&req, "raid1", 0, false);
|
|
|
|
count = snprintf(req.base_bdevs.base_bdevs[g_max_base_drives - 1], 15, "%s", "Nvme0n1");
|
|
|
|
req.base_bdevs.base_bdevs[g_max_base_drives - 1][count] = '\0';
|
|
|
|
CU_ASSERT(raid_bdev_init() != 0);
|
|
|
|
free_test_req(&req);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_raid_json_dump_info(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct raid_bdev *pbdev;
|
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&req, "raid1", 0, true);
|
|
|
|
rpc_req = &req;
|
|
|
|
rpc_req_size = sizeof(req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
|
|
|
|
verify_raid_config_present(req.name, false);
|
|
|
|
verify_raid_bdev_present(req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
|
|
|
|
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_FOREACH(pbdev, &g_raid_bdev_list, global_link) {
|
2018-07-31 00:14:18 +00:00
|
|
|
if (strcmp(pbdev->bdev.name, req.name) == 0) {
|
2018-05-08 11:30:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(pbdev != NULL);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2018-07-31 00:14:18 +00:00
|
|
|
CU_ASSERT(raid_bdev_dump_info_json(pbdev, NULL) == 0);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&req);
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_context_size(void)
|
|
|
|
{
|
|
|
|
CU_ASSERT(raid_bdev_get_ctx_size() == sizeof(struct raid_bdev_io));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_asym_base_drives_blockcnt(void)
|
|
|
|
{
|
|
|
|
struct rpc_construct_raid_bdev construct_req;
|
|
|
|
struct rpc_destroy_raid_bdev destroy_req;
|
|
|
|
struct spdk_bdev *bbdev;
|
2018-07-23 06:03:28 +00:00
|
|
|
uint32_t i;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
set_globals();
|
|
|
|
create_test_req(&construct_req, "raid1", 0, true);
|
|
|
|
rpc_req = &construct_req;
|
|
|
|
rpc_req_size = sizeof(construct_req);
|
|
|
|
CU_ASSERT(raid_bdev_init() == 0);
|
|
|
|
verify_raid_config_present(construct_req.name, false);
|
|
|
|
verify_raid_bdev_present(construct_req.name, false);
|
|
|
|
g_rpc_err = 0;
|
2018-07-23 06:03:28 +00:00
|
|
|
for (i = 0; i < construct_req.base_bdevs.num_base_bdevs; i++) {
|
|
|
|
bbdev = spdk_bdev_get_by_name(construct_req.base_bdevs.base_bdevs[i]);
|
2018-05-08 11:30:29 +00:00
|
|
|
SPDK_CU_ASSERT_FATAL(bbdev != NULL);
|
|
|
|
bbdev->blockcnt = rand() + 1;
|
|
|
|
}
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 1;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_construct_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config(&construct_req, true);
|
|
|
|
verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
|
2018-07-24 23:49:05 +00:00
|
|
|
free_test_req(&construct_req);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
destroy_req.name = strdup("raid1");
|
|
|
|
rpc_req = &destroy_req;
|
|
|
|
rpc_req_size = sizeof(destroy_req);
|
|
|
|
g_rpc_err = 0;
|
2018-07-24 23:49:05 +00:00
|
|
|
g_json_decode_obj_construct = 0;
|
2018-05-08 11:30:29 +00:00
|
|
|
spdk_rpc_destroy_raid_bdev(NULL, NULL);
|
|
|
|
CU_ASSERT(g_rpc_err == 0);
|
|
|
|
verify_raid_config_present("raid1", false);
|
|
|
|
verify_raid_bdev_present("raid1", false);
|
|
|
|
|
|
|
|
raid_bdev_exit();
|
|
|
|
base_bdevs_cleanup();
|
|
|
|
reset_globals();
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
CU_pSuite suite = NULL;
|
|
|
|
unsigned int num_failures;
|
|
|
|
|
|
|
|
if (CU_initialize_registry() != CUE_SUCCESS) {
|
|
|
|
return CU_get_error();
|
|
|
|
}
|
|
|
|
|
|
|
|
suite = CU_add_suite("raid", NULL, NULL);
|
|
|
|
if (suite == NULL) {
|
|
|
|
CU_cleanup_registry();
|
|
|
|
return CU_get_error();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
CU_add_test(suite, "test_construct_raid", test_construct_raid) == NULL ||
|
|
|
|
CU_add_test(suite, "test_destroy_raid", test_destroy_raid) == NULL ||
|
|
|
|
CU_add_test(suite, "test_construct_raid_invalid_args", test_construct_raid_invalid_args) == NULL ||
|
|
|
|
CU_add_test(suite, "test_destroy_raid_invalid_args", test_destroy_raid_invalid_args) == NULL ||
|
|
|
|
CU_add_test(suite, "test_io_channel", test_io_channel) == NULL ||
|
2019-01-21 13:09:15 +00:00
|
|
|
CU_add_test(suite, "test_reset_io", test_reset_io) == NULL ||
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_add_test(suite, "test_write_io", test_write_io) == NULL ||
|
|
|
|
CU_add_test(suite, "test_read_io", test_read_io) == NULL ||
|
2019-01-21 13:34:21 +00:00
|
|
|
CU_add_test(suite, "test_unmap_io", test_unmap_io) == NULL ||
|
2018-05-08 11:30:29 +00:00
|
|
|
CU_add_test(suite, "test_io_failure", test_io_failure) == NULL ||
|
|
|
|
CU_add_test(suite, "test_io_waitq", test_io_waitq) == NULL ||
|
|
|
|
CU_add_test(suite, "test_multi_raid_no_io", test_multi_raid_no_io) == NULL ||
|
|
|
|
CU_add_test(suite, "test_multi_raid_with_io", test_multi_raid_with_io) == NULL ||
|
|
|
|
CU_add_test(suite, "test_io_type_supported", test_io_type_supported) == NULL ||
|
|
|
|
CU_add_test(suite, "test_create_raid_from_config", test_create_raid_from_config) == NULL ||
|
|
|
|
CU_add_test(suite, "test_create_raid_from_config_invalid_params",
|
|
|
|
test_create_raid_from_config_invalid_params) == NULL ||
|
|
|
|
CU_add_test(suite, "test_raid_json_dump_info", test_raid_json_dump_info) == NULL ||
|
|
|
|
CU_add_test(suite, "test_context_size", test_context_size) == NULL ||
|
|
|
|
CU_add_test(suite, "test_asym_base_drives_blockcnt", test_asym_base_drives_blockcnt) == NULL
|
|
|
|
) {
|
|
|
|
CU_cleanup_registry();
|
|
|
|
return CU_get_error();
|
|
|
|
}
|
|
|
|
|
|
|
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
|
|
|
set_test_opts();
|
|
|
|
CU_basic_run_tests();
|
|
|
|
num_failures = CU_get_number_of_failures();
|
|
|
|
CU_cleanup_registry();
|
|
|
|
return num_failures;
|
|
|
|
}
|