LCOV - code coverage report
Current view: top level - spdk/lib/ublk - ublk_rpc.c (source / functions) Hit Total Coverage
Test: Combined Lines: 7 180 3.9 %
Date: 2024-07-12 12:30:19 Functions: 7 24 29.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 48 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2022 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/string.h"
       7                 :            : #include "spdk/env.h"
       8                 :            : #include "spdk/rpc.h"
       9                 :            : #include "spdk/util.h"
      10                 :            : #include "spdk/log.h"
      11                 :            : 
      12                 :            : #include "ublk_internal.h"
      13                 :            : 
      14                 :            : struct rpc_ublk_create_target {
      15                 :            :         char            *cpumask;
      16                 :            : };
      17                 :            : 
      18                 :            : static const struct spdk_json_object_decoder rpc_ublk_create_target_decoders[] = {
      19                 :            :         {"cpumask", offsetof(struct rpc_ublk_create_target, cpumask), spdk_json_decode_string, true},
      20                 :            : };
      21                 :            : 
      22                 :            : static void
      23                 :          0 : free_rpc_ublk_create_target(struct rpc_ublk_create_target *req)
      24                 :            : {
      25                 :          0 :         free(req->cpumask);
      26                 :          0 : }
      27                 :            : 
      28                 :            : static void
      29                 :          0 : rpc_ublk_create_target(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
      30                 :            : {
      31                 :          0 :         int rc = 0;
      32                 :          0 :         struct rpc_ublk_create_target req = {};
      33                 :            : 
      34         [ #  # ]:          0 :         if (params != NULL) {
      35         [ #  # ]:          0 :                 if (spdk_json_decode_object_relaxed(params, rpc_ublk_create_target_decoders,
      36                 :            :                                                     SPDK_COUNTOF(rpc_ublk_create_target_decoders),
      37                 :            :                                                     &req)) {
      38                 :          0 :                         SPDK_ERRLOG("spdk_json_decode_object failed\n");
      39                 :          0 :                         rc = -EINVAL;
      40                 :          0 :                         goto invalid;
      41                 :            :                 }
      42                 :            :         }
      43                 :          0 :         rc = ublk_create_target(req.cpumask, params);
      44         [ #  # ]:          0 :         if (rc != 0) {
      45                 :          0 :                 goto invalid;
      46                 :            :         }
      47                 :          0 :         spdk_jsonrpc_send_bool_response(request, true);
      48                 :          0 :         free_rpc_ublk_create_target(&req);
      49                 :          0 :         return;
      50                 :          0 : invalid:
      51                 :          0 :         SPDK_ERRLOG("Can't create ublk target: %s\n", spdk_strerror(-rc));
      52                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, spdk_strerror(-rc));
      53                 :          0 :         free_rpc_ublk_create_target(&req);
      54                 :            : }
      55                 :        476 : SPDK_RPC_REGISTER("ublk_create_target", rpc_ublk_create_target, SPDK_RPC_RUNTIME)
      56                 :            : 
      57                 :            : static void
      58                 :          0 : ublk_destroy_target_done(void *arg)
      59                 :            : {
      60                 :          0 :         struct spdk_jsonrpc_request *req = arg;
      61                 :            : 
      62                 :          0 :         spdk_jsonrpc_send_bool_response(req, true);
      63                 :          0 :         SPDK_NOTICELOG("ublk target has been destroyed\n");
      64                 :          0 : }
      65                 :            : 
      66                 :            : static void
      67                 :          0 : rpc_ublk_destroy_target(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
      68                 :            : {
      69                 :          0 :         int rc = 0;
      70                 :            : 
      71                 :          0 :         rc = ublk_destroy_target(ublk_destroy_target_done, request);
      72         [ #  # ]:          0 :         if (rc != 0) {
      73                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, spdk_strerror(-rc));
      74                 :          0 :                 SPDK_ERRLOG("Can't destroy ublk target: %s\n", spdk_strerror(-rc));
      75                 :            :         }
      76                 :          0 : }
      77                 :        476 : SPDK_RPC_REGISTER("ublk_destroy_target", rpc_ublk_destroy_target, SPDK_RPC_RUNTIME)
      78                 :            : 
      79                 :            : struct rpc_ublk_use_fixed_files {
      80                 :            :         char *state;
      81                 :            : };
      82                 :            : 
      83                 :            : static const struct spdk_json_object_decoder rpc_ublk_use_fixed_files_decoders[] = {
      84                 :            :         {"state", offsetof(struct rpc_ublk_use_fixed_files, state),  spdk_json_decode_string},
      85                 :            : };
      86                 :            : 
      87                 :            : static void
      88                 :          0 : free_rpc_ublk_use_fixed_files(struct rpc_ublk_use_fixed_files *req)
      89                 :            : {
      90                 :          0 :         free(req->state);
      91                 :          0 : }
      92                 :            : 
      93                 :            : static void
      94                 :          0 : rpc_ublk_use_fixed_files(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
      95                 :            : {
      96                 :          0 :         int rc = 0;
      97                 :          0 :         struct rpc_ublk_use_fixed_files req = {};
      98                 :            : 
      99         [ #  # ]:          0 :         if (params != NULL) {
     100         [ #  # ]:          0 :                 if (spdk_json_decode_object(params, rpc_ublk_use_fixed_files_decoders,
     101                 :            :                                             SPDK_COUNTOF(rpc_ublk_use_fixed_files_decoders),
     102                 :            :                                             &req)) {
     103                 :          0 :                         SPDK_ERRLOG("spdk_json_decode_object failed\n");
     104                 :          0 :                         rc = -EINVAL;
     105                 :          0 :                         goto invalid;
     106                 :            :                 }
     107                 :            :         }
     108                 :          0 :         rc = ublk_use_fixed_files(req.state);
     109         [ #  # ]:          0 :         if (rc != 0) {
     110                 :          0 :                 goto invalid;
     111                 :            :         }
     112                 :          0 :         free_rpc_ublk_use_fixed_files(&req);
     113                 :          0 :         spdk_jsonrpc_send_bool_response(request, true);
     114                 :          0 :         return;
     115                 :          0 : invalid:
     116                 :          0 :         SPDK_ERRLOG("Can't change fixed file state: %s\n", spdk_strerror(-rc));
     117                 :          0 :         free_rpc_ublk_use_fixed_files(&req);
     118                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, spdk_strerror(-rc));
     119                 :            : 
     120                 :            : }
     121                 :        476 : SPDK_RPC_REGISTER("ublk_use_fixed_files", rpc_ublk_use_fixed_files, SPDK_RPC_RUNTIME)
     122                 :            : 
     123                 :            : struct rpc_ublk_start_disk {
     124                 :            :         char            *bdev_name;
     125                 :            :         uint32_t        ublk_id;
     126                 :            :         uint32_t        num_queues;
     127                 :            :         uint32_t        queue_depth;
     128                 :            :         struct spdk_jsonrpc_request *request;
     129                 :            : };
     130                 :            : 
     131                 :            : static const struct spdk_json_object_decoder rpc_ublk_start_disk_decoders[] = {
     132                 :            :         {"bdev_name", offsetof(struct rpc_ublk_start_disk, bdev_name), spdk_json_decode_string},
     133                 :            :         {"ublk_id", offsetof(struct rpc_ublk_start_disk, ublk_id), spdk_json_decode_uint32},
     134                 :            :         {"num_queues", offsetof(struct rpc_ublk_start_disk, num_queues), spdk_json_decode_uint32, true},
     135                 :            :         {"queue_depth", offsetof(struct rpc_ublk_start_disk, queue_depth), spdk_json_decode_uint32, true},
     136                 :            : };
     137                 :            : 
     138                 :            : static void
     139                 :          0 : free_rpc_ublk_start_disk(struct rpc_ublk_start_disk *req)
     140                 :            : {
     141                 :          0 :         free(req->bdev_name);
     142                 :          0 :         free(req);
     143                 :          0 : }
     144                 :            : 
     145                 :            : static void
     146                 :          0 : rpc_ublk_start_disk_done(void *cb_arg, int rc)
     147                 :            : {
     148                 :          0 :         struct rpc_ublk_start_disk *req = cb_arg;
     149                 :            :         struct spdk_json_write_ctx *w;
     150                 :            : 
     151         [ #  # ]:          0 :         if (rc == 0) {
     152                 :          0 :                 w = spdk_jsonrpc_begin_result(req->request);
     153                 :          0 :                 spdk_json_write_uint32(w, req->ublk_id);
     154                 :          0 :                 spdk_jsonrpc_end_result(req->request, w);
     155                 :            :         } else {
     156                 :          0 :                 spdk_jsonrpc_send_error_response(req->request, rc, spdk_strerror(-rc));
     157                 :            :         }
     158                 :            : 
     159                 :          0 :         free_rpc_ublk_start_disk(req);
     160                 :          0 : }
     161                 :            : 
     162                 :            : static void
     163                 :          0 : rpc_ublk_start_disk(struct spdk_jsonrpc_request *request,
     164                 :            :                     const struct spdk_json_val *params)
     165                 :            : {
     166                 :            :         struct rpc_ublk_start_disk *req;
     167                 :            :         int rc;
     168                 :            : 
     169                 :          0 :         req = calloc(1, sizeof(*req));
     170         [ #  # ]:          0 :         if (req == NULL) {
     171                 :          0 :                 SPDK_ERRLOG("could not allocate request.\n");
     172                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
     173                 :          0 :                 return;
     174                 :            :         }
     175                 :          0 :         req->request = request;
     176                 :          0 :         req->queue_depth = UBLK_DEV_QUEUE_DEPTH;
     177                 :          0 :         req->num_queues = UBLK_DEV_NUM_QUEUE;
     178                 :            : 
     179         [ #  # ]:          0 :         if (spdk_json_decode_object(params, rpc_ublk_start_disk_decoders,
     180                 :            :                                     SPDK_COUNTOF(rpc_ublk_start_disk_decoders),
     181                 :            :                                     req)) {
     182                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     183                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     184                 :            :                                                  "spdk_json_decode_object failed");
     185                 :          0 :                 goto out;
     186                 :            :         }
     187                 :            : 
     188                 :          0 :         rc = ublk_start_disk(req->bdev_name, req->ublk_id, req->num_queues, req->queue_depth,
     189                 :            :                              rpc_ublk_start_disk_done, req);
     190         [ #  # ]:          0 :         if (rc != 0) {
     191                 :          0 :                 rpc_ublk_start_disk_done(req, rc);
     192                 :            :         }
     193                 :            : 
     194                 :          0 :         return;
     195                 :            : 
     196                 :          0 : out:
     197                 :          0 :         free_rpc_ublk_start_disk(req);
     198                 :            : }
     199                 :            : 
     200                 :        476 : SPDK_RPC_REGISTER("ublk_start_disk", rpc_ublk_start_disk, SPDK_RPC_RUNTIME)
     201                 :            : 
     202                 :            : struct rpc_ublk_stop_disk {
     203                 :            :         uint32_t ublk_id;
     204                 :            :         struct spdk_jsonrpc_request *request;
     205                 :            : };
     206                 :            : 
     207                 :            : static void
     208                 :          0 : free_rpc_ublk_stop_disk(struct rpc_ublk_stop_disk *req)
     209                 :            : {
     210                 :          0 :         free(req);
     211                 :          0 : }
     212                 :            : 
     213                 :            : static const struct spdk_json_object_decoder rpc_ublk_stop_disk_decoders[] = {
     214                 :            :         {"ublk_id", offsetof(struct rpc_ublk_stop_disk, ublk_id), spdk_json_decode_uint32},
     215                 :            : };
     216                 :            : 
     217                 :            : static void
     218                 :          0 : rpc_ublk_stop_disk_done(void *cb_arg, int rc)
     219                 :            : {
     220                 :          0 :         struct rpc_ublk_stop_disk *req = cb_arg;
     221                 :            : 
     222                 :          0 :         spdk_jsonrpc_send_bool_response(req->request, true);
     223                 :          0 :         free_rpc_ublk_stop_disk(req);
     224                 :          0 : }
     225                 :            : 
     226                 :            : static void
     227                 :          0 : rpc_ublk_stop_disk(struct spdk_jsonrpc_request *request,
     228                 :            :                    const struct spdk_json_val *params)
     229                 :            : {
     230                 :            :         struct rpc_ublk_stop_disk *req;
     231                 :            :         int rc;
     232                 :            : 
     233                 :          0 :         req = calloc(1, sizeof(*req));
     234         [ #  # ]:          0 :         if (req == NULL) {
     235                 :          0 :                 SPDK_ERRLOG("could not allocate request.\n");
     236                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
     237                 :          0 :                 return;
     238                 :            :         }
     239                 :          0 :         req->request = request;
     240                 :            : 
     241         [ #  # ]:          0 :         if (spdk_json_decode_object(params, rpc_ublk_stop_disk_decoders,
     242                 :            :                                     SPDK_COUNTOF(rpc_ublk_stop_disk_decoders),
     243                 :            :                                     req)) {
     244                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     245                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     246                 :            :                                                  "spdk_json_decode_object failed");
     247                 :          0 :                 goto invalid;
     248                 :            :         }
     249                 :            : 
     250                 :          0 :         rc = ublk_stop_disk(req->ublk_id, rpc_ublk_stop_disk_done, req);
     251         [ #  # ]:          0 :         if (rc) {
     252                 :          0 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     253                 :          0 :                 goto invalid;
     254                 :            :         }
     255                 :          0 :         return;
     256                 :            : 
     257                 :          0 : invalid:
     258                 :          0 :         free_rpc_ublk_stop_disk(req);
     259                 :            : }
     260                 :            : 
     261                 :        476 : SPDK_RPC_REGISTER("ublk_stop_disk", rpc_ublk_stop_disk, SPDK_RPC_RUNTIME)
     262                 :            : 
     263                 :            : static void
     264                 :          0 : rpc_dump_ublk_info(struct spdk_json_write_ctx *w,
     265                 :            :                    struct spdk_ublk_dev *ublk)
     266                 :            : {
     267                 :          0 :         char ublk_path[32];
     268                 :            : 
     269         [ #  # ]:          0 :         snprintf(ublk_path, 32, "%s%u", "/dev/ublkb", ublk_dev_get_id(ublk));
     270                 :          0 :         spdk_json_write_object_begin(w);
     271                 :            : 
     272                 :          0 :         spdk_json_write_named_string(w, "ublk_device", ublk_path);
     273                 :          0 :         spdk_json_write_named_uint32(w, "id", ublk_dev_get_id(ublk));
     274                 :          0 :         spdk_json_write_named_uint32(w, "queue_depth", ublk_dev_get_queue_depth(ublk));
     275                 :          0 :         spdk_json_write_named_uint32(w, "num_queues", ublk_dev_get_num_queues(ublk));
     276                 :          0 :         spdk_json_write_named_string(w, "bdev_name", ublk_dev_get_bdev_name(ublk));
     277                 :            : 
     278                 :          0 :         spdk_json_write_object_end(w);
     279                 :          0 : }
     280                 :            : 
     281                 :            : struct rpc_ublk_get_disks {
     282                 :            :         uint32_t ublk_id;
     283                 :            : };
     284                 :            : 
     285                 :            : static const struct spdk_json_object_decoder rpc_ublk_get_disks_decoders[] = {
     286                 :            :         {"ublk_id", offsetof(struct rpc_ublk_get_disks, ublk_id), spdk_json_decode_uint32, true},
     287                 :            : };
     288                 :            : 
     289                 :            : static void
     290                 :          0 : rpc_ublk_get_disks(struct spdk_jsonrpc_request *request,
     291                 :            :                    const struct spdk_json_val *params)
     292                 :            : {
     293                 :          0 :         struct rpc_ublk_get_disks req = {};
     294                 :            :         struct spdk_json_write_ctx *w;
     295                 :          0 :         struct spdk_ublk_dev *ublk = NULL;
     296                 :            : 
     297         [ #  # ]:          0 :         if (params != NULL) {
     298         [ #  # ]:          0 :                 if (spdk_json_decode_object(params, rpc_ublk_get_disks_decoders,
     299                 :            :                                             SPDK_COUNTOF(rpc_ublk_get_disks_decoders),
     300                 :            :                                             &req)) {
     301                 :          0 :                         SPDK_ERRLOG("spdk_json_decode_object failed\n");
     302                 :          0 :                         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     303                 :            :                                                          "spdk_json_decode_object failed");
     304                 :          0 :                         return;
     305                 :            :                 }
     306                 :            : 
     307         [ #  # ]:          0 :                 if (req.ublk_id) {
     308                 :          0 :                         ublk = ublk_dev_find_by_id(req.ublk_id);
     309         [ #  # ]:          0 :                         if (ublk == NULL) {
     310                 :          0 :                                 SPDK_ERRLOG("ublk device '%d' does not exist\n", req.ublk_id);
     311                 :          0 :                                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     312                 :          0 :                                 return;
     313                 :            :                         }
     314                 :            :                 }
     315                 :            :         }
     316                 :            : 
     317                 :          0 :         w = spdk_jsonrpc_begin_result(request);
     318                 :          0 :         spdk_json_write_array_begin(w);
     319                 :            : 
     320         [ #  # ]:          0 :         if (ublk != NULL) {
     321                 :          0 :                 rpc_dump_ublk_info(w, ublk);
     322                 :            :         } else {
     323         [ #  # ]:          0 :                 for (ublk = ublk_dev_first(); ublk != NULL; ublk = ublk_dev_next(ublk)) {
     324                 :          0 :                         rpc_dump_ublk_info(w, ublk);
     325                 :            :                 }
     326                 :            :         }
     327                 :            : 
     328                 :          0 :         spdk_json_write_array_end(w);
     329                 :          0 :         spdk_jsonrpc_end_result(request, w);
     330                 :            : 
     331                 :          0 :         return;
     332                 :            : }
     333                 :        476 : SPDK_RPC_REGISTER("ublk_get_disks", rpc_ublk_get_disks, SPDK_RPC_RUNTIME)
     334                 :            : 
     335                 :            : struct rpc_ublk_recover_disk {
     336                 :            :         char            *bdev_name;
     337                 :            :         uint32_t        ublk_id;
     338                 :            :         struct spdk_jsonrpc_request *request;
     339                 :            : };
     340                 :            : 
     341                 :            : static const struct spdk_json_object_decoder rpc_ublk_recover_disk_decoders[] = {
     342                 :            :         {"bdev_name", offsetof(struct rpc_ublk_recover_disk, bdev_name), spdk_json_decode_string},
     343                 :            :         {"ublk_id", offsetof(struct rpc_ublk_recover_disk, ublk_id), spdk_json_decode_uint32},
     344                 :            : };
     345                 :            : 
     346                 :            : static void
     347                 :          0 : free_rpc_ublk_recover_disk(struct rpc_ublk_recover_disk *req)
     348                 :            : {
     349                 :          0 :         free(req->bdev_name);
     350                 :          0 :         free(req);
     351                 :          0 : }
     352                 :            : 
     353                 :            : static void
     354                 :          0 : rpc_ublk_recover_disk_done(void *cb_arg, int rc)
     355                 :            : {
     356                 :          0 :         struct rpc_ublk_recover_disk *req = cb_arg;
     357                 :            :         struct spdk_json_write_ctx *w;
     358                 :            : 
     359         [ #  # ]:          0 :         if (rc == 0) {
     360                 :          0 :                 w = spdk_jsonrpc_begin_result(req->request);
     361                 :          0 :                 spdk_json_write_uint32(w, req->ublk_id);
     362                 :          0 :                 spdk_jsonrpc_end_result(req->request, w);
     363                 :            :         } else {
     364                 :          0 :                 spdk_jsonrpc_send_error_response(req->request, rc, spdk_strerror(-rc));
     365                 :            :         }
     366                 :            : 
     367                 :          0 :         free_rpc_ublk_recover_disk(req);
     368                 :          0 : }
     369                 :            : 
     370                 :            : static void
     371                 :          0 : rpc_ublk_recover_disk(struct spdk_jsonrpc_request *request,
     372                 :            :                       const struct spdk_json_val *params)
     373                 :            : {
     374                 :            :         struct rpc_ublk_recover_disk *req;
     375                 :            :         int rc;
     376                 :            : 
     377                 :          0 :         req = calloc(1, sizeof(*req));
     378         [ #  # ]:          0 :         if (req == NULL) {
     379                 :          0 :                 SPDK_ERRLOG("could not allocate request.\n");
     380                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
     381                 :          0 :                 return;
     382                 :            :         }
     383                 :          0 :         req->request = request;
     384                 :            : 
     385         [ #  # ]:          0 :         if (spdk_json_decode_object(params, rpc_ublk_recover_disk_decoders,
     386                 :            :                                     SPDK_COUNTOF(rpc_ublk_recover_disk_decoders),
     387                 :            :                                     req)) {
     388                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     389                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     390                 :            :                                                  "spdk_json_decode_object failed");
     391                 :          0 :                 free(req);
     392                 :          0 :                 return;
     393                 :            :         }
     394                 :            : 
     395                 :          0 :         rc = ublk_start_disk_recovery(req->bdev_name, req->ublk_id, NULL, NULL);
     396                 :          0 :         rpc_ublk_recover_disk_done(req, rc);
     397                 :            : }
     398                 :            : 
     399                 :        476 : SPDK_RPC_REGISTER("ublk_recover_disk", rpc_ublk_recover_disk, SPDK_RPC_RUNTIME)

Generated by: LCOV version 1.14