xref: /spdk/module/bdev/error/vbdev_error_rpc.c (revision 5d39b20a5093a1423c393a8872e7ee9738034029)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 #include "spdk/string.h"
8 #include "spdk/rpc.h"
9 #include "spdk/util.h"
10 #include "spdk/string.h"
11 #include "spdk/log.h"
12 #include "vbdev_error.h"
13 
14 static int
15 rpc_error_bdev_decode_io_type(const struct spdk_json_val *val, void *out)
16 {
17 	uint32_t *io_type = out;
18 
19 	if (spdk_json_strequal(val, "read") == true) {
20 		*io_type = SPDK_BDEV_IO_TYPE_READ;
21 	} else if (spdk_json_strequal(val, "write") == true) {
22 		*io_type = SPDK_BDEV_IO_TYPE_WRITE;
23 	} else if (spdk_json_strequal(val, "flush") == true) {
24 		*io_type = SPDK_BDEV_IO_TYPE_FLUSH;
25 	} else if (spdk_json_strequal(val, "unmap") == true) {
26 		*io_type = SPDK_BDEV_IO_TYPE_UNMAP;
27 	} else if (spdk_json_strequal(val, "all") == true) {
28 		*io_type = 0xffffffff;
29 	} else if (spdk_json_strequal(val, "clear") == true) {
30 		*io_type = 0;
31 	} else {
32 		SPDK_NOTICELOG("Invalid parameter value: io_type\n");
33 		return -EINVAL;
34 	}
35 
36 	return 0;
37 }
38 
39 static int
40 rpc_error_bdev_decode_error_type(const struct spdk_json_val *val, void *out)
41 {
42 	uint32_t *error_type = out;
43 
44 	if (spdk_json_strequal(val, "failure") == true) {
45 		*error_type = VBDEV_IO_FAILURE;
46 	} else if (spdk_json_strequal(val, "pending") == true) {
47 		*error_type = VBDEV_IO_PENDING;
48 	} else {
49 		SPDK_NOTICELOG("Invalid parameter value: error_type\n");
50 		return -EINVAL;
51 	}
52 
53 	return 0;
54 }
55 
56 struct rpc_bdev_error_create {
57 	char *base_name;
58 };
59 
60 static void
61 free_rpc_bdev_error_create(struct rpc_bdev_error_create *req)
62 {
63 	free(req->base_name);
64 }
65 
66 static const struct spdk_json_object_decoder rpc_bdev_error_create_decoders[] = {
67 	{"base_name", offsetof(struct rpc_bdev_error_create, base_name), spdk_json_decode_string},
68 };
69 
70 static void
71 rpc_bdev_error_create(struct spdk_jsonrpc_request *request,
72 		      const struct spdk_json_val *params)
73 {
74 	struct rpc_bdev_error_create req = {};
75 	int rc = 0;
76 
77 	if (spdk_json_decode_object(params, rpc_bdev_error_create_decoders,
78 				    SPDK_COUNTOF(rpc_bdev_error_create_decoders),
79 				    &req)) {
80 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
81 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
82 						 "spdk_json_decode_object failed");
83 		goto cleanup;
84 	}
85 
86 	rc = vbdev_error_create(req.base_name);
87 	if (rc) {
88 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
89 		goto cleanup;
90 	}
91 
92 	spdk_jsonrpc_send_bool_response(request, true);
93 
94 cleanup:
95 	free_rpc_bdev_error_create(&req);
96 }
97 SPDK_RPC_REGISTER("bdev_error_create", rpc_bdev_error_create, SPDK_RPC_RUNTIME)
98 
99 struct rpc_delete_error {
100 	char *name;
101 };
102 
103 static void
104 free_rpc_delete_error(struct rpc_delete_error *r)
105 {
106 	free(r->name);
107 }
108 
109 static const struct spdk_json_object_decoder rpc_delete_error_decoders[] = {
110 	{"name", offsetof(struct rpc_delete_error, name), spdk_json_decode_string},
111 };
112 
113 static void
114 rpc_bdev_error_delete_cb(void *cb_arg, int bdeverrno)
115 {
116 	struct spdk_jsonrpc_request *request = cb_arg;
117 
118 	if (bdeverrno == 0) {
119 		spdk_jsonrpc_send_bool_response(request, true);
120 	} else {
121 		spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
122 	}
123 }
124 
125 static void
126 rpc_bdev_error_delete(struct spdk_jsonrpc_request *request,
127 		      const struct spdk_json_val *params)
128 {
129 	struct rpc_delete_error req = {NULL};
130 
131 	if (spdk_json_decode_object(params, rpc_delete_error_decoders,
132 				    SPDK_COUNTOF(rpc_delete_error_decoders),
133 				    &req)) {
134 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
135 						 "spdk_json_decode_object failed");
136 		goto cleanup;
137 	}
138 
139 	vbdev_error_delete(req.name, rpc_bdev_error_delete_cb, request);
140 
141 cleanup:
142 	free_rpc_delete_error(&req);
143 }
144 SPDK_RPC_REGISTER("bdev_error_delete", rpc_bdev_error_delete, SPDK_RPC_RUNTIME)
145 
146 struct rpc_error_information {
147 	char *name;
148 	struct vbdev_error_inject_opts opts;
149 };
150 
151 static const struct spdk_json_object_decoder rpc_error_information_decoders[] = {
152 	{"name", offsetof(struct rpc_error_information, name), spdk_json_decode_string},
153 	{"io_type", offsetof(struct rpc_error_information, opts.io_type), rpc_error_bdev_decode_io_type},
154 	{"error_type", offsetof(struct rpc_error_information, opts.error_type), rpc_error_bdev_decode_error_type},
155 	{"num", offsetof(struct rpc_error_information, opts.error_num), spdk_json_decode_uint32, true},
156 };
157 
158 static void
159 free_rpc_error_information(struct rpc_error_information *p)
160 {
161 	free(p->name);
162 }
163 
164 static void
165 rpc_bdev_error_inject_error(struct spdk_jsonrpc_request *request,
166 			    const struct spdk_json_val *params)
167 {
168 	struct rpc_error_information req = {.opts.error_num = 1};
169 	int rc = 0;
170 
171 	if (spdk_json_decode_object(params, rpc_error_information_decoders,
172 				    SPDK_COUNTOF(rpc_error_information_decoders),
173 				    &req)) {
174 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
175 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
176 						 "spdk_json_decode_object failed");
177 		goto cleanup;
178 	}
179 
180 	rc = vbdev_error_inject_error(req.name, &req.opts);
181 	if (rc) {
182 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
183 		goto cleanup;
184 	}
185 
186 	spdk_jsonrpc_send_bool_response(request, true);
187 
188 cleanup:
189 	free_rpc_error_information(&req);
190 }
191 SPDK_RPC_REGISTER("bdev_error_inject_error", rpc_bdev_error_inject_error, SPDK_RPC_RUNTIME)
192