xref: /spdk/module/bdev/passthru/vbdev_passthru_rpc.c (revision 73bc324b0df56dc389f7030d52d3ed920b1f66b9)
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