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