xref: /spdk/module/bdev/ftl/bdev_ftl_rpc.c (revision ea8f5b27612fa03698a9ce3ad4bd37765d9cdfa5)
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 		"l2p_dram_limit", offsetof(struct spdk_ftl_conf, l2p_dram_limit),
42 		spdk_json_decode_uint64, true
43 	},
44 	{
45 		"core_mask", offsetof(struct spdk_ftl_conf, core_mask),
46 		spdk_json_decode_string, true
47 	},
48 	{
49 		"fast_shutdown", offsetof(struct spdk_ftl_conf, fast_shutdown),
50 		spdk_json_decode_bool, true
51 	},
52 };
53 
54 static void
55 rpc_bdev_ftl_create_cb(const struct ftl_bdev_info *bdev_info, void *ctx, int status)
56 {
57 	struct spdk_jsonrpc_request *request = ctx;
58 	char bdev_uuid[SPDK_UUID_STRING_LEN];
59 	struct spdk_json_write_ctx *w;
60 
61 	if (status) {
62 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
63 						     "Failed to create FTL bdev: %s",
64 						     spdk_strerror(-status));
65 		return;
66 	}
67 
68 	w = spdk_jsonrpc_begin_result(request);
69 	spdk_uuid_fmt_lower(bdev_uuid, sizeof(bdev_uuid), &bdev_info->uuid);
70 	spdk_json_write_object_begin(w);
71 	spdk_json_write_named_string(w, "name", bdev_info->name);
72 	spdk_json_write_named_string(w, "uuid", bdev_uuid);
73 	spdk_json_write_object_end(w);
74 	spdk_jsonrpc_end_result(request, w);
75 }
76 
77 static void
78 rpc_bdev_ftl_create(struct spdk_jsonrpc_request *request,
79 		    const struct spdk_json_val *params)
80 {
81 	struct spdk_ftl_conf conf = {};
82 	struct spdk_json_write_ctx *w;
83 	int rc;
84 
85 	spdk_ftl_get_default_conf(&conf);
86 
87 	if (spdk_json_decode_object(params, rpc_bdev_ftl_create_decoders,
88 				    SPDK_COUNTOF(rpc_bdev_ftl_create_decoders),
89 				    &conf)) {
90 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
91 						 "Invalid parameters");
92 		goto out;
93 	}
94 
95 	if (spdk_mem_all_zero(&conf.uuid, sizeof(conf.uuid))) {
96 		conf.mode |= SPDK_FTL_MODE_CREATE;
97 	}
98 
99 	rc = bdev_ftl_create_bdev(&conf, rpc_bdev_ftl_create_cb, request);
100 	if (rc == -ENODEV) {
101 		rc = bdev_ftl_defer_init(&conf);
102 		if (rc == 0) {
103 			w = spdk_jsonrpc_begin_result(request);
104 			spdk_json_write_string_fmt(w, "FTL bdev: %s creation deferred", conf.name);
105 			spdk_jsonrpc_end_result(request, w);
106 		}
107 	}
108 
109 	if (rc) {
110 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
111 						     "Failed to create FTL bdev: %s",
112 						     spdk_strerror(-rc));
113 	}
114 out:
115 	spdk_ftl_conf_deinit(&conf);
116 }
117 SPDK_RPC_REGISTER("bdev_ftl_create", rpc_bdev_ftl_create, SPDK_RPC_RUNTIME)
118 
119 static void
120 rpc_bdev_ftl_load(struct spdk_jsonrpc_request *request,
121 		  const struct spdk_json_val *params)
122 {
123 	rpc_bdev_ftl_create(request, params);
124 }
125 SPDK_RPC_REGISTER("bdev_ftl_load", rpc_bdev_ftl_load, SPDK_RPC_RUNTIME)
126 
127 struct rpc_delete_ftl {
128 	char *name;
129 	bool fast_shutdown;
130 };
131 
132 static const struct spdk_json_object_decoder rpc_delete_ftl_decoders[] = {
133 	{"name", offsetof(struct rpc_delete_ftl, name), spdk_json_decode_string},
134 	{
135 		"fast_shutdown", offsetof(struct rpc_delete_ftl, fast_shutdown),
136 		spdk_json_decode_bool, true
137 	},
138 };
139 
140 static void
141 rpc_bdev_ftl_delete_cb(void *cb_arg, int bdeverrno)
142 {
143 	struct spdk_jsonrpc_request *request = cb_arg;
144 
145 	spdk_jsonrpc_send_bool_response(request, bdeverrno == 0);
146 }
147 
148 static void
149 rpc_bdev_ftl_delete(struct spdk_jsonrpc_request *request,
150 		    const struct spdk_json_val *params)
151 {
152 	struct rpc_delete_ftl attrs = {};
153 
154 	if (spdk_json_decode_object(params, rpc_delete_ftl_decoders,
155 				    SPDK_COUNTOF(rpc_delete_ftl_decoders),
156 				    &attrs)) {
157 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
158 						 "Invalid parameters");
159 		goto invalid;
160 	}
161 
162 	bdev_ftl_delete_bdev(attrs.name, attrs.fast_shutdown, rpc_bdev_ftl_delete_cb, request);
163 invalid:
164 	free(attrs.name);
165 }
166 SPDK_RPC_REGISTER("bdev_ftl_delete", rpc_bdev_ftl_delete, SPDK_RPC_RUNTIME)
167 
168 static void
169 rpc_bdev_ftl_unload(struct spdk_jsonrpc_request *request,
170 		    const struct spdk_json_val *params)
171 {
172 	rpc_bdev_ftl_delete(request, params);
173 }
174 SPDK_RPC_REGISTER("bdev_ftl_unload", rpc_bdev_ftl_unload, SPDK_RPC_RUNTIME)
175