1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2020 Intel Corporation. 3 * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 * All rights reserved. 5 */ 6 7 #include "vbdev_passthru.h" 8 #include "spdk/rpc.h" 9 #include "spdk/util.h" 10 #include "spdk/string.h" 11 #include "spdk/log.h" 12 13 /* Structure to hold the parameters for this RPC method. */ 14 struct rpc_bdev_passthru_create { 15 char *base_bdev_name; 16 char *name; 17 }; 18 19 /* Free the allocated memory resource after the RPC handling. */ 20 static void 21 free_rpc_bdev_passthru_create(struct rpc_bdev_passthru_create *r) 22 { 23 free(r->base_bdev_name); 24 free(r->name); 25 } 26 27 /* Structure to decode the input parameters for this RPC method. */ 28 static const struct spdk_json_object_decoder rpc_bdev_passthru_create_decoders[] = { 29 {"base_bdev_name", offsetof(struct rpc_bdev_passthru_create, base_bdev_name), spdk_json_decode_string}, 30 {"name", offsetof(struct rpc_bdev_passthru_create, name), spdk_json_decode_string}, 31 }; 32 33 /* Decode the parameters for this RPC method and properly construct the passthru 34 * device. Error status returned in the failed cases. 35 */ 36 static void 37 rpc_bdev_passthru_create(struct spdk_jsonrpc_request *request, 38 const struct spdk_json_val *params) 39 { 40 struct rpc_bdev_passthru_create req = {NULL}; 41 struct spdk_json_write_ctx *w; 42 int rc; 43 44 if (spdk_json_decode_object(params, rpc_bdev_passthru_create_decoders, 45 SPDK_COUNTOF(rpc_bdev_passthru_create_decoders), 46 &req)) { 47 SPDK_DEBUGLOG(vbdev_passthru, "spdk_json_decode_object failed\n"); 48 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 49 "spdk_json_decode_object failed"); 50 goto cleanup; 51 } 52 53 rc = bdev_passthru_external_create_disk(req.base_bdev_name, req.name); 54 if (rc != 0) { 55 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 56 goto cleanup; 57 } 58 59 w = spdk_jsonrpc_begin_result(request); 60 spdk_json_write_string(w, req.name); 61 spdk_jsonrpc_end_result(request, w); 62 63 cleanup: 64 free_rpc_bdev_passthru_create(&req); 65 } 66 SPDK_RPC_REGISTER("construct_ext_passthru_bdev", rpc_bdev_passthru_create, SPDK_RPC_RUNTIME) 67 68 struct rpc_bdev_passthru_delete { 69 char *name; 70 }; 71 72 static void 73 free_rpc_bdev_passthru_delete(struct rpc_bdev_passthru_delete *req) 74 { 75 free(req->name); 76 } 77 78 static const struct spdk_json_object_decoder rpc_bdev_passthru_delete_decoders[] = { 79 {"name", offsetof(struct rpc_bdev_passthru_delete, name), spdk_json_decode_string}, 80 }; 81 82 static void 83 rpc_bdev_passthru_delete_cb(void *cb_arg, int bdeverrno) 84 { 85 struct spdk_jsonrpc_request *request = cb_arg; 86 87 if (bdeverrno == 0) { 88 spdk_jsonrpc_send_bool_response(request, true); 89 } else { 90 spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno)); 91 92 } 93 } 94 95 static void 96 rpc_bdev_passthru_delete(struct spdk_jsonrpc_request *request, 97 const struct spdk_json_val *params) 98 { 99 struct rpc_bdev_passthru_delete req = {NULL}; 100 struct spdk_bdev *bdev; 101 102 if (spdk_json_decode_object(params, rpc_bdev_passthru_delete_decoders, 103 SPDK_COUNTOF(rpc_bdev_passthru_delete_decoders), 104 &req)) { 105 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 106 "spdk_json_decode_object failed"); 107 goto cleanup; 108 } 109 110 bdev_passthru_external_delete_disk(req.name, rpc_bdev_passthru_delete_cb, request); 111 112 cleanup: 113 free_rpc_bdev_passthru_delete(&req); 114 } 115 SPDK_RPC_REGISTER("delete_ext_passthru_bdev", rpc_bdev_passthru_delete, SPDK_RPC_RUNTIME) 116