4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/stdinc.h"
35 #include "spdk/string.h"
37 #include "spdk/util.h"
38 #include "spdk/string.h"
39 #include "spdk_internal/log.h"
40 #include "vbdev_error.h"
42 #define ERROR_BDEV_IO_TYPE_INVALID (SPDK_BDEV_IO_TYPE_RESET + 1)
43 #define ERROR_BDEV_ERROR_TYPE_INVALID (VBDEV_IO_PENDING + 1)
46 spdk_rpc_error_bdev_io_type_parse(char *name
)
48 if (strcmp(name
, "read") == 0) {
49 return SPDK_BDEV_IO_TYPE_READ
;
50 } else if (strcmp(name
, "write") == 0) {
51 return SPDK_BDEV_IO_TYPE_WRITE
;
52 } else if (strcmp(name
, "flush") == 0) {
53 return SPDK_BDEV_IO_TYPE_FLUSH
;
54 } else if (strcmp(name
, "unmap") == 0) {
55 return SPDK_BDEV_IO_TYPE_UNMAP
;
56 } else if (strcmp(name
, "all") == 0) {
58 } else if (strcmp(name
, "clear") == 0) {
61 return ERROR_BDEV_IO_TYPE_INVALID
;
65 spdk_rpc_error_bdev_error_type_parse(char *name
)
67 if (strcmp(name
, "failure") == 0) {
68 return VBDEV_IO_FAILURE
;
69 } else if (strcmp(name
, "pending") == 0) {
70 return VBDEV_IO_PENDING
;
72 return ERROR_BDEV_ERROR_TYPE_INVALID
;
75 struct rpc_construct_error_bdev
{
80 free_rpc_construct_error_bdev(struct rpc_construct_error_bdev
*req
)
85 static const struct spdk_json_object_decoder rpc_construct_error_bdev_decoders
[] = {
86 {"base_name", offsetof(struct rpc_construct_error_bdev
, base_name
), spdk_json_decode_string
},
90 spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_request
*request
,
91 const struct spdk_json_val
*params
)
93 struct rpc_construct_error_bdev req
= {};
94 struct spdk_json_write_ctx
*w
;
96 if (spdk_json_decode_object(params
, rpc_construct_error_bdev_decoders
,
97 SPDK_COUNTOF(rpc_construct_error_bdev_decoders
),
99 SPDK_ERRLOG("spdk_json_decode_object failed\n");
103 if (spdk_vbdev_error_create(req
.base_name
)) {
104 SPDK_ERRLOG("Could not create ErrorInjection bdev %s\n", req
.base_name
);
108 w
= spdk_jsonrpc_begin_result(request
);
110 free_rpc_construct_error_bdev(&req
);
114 spdk_json_write_bool(w
, true);
115 spdk_jsonrpc_end_result(request
, w
);
117 free_rpc_construct_error_bdev(&req
);
122 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
123 free_rpc_construct_error_bdev(&req
);
125 SPDK_RPC_REGISTER("construct_error_bdev", spdk_rpc_construct_error_bdev
, SPDK_RPC_RUNTIME
)
127 struct rpc_delete_error
{
132 free_rpc_delete_error(struct rpc_delete_error
*r
)
137 static const struct spdk_json_object_decoder rpc_delete_error_decoders
[] = {
138 {"name", offsetof(struct rpc_delete_error
, name
), spdk_json_decode_string
},
142 _spdk_rpc_delete_error_bdev_cb(void *cb_arg
, int bdeverrno
)
144 struct spdk_jsonrpc_request
*request
= cb_arg
;
145 struct spdk_json_write_ctx
*w
;
147 w
= spdk_jsonrpc_begin_result(request
);
152 spdk_json_write_bool(w
, bdeverrno
== 0);
153 spdk_jsonrpc_end_result(request
, w
);
157 spdk_rpc_delete_error_bdev(struct spdk_jsonrpc_request
*request
,
158 const struct spdk_json_val
*params
)
160 struct rpc_delete_error req
= {NULL
};
161 struct spdk_bdev
*vbdev
;
164 if (spdk_json_decode_object(params
, rpc_delete_error_decoders
,
165 SPDK_COUNTOF(rpc_delete_error_decoders
),
171 vbdev
= spdk_bdev_get_by_name(req
.name
);
177 spdk_vbdev_error_delete(vbdev
, _spdk_rpc_delete_error_bdev_cb
, request
);
179 free_rpc_delete_error(&req
);
184 free_rpc_delete_error(&req
);
185 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, spdk_strerror(-rc
));
187 SPDK_RPC_REGISTER("delete_error_bdev", spdk_rpc_delete_error_bdev
, SPDK_RPC_RUNTIME
)
189 struct rpc_error_information
{
196 static const struct spdk_json_object_decoder rpc_error_information_decoders
[] = {
197 {"name", offsetof(struct rpc_error_information
, name
), spdk_json_decode_string
},
198 {"io_type", offsetof(struct rpc_error_information
, io_type
), spdk_json_decode_string
},
199 {"error_type", offsetof(struct rpc_error_information
, error_type
), spdk_json_decode_string
},
200 {"num", offsetof(struct rpc_error_information
, num
), spdk_json_decode_uint32
, true},
204 free_rpc_error_information(struct rpc_error_information
*p
)
212 spdk_rpc_bdev_inject_error(struct spdk_jsonrpc_request
*request
,
213 const struct spdk_json_val
*params
)
215 struct rpc_error_information req
= {};
216 struct spdk_json_write_ctx
*w
;
221 if (spdk_json_decode_object(params
, rpc_error_information_decoders
,
222 SPDK_COUNTOF(rpc_error_information_decoders
),
224 SPDK_ERRLOG("spdk_json_decode_object failed\n");
228 io_type
= spdk_rpc_error_bdev_io_type_parse(req
.io_type
);
229 if (io_type
== ERROR_BDEV_IO_TYPE_INVALID
) {
233 error_type
= spdk_rpc_error_bdev_error_type_parse(req
.error_type
);
234 if (error_type
== ERROR_BDEV_ERROR_TYPE_INVALID
) {
238 ret
= spdk_vbdev_inject_error(req
.name
, io_type
, error_type
, req
.num
);
243 free_rpc_error_information(&req
);
245 w
= spdk_jsonrpc_begin_result(request
);
250 spdk_json_write_bool(w
, true);
251 spdk_jsonrpc_end_result(request
, w
);
255 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
256 free_rpc_error_information(&req
);
258 SPDK_RPC_REGISTER("bdev_inject_error", spdk_rpc_bdev_inject_error
, SPDK_RPC_RUNTIME
)