xref: /spdk/module/bdev/error/vbdev_error_rpc.c (revision f8abbede89d30584d2a4f8427b13896f8591b873)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2017 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 if (spdk_json_strequal(val, "corrupt_data") == true) {
49 		*error_type = VBDEV_IO_CORRUPT_DATA;
50 	} else if (spdk_json_strequal(val, "nomem") == true) {
51 		*error_type = VBDEV_IO_NOMEM;
52 	} else {
53 		SPDK_NOTICELOG("Invalid parameter value: error_type\n");
54 		return -EINVAL;
55 	}
56 
57 	return 0;
58 }
59 
60 struct rpc_bdev_error_create {
61 	char *base_name;
62 	struct spdk_uuid uuid;
63 };
64 
65 static void
66 free_rpc_bdev_error_create(struct rpc_bdev_error_create *req)
67 {
68 	free(req->base_name);
69 }
70 
71 static const struct spdk_json_object_decoder rpc_bdev_error_create_decoders[] = {
72 	{"base_name", offsetof(struct rpc_bdev_error_create, base_name), spdk_json_decode_string},
73 	{"uuid", offsetof(struct rpc_bdev_error_create, uuid), spdk_json_decode_uuid, true},
74 };
75 
76 static void
77 rpc_bdev_error_create(struct spdk_jsonrpc_request *request,
78 		      const struct spdk_json_val *params)
79 {
80 	struct rpc_bdev_error_create req = {};
81 	int rc = 0;
82 
83 	if (spdk_json_decode_object(params, rpc_bdev_error_create_decoders,
84 				    SPDK_COUNTOF(rpc_bdev_error_create_decoders),
85 				    &req)) {
86 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
87 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
88 						 "spdk_json_decode_object failed");
89 		goto cleanup;
90 	}
91 
92 	rc = vbdev_error_create(req.base_name, &req.uuid);
93 	if (rc) {
94 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
95 		goto cleanup;
96 	}
97 
98 	spdk_jsonrpc_send_bool_response(request, true);
99 
100 cleanup:
101 	free_rpc_bdev_error_create(&req);
102 }
103 SPDK_RPC_REGISTER("bdev_error_create", rpc_bdev_error_create, SPDK_RPC_RUNTIME)
104 
105 struct rpc_delete_error {
106 	char *name;
107 };
108 
109 static void
110 free_rpc_delete_error(struct rpc_delete_error *r)
111 {
112 	free(r->name);
113 }
114 
115 static const struct spdk_json_object_decoder rpc_delete_error_decoders[] = {
116 	{"name", offsetof(struct rpc_delete_error, name), spdk_json_decode_string},
117 };
118 
119 static void
120 rpc_bdev_error_delete_cb(void *cb_arg, int bdeverrno)
121 {
122 	struct spdk_jsonrpc_request *request = cb_arg;
123 
124 	if (bdeverrno == 0) {
125 		spdk_jsonrpc_send_bool_response(request, true);
126 	} else {
127 		spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
128 	}
129 }
130 
131 static void
132 rpc_bdev_error_delete(struct spdk_jsonrpc_request *request,
133 		      const struct spdk_json_val *params)
134 {
135 	struct rpc_delete_error req = {NULL};
136 
137 	if (spdk_json_decode_object(params, rpc_delete_error_decoders,
138 				    SPDK_COUNTOF(rpc_delete_error_decoders),
139 				    &req)) {
140 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
141 						 "spdk_json_decode_object failed");
142 		goto cleanup;
143 	}
144 
145 	vbdev_error_delete(req.name, rpc_bdev_error_delete_cb, request);
146 
147 cleanup:
148 	free_rpc_delete_error(&req);
149 }
150 SPDK_RPC_REGISTER("bdev_error_delete", rpc_bdev_error_delete, SPDK_RPC_RUNTIME)
151 
152 struct rpc_error_information {
153 	char *name;
154 	struct vbdev_error_inject_opts opts;
155 };
156 
157 static const struct spdk_json_object_decoder rpc_error_information_decoders[] = {
158 	{"name", offsetof(struct rpc_error_information, name), spdk_json_decode_string},
159 	{"io_type", offsetof(struct rpc_error_information, opts.io_type), rpc_error_bdev_decode_io_type},
160 	{"error_type", offsetof(struct rpc_error_information, opts.error_type), rpc_error_bdev_decode_error_type},
161 	{"num", offsetof(struct rpc_error_information, opts.error_num), spdk_json_decode_uint32, true},
162 	{"queue_depth", offsetof(struct rpc_error_information, opts.error_qd), spdk_json_decode_uint64, true},
163 	{"corrupt_offset", offsetof(struct rpc_error_information, opts.corrupt_offset), spdk_json_decode_uint64, true},
164 	{"corrupt_value", offsetof(struct rpc_error_information, opts.corrupt_value), spdk_json_decode_uint8, true},
165 };
166 
167 static void
168 free_rpc_error_information(struct rpc_error_information *p)
169 {
170 	free(p->name);
171 }
172 
173 static void
174 rpc_bdev_error_inject_error(struct spdk_jsonrpc_request *request,
175 			    const struct spdk_json_val *params)
176 {
177 	struct rpc_error_information req = {.opts.error_num = 1};
178 	int rc = 0;
179 
180 	if (spdk_json_decode_object(params, rpc_error_information_decoders,
181 				    SPDK_COUNTOF(rpc_error_information_decoders),
182 				    &req)) {
183 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
184 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
185 						 "spdk_json_decode_object failed");
186 		goto cleanup;
187 	}
188 
189 	rc = vbdev_error_inject_error(req.name, &req.opts);
190 	if (rc) {
191 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
192 		goto cleanup;
193 	}
194 
195 	spdk_jsonrpc_send_bool_response(request, true);
196 
197 cleanup:
198 	free_rpc_error_information(&req);
199 }
200 SPDK_RPC_REGISTER("bdev_error_inject_error", rpc_bdev_error_inject_error, SPDK_RPC_RUNTIME)
201