LCOV - code coverage report
Current view: top level - module/bdev/raid - bdev_raid_rpc.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 116 205 56.6 %
Date: 2024-07-14 05:23:08 Functions: 14 23 60.9 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2018 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include "spdk/rpc.h"
       7             : #include "spdk/bdev.h"
       8             : #include "bdev_raid.h"
       9             : #include "spdk/util.h"
      10             : #include "spdk/string.h"
      11             : #include "spdk/log.h"
      12             : #include "spdk/env.h"
      13             : 
      14             : #define RPC_MAX_BASE_BDEVS 255
      15             : 
      16             : /*
      17             :  * Input structure for bdev_raid_get_bdevs RPC
      18             :  */
      19             : struct rpc_bdev_raid_get_bdevs {
      20             :         /* category - all or online or configuring or offline */
      21             :         char *category;
      22             : };
      23             : 
      24             : /*
      25             :  * brief:
      26             :  * free_rpc_bdev_raid_get_bdevs function frees RPC bdev_raid_get_bdevs related parameters
      27             :  * params:
      28             :  * req - pointer to RPC request
      29             :  * returns:
      30             :  * none
      31             :  */
      32             : static void
      33           7 : free_rpc_bdev_raid_get_bdevs(struct rpc_bdev_raid_get_bdevs *req)
      34             : {
      35           7 :         free(req->category);
      36           7 : }
      37             : 
      38             : /*
      39             :  * Decoder object for RPC get_raids
      40             :  */
      41             : static const struct spdk_json_object_decoder rpc_bdev_raid_get_bdevs_decoders[] = {
      42             :         {"category", offsetof(struct rpc_bdev_raid_get_bdevs, category), spdk_json_decode_string},
      43             : };
      44             : 
      45             : /*
      46             :  * brief:
      47             :  * rpc_bdev_raid_get_bdevs function is the RPC for rpc_bdev_raid_get_bdevs. This is used to list
      48             :  * all the raid bdev names based on the input category requested. Category should be
      49             :  * one of "all", "online", "configuring" or "offline". "all" means all the raids
      50             :  * whether they are online or configuring or offline. "online" is the raid bdev which
      51             :  * is registered with bdev layer. "configuring" is the raid bdev which does not have
      52             :  * full configuration discovered yet. "offline" is the raid bdev which is not
      53             :  * registered with bdev as of now and it has encountered any error or user has
      54             :  * requested to offline the raid.
      55             :  * params:
      56             :  * request - pointer to json rpc request
      57             :  * params - pointer to request parameters
      58             :  * returns:
      59             :  * none
      60             :  */
      61             : static void
      62           7 : rpc_bdev_raid_get_bdevs(struct spdk_jsonrpc_request *request,
      63             :                         const struct spdk_json_val *params)
      64             : {
      65           7 :         struct rpc_bdev_raid_get_bdevs   req = {};
      66             :         struct spdk_json_write_ctx  *w;
      67             :         struct raid_bdev            *raid_bdev;
      68             :         enum raid_bdev_state        state;
      69             : 
      70           7 :         if (spdk_json_decode_object(params, rpc_bdev_raid_get_bdevs_decoders,
      71             :                                     SPDK_COUNTOF(rpc_bdev_raid_get_bdevs_decoders),
      72             :                                     &req)) {
      73           1 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
      74             :                                                  "spdk_json_decode_object failed");
      75           1 :                 goto cleanup;
      76             :         }
      77             : 
      78           6 :         state = raid_bdev_str_to_state(req.category);
      79           6 :         if (state == RAID_BDEV_STATE_MAX && strcmp(req.category, "all") != 0) {
      80           1 :                 spdk_jsonrpc_send_error_response(request, -EINVAL, spdk_strerror(EINVAL));
      81           1 :                 goto cleanup;
      82             :         }
      83             : 
      84           5 :         w = spdk_jsonrpc_begin_result(request);
      85           5 :         spdk_json_write_array_begin(w);
      86             : 
      87             :         /* Get raid bdev list based on the category requested */
      88          15 :         TAILQ_FOREACH(raid_bdev, &g_raid_bdev_list, global_link) {
      89          10 :                 if (raid_bdev->state == state || state == RAID_BDEV_STATE_MAX) {
      90           6 :                         char uuid_str[SPDK_UUID_STRING_LEN];
      91             : 
      92           6 :                         spdk_json_write_object_begin(w);
      93           6 :                         spdk_json_write_named_string(w, "name", raid_bdev->bdev.name);
      94           6 :                         spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &raid_bdev->bdev.uuid);
      95           6 :                         spdk_json_write_named_string(w, "uuid", uuid_str);
      96           6 :                         raid_bdev_write_info_json(raid_bdev, w);
      97           6 :                         spdk_json_write_object_end(w);
      98             :                 }
      99             :         }
     100           5 :         spdk_json_write_array_end(w);
     101           5 :         spdk_jsonrpc_end_result(request, w);
     102             : 
     103           7 : cleanup:
     104           7 :         free_rpc_bdev_raid_get_bdevs(&req);
     105           7 : }
     106           1 : SPDK_RPC_REGISTER("bdev_raid_get_bdevs", rpc_bdev_raid_get_bdevs, SPDK_RPC_RUNTIME)
     107             : 
     108             : /*
     109             :  * Base bdevs in RPC bdev_raid_create
     110             :  */
     111             : struct rpc_bdev_raid_create_base_bdevs {
     112             :         /* Number of base bdevs */
     113             :         size_t           num_base_bdevs;
     114             : 
     115             :         /* List of base bdevs names */
     116             :         char             *base_bdevs[RPC_MAX_BASE_BDEVS];
     117             : };
     118             : 
     119             : /*
     120             :  * Input structure for RPC rpc_bdev_raid_create
     121             :  */
     122             : struct rpc_bdev_raid_create {
     123             :         /* Raid bdev name */
     124             :         char                                 *name;
     125             : 
     126             :         /* RAID strip size in KB */
     127             :         uint32_t                             strip_size_kb;
     128             : 
     129             :         /* RAID raid level */
     130             :         enum raid_level                      level;
     131             : 
     132             :         /* Base bdevs information */
     133             :         struct rpc_bdev_raid_create_base_bdevs base_bdevs;
     134             : 
     135             :         /* UUID for this raid bdev */
     136             :         struct spdk_uuid                     uuid;
     137             : 
     138             :         /* If set, information about raid bdev will be stored in superblock on each base bdev */
     139             :         bool                                 superblock_enabled;
     140             : };
     141             : 
     142             : /*
     143             :  * Decoder function for RPC bdev_raid_create to decode raid level
     144             :  */
     145             : static int
     146           0 : decode_raid_level(const struct spdk_json_val *val, void *out)
     147             : {
     148             :         int ret;
     149           0 :         char *str = NULL;
     150             :         enum raid_level level;
     151             : 
     152           0 :         ret = spdk_json_decode_string(val, &str);
     153           0 :         if (ret == 0 && str != NULL) {
     154           0 :                 level = raid_bdev_str_to_level(str);
     155           0 :                 if (level == INVALID_RAID_LEVEL) {
     156           0 :                         ret = -EINVAL;
     157             :                 } else {
     158           0 :                         *(enum raid_level *)out = level;
     159             :                 }
     160             :         }
     161             : 
     162           0 :         free(str);
     163           0 :         return ret;
     164             : }
     165             : 
     166             : /*
     167             :  * Decoder function for RPC bdev_raid_create to decode base bdevs list
     168             :  */
     169             : static int
     170           0 : decode_base_bdevs(const struct spdk_json_val *val, void *out)
     171             : {
     172           0 :         struct rpc_bdev_raid_create_base_bdevs *base_bdevs = out;
     173           0 :         return spdk_json_decode_array(val, spdk_json_decode_string, base_bdevs->base_bdevs,
     174             :                                       RPC_MAX_BASE_BDEVS, &base_bdevs->num_base_bdevs, sizeof(char *));
     175             : }
     176             : 
     177             : /*
     178             :  * Decoder object for RPC bdev_raid_create
     179             :  */
     180             : static const struct spdk_json_object_decoder rpc_bdev_raid_create_decoders[] = {
     181             :         {"name", offsetof(struct rpc_bdev_raid_create, name), spdk_json_decode_string},
     182             :         {"strip_size_kb", offsetof(struct rpc_bdev_raid_create, strip_size_kb), spdk_json_decode_uint32, true},
     183             :         {"raid_level", offsetof(struct rpc_bdev_raid_create, level), decode_raid_level},
     184             :         {"base_bdevs", offsetof(struct rpc_bdev_raid_create, base_bdevs), decode_base_bdevs},
     185             :         {"uuid", offsetof(struct rpc_bdev_raid_create, uuid), spdk_json_decode_uuid, true},
     186             :         {"superblock", offsetof(struct rpc_bdev_raid_create, superblock_enabled), spdk_json_decode_bool, true},
     187             : };
     188             : 
     189             : struct rpc_bdev_raid_create_ctx {
     190             :         struct rpc_bdev_raid_create req;
     191             :         struct raid_bdev *raid_bdev;
     192             :         struct spdk_jsonrpc_request *request;
     193             :         uint8_t remaining;
     194             :         int status;
     195             : };
     196             : 
     197             : static void
     198          26 : free_rpc_bdev_raid_create_ctx(struct rpc_bdev_raid_create_ctx *ctx)
     199             : {
     200             :         struct rpc_bdev_raid_create *req;
     201             :         size_t i;
     202             : 
     203          26 :         if (!ctx) {
     204           0 :                 return;
     205             :         }
     206             : 
     207          26 :         req = &ctx->req;
     208             : 
     209          26 :         free(req->name);
     210         826 :         for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) {
     211         800 :                 free(req->base_bdevs.base_bdevs[i]);
     212             :         }
     213             : 
     214          26 :         free(ctx);
     215             : }
     216             : 
     217             : static void
     218         673 : rpc_bdev_raid_create_add_base_bdev_cb(void *_ctx, int status)
     219             : {
     220         673 :         struct rpc_bdev_raid_create_ctx *ctx = _ctx;
     221             : 
     222         673 :         if (status != 0) {
     223           2 :                 ctx->status = status;
     224             :         }
     225             : 
     226         673 :         assert(ctx->remaining != 0);
     227         673 :         if (--ctx->remaining > 0) {
     228         651 :                 return;
     229             :         }
     230             : 
     231          22 :         if (ctx->status != 0) {
     232           2 :                 raid_bdev_delete(ctx->raid_bdev, NULL, NULL);
     233           2 :                 spdk_jsonrpc_send_error_response_fmt(ctx->request, ctx->status,
     234             :                                                      "Failed to create RAID bdev %s: %s",
     235             :                                                      ctx->req.name,
     236           2 :                                                      spdk_strerror(-ctx->status));
     237             :         } else {
     238          20 :                 spdk_jsonrpc_send_bool_response(ctx->request, true);
     239             :         }
     240             : 
     241          22 :         free_rpc_bdev_raid_create_ctx(ctx);
     242             : }
     243             : 
     244             : /*
     245             :  * brief:
     246             :  * rpc_bdev_raid_create function is the RPC for creating RAID bdevs. It takes
     247             :  * input as raid bdev name, raid level, strip size in KB and list of base bdev names.
     248             :  * params:
     249             :  * request - pointer to json rpc request
     250             :  * params - pointer to request parameters
     251             :  * returns:
     252             :  * none
     253             :  */
     254             : static void
     255          26 : rpc_bdev_raid_create(struct spdk_jsonrpc_request *request,
     256             :                      const struct spdk_json_val *params)
     257             : {
     258             :         struct rpc_bdev_raid_create     *req;
     259          26 :         struct raid_bdev                *raid_bdev;
     260             :         int                             rc;
     261             :         size_t                          i;
     262             :         struct rpc_bdev_raid_create_ctx *ctx;
     263             :         uint8_t                         num_base_bdevs;
     264             : 
     265          26 :         ctx = calloc(1, sizeof(*ctx));
     266          26 :         if (ctx == NULL) {
     267           0 :                 spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
     268           0 :                 goto cleanup;
     269             :         }
     270          26 :         req = &ctx->req;
     271             : 
     272          26 :         if (spdk_json_decode_object(params, rpc_bdev_raid_create_decoders,
     273             :                                     SPDK_COUNTOF(rpc_bdev_raid_create_decoders),
     274             :                                     req)) {
     275           1 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
     276             :                                                  "spdk_json_decode_object failed");
     277           1 :                 goto cleanup;
     278             :         }
     279          25 :         num_base_bdevs = req->base_bdevs.num_base_bdevs;
     280             : 
     281          25 :         rc = raid_bdev_create(req->name, req->strip_size_kb, num_base_bdevs,
     282          25 :                               req->level, req->superblock_enabled, &req->uuid, &raid_bdev);
     283          25 :         if (rc != 0) {
     284           3 :                 spdk_jsonrpc_send_error_response_fmt(request, rc,
     285             :                                                      "Failed to create RAID bdev %s: %s",
     286             :                                                      req->name, spdk_strerror(-rc));
     287           3 :                 goto cleanup;
     288             :         }
     289             : 
     290          22 :         ctx->raid_bdev = raid_bdev;
     291          22 :         ctx->request = request;
     292          22 :         ctx->remaining = num_base_bdevs;
     293             : 
     294          22 :         assert(num_base_bdevs > 0);
     295             : 
     296         693 :         for (i = 0; i < num_base_bdevs; i++) {
     297         673 :                 const char *base_bdev_name = req->base_bdevs.base_bdevs[i];
     298             : 
     299         673 :                 rc = raid_bdev_add_base_device(raid_bdev, base_bdev_name, i,
     300             :                                                rpc_bdev_raid_create_add_base_bdev_cb, ctx);
     301         673 :                 if (rc == -ENODEV) {
     302           1 :                         SPDK_DEBUGLOG(bdev_raid, "base bdev %s doesn't exist now\n", base_bdev_name);
     303           1 :                         assert(ctx->remaining > 1 || i + 1 == num_base_bdevs);
     304           1 :                         rpc_bdev_raid_create_add_base_bdev_cb(ctx, 0);
     305         672 :                 } else if (rc != 0) {
     306           2 :                         SPDK_DEBUGLOG(bdev_raid, "Failed to add base bdev %s to RAID bdev %s: %s",
     307             :                                       base_bdev_name, req->name, spdk_strerror(-rc));
     308           2 :                         ctx->remaining -= (num_base_bdevs - i - 1);
     309           2 :                         rpc_bdev_raid_create_add_base_bdev_cb(ctx, rc);
     310           2 :                         break;
     311             :                 }
     312             :         }
     313          22 :         return;
     314           4 : cleanup:
     315           4 :         free_rpc_bdev_raid_create_ctx(ctx);
     316             : }
     317           1 : SPDK_RPC_REGISTER("bdev_raid_create", rpc_bdev_raid_create, SPDK_RPC_RUNTIME)
     318             : 
     319             : /*
     320             :  * Input structure for RPC deleting a raid bdev
     321             :  */
     322             : struct rpc_bdev_raid_delete {
     323             :         /* raid bdev name */
     324             :         char *name;
     325             : };
     326             : 
     327             : /*
     328             :  * brief:
     329             :  * free_rpc_bdev_raid_delete function is used to free RPC bdev_raid_delete related parameters
     330             :  * params:
     331             :  * req - pointer to RPC request
     332             :  * params:
     333             :  * none
     334             :  */
     335             : static void
     336          21 : free_rpc_bdev_raid_delete(struct rpc_bdev_raid_delete *req)
     337             : {
     338          21 :         free(req->name);
     339          21 : }
     340             : 
     341             : /*
     342             :  * Decoder object for RPC raid_bdev_delete
     343             :  */
     344             : static const struct spdk_json_object_decoder rpc_bdev_raid_delete_decoders[] = {
     345             :         {"name", offsetof(struct rpc_bdev_raid_delete, name), spdk_json_decode_string},
     346             : };
     347             : 
     348             : struct rpc_bdev_raid_delete_ctx {
     349             :         struct rpc_bdev_raid_delete req;
     350             :         struct spdk_jsonrpc_request *request;
     351             : };
     352             : 
     353             : /*
     354             :  * brief:
     355             :  * params:
     356             :  * cb_arg - pointer to the callback context.
     357             :  * rc - return code of the deletion of the raid bdev.
     358             :  * returns:
     359             :  * none
     360             :  */
     361             : static void
     362          19 : bdev_raid_delete_done(void *cb_arg, int rc)
     363             : {
     364          19 :         struct rpc_bdev_raid_delete_ctx *ctx = cb_arg;
     365          19 :         struct spdk_jsonrpc_request *request = ctx->request;
     366             : 
     367          19 :         if (rc != 0) {
     368           0 :                 SPDK_ERRLOG("Failed to delete raid bdev %s (%d): %s\n",
     369             :                             ctx->req.name, rc, spdk_strerror(-rc));
     370           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     371             :                                                  spdk_strerror(-rc));
     372           0 :                 goto exit;
     373             :         }
     374             : 
     375          19 :         spdk_jsonrpc_send_bool_response(request, true);
     376          19 : exit:
     377          19 :         free_rpc_bdev_raid_delete(&ctx->req);
     378          19 :         free(ctx);
     379          19 : }
     380             : 
     381             : /*
     382             :  * brief:
     383             :  * rpc_bdev_raid_delete function is the RPC for deleting a raid bdev. It takes raid
     384             :  * name as input and delete that raid bdev including freeing the base bdev
     385             :  * resources.
     386             :  * params:
     387             :  * request - pointer to json rpc request
     388             :  * params - pointer to request parameters
     389             :  * returns:
     390             :  * none
     391             :  */
     392             : static void
     393          21 : rpc_bdev_raid_delete(struct spdk_jsonrpc_request *request,
     394             :                      const struct spdk_json_val *params)
     395             : {
     396             :         struct rpc_bdev_raid_delete_ctx *ctx;
     397             :         struct raid_bdev *raid_bdev;
     398             : 
     399          21 :         ctx = calloc(1, sizeof(*ctx));
     400          21 :         if (!ctx) {
     401           0 :                 spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
     402           0 :                 return;
     403             :         }
     404             : 
     405          21 :         if (spdk_json_decode_object(params, rpc_bdev_raid_delete_decoders,
     406             :                                     SPDK_COUNTOF(rpc_bdev_raid_delete_decoders),
     407          21 :                                     &ctx->req)) {
     408           1 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
     409             :                                                  "spdk_json_decode_object failed");
     410           1 :                 goto cleanup;
     411             :         }
     412             : 
     413          20 :         raid_bdev = raid_bdev_find_by_name(ctx->req.name);
     414          20 :         if (raid_bdev == NULL) {
     415           1 :                 spdk_jsonrpc_send_error_response_fmt(request, -ENODEV,
     416             :                                                      "raid bdev %s not found",
     417             :                                                      ctx->req.name);
     418           1 :                 goto cleanup;
     419             :         }
     420             : 
     421          19 :         ctx->request = request;
     422             : 
     423          19 :         raid_bdev_delete(raid_bdev, bdev_raid_delete_done, ctx);
     424             : 
     425          19 :         return;
     426             : 
     427           2 : cleanup:
     428           2 :         free_rpc_bdev_raid_delete(&ctx->req);
     429           2 :         free(ctx);
     430             : }
     431           1 : SPDK_RPC_REGISTER("bdev_raid_delete", rpc_bdev_raid_delete, SPDK_RPC_RUNTIME)
     432             : 
     433             : /*
     434             :  * Base bdevs in RPC bdev_raid_add_base_bdev
     435             :  */
     436             : struct rpc_bdev_raid_add_base_bdev {
     437             :         /* Base bdev name */
     438             :         char                    *base_bdev;
     439             : 
     440             :         /* Raid bdev name */
     441             :         char                    *raid_bdev;
     442             : };
     443             : 
     444             : /*
     445             :  * brief:
     446             :  * free_rpc_bdev_raid_add_base_bdev function is to free RPC
     447             :  * bdev_raid_add_base_bdev related parameters.
     448             :  * params:
     449             :  * req - pointer to RPC request
     450             :  * returns:
     451             :  * none
     452             :  */
     453             : static void
     454           0 : free_rpc_bdev_raid_add_base_bdev(struct rpc_bdev_raid_add_base_bdev *req)
     455             : {
     456           0 :         free(req->base_bdev);
     457           0 :         free(req->raid_bdev);
     458           0 : }
     459             : 
     460             : /*
     461             :  * Decoder object for RPC bdev_raid_add_base_bdev
     462             :  */
     463             : static const struct spdk_json_object_decoder rpc_bdev_raid_add_base_bdev_decoders[] = {
     464             :         {"base_bdev", offsetof(struct rpc_bdev_raid_add_base_bdev, base_bdev), spdk_json_decode_string},
     465             :         {"raid_bdev", offsetof(struct rpc_bdev_raid_add_base_bdev, raid_bdev), spdk_json_decode_string},
     466             : };
     467             : 
     468             : static void
     469           0 : rpc_bdev_raid_add_base_bdev_done(void *ctx, int status)
     470             : {
     471           0 :         struct spdk_jsonrpc_request *request = ctx;
     472             : 
     473           0 :         if (status != 0) {
     474           0 :                 spdk_jsonrpc_send_error_response_fmt(request, status, "Failed to add base bdev to RAID bdev: %s",
     475             :                                                      spdk_strerror(-status));
     476           0 :                 return;
     477             :         }
     478             : 
     479           0 :         spdk_jsonrpc_send_bool_response(request, true);
     480             : }
     481             : 
     482             : static void
     483           0 : rpc_bdev_raid_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx)
     484             : {
     485           0 : }
     486             : 
     487             : /*
     488             :  * brief:
     489             :  * bdev_raid_add_base_bdev function is the RPC for adding base bdev to a raid bdev.
     490             :  * It takes base bdev and raid bdev names as input.
     491             :  * params:
     492             :  * request - pointer to json rpc request
     493             :  * params - pointer to request parameters
     494             :  * returns:
     495             :  * none
     496             :  */
     497             : static void
     498           0 : rpc_bdev_raid_add_base_bdev(struct spdk_jsonrpc_request *request,
     499             :                             const struct spdk_json_val *params)
     500             : {
     501           0 :         struct rpc_bdev_raid_add_base_bdev req = {};
     502             :         struct raid_bdev *raid_bdev;
     503           0 :         struct spdk_bdev_desc *desc;
     504             :         int rc;
     505             : 
     506           0 :         if (spdk_json_decode_object(params, rpc_bdev_raid_add_base_bdev_decoders,
     507             :                                     SPDK_COUNTOF(rpc_bdev_raid_add_base_bdev_decoders),
     508             :                                     &req)) {
     509           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     510             :                                                  "spdk_json_decode_object failed");
     511           0 :                 goto cleanup;
     512             :         }
     513             : 
     514           0 :         raid_bdev = raid_bdev_find_by_name(req.raid_bdev);
     515           0 :         if (raid_bdev == NULL) {
     516           0 :                 spdk_jsonrpc_send_error_response_fmt(request, -ENODEV, "raid bdev %s is not found in config",
     517             :                                                      req.raid_bdev);
     518           0 :                 goto cleanup;
     519             :         }
     520             : 
     521           0 :         rc = spdk_bdev_open_ext(req.base_bdev, false, rpc_bdev_raid_event_cb, NULL, &desc);
     522           0 :         if (rc != 0) {
     523           0 :                 spdk_jsonrpc_send_error_response_fmt(request, rc, "Failed to open bdev %s: %s",
     524             :                                                      req.base_bdev, spdk_strerror(-rc));
     525           0 :                 goto cleanup;
     526             :         }
     527             : 
     528           0 :         rc = raid_bdev_attach_base_bdev(raid_bdev, spdk_bdev_desc_get_bdev(desc),
     529             :                                         rpc_bdev_raid_add_base_bdev_done, request);
     530           0 :         spdk_bdev_close(desc);
     531           0 :         if (rc != 0) {
     532           0 :                 spdk_jsonrpc_send_error_response_fmt(request, rc,
     533             :                                                      "Failed to attach base bdev %s to RAID bdev %s: %s",
     534             :                                                      req.base_bdev, req.raid_bdev,
     535             :                                                      spdk_strerror(-rc));
     536           0 :                 goto cleanup;
     537             :         }
     538             : 
     539           0 : cleanup:
     540           0 :         free_rpc_bdev_raid_add_base_bdev(&req);
     541           0 : }
     542           1 : SPDK_RPC_REGISTER("bdev_raid_add_base_bdev", rpc_bdev_raid_add_base_bdev, SPDK_RPC_RUNTIME)
     543             : 
     544             : /*
     545             :  * Decoder object for RPC bdev_raid_remove_base_bdev
     546             :  */
     547             : static const struct spdk_json_object_decoder rpc_bdev_raid_remove_base_bdev_decoders[] = {
     548             :         {"name", 0, spdk_json_decode_string},
     549             : };
     550             : 
     551             : static void
     552           0 : rpc_bdev_raid_remove_base_bdev_done(void *ctx, int status)
     553             : {
     554           0 :         struct spdk_jsonrpc_request *request = ctx;
     555             : 
     556           0 :         if (status != 0) {
     557           0 :                 spdk_jsonrpc_send_error_response_fmt(request, status, "Failed to remove base bdev from raid bdev");
     558           0 :                 return;
     559             :         }
     560             : 
     561           0 :         spdk_jsonrpc_send_bool_response(request, true);
     562             : }
     563             : 
     564             : /*
     565             :  * brief:
     566             :  * bdev_raid_remove_base_bdev function is the RPC for removing base bdev from a raid bdev.
     567             :  * It takes base bdev name as input.
     568             :  * params:
     569             :  * request - pointer to json rpc request
     570             :  * params - pointer to request parameters
     571             :  * returns:
     572             :  * none
     573             :  */
     574             : static void
     575           0 : rpc_bdev_raid_remove_base_bdev(struct spdk_jsonrpc_request *request,
     576             :                                const struct spdk_json_val *params)
     577             : {
     578           0 :         struct spdk_bdev_desc *desc;
     579           0 :         char *name = NULL;
     580             :         int rc;
     581             : 
     582           0 :         if (spdk_json_decode_object(params, rpc_bdev_raid_remove_base_bdev_decoders,
     583             :                                     SPDK_COUNTOF(rpc_bdev_raid_remove_base_bdev_decoders),
     584             :                                     &name)) {
     585           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
     586             :                                                  "spdk_json_decode_object failed");
     587           0 :                 return;
     588             :         }
     589             : 
     590           0 :         rc = spdk_bdev_open_ext(name, false, rpc_bdev_raid_event_cb, NULL, &desc);
     591           0 :         free(name);
     592           0 :         if (rc != 0) {
     593           0 :                 goto err;
     594             :         }
     595             : 
     596           0 :         rc = raid_bdev_remove_base_bdev(spdk_bdev_desc_get_bdev(desc), rpc_bdev_raid_remove_base_bdev_done,
     597             :                                         request);
     598           0 :         spdk_bdev_close(desc);
     599           0 :         if (rc != 0) {
     600           0 :                 goto err;
     601             :         }
     602             : 
     603           0 :         return;
     604           0 : err:
     605           0 :         rpc_bdev_raid_remove_base_bdev_done(request, rc);
     606             : }
     607           1 : SPDK_RPC_REGISTER("bdev_raid_remove_base_bdev", rpc_bdev_raid_remove_base_bdev, SPDK_RPC_RUNTIME)
     608             : 
     609             : static const struct spdk_json_object_decoder rpc_bdev_raid_options_decoders[] = {
     610             :         {"process_window_size_kb", offsetof(struct spdk_raid_bdev_opts, process_window_size_kb), spdk_json_decode_uint32, true},
     611             : };
     612             : 
     613             : static void
     614           0 : rpc_bdev_raid_set_options(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
     615             : {
     616           0 :         struct spdk_raid_bdev_opts opts;
     617             :         int rc;
     618             : 
     619           0 :         raid_bdev_get_opts(&opts);
     620           0 :         if (params && spdk_json_decode_object(params, rpc_bdev_raid_options_decoders,
     621             :                                               SPDK_COUNTOF(rpc_bdev_raid_options_decoders),
     622             :                                               &opts)) {
     623           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
     624             :                                                  "spdk_json_decode_object failed");
     625           0 :                 return;
     626             :         }
     627             : 
     628           0 :         rc = raid_bdev_set_opts(&opts);
     629           0 :         if (rc) {
     630           0 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     631             :         } else {
     632           0 :                 spdk_jsonrpc_send_bool_response(request, true);
     633             :         }
     634             : 
     635           0 :         return;
     636             : }
     637           1 : SPDK_RPC_REGISTER("bdev_raid_set_options", rpc_bdev_raid_set_options,
     638             :                   SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)

Generated by: LCOV version 1.15