LCOV - code coverage report
Current view: top level - spdk/lib/ublk - ublk_rpc.c (source / functions) Hit Total Coverage
Test: Combined Lines: 113 158 71.5 %
Date: 2024-07-11 18:14:01 Functions: 21 21 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 21 42 50.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                 :          5 : free_rpc_ublk_create_target(struct rpc_ublk_create_target *req)
      24                 :            : {
      25                 :          5 :         free(req->cpumask);
      26                 :          5 : }
      27                 :            : 
      28                 :            : static void
      29                 :          5 : rpc_ublk_create_target(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
      30                 :            : {
      31                 :          5 :         int rc = 0;
      32                 :          5 :         struct rpc_ublk_create_target req = {};
      33                 :            : 
      34         [ +  + ]:          5 :         if (params != NULL) {
      35         [ -  + ]:          1 :                 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                 :          5 :         rc = ublk_create_target(req.cpumask, params);
      44         [ -  + ]:          5 :         if (rc != 0) {
      45                 :          0 :                 goto invalid;
      46                 :            :         }
      47                 :          5 :         spdk_jsonrpc_send_bool_response(request, true);
      48                 :          5 :         free_rpc_ublk_create_target(&req);
      49                 :          5 :         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                 :        585 : SPDK_RPC_REGISTER("ublk_create_target", rpc_ublk_create_target, SPDK_RPC_RUNTIME)
      56                 :            : 
      57                 :            : static void
      58                 :          3 : ublk_destroy_target_done(void *arg)
      59                 :            : {
      60                 :          3 :         struct spdk_jsonrpc_request *req = arg;
      61                 :            : 
      62                 :          3 :         spdk_jsonrpc_send_bool_response(req, true);
      63                 :          3 :         SPDK_NOTICELOG("ublk target has been destroyed\n");
      64                 :          3 : }
      65                 :            : 
      66                 :            : static void
      67                 :          3 : rpc_ublk_destroy_target(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
      68                 :            : {
      69                 :          3 :         int rc = 0;
      70                 :            : 
      71                 :          3 :         rc = ublk_destroy_target(ublk_destroy_target_done, request);
      72         [ -  + ]:          3 :         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                 :          3 : }
      77                 :        585 : SPDK_RPC_REGISTER("ublk_destroy_target", rpc_ublk_destroy_target, SPDK_RPC_RUNTIME)
      78                 :            : 
      79                 :            : struct rpc_ublk_start_disk {
      80                 :            :         char            *bdev_name;
      81                 :            :         uint32_t        ublk_id;
      82                 :            :         uint32_t        num_queues;
      83                 :            :         uint32_t        queue_depth;
      84                 :            :         struct spdk_jsonrpc_request *request;
      85                 :            : };
      86                 :            : 
      87                 :            : static const struct spdk_json_object_decoder rpc_ublk_start_disk_decoders[] = {
      88                 :            :         {"bdev_name", offsetof(struct rpc_ublk_start_disk, bdev_name), spdk_json_decode_string},
      89                 :            :         {"ublk_id", offsetof(struct rpc_ublk_start_disk, ublk_id), spdk_json_decode_uint32},
      90                 :            :         {"num_queues", offsetof(struct rpc_ublk_start_disk, num_queues), spdk_json_decode_uint32, true},
      91                 :            :         {"queue_depth", offsetof(struct rpc_ublk_start_disk, queue_depth), spdk_json_decode_uint32, true},
      92                 :            : };
      93                 :            : 
      94                 :            : static void
      95                 :          7 : free_rpc_ublk_start_disk(struct rpc_ublk_start_disk *req)
      96                 :            : {
      97                 :          7 :         free(req->bdev_name);
      98                 :          7 :         free(req);
      99                 :          7 : }
     100                 :            : 
     101                 :            : static void
     102                 :          7 : rpc_ublk_start_disk_done(void *cb_arg, int rc)
     103                 :            : {
     104                 :          7 :         struct rpc_ublk_start_disk *req = cb_arg;
     105                 :            :         struct spdk_json_write_ctx *w;
     106                 :            : 
     107         [ +  - ]:          7 :         if (rc == 0) {
     108                 :          7 :                 w = spdk_jsonrpc_begin_result(req->request);
     109                 :          7 :                 spdk_json_write_uint32(w, req->ublk_id);
     110                 :          7 :                 spdk_jsonrpc_end_result(req->request, w);
     111                 :            :         } else {
     112                 :          0 :                 spdk_jsonrpc_send_error_response(req->request, rc, spdk_strerror(-rc));
     113                 :            :         }
     114                 :            : 
     115                 :          7 :         free_rpc_ublk_start_disk(req);
     116                 :          7 : }
     117                 :            : 
     118                 :            : static void
     119                 :          7 : rpc_ublk_start_disk(struct spdk_jsonrpc_request *request,
     120                 :            :                     const struct spdk_json_val *params)
     121                 :            : {
     122                 :            :         struct rpc_ublk_start_disk *req;
     123                 :            :         int rc;
     124                 :            : 
     125                 :          7 :         req = calloc(1, sizeof(*req));
     126         [ -  + ]:          7 :         if (req == NULL) {
     127                 :          0 :                 SPDK_ERRLOG("could not allocate request.\n");
     128                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
     129                 :          0 :                 return;
     130                 :            :         }
     131                 :          7 :         req->request = request;
     132                 :          7 :         req->queue_depth = UBLK_DEV_QUEUE_DEPTH;
     133                 :          7 :         req->num_queues = UBLK_DEV_NUM_QUEUE;
     134                 :            : 
     135         [ -  + ]:          7 :         if (spdk_json_decode_object(params, rpc_ublk_start_disk_decoders,
     136                 :            :                                     SPDK_COUNTOF(rpc_ublk_start_disk_decoders),
     137                 :            :                                     req)) {
     138                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     139                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     140                 :            :                                                  "spdk_json_decode_object failed");
     141                 :          0 :                 goto out;
     142                 :            :         }
     143                 :            : 
     144                 :          7 :         rc = ublk_start_disk(req->bdev_name, req->ublk_id, req->num_queues, req->queue_depth,
     145                 :            :                              rpc_ublk_start_disk_done, req);
     146         [ -  + ]:          7 :         if (rc != 0) {
     147                 :          0 :                 rpc_ublk_start_disk_done(req, rc);
     148                 :            :         }
     149                 :            : 
     150                 :          7 :         return;
     151                 :            : 
     152                 :          0 : out:
     153                 :          0 :         free_rpc_ublk_start_disk(req);
     154                 :            : }
     155                 :            : 
     156                 :        585 : SPDK_RPC_REGISTER("ublk_start_disk", rpc_ublk_start_disk, SPDK_RPC_RUNTIME)
     157                 :            : 
     158                 :            : struct rpc_ublk_stop_disk {
     159                 :            :         uint32_t ublk_id;
     160                 :            :         struct spdk_jsonrpc_request *request;
     161                 :            : };
     162                 :            : 
     163                 :            : static void
     164                 :          7 : free_rpc_ublk_stop_disk(struct rpc_ublk_stop_disk *req)
     165                 :            : {
     166                 :          7 :         free(req);
     167                 :          7 : }
     168                 :            : 
     169                 :            : static const struct spdk_json_object_decoder rpc_ublk_stop_disk_decoders[] = {
     170                 :            :         {"ublk_id", offsetof(struct rpc_ublk_stop_disk, ublk_id), spdk_json_decode_uint32},
     171                 :            : };
     172                 :            : 
     173                 :            : static void
     174                 :          6 : rpc_ublk_stop_disk_done(void *cb_arg, int rc)
     175                 :            : {
     176                 :          6 :         struct rpc_ublk_stop_disk *req = cb_arg;
     177                 :            : 
     178                 :          6 :         spdk_jsonrpc_send_bool_response(req->request, true);
     179                 :          6 :         free_rpc_ublk_stop_disk(req);
     180                 :          6 : }
     181                 :            : 
     182                 :            : static void
     183                 :          7 : rpc_ublk_stop_disk(struct spdk_jsonrpc_request *request,
     184                 :            :                    const struct spdk_json_val *params)
     185                 :            : {
     186                 :            :         struct rpc_ublk_stop_disk *req;
     187                 :            :         int rc;
     188                 :            : 
     189                 :          7 :         req = calloc(1, sizeof(*req));
     190         [ -  + ]:          7 :         if (req == NULL) {
     191                 :          0 :                 SPDK_ERRLOG("could not allocate request.\n");
     192                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
     193                 :          0 :                 return;
     194                 :            :         }
     195                 :          7 :         req->request = request;
     196                 :            : 
     197         [ -  + ]:          7 :         if (spdk_json_decode_object(params, rpc_ublk_stop_disk_decoders,
     198                 :            :                                     SPDK_COUNTOF(rpc_ublk_stop_disk_decoders),
     199                 :            :                                     req)) {
     200                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     201                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     202                 :            :                                                  "spdk_json_decode_object failed");
     203                 :          0 :                 goto invalid;
     204                 :            :         }
     205                 :            : 
     206                 :          7 :         rc = ublk_stop_disk(req->ublk_id, rpc_ublk_stop_disk_done, req);
     207         [ +  + ]:          7 :         if (rc) {
     208                 :          1 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     209                 :          1 :                 goto invalid;
     210                 :            :         }
     211                 :          6 :         return;
     212                 :            : 
     213                 :          1 : invalid:
     214                 :          1 :         free_rpc_ublk_stop_disk(req);
     215                 :            : }
     216                 :            : 
     217                 :        585 : SPDK_RPC_REGISTER("ublk_stop_disk", rpc_ublk_stop_disk, SPDK_RPC_RUNTIME)
     218                 :            : 
     219                 :            : static void
     220                 :          6 : rpc_dump_ublk_info(struct spdk_json_write_ctx *w,
     221                 :            :                    struct spdk_ublk_dev *ublk)
     222                 :            : {
     223                 :          6 :         char ublk_path[32];
     224                 :            : 
     225         [ -  + ]:          6 :         snprintf(ublk_path, 32, "%s%u", "/dev/ublkb", ublk_dev_get_id(ublk));
     226                 :          6 :         spdk_json_write_object_begin(w);
     227                 :            : 
     228                 :          6 :         spdk_json_write_named_string(w, "ublk_device", ublk_path);
     229                 :          6 :         spdk_json_write_named_uint32(w, "id", ublk_dev_get_id(ublk));
     230                 :          6 :         spdk_json_write_named_uint32(w, "queue_depth", ublk_dev_get_queue_depth(ublk));
     231                 :          6 :         spdk_json_write_named_uint32(w, "num_queues", ublk_dev_get_num_queues(ublk));
     232                 :          6 :         spdk_json_write_named_string(w, "bdev_name", ublk_dev_get_bdev_name(ublk));
     233                 :            : 
     234                 :          6 :         spdk_json_write_object_end(w);
     235                 :          6 : }
     236                 :            : 
     237                 :            : struct rpc_ublk_get_disks {
     238                 :            :         uint32_t ublk_id;
     239                 :            : };
     240                 :            : 
     241                 :            : static const struct spdk_json_object_decoder rpc_ublk_get_disks_decoders[] = {
     242                 :            :         {"ublk_id", offsetof(struct rpc_ublk_get_disks, ublk_id), spdk_json_decode_uint32, true},
     243                 :            : };
     244                 :            : 
     245                 :            : static void
     246                 :          3 : rpc_ublk_get_disks(struct spdk_jsonrpc_request *request,
     247                 :            :                    const struct spdk_json_val *params)
     248                 :            : {
     249                 :          3 :         struct rpc_ublk_get_disks req = {};
     250                 :            :         struct spdk_json_write_ctx *w;
     251                 :          3 :         struct spdk_ublk_dev *ublk = NULL;
     252                 :            : 
     253         [ -  + ]:          3 :         if (params != NULL) {
     254         [ #  # ]:          0 :                 if (spdk_json_decode_object(params, rpc_ublk_get_disks_decoders,
     255                 :            :                                             SPDK_COUNTOF(rpc_ublk_get_disks_decoders),
     256                 :            :                                             &req)) {
     257                 :          0 :                         SPDK_ERRLOG("spdk_json_decode_object failed\n");
     258                 :          0 :                         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     259                 :            :                                                          "spdk_json_decode_object failed");
     260                 :          0 :                         return;
     261                 :            :                 }
     262                 :            : 
     263         [ #  # ]:          0 :                 if (req.ublk_id) {
     264                 :          0 :                         ublk = ublk_dev_find_by_id(req.ublk_id);
     265         [ #  # ]:          0 :                         if (ublk == NULL) {
     266                 :          0 :                                 SPDK_ERRLOG("ublk device '%d' does not exist\n", req.ublk_id);
     267                 :          0 :                                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     268                 :          0 :                                 return;
     269                 :            :                         }
     270                 :            :                 }
     271                 :            :         }
     272                 :            : 
     273                 :          3 :         w = spdk_jsonrpc_begin_result(request);
     274                 :          3 :         spdk_json_write_array_begin(w);
     275                 :            : 
     276         [ -  + ]:          3 :         if (ublk != NULL) {
     277                 :          0 :                 rpc_dump_ublk_info(w, ublk);
     278                 :            :         } else {
     279         [ +  + ]:          9 :                 for (ublk = ublk_dev_first(); ublk != NULL; ublk = ublk_dev_next(ublk)) {
     280                 :          6 :                         rpc_dump_ublk_info(w, ublk);
     281                 :            :                 }
     282                 :            :         }
     283                 :            : 
     284                 :          3 :         spdk_json_write_array_end(w);
     285                 :          3 :         spdk_jsonrpc_end_result(request, w);
     286                 :            : 
     287                 :          3 :         return;
     288                 :            : }
     289                 :        585 : SPDK_RPC_REGISTER("ublk_get_disks", rpc_ublk_get_disks, SPDK_RPC_RUNTIME)
     290                 :            : 
     291                 :            : struct rpc_ublk_recover_disk {
     292                 :            :         char            *bdev_name;
     293                 :            :         uint32_t        ublk_id;
     294                 :            :         struct spdk_jsonrpc_request *request;
     295                 :            : };
     296                 :            : 
     297                 :            : static const struct spdk_json_object_decoder rpc_ublk_recover_disk_decoders[] = {
     298                 :            :         {"bdev_name", offsetof(struct rpc_ublk_recover_disk, bdev_name), spdk_json_decode_string},
     299                 :            :         {"ublk_id", offsetof(struct rpc_ublk_recover_disk, ublk_id), spdk_json_decode_uint32},
     300                 :            : };
     301                 :            : 
     302                 :            : static void
     303                 :          1 : free_rpc_ublk_recover_disk(struct rpc_ublk_recover_disk *req)
     304                 :            : {
     305                 :          1 :         free(req->bdev_name);
     306                 :          1 :         free(req);
     307                 :          1 : }
     308                 :            : 
     309                 :            : static void
     310                 :          1 : rpc_ublk_recover_disk_done(void *cb_arg, int rc)
     311                 :            : {
     312                 :          1 :         struct rpc_ublk_recover_disk *req = cb_arg;
     313                 :            :         struct spdk_json_write_ctx *w;
     314                 :            : 
     315         [ +  - ]:          1 :         if (rc == 0) {
     316                 :          1 :                 w = spdk_jsonrpc_begin_result(req->request);
     317                 :          1 :                 spdk_json_write_uint32(w, req->ublk_id);
     318                 :          1 :                 spdk_jsonrpc_end_result(req->request, w);
     319                 :            :         } else {
     320                 :          0 :                 spdk_jsonrpc_send_error_response(req->request, rc, spdk_strerror(-rc));
     321                 :            :         }
     322                 :            : 
     323                 :          1 :         free_rpc_ublk_recover_disk(req);
     324                 :          1 : }
     325                 :            : 
     326                 :            : static void
     327                 :          1 : rpc_ublk_recover_disk(struct spdk_jsonrpc_request *request,
     328                 :            :                       const struct spdk_json_val *params)
     329                 :            : {
     330                 :            :         struct rpc_ublk_recover_disk *req;
     331                 :            :         int rc;
     332                 :            : 
     333                 :          1 :         req = calloc(1, sizeof(*req));
     334         [ -  + ]:          1 :         if (req == NULL) {
     335                 :          0 :                 SPDK_ERRLOG("could not allocate request.\n");
     336                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
     337                 :          0 :                 return;
     338                 :            :         }
     339                 :          1 :         req->request = request;
     340                 :            : 
     341         [ -  + ]:          1 :         if (spdk_json_decode_object(params, rpc_ublk_recover_disk_decoders,
     342                 :            :                                     SPDK_COUNTOF(rpc_ublk_recover_disk_decoders),
     343                 :            :                                     req)) {
     344                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     345                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     346                 :            :                                                  "spdk_json_decode_object failed");
     347                 :          0 :                 free(req);
     348                 :          0 :                 return;
     349                 :            :         }
     350                 :            : 
     351                 :          1 :         rc = ublk_start_disk_recovery(req->bdev_name, req->ublk_id, NULL, NULL);
     352                 :          1 :         rpc_ublk_recover_disk_done(req, rc);
     353                 :            : }
     354                 :            : 
     355                 :        585 : SPDK_RPC_REGISTER("ublk_recover_disk", rpc_ublk_recover_disk, SPDK_RPC_RUNTIME)

Generated by: LCOV version 1.14