LCOV - code coverage report
Current view: top level - spdk/module/vfu_device - vfu_virtio_rpc.c (source / functions) Hit Total Coverage
Test: Combined Lines: 58 110 52.7 %
Date: 2024-07-14 19:29:32 Functions: 13 15 86.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 12 28 42.9 %

           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/bdev.h"
       7                 :            : #include "spdk/log.h"
       8                 :            : #include "spdk/rpc.h"
       9                 :            : #include "spdk/env.h"
      10                 :            : #include "spdk/string.h"
      11                 :            : #include "spdk/util.h"
      12                 :            : #include "spdk/thread.h"
      13                 :            : 
      14                 :            : #include "vfu_virtio_internal.h"
      15                 :            : 
      16                 :            : struct rpc_delete_vfu_endpoint {
      17                 :            :         char            *name;
      18                 :            : };
      19                 :            : 
      20                 :            : static const struct spdk_json_object_decoder rpc_delete_vfu_endpoint_decode[] = {
      21                 :            :         {"name", offsetof(struct rpc_delete_vfu_endpoint, name), spdk_json_decode_string }
      22                 :            : };
      23                 :            : 
      24                 :            : static void
      25                 :          2 : free_rpc_delete_vfu_endpoint(struct rpc_delete_vfu_endpoint *req)
      26                 :            : {
      27                 :          2 :         free(req->name);
      28                 :          2 : }
      29                 :            : 
      30                 :            : static void
      31                 :          2 : rpc_vfu_virtio_delete_endpoint(struct spdk_jsonrpc_request *request,
      32                 :            :                                const struct spdk_json_val *params)
      33                 :            : {
      34                 :          2 :         struct rpc_delete_vfu_endpoint req = {0};
      35                 :            :         int rc;
      36                 :            : 
      37         [ -  + ]:          2 :         if (spdk_json_decode_object(params, rpc_delete_vfu_endpoint_decode,
      38                 :            :                                     SPDK_COUNTOF(rpc_delete_vfu_endpoint_decode),
      39                 :            :                                     &req)) {
      40                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
      41                 :          0 :                 rc = -EINVAL;
      42                 :          0 :                 goto invalid;
      43                 :            :         }
      44                 :            : 
      45                 :          2 :         rc = spdk_vfu_delete_endpoint(req.name);
      46         [ -  + ]:          2 :         if (rc < 0) {
      47                 :          0 :                 goto invalid;
      48                 :            :         }
      49                 :          2 :         free_rpc_delete_vfu_endpoint(&req);
      50                 :            : 
      51                 :          2 :         spdk_jsonrpc_send_bool_response(request, true);
      52                 :          2 :         return;
      53                 :            : 
      54                 :          0 : invalid:
      55                 :          0 :         free_rpc_delete_vfu_endpoint(&req);
      56                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
      57                 :            :                                          spdk_strerror(-rc));
      58                 :            : }
      59                 :        202 : SPDK_RPC_REGISTER("vfu_virtio_delete_endpoint", rpc_vfu_virtio_delete_endpoint,
      60                 :            :                   SPDK_RPC_RUNTIME)
      61                 :            : 
      62                 :            : struct rpc_vfu_virtio_create_blk {
      63                 :            :         char            *name;
      64                 :            :         char            *bdev_name;
      65                 :            :         char            *cpumask;
      66                 :            :         uint16_t        num_queues;
      67                 :            :         uint16_t        qsize;
      68                 :            :         bool            packed_ring;
      69                 :            : };
      70                 :            : 
      71                 :            : static const struct spdk_json_object_decoder rpc_construct_vfu_virtio_create_blk[] = {
      72                 :            :         {"name", offsetof(struct rpc_vfu_virtio_create_blk, name), spdk_json_decode_string },
      73                 :            :         {"bdev_name", offsetof(struct rpc_vfu_virtio_create_blk, bdev_name), spdk_json_decode_string },
      74                 :            :         {"cpumask", offsetof(struct rpc_vfu_virtio_create_blk, cpumask), spdk_json_decode_string, true},
      75                 :            :         {"num_queues", offsetof(struct rpc_vfu_virtio_create_blk, num_queues), spdk_json_decode_uint16, true },
      76                 :            :         {"qsize", offsetof(struct rpc_vfu_virtio_create_blk, qsize), spdk_json_decode_uint16, true },
      77                 :            :         {"packed_ring", offsetof(struct rpc_vfu_virtio_create_blk, packed_ring), spdk_json_decode_bool, true},
      78                 :            : };
      79                 :            : 
      80                 :            : static void
      81                 :          2 : free_rpc_vfu_virtio_create_blk(struct rpc_vfu_virtio_create_blk *req)
      82                 :            : {
      83                 :          2 :         free(req->name);
      84                 :          2 :         free(req->bdev_name);
      85                 :          2 :         free(req->cpumask);
      86                 :          2 : }
      87                 :            : 
      88                 :            : static void
      89                 :          2 : rpc_vfu_virtio_create_blk_endpoint(struct spdk_jsonrpc_request *request,
      90                 :            :                                    const struct spdk_json_val *params)
      91                 :            : {
      92                 :          2 :         struct rpc_vfu_virtio_create_blk req = {0};
      93                 :            :         int rc;
      94                 :            : 
      95         [ -  + ]:          2 :         if (spdk_json_decode_object(params, rpc_construct_vfu_virtio_create_blk,
      96                 :            :                                     SPDK_COUNTOF(rpc_construct_vfu_virtio_create_blk),
      97                 :            :                                     &req)) {
      98                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
      99                 :          0 :                 rc = -EINVAL;
     100                 :          0 :                 goto invalid;
     101                 :            :         }
     102                 :            : 
     103                 :          2 :         rc = spdk_vfu_create_endpoint(req.name, req.cpumask, "virtio_blk");
     104         [ -  + ]:          2 :         if (rc) {
     105                 :          0 :                 SPDK_ERRLOG("Failed to create virtio_blk endpoint\n");
     106                 :          0 :                 goto invalid;
     107                 :            :         }
     108                 :            : 
     109                 :          2 :         rc = vfu_virtio_blk_add_bdev(req.name, req.bdev_name, req.num_queues, req.qsize,
     110         [ -  + ]:          2 :                                      req.packed_ring);
     111         [ -  + ]:          2 :         if (rc < 0) {
     112                 :          0 :                 spdk_vfu_delete_endpoint(req.name);
     113                 :          0 :                 goto invalid;
     114                 :            :         }
     115                 :          2 :         free_rpc_vfu_virtio_create_blk(&req);
     116                 :            : 
     117                 :          2 :         spdk_jsonrpc_send_bool_response(request, true);
     118                 :          2 :         return;
     119                 :            : 
     120                 :          0 : invalid:
     121                 :          0 :         free_rpc_vfu_virtio_create_blk(&req);
     122                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     123                 :            :                                          spdk_strerror(-rc));
     124                 :            : }
     125                 :        202 : SPDK_RPC_REGISTER("vfu_virtio_create_blk_endpoint", rpc_vfu_virtio_create_blk_endpoint,
     126                 :            :                   SPDK_RPC_RUNTIME)
     127                 :            : 
     128                 :            : struct rpc_vfu_virtio_scsi {
     129                 :            :         char            *name;
     130                 :            :         uint8_t         scsi_target_num;
     131                 :            :         char            *bdev_name;
     132                 :            : };
     133                 :            : 
     134                 :            : static const struct spdk_json_object_decoder rpc_construct_vfu_virtio_scsi[] = {
     135                 :            :         {"name", offsetof(struct rpc_vfu_virtio_scsi, name), spdk_json_decode_string },
     136                 :            :         {"scsi_target_num", offsetof(struct rpc_vfu_virtio_scsi, scsi_target_num), spdk_json_decode_uint8 },
     137                 :            :         {"bdev_name", offsetof(struct rpc_vfu_virtio_scsi, bdev_name), spdk_json_decode_string },
     138                 :            : };
     139                 :            : 
     140                 :            : static void
     141                 :          3 : free_rpc_vfu_virtio_scsi(struct rpc_vfu_virtio_scsi *req)
     142                 :            : {
     143                 :          3 :         free(req->name);
     144                 :          3 :         free(req->bdev_name);
     145                 :          3 : }
     146                 :            : 
     147                 :            : static void
     148                 :          3 : rpc_vfu_virtio_scsi_add_target(struct spdk_jsonrpc_request *request,
     149                 :            :                                const struct spdk_json_val *params)
     150                 :            : {
     151                 :          3 :         struct rpc_vfu_virtio_scsi req = {0};
     152                 :            :         int rc;
     153                 :            : 
     154         [ -  + ]:          3 :         if (spdk_json_decode_object(params, rpc_construct_vfu_virtio_scsi,
     155                 :            :                                     SPDK_COUNTOF(rpc_construct_vfu_virtio_scsi),
     156                 :            :                                     &req)) {
     157                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     158                 :          0 :                 rc = -EINVAL;
     159                 :          0 :                 goto invalid;
     160                 :            :         }
     161                 :            : 
     162                 :          3 :         rc = vfu_virtio_scsi_add_target(req.name, req.scsi_target_num, req.bdev_name);;
     163         [ -  + ]:          3 :         if (rc < 0) {
     164                 :          0 :                 goto invalid;
     165                 :            :         }
     166                 :            : 
     167                 :          3 :         free_rpc_vfu_virtio_scsi(&req);
     168                 :          3 :         spdk_jsonrpc_send_bool_response(request, true);
     169                 :          3 :         return;
     170                 :            : 
     171                 :          0 : invalid:
     172                 :          0 :         free_rpc_vfu_virtio_scsi(&req);
     173                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     174                 :            :                                          spdk_strerror(-rc));
     175                 :            : }
     176                 :        202 : SPDK_RPC_REGISTER("vfu_virtio_scsi_add_target", rpc_vfu_virtio_scsi_add_target,
     177                 :            :                   SPDK_RPC_RUNTIME)
     178                 :            : 
     179                 :            : struct rpc_vfu_virtio_scsi_remove {
     180                 :            :         char            *name;
     181                 :            :         uint8_t         scsi_target_num;
     182                 :            : };
     183                 :            : 
     184                 :            : static const struct spdk_json_object_decoder rpc_remove_vfu_virtio_scsi_target[] = {
     185                 :            :         {"name", offsetof(struct rpc_vfu_virtio_scsi_remove, name), spdk_json_decode_string },
     186                 :            :         {"scsi_target_num", offsetof(struct rpc_vfu_virtio_scsi_remove, scsi_target_num), spdk_json_decode_uint8 },
     187                 :            : };
     188                 :            : 
     189                 :            : static void
     190                 :          0 : free_rpc_vfu_virtio_scsi_remove(struct rpc_vfu_virtio_scsi_remove *req)
     191                 :            : {
     192                 :          0 :         free(req->name);
     193                 :          0 : }
     194                 :            : 
     195                 :            : static void
     196                 :          0 : rpc_vfu_virtio_scsi_remove_target(struct spdk_jsonrpc_request *request,
     197                 :            :                                   const struct spdk_json_val *params)
     198                 :            : {
     199                 :          0 :         struct rpc_vfu_virtio_scsi_remove req = {0};
     200                 :            :         int rc;
     201                 :            : 
     202         [ #  # ]:          0 :         if (spdk_json_decode_object(params, rpc_remove_vfu_virtio_scsi_target,
     203                 :            :                                     SPDK_COUNTOF(rpc_remove_vfu_virtio_scsi_target),
     204                 :            :                                     &req)) {
     205                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     206                 :          0 :                 rc = -EINVAL;
     207                 :          0 :                 goto invalid;
     208                 :            :         }
     209                 :            : 
     210                 :          0 :         rc = vfu_virtio_scsi_remove_target(req.name, req.scsi_target_num);
     211         [ #  # ]:          0 :         if (rc < 0) {
     212                 :          0 :                 goto invalid;
     213                 :            :         }
     214                 :            : 
     215                 :          0 :         free_rpc_vfu_virtio_scsi_remove(&req);
     216                 :          0 :         spdk_jsonrpc_send_bool_response(request, true);
     217                 :          0 :         return;
     218                 :            : 
     219                 :          0 : invalid:
     220                 :          0 :         free_rpc_vfu_virtio_scsi_remove(&req);
     221                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     222                 :            :                                          spdk_strerror(-rc));
     223                 :            : }
     224                 :        202 : SPDK_RPC_REGISTER("vfu_virtio_scsi_remove_target", rpc_vfu_virtio_scsi_remove_target,
     225                 :            :                   SPDK_RPC_RUNTIME)
     226                 :            : 
     227                 :            : struct rpc_vfu_virtio_create_scsi {
     228                 :            :         char            *name;
     229                 :            :         char            *cpumask;
     230                 :            :         uint16_t        num_io_queues;
     231                 :            :         uint16_t        qsize;
     232                 :            :         bool            packed_ring;
     233                 :            : };
     234                 :            : 
     235                 :            : static const struct spdk_json_object_decoder rpc_construct_vfu_virtio_create_scsi[] = {
     236                 :            :         {"name", offsetof(struct rpc_vfu_virtio_create_scsi, name), spdk_json_decode_string },
     237                 :            :         {"cpumask", offsetof(struct rpc_vfu_virtio_create_scsi, cpumask), spdk_json_decode_string, true},
     238                 :            :         {"num_io_queues", offsetof(struct rpc_vfu_virtio_create_scsi, num_io_queues), spdk_json_decode_uint16, true },
     239                 :            :         {"qsize", offsetof(struct rpc_vfu_virtio_create_scsi, qsize), spdk_json_decode_uint16, true },
     240                 :            :         {"packed_ring", offsetof(struct rpc_vfu_virtio_create_scsi, packed_ring), spdk_json_decode_bool, true},
     241                 :            : };
     242                 :            : 
     243                 :            : static void
     244                 :          2 : free_rpc_vfu_virtio_create_scsi(struct rpc_vfu_virtio_create_scsi *req)
     245                 :            : {
     246                 :          2 :         free(req->name);
     247                 :          2 :         free(req->cpumask);
     248                 :          2 : }
     249                 :            : 
     250                 :            : static void
     251                 :          2 : rpc_vfu_virtio_create_scsi_endpoint(struct spdk_jsonrpc_request *request,
     252                 :            :                                     const struct spdk_json_val *params)
     253                 :            : {
     254                 :          2 :         struct rpc_vfu_virtio_create_scsi req = {0};
     255                 :            :         int rc;
     256                 :            : 
     257         [ -  + ]:          2 :         if (spdk_json_decode_object(params, rpc_construct_vfu_virtio_create_scsi,
     258                 :            :                                     SPDK_COUNTOF(rpc_construct_vfu_virtio_create_scsi),
     259                 :            :                                     &req)) {
     260                 :          0 :                 SPDK_ERRLOG("spdk_json_decode_object failed\n");
     261                 :          0 :                 rc = -EINVAL;
     262                 :          0 :                 goto invalid;
     263                 :            :         }
     264                 :            : 
     265                 :          2 :         rc = spdk_vfu_create_endpoint(req.name, req.cpumask, "virtio_scsi");
     266         [ -  + ]:          2 :         if (rc) {
     267                 :          0 :                 SPDK_ERRLOG("Failed to create virtio_blk endpoint\n");
     268                 :          0 :                 goto invalid;
     269                 :            :         }
     270                 :            : 
     271         [ -  + ]:          2 :         rc = vfu_virtio_scsi_set_options(req.name, req.num_io_queues, req.qsize, req.packed_ring);
     272         [ -  + ]:          2 :         if (rc < 0) {
     273                 :          0 :                 spdk_vfu_delete_endpoint(req.name);
     274                 :          0 :                 goto invalid;
     275                 :            :         }
     276                 :          2 :         free_rpc_vfu_virtio_create_scsi(&req);
     277                 :            : 
     278                 :          2 :         spdk_jsonrpc_send_bool_response(request, true);
     279                 :          2 :         return;
     280                 :            : 
     281                 :          0 : invalid:
     282                 :          0 :         free_rpc_vfu_virtio_create_scsi(&req);
     283                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     284                 :            :                                          spdk_strerror(-rc));
     285                 :            : }
     286                 :        202 : SPDK_RPC_REGISTER("vfu_virtio_create_scsi_endpoint", rpc_vfu_virtio_create_scsi_endpoint,
     287                 :            :                   SPDK_RPC_RUNTIME)

Generated by: LCOV version 1.14