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