Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2016 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "bdev_rbd.h"
7 : : #include "spdk/util.h"
8 : : #include "spdk/uuid.h"
9 : : #include "spdk/string.h"
10 : : #include "spdk/log.h"
11 : :
12 : : struct rpc_create_rbd {
13 : : char *name;
14 : : char *user_id;
15 : : char *pool_name;
16 : : char *rbd_name;
17 : : uint32_t block_size;
18 : : char **config;
19 : : char *cluster_name;
20 : : struct spdk_uuid uuid;
21 : : };
22 : :
23 : : static void
24 : 10 : free_rpc_create_rbd(struct rpc_create_rbd *req)
25 : : {
26 : 10 : free(req->name);
27 : 10 : free(req->user_id);
28 : 10 : free(req->pool_name);
29 : 10 : free(req->rbd_name);
30 : 10 : bdev_rbd_free_config(req->config);
31 : 10 : free(req->cluster_name);
32 : 10 : }
33 : :
34 : : static int
35 : 0 : bdev_rbd_decode_config(const struct spdk_json_val *values, void *out)
36 : : {
37 : 0 : char ***map = out;
38 : : char **entry;
39 : : uint32_t i;
40 : :
41 [ # # ]: 0 : if (values->type == SPDK_JSON_VAL_NULL) {
42 : : /* treated like empty object: empty config */
43 : 0 : *map = calloc(1, sizeof(**map));
44 [ # # ]: 0 : if (!*map) {
45 : 0 : return -1;
46 : : }
47 : 0 : return 0;
48 : : }
49 : :
50 [ # # ]: 0 : if (values->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
51 : 0 : return -1;
52 : : }
53 : :
54 : 0 : *map = calloc(values->len + 1, sizeof(**map));
55 [ # # ]: 0 : if (!*map) {
56 : 0 : return -1;
57 : : }
58 : :
59 [ # # ]: 0 : for (i = 0, entry = *map; i < values->len;) {
60 : 0 : const struct spdk_json_val *name = &values[i + 1];
61 : 0 : const struct spdk_json_val *v = &values[i + 2];
62 : : /* Here we catch errors like invalid types. */
63 [ # # ]: 0 : if (!(entry[0] = spdk_json_strdup(name)) ||
64 [ # # ]: 0 : !(entry[1] = spdk_json_strdup(v))) {
65 : 0 : bdev_rbd_free_config(*map);
66 : 0 : *map = NULL;
67 : 0 : return -1;
68 : : }
69 : 0 : i += 1 + spdk_json_val_len(v);
70 : 0 : entry += 2;
71 : : }
72 : :
73 : 0 : return 0;
74 : : }
75 : :
76 : : static const struct spdk_json_object_decoder rpc_create_rbd_decoders[] = {
77 : : {"name", offsetof(struct rpc_create_rbd, name), spdk_json_decode_string, true},
78 : : {"user_id", offsetof(struct rpc_create_rbd, user_id), spdk_json_decode_string, true},
79 : : {"pool_name", offsetof(struct rpc_create_rbd, pool_name), spdk_json_decode_string},
80 : : {"rbd_name", offsetof(struct rpc_create_rbd, rbd_name), spdk_json_decode_string},
81 : : {"block_size", offsetof(struct rpc_create_rbd, block_size), spdk_json_decode_uint32},
82 : : {"config", offsetof(struct rpc_create_rbd, config), bdev_rbd_decode_config, true},
83 : : {"cluster_name", offsetof(struct rpc_create_rbd, cluster_name), spdk_json_decode_string, true},
84 : : {"uuid", offsetof(struct rpc_create_rbd, uuid), spdk_json_decode_uuid, true}
85 : : };
86 : :
87 : : static void
88 : 10 : rpc_bdev_rbd_create(struct spdk_jsonrpc_request *request,
89 : : const struct spdk_json_val *params)
90 : : {
91 : 10 : struct rpc_create_rbd req = {};
92 : : struct spdk_json_write_ctx *w;
93 : : struct spdk_bdev *bdev;
94 : 10 : int rc = 0;
95 : :
96 [ - + ]: 10 : if (spdk_json_decode_object(params, rpc_create_rbd_decoders,
97 : : SPDK_COUNTOF(rpc_create_rbd_decoders),
98 : : &req)) {
99 [ # # # # ]: 0 : SPDK_DEBUGLOG(bdev_rbd, "spdk_json_decode_object failed\n");
100 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
101 : : "spdk_json_decode_object failed");
102 : 0 : goto cleanup;
103 : : }
104 : :
105 : 10 : rc = bdev_rbd_create(&bdev, req.name, req.user_id, req.pool_name,
106 : 10 : (const char *const *)req.config,
107 : 10 : req.rbd_name,
108 : 10 : req.block_size, req.cluster_name, &req.uuid);
109 [ - + ]: 10 : if (rc) {
110 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
111 : 0 : goto cleanup;
112 : : }
113 : :
114 : 10 : w = spdk_jsonrpc_begin_result(request);
115 : 10 : spdk_json_write_string(w, spdk_bdev_get_name(bdev));
116 : 10 : spdk_jsonrpc_end_result(request, w);
117 : :
118 : 10 : cleanup:
119 : 10 : free_rpc_create_rbd(&req);
120 : 10 : }
121 : 74 : SPDK_RPC_REGISTER("bdev_rbd_create", rpc_bdev_rbd_create, SPDK_RPC_RUNTIME)
122 : :
123 : : struct rpc_bdev_rbd_delete {
124 : : char *name;
125 : : };
126 : :
127 : : static void
128 : 1 : free_rpc_bdev_rbd_delete(struct rpc_bdev_rbd_delete *req)
129 : : {
130 : 1 : free(req->name);
131 : 1 : }
132 : :
133 : : static const struct spdk_json_object_decoder rpc_bdev_rbd_delete_decoders[] = {
134 : : {"name", offsetof(struct rpc_bdev_rbd_delete, name), spdk_json_decode_string},
135 : : };
136 : :
137 : : static void
138 : 1 : _rpc_bdev_rbd_delete_cb(void *cb_arg, int bdeverrno)
139 : : {
140 : 1 : struct spdk_jsonrpc_request *request = cb_arg;
141 : :
142 [ + - ]: 1 : if (bdeverrno == 0) {
143 : 1 : spdk_jsonrpc_send_bool_response(request, true);
144 : : } else {
145 : 0 : spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
146 : : }
147 : 1 : }
148 : :
149 : : static void
150 : 1 : rpc_bdev_rbd_delete(struct spdk_jsonrpc_request *request,
151 : : const struct spdk_json_val *params)
152 : : {
153 : 1 : struct rpc_bdev_rbd_delete req = {NULL};
154 : :
155 [ - + ]: 1 : if (spdk_json_decode_object(params, rpc_bdev_rbd_delete_decoders,
156 : : SPDK_COUNTOF(rpc_bdev_rbd_delete_decoders),
157 : : &req)) {
158 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
159 : : "spdk_json_decode_object failed");
160 : 0 : goto cleanup;
161 : : }
162 : :
163 : 1 : bdev_rbd_delete(req.name, _rpc_bdev_rbd_delete_cb, request);
164 : :
165 : 1 : cleanup:
166 : 1 : free_rpc_bdev_rbd_delete(&req);
167 : 1 : }
168 : 74 : SPDK_RPC_REGISTER("bdev_rbd_delete", rpc_bdev_rbd_delete, SPDK_RPC_RUNTIME)
169 : :
170 : : struct rpc_bdev_rbd_resize {
171 : : char *name;
172 : : uint64_t new_size;
173 : : };
174 : :
175 : : static const struct spdk_json_object_decoder rpc_bdev_rbd_resize_decoders[] = {
176 : : {"name", offsetof(struct rpc_bdev_rbd_resize, name), spdk_json_decode_string},
177 : : {"new_size", offsetof(struct rpc_bdev_rbd_resize, new_size), spdk_json_decode_uint64}
178 : : };
179 : :
180 : : static void
181 : 1 : free_rpc_bdev_rbd_resize(struct rpc_bdev_rbd_resize *req)
182 : : {
183 : 1 : free(req->name);
184 : 1 : }
185 : :
186 : : static void
187 : 1 : rpc_bdev_rbd_resize(struct spdk_jsonrpc_request *request,
188 : : const struct spdk_json_val *params)
189 : : {
190 : 1 : struct rpc_bdev_rbd_resize req = {};
191 : : int rc;
192 : :
193 [ - + ]: 1 : if (spdk_json_decode_object(params, rpc_bdev_rbd_resize_decoders,
194 : : SPDK_COUNTOF(rpc_bdev_rbd_resize_decoders),
195 : : &req)) {
196 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
197 : : "spdk_json_decode_object failed");
198 : 0 : goto cleanup;
199 : : }
200 : :
201 : 1 : rc = bdev_rbd_resize(req.name, req.new_size);
202 [ - + ]: 1 : if (rc) {
203 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
204 : 0 : goto cleanup;
205 : : }
206 : :
207 : 1 : spdk_jsonrpc_send_bool_response(request, true);
208 : 1 : cleanup:
209 : 1 : free_rpc_bdev_rbd_resize(&req);
210 : 1 : }
211 : 74 : SPDK_RPC_REGISTER("bdev_rbd_resize", rpc_bdev_rbd_resize, SPDK_RPC_RUNTIME)
212 : :
213 : : static void
214 : 1 : free_rpc_register_cluster(struct cluster_register_info *req)
215 : : {
216 : 1 : free(req->name);
217 : 1 : free(req->user_id);
218 : 1 : bdev_rbd_free_config(req->config_param);
219 : 1 : free(req->config_file);
220 : 1 : free(req->key_file);
221 : 1 : free(req->core_mask);
222 : 1 : }
223 : :
224 : : static const struct spdk_json_object_decoder rpc_register_cluster_decoders[] = {
225 : : {"name", offsetof(struct cluster_register_info, name), spdk_json_decode_string, true},
226 : : {"user_id", offsetof(struct cluster_register_info, user_id), spdk_json_decode_string, true},
227 : : {"config_param", offsetof(struct cluster_register_info, config_param), bdev_rbd_decode_config, true},
228 : : {"config_file", offsetof(struct cluster_register_info, config_file), spdk_json_decode_string, true},
229 : : {"key_file", offsetof(struct cluster_register_info, key_file), spdk_json_decode_string, true},
230 : : {"core_mask", offsetof(struct cluster_register_info, core_mask), spdk_json_decode_string, true}
231 : : };
232 : :
233 : : static void
234 : 1 : rpc_bdev_rbd_register_cluster(struct spdk_jsonrpc_request *request,
235 : : const struct spdk_json_val *params)
236 : : {
237 : 1 : struct cluster_register_info req = {};
238 : 1 : int rc = 0;
239 : : struct spdk_json_write_ctx *w;
240 : :
241 [ - + ]: 1 : if (spdk_json_decode_object(params, rpc_register_cluster_decoders,
242 : : SPDK_COUNTOF(rpc_register_cluster_decoders),
243 : : &req)) {
244 [ # # # # ]: 0 : SPDK_DEBUGLOG(bdev_rbd, "spdk_json_decode_object failed\n");
245 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
246 : : "spdk_json_decode_object failed");
247 : 0 : goto cleanup;
248 : : }
249 : :
250 : 1 : rc = bdev_rbd_register_cluster(&req);
251 [ - + ]: 1 : if (rc) {
252 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
253 : 0 : goto cleanup;
254 : : }
255 : :
256 : 1 : w = spdk_jsonrpc_begin_result(request);
257 : 1 : spdk_json_write_string(w, req.name);
258 : 1 : spdk_jsonrpc_end_result(request, w);
259 : 1 : cleanup:
260 : 1 : free_rpc_register_cluster(&req);
261 : 1 : }
262 : 74 : SPDK_RPC_REGISTER("bdev_rbd_register_cluster", rpc_bdev_rbd_register_cluster, SPDK_RPC_RUNTIME)
263 : :
264 : : struct rpc_bdev_rbd_unregister_cluster {
265 : : char *name;
266 : : };
267 : :
268 : : static void
269 : 1 : free_rpc_bdev_cluster_unregister(struct rpc_bdev_rbd_unregister_cluster *req)
270 : : {
271 : 1 : free(req->name);
272 : 1 : }
273 : :
274 : : static const struct spdk_json_object_decoder rpc_bdev_rbd_unregister_cluster_decoders[] = {
275 : : {"name", offsetof(struct rpc_bdev_rbd_unregister_cluster, name), spdk_json_decode_string},
276 : : };
277 : :
278 : : static void
279 : 1 : rpc_bdev_rbd_unregister_cluster(struct spdk_jsonrpc_request *request,
280 : : const struct spdk_json_val *params)
281 : : {
282 : 1 : struct rpc_bdev_rbd_unregister_cluster req = {NULL};
283 : : int rc;
284 : :
285 [ - + ]: 1 : if (spdk_json_decode_object(params, rpc_bdev_rbd_unregister_cluster_decoders,
286 : : SPDK_COUNTOF(rpc_bdev_rbd_unregister_cluster_decoders),
287 : : &req)) {
288 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
289 : : "spdk_json_decode_object failed");
290 : 0 : goto cleanup;
291 : : }
292 : :
293 : 1 : rc = bdev_rbd_unregister_cluster(req.name);
294 [ - + ]: 1 : if (rc) {
295 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
296 : 0 : goto cleanup;
297 : : }
298 : :
299 : 1 : spdk_jsonrpc_send_bool_response(request, true);
300 : :
301 : 1 : cleanup:
302 : 1 : free_rpc_bdev_cluster_unregister(&req);
303 : 1 : }
304 : 74 : SPDK_RPC_REGISTER("bdev_rbd_unregister_cluster", rpc_bdev_rbd_unregister_cluster, SPDK_RPC_RUNTIME)
305 : :
306 : : struct rpc_bdev_rbd_get_cluster_info {
307 : : char *name;
308 : : };
309 : :
310 : : static void
311 : 1 : free_rpc_bdev_rbd_get_cluster_info(struct rpc_bdev_rbd_get_cluster_info *req)
312 : : {
313 : 1 : free(req->name);
314 : 1 : }
315 : :
316 : : static const struct spdk_json_object_decoder rpc_bdev_rbd_get_cluster_info_decoders[] = {
317 : : {"name", offsetof(struct rpc_bdev_rbd_get_cluster_info, name), spdk_json_decode_string, true},
318 : : };
319 : :
320 : : static void
321 : 1 : rpc_bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request,
322 : : const struct spdk_json_val *params)
323 : : {
324 : 1 : struct rpc_bdev_rbd_get_cluster_info req = {NULL};
325 : : int rc;
326 : :
327 [ + - - + ]: 1 : if (params && spdk_json_decode_object(params, rpc_bdev_rbd_get_cluster_info_decoders,
328 : : SPDK_COUNTOF(rpc_bdev_rbd_get_cluster_info_decoders),
329 : : &req)) {
330 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
331 : : "spdk_json_decode_object failed");
332 : 0 : goto cleanup;
333 : : }
334 : :
335 : 1 : rc = bdev_rbd_get_clusters_info(request, req.name);
336 [ + - ]: 1 : if (rc) {
337 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
338 : 0 : goto cleanup;
339 : : }
340 : :
341 : 1 : cleanup:
342 : 1 : free_rpc_bdev_rbd_get_cluster_info(&req);
343 : 1 : }
344 : 74 : SPDK_RPC_REGISTER("bdev_rbd_get_clusters_info", rpc_bdev_rbd_get_clusters_info, SPDK_RPC_RUNTIME)
|