1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 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 char *uuid; 18 }; 19 20 /* Free the allocated memory resource after the RPC handling. */ 21 static void 22 free_rpc_bdev_passthru_create(struct rpc_bdev_passthru_create *r) 23 { 24 free(r->base_bdev_name); 25 free(r->name); 26 free(r->uuid); 27 } 28 29 /* Structure to decode the input parameters for this RPC method. */ 30 static const struct spdk_json_object_decoder rpc_bdev_passthru_create_decoders[] = { 31 {"base_bdev_name", offsetof(struct rpc_bdev_passthru_create, base_bdev_name), spdk_json_decode_string}, 32 {"name", offsetof(struct rpc_bdev_passthru_create, name), spdk_json_decode_string}, 33 {"uuid", offsetof(struct rpc_bdev_passthru_create, uuid), spdk_json_decode_string, true}, 34 }; 35 36 /* Decode the parameters for this RPC method and properly construct the passthru 37 * device. Error status returned in the failed cases. 38 */ 39 static void 40 rpc_bdev_passthru_create(struct spdk_jsonrpc_request *request, 41 const struct spdk_json_val *params) 42 { 43 struct rpc_bdev_passthru_create req = {NULL}; 44 struct spdk_json_write_ctx *w; 45 struct spdk_uuid *uuid = NULL; 46 struct spdk_uuid decoded_uuid; 47 int rc; 48 49 if (spdk_json_decode_object(params, rpc_bdev_passthru_create_decoders, 50 SPDK_COUNTOF(rpc_bdev_passthru_create_decoders), 51 &req)) { 52 SPDK_DEBUGLOG(vbdev_passthru, "spdk_json_decode_object failed\n"); 53 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 54 "spdk_json_decode_object failed"); 55 goto cleanup; 56 } 57 58 if (req.uuid) { 59 if (spdk_uuid_parse(&decoded_uuid, req.uuid)) { 60 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 61 "Failed to parse bdev UUID"); 62 goto cleanup; 63 } 64 uuid = &decoded_uuid; 65 } 66 67 rc = bdev_passthru_create_disk(req.base_bdev_name, req.name, uuid); 68 if (rc != 0) { 69 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 70 goto cleanup; 71 } 72 73 w = spdk_jsonrpc_begin_result(request); 74 spdk_json_write_string(w, req.name); 75 spdk_jsonrpc_end_result(request, w); 76 77 cleanup: 78 free_rpc_bdev_passthru_create(&req); 79 } 80 SPDK_RPC_REGISTER("bdev_passthru_create", rpc_bdev_passthru_create, SPDK_RPC_RUNTIME) 81 82 struct rpc_bdev_passthru_delete { 83 char *name; 84 }; 85 86 static void 87 free_rpc_bdev_passthru_delete(struct rpc_bdev_passthru_delete *req) 88 { 89 free(req->name); 90 } 91 92 static const struct spdk_json_object_decoder rpc_bdev_passthru_delete_decoders[] = { 93 {"name", offsetof(struct rpc_bdev_passthru_delete, name), spdk_json_decode_string}, 94 }; 95 96 static void 97 rpc_bdev_passthru_delete_cb(void *cb_arg, int bdeverrno) 98 { 99 struct spdk_jsonrpc_request *request = cb_arg; 100 101 if (bdeverrno == 0) { 102 spdk_jsonrpc_send_bool_response(request, true); 103 } else { 104 spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno)); 105 } 106 } 107 108 static void 109 rpc_bdev_passthru_delete(struct spdk_jsonrpc_request *request, 110 const struct spdk_json_val *params) 111 { 112 struct rpc_bdev_passthru_delete req = {NULL}; 113 114 if (spdk_json_decode_object(params, rpc_bdev_passthru_delete_decoders, 115 SPDK_COUNTOF(rpc_bdev_passthru_delete_decoders), 116 &req)) { 117 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 118 "spdk_json_decode_object failed"); 119 goto cleanup; 120 } 121 122 bdev_passthru_delete_disk(req.name, rpc_bdev_passthru_delete_cb, request); 123 124 cleanup: 125 free_rpc_bdev_passthru_delete(&req); 126 } 127 SPDK_RPC_REGISTER("bdev_passthru_delete", rpc_bdev_passthru_delete, SPDK_RPC_RUNTIME) 128