xref: /spdk/module/bdev/ftl/bdev_ftl_rpc.c (revision fa09c9ac9b0ce66dcacb64b02aae778014b6c2b3)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/rpc.h"
7 #include "spdk/util.h"
8 #include "spdk/bdev_module.h"
9 #include "spdk/string.h"
10 #include "spdk/log.h"
11 
12 #include "bdev_ftl.h"
13 
14 static int
15 rpc_bdev_ftl_decode_uuid(const struct spdk_json_val *val, void *out)
16 {
17 	char *uuid_str;
18 	int ret;
19 
20 	uuid_str = spdk_json_strdup(val);
21 	if (!uuid_str) {
22 		return -ENOMEM;
23 	}
24 
25 	ret = spdk_uuid_parse(out, uuid_str);
26 
27 	free(uuid_str);
28 	return ret;
29 }
30 
31 static const struct spdk_json_object_decoder rpc_bdev_ftl_create_decoders[] = {
32 	{"name", offsetof(struct spdk_ftl_conf, name), spdk_json_decode_string},
33 	{"base_bdev", offsetof(struct spdk_ftl_conf, base_bdev), spdk_json_decode_string},
34 	{"uuid", offsetof(struct spdk_ftl_conf, uuid), rpc_bdev_ftl_decode_uuid, true},
35 	{"cache", offsetof(struct spdk_ftl_conf, cache_bdev), spdk_json_decode_string},
36 	{
37 		"overprovisioning", offsetof(struct spdk_ftl_conf, overprovisioning),
38 		spdk_json_decode_uint64, true
39 	},
40 	{
41 		"core_mask", offsetof(struct spdk_ftl_conf, core_mask),
42 		spdk_json_decode_string, true
43 	},
44 };
45 
46 static void
47 rpc_bdev_ftl_create_cb(const struct ftl_bdev_info *bdev_info, void *ctx, int status)
48 {
49 	struct spdk_jsonrpc_request *request = ctx;
50 	char bdev_uuid[SPDK_UUID_STRING_LEN];
51 	struct spdk_json_write_ctx *w;
52 
53 	if (status) {
54 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
55 						     "Failed to create FTL bdev: %s",
56 						     spdk_strerror(-status));
57 		return;
58 	}
59 
60 	w = spdk_jsonrpc_begin_result(request);
61 	spdk_uuid_fmt_lower(bdev_uuid, sizeof(bdev_uuid), &bdev_info->uuid);
62 	spdk_json_write_object_begin(w);
63 	spdk_json_write_named_string(w, "name", bdev_info->name);
64 	spdk_json_write_named_string(w, "uuid", bdev_uuid);
65 	spdk_json_write_object_end(w);
66 	spdk_jsonrpc_end_result(request, w);
67 }
68 
69 static void
70 rpc_bdev_ftl_create(struct spdk_jsonrpc_request *request,
71 		    const struct spdk_json_val *params)
72 {
73 	struct spdk_ftl_conf conf = {};
74 	struct spdk_json_write_ctx *w;
75 	int rc;
76 
77 	spdk_ftl_get_default_conf(&conf);
78 
79 	if (spdk_json_decode_object(params, rpc_bdev_ftl_create_decoders,
80 				    SPDK_COUNTOF(rpc_bdev_ftl_create_decoders),
81 				    &conf)) {
82 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
83 						 "Invalid parameters");
84 		goto out;
85 	}
86 
87 	if (spdk_mem_all_zero(&conf.uuid, sizeof(conf.uuid))) {
88 		conf.mode |= SPDK_FTL_MODE_CREATE;
89 	}
90 
91 	rc = bdev_ftl_create_bdev(&conf, rpc_bdev_ftl_create_cb, request);
92 	if (rc == -ENODEV) {
93 		rc = bdev_ftl_defer_init(&conf);
94 		if (rc == 0) {
95 			w = spdk_jsonrpc_begin_result(request);
96 			spdk_json_write_string_fmt(w, "FTL bdev: %s creation deferred", conf.name);
97 			spdk_jsonrpc_end_result(request, w);
98 		}
99 	}
100 
101 	if (rc) {
102 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
103 						     "Failed to create FTL bdev: %s",
104 						     spdk_strerror(-rc));
105 	}
106 out:
107 	spdk_ftl_conf_deinit(&conf);
108 }
109 SPDK_RPC_REGISTER("bdev_ftl_create", rpc_bdev_ftl_create, SPDK_RPC_RUNTIME)
110 
111 static void
112 rpc_bdev_ftl_load(struct spdk_jsonrpc_request *request,
113 		  const struct spdk_json_val *params)
114 {
115 	rpc_bdev_ftl_create(request, params);
116 }
117 SPDK_RPC_REGISTER("bdev_ftl_load", rpc_bdev_ftl_load, SPDK_RPC_RUNTIME)
118 
119 struct rpc_delete_ftl {
120 	char *name;
121 };
122 
123 static const struct spdk_json_object_decoder rpc_delete_ftl_decoders[] = {
124 	{"name", offsetof(struct rpc_delete_ftl, name), spdk_json_decode_string},
125 };
126 
127 static void
128 rpc_bdev_ftl_delete_cb(void *cb_arg, int bdeverrno)
129 {
130 	struct spdk_jsonrpc_request *request = cb_arg;
131 
132 	spdk_jsonrpc_send_bool_response(request, bdeverrno == 0);
133 }
134 
135 static void
136 rpc_bdev_ftl_delete(struct spdk_jsonrpc_request *request,
137 		    const struct spdk_json_val *params)
138 {
139 	struct rpc_delete_ftl attrs = {};
140 
141 	if (spdk_json_decode_object(params, rpc_delete_ftl_decoders,
142 				    SPDK_COUNTOF(rpc_delete_ftl_decoders),
143 				    &attrs)) {
144 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
145 						 "Invalid parameters");
146 		goto invalid;
147 	}
148 
149 	bdev_ftl_delete_bdev(attrs.name, rpc_bdev_ftl_delete_cb, request);
150 invalid:
151 	free(attrs.name);
152 }
153 SPDK_RPC_REGISTER("bdev_ftl_delete", rpc_bdev_ftl_delete, SPDK_RPC_RUNTIME)
154 
155 static void
156 rpc_bdev_ftl_unload(struct spdk_jsonrpc_request *request,
157 		    const struct spdk_json_val *params)
158 {
159 	rpc_bdev_ftl_delete(request, params);
160 }
161 SPDK_RPC_REGISTER("bdev_ftl_unload", rpc_bdev_ftl_unload, SPDK_RPC_RUNTIME)
162