Line data Source code
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 0 : rpc_error_bdev_decode_io_type(const struct spdk_json_val *val, void *out)
16 : {
17 0 : uint32_t *io_type = out;
18 :
19 0 : if (spdk_json_strequal(val, "read") == true) {
20 0 : *io_type = SPDK_BDEV_IO_TYPE_READ;
21 0 : } else if (spdk_json_strequal(val, "write") == true) {
22 0 : *io_type = SPDK_BDEV_IO_TYPE_WRITE;
23 0 : } else if (spdk_json_strequal(val, "flush") == true) {
24 0 : *io_type = SPDK_BDEV_IO_TYPE_FLUSH;
25 0 : } else if (spdk_json_strequal(val, "unmap") == true) {
26 0 : *io_type = SPDK_BDEV_IO_TYPE_UNMAP;
27 0 : } else if (spdk_json_strequal(val, "all") == true) {
28 0 : *io_type = 0xffffffff;
29 0 : } else if (spdk_json_strequal(val, "clear") == true) {
30 0 : *io_type = 0;
31 : } else {
32 0 : SPDK_NOTICELOG("Invalid parameter value: io_type\n");
33 0 : return -EINVAL;
34 : }
35 :
36 0 : return 0;
37 : }
38 :
39 : static int
40 0 : rpc_error_bdev_decode_error_type(const struct spdk_json_val *val, void *out)
41 : {
42 0 : uint32_t *error_type = out;
43 :
44 0 : if (spdk_json_strequal(val, "failure") == true) {
45 0 : *error_type = VBDEV_IO_FAILURE;
46 0 : } else if (spdk_json_strequal(val, "pending") == true) {
47 0 : *error_type = VBDEV_IO_PENDING;
48 0 : } else if (spdk_json_strequal(val, "corrupt_data") == true) {
49 0 : *error_type = VBDEV_IO_CORRUPT_DATA;
50 0 : } else if (spdk_json_strequal(val, "nomem") == true) {
51 0 : *error_type = VBDEV_IO_NOMEM;
52 : } else {
53 0 : SPDK_NOTICELOG("Invalid parameter value: error_type\n");
54 0 : return -EINVAL;
55 : }
56 :
57 0 : 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 0 : free_rpc_bdev_error_create(struct rpc_bdev_error_create *req)
67 : {
68 0 : free(req->base_name);
69 0 : }
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 0 : rpc_bdev_error_create(struct spdk_jsonrpc_request *request,
78 : const struct spdk_json_val *params)
79 : {
80 0 : struct rpc_bdev_error_create req = {};
81 0 : int rc = 0;
82 :
83 0 : if (spdk_json_decode_object(params, rpc_bdev_error_create_decoders,
84 : SPDK_COUNTOF(rpc_bdev_error_create_decoders),
85 : &req)) {
86 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
87 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
88 : "spdk_json_decode_object failed");
89 0 : goto cleanup;
90 : }
91 :
92 0 : rc = vbdev_error_create(req.base_name, &req.uuid);
93 0 : if (rc) {
94 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
95 0 : goto cleanup;
96 : }
97 :
98 0 : spdk_jsonrpc_send_bool_response(request, true);
99 :
100 0 : cleanup:
101 0 : free_rpc_bdev_error_create(&req);
102 0 : }
103 0 : 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 0 : free_rpc_delete_error(struct rpc_delete_error *r)
111 : {
112 0 : free(r->name);
113 0 : }
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 0 : rpc_bdev_error_delete_cb(void *cb_arg, int bdeverrno)
121 : {
122 0 : struct spdk_jsonrpc_request *request = cb_arg;
123 :
124 0 : if (bdeverrno == 0) {
125 0 : spdk_jsonrpc_send_bool_response(request, true);
126 : } else {
127 0 : spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
128 : }
129 0 : }
130 :
131 : static void
132 0 : rpc_bdev_error_delete(struct spdk_jsonrpc_request *request,
133 : const struct spdk_json_val *params)
134 : {
135 0 : struct rpc_delete_error req = {NULL};
136 :
137 0 : if (spdk_json_decode_object(params, rpc_delete_error_decoders,
138 : SPDK_COUNTOF(rpc_delete_error_decoders),
139 : &req)) {
140 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
141 : "spdk_json_decode_object failed");
142 0 : goto cleanup;
143 : }
144 :
145 0 : vbdev_error_delete(req.name, rpc_bdev_error_delete_cb, request);
146 :
147 0 : cleanup:
148 0 : free_rpc_delete_error(&req);
149 0 : }
150 0 : 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 0 : free_rpc_error_information(struct rpc_error_information *p)
169 : {
170 0 : free(p->name);
171 0 : }
172 :
173 : static void
174 0 : rpc_bdev_error_inject_error(struct spdk_jsonrpc_request *request,
175 : const struct spdk_json_val *params)
176 : {
177 0 : struct rpc_error_information req = {.opts.error_num = 1};
178 0 : int rc = 0;
179 :
180 0 : if (spdk_json_decode_object(params, rpc_error_information_decoders,
181 : SPDK_COUNTOF(rpc_error_information_decoders),
182 : &req)) {
183 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
184 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
185 : "spdk_json_decode_object failed");
186 0 : goto cleanup;
187 : }
188 :
189 0 : rc = vbdev_error_inject_error(req.name, &req.opts);
190 0 : if (rc) {
191 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
192 0 : goto cleanup;
193 : }
194 :
195 0 : spdk_jsonrpc_send_bool_response(request, true);
196 :
197 0 : cleanup:
198 0 : free_rpc_error_information(&req);
199 0 : }
200 0 : SPDK_RPC_REGISTER("bdev_error_inject_error", rpc_bdev_error_inject_error, SPDK_RPC_RUNTIME)
|