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