xref: /spdk/module/bdev/error/vbdev_error_rpc.c (revision d65bd99e4f997710816545eb25185a247a4f010f)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2017 Intel Corporation.
307fe6a43SSeth Howell  *   All rights reserved.
407fe6a43SSeth Howell  */
507fe6a43SSeth Howell 
607fe6a43SSeth Howell #include "spdk/stdinc.h"
707fe6a43SSeth Howell #include "spdk/string.h"
807fe6a43SSeth Howell #include "spdk/rpc.h"
907fe6a43SSeth Howell #include "spdk/util.h"
104e8e97c8STomasz Zawadzki #include "spdk/log.h"
1107fe6a43SSeth Howell #include "vbdev_error.h"
1207fe6a43SSeth Howell 
13972013e2SShuhei Matsumoto static int
rpc_error_bdev_decode_io_type(const struct spdk_json_val * val,void * out)14972013e2SShuhei Matsumoto rpc_error_bdev_decode_io_type(const struct spdk_json_val *val, void *out)
1507fe6a43SSeth Howell {
16972013e2SShuhei Matsumoto 	uint32_t *io_type = out;
17972013e2SShuhei Matsumoto 
18972013e2SShuhei Matsumoto 	if (spdk_json_strequal(val, "read") == true) {
19972013e2SShuhei Matsumoto 		*io_type = SPDK_BDEV_IO_TYPE_READ;
20972013e2SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "write") == true) {
21972013e2SShuhei Matsumoto 		*io_type = SPDK_BDEV_IO_TYPE_WRITE;
22972013e2SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "flush") == true) {
23972013e2SShuhei Matsumoto 		*io_type = SPDK_BDEV_IO_TYPE_FLUSH;
24972013e2SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "unmap") == true) {
25972013e2SShuhei Matsumoto 		*io_type = SPDK_BDEV_IO_TYPE_UNMAP;
26972013e2SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "all") == true) {
27972013e2SShuhei Matsumoto 		*io_type = 0xffffffff;
28972013e2SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "clear") == true) {
29972013e2SShuhei Matsumoto 		*io_type = 0;
30972013e2SShuhei Matsumoto 	} else {
31972013e2SShuhei Matsumoto 		SPDK_NOTICELOG("Invalid parameter value: io_type\n");
32972013e2SShuhei Matsumoto 		return -EINVAL;
33972013e2SShuhei Matsumoto 	}
34972013e2SShuhei Matsumoto 
3507fe6a43SSeth Howell 	return 0;
3607fe6a43SSeth Howell }
37972013e2SShuhei Matsumoto 
38972013e2SShuhei Matsumoto static int
rpc_error_bdev_decode_error_type(const struct spdk_json_val * val,void * out)39972013e2SShuhei Matsumoto rpc_error_bdev_decode_error_type(const struct spdk_json_val *val, void *out)
40972013e2SShuhei Matsumoto {
41972013e2SShuhei Matsumoto 	uint32_t *error_type = out;
42972013e2SShuhei Matsumoto 
43972013e2SShuhei Matsumoto 	if (spdk_json_strequal(val, "failure") == true) {
44972013e2SShuhei Matsumoto 		*error_type = VBDEV_IO_FAILURE;
45972013e2SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "pending") == true) {
46972013e2SShuhei Matsumoto 		*error_type = VBDEV_IO_PENDING;
473d2a3ee4SShuhei Matsumoto 	} else if (spdk_json_strequal(val, "corrupt_data") == true) {
483d2a3ee4SShuhei Matsumoto 		*error_type = VBDEV_IO_CORRUPT_DATA;
49408a2155SArtur Paszkiewicz 	} else if (spdk_json_strequal(val, "nomem") == true) {
50408a2155SArtur Paszkiewicz 		*error_type = VBDEV_IO_NOMEM;
51972013e2SShuhei Matsumoto 	} else {
52972013e2SShuhei Matsumoto 		SPDK_NOTICELOG("Invalid parameter value: error_type\n");
53972013e2SShuhei Matsumoto 		return -EINVAL;
5407fe6a43SSeth Howell 	}
5507fe6a43SSeth Howell 
56972013e2SShuhei Matsumoto 	return 0;
5707fe6a43SSeth Howell }
5807fe6a43SSeth Howell 
59cabb6a7dSMaciej Wawryk struct rpc_bdev_error_create {
6007fe6a43SSeth Howell 	char *base_name;
61*e85f1f11SKonrad Sztyber 	struct spdk_uuid uuid;
6207fe6a43SSeth Howell };
6307fe6a43SSeth Howell 
6407fe6a43SSeth Howell static void
free_rpc_bdev_error_create(struct rpc_bdev_error_create * req)65cabb6a7dSMaciej Wawryk free_rpc_bdev_error_create(struct rpc_bdev_error_create *req)
6607fe6a43SSeth Howell {
6707fe6a43SSeth Howell 	free(req->base_name);
6807fe6a43SSeth Howell }
6907fe6a43SSeth Howell 
70cabb6a7dSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_error_create_decoders[] = {
71cabb6a7dSMaciej Wawryk 	{"base_name", offsetof(struct rpc_bdev_error_create, base_name), spdk_json_decode_string},
72*e85f1f11SKonrad Sztyber 	{"uuid", offsetof(struct rpc_bdev_error_create, uuid), spdk_json_decode_uuid, true},
7307fe6a43SSeth Howell };
7407fe6a43SSeth Howell 
7507fe6a43SSeth Howell static void
rpc_bdev_error_create(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)76ef78704fSSeth Howell rpc_bdev_error_create(struct spdk_jsonrpc_request *request,
7707fe6a43SSeth Howell 		      const struct spdk_json_val *params)
7807fe6a43SSeth Howell {
79cabb6a7dSMaciej Wawryk 	struct rpc_bdev_error_create req = {};
8007fe6a43SSeth Howell 	int rc = 0;
8107fe6a43SSeth Howell 
82cabb6a7dSMaciej Wawryk 	if (spdk_json_decode_object(params, rpc_bdev_error_create_decoders,
83cabb6a7dSMaciej Wawryk 				    SPDK_COUNTOF(rpc_bdev_error_create_decoders),
8407fe6a43SSeth Howell 				    &req)) {
8507fe6a43SSeth Howell 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
8607fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
8707fe6a43SSeth Howell 						 "spdk_json_decode_object failed");
8807fe6a43SSeth Howell 		goto cleanup;
8907fe6a43SSeth Howell 	}
9007fe6a43SSeth Howell 
91*e85f1f11SKonrad Sztyber 	rc = vbdev_error_create(req.base_name, &req.uuid);
9207fe6a43SSeth Howell 	if (rc) {
9307fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
9407fe6a43SSeth Howell 		goto cleanup;
9507fe6a43SSeth Howell 	}
9607fe6a43SSeth Howell 
97d73077b8Syidong0635 	spdk_jsonrpc_send_bool_response(request, true);
9807fe6a43SSeth Howell 
9907fe6a43SSeth Howell cleanup:
100cabb6a7dSMaciej Wawryk 	free_rpc_bdev_error_create(&req);
10107fe6a43SSeth Howell }
102ef78704fSSeth Howell SPDK_RPC_REGISTER("bdev_error_create", rpc_bdev_error_create, SPDK_RPC_RUNTIME)
10307fe6a43SSeth Howell 
10407fe6a43SSeth Howell struct rpc_delete_error {
10507fe6a43SSeth Howell 	char *name;
10607fe6a43SSeth Howell };
10707fe6a43SSeth Howell 
10807fe6a43SSeth Howell static void
free_rpc_delete_error(struct rpc_delete_error * r)10907fe6a43SSeth Howell free_rpc_delete_error(struct rpc_delete_error *r)
11007fe6a43SSeth Howell {
11107fe6a43SSeth Howell 	free(r->name);
11207fe6a43SSeth Howell }
11307fe6a43SSeth Howell 
11407fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_delete_error_decoders[] = {
11507fe6a43SSeth Howell 	{"name", offsetof(struct rpc_delete_error, name), spdk_json_decode_string},
11607fe6a43SSeth Howell };
11707fe6a43SSeth Howell 
11807fe6a43SSeth Howell static void
rpc_bdev_error_delete_cb(void * cb_arg,int bdeverrno)119ef78704fSSeth Howell rpc_bdev_error_delete_cb(void *cb_arg, int bdeverrno)
12007fe6a43SSeth Howell {
12107fe6a43SSeth Howell 	struct spdk_jsonrpc_request *request = cb_arg;
12207fe6a43SSeth Howell 
123d3e394aeSShuhei Matsumoto 	if (bdeverrno == 0) {
124d3e394aeSShuhei Matsumoto 		spdk_jsonrpc_send_bool_response(request, true);
125d3e394aeSShuhei Matsumoto 	} else {
126d3e394aeSShuhei Matsumoto 		spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
127d3e394aeSShuhei Matsumoto 	}
12807fe6a43SSeth Howell }
12907fe6a43SSeth Howell 
13007fe6a43SSeth Howell static void
rpc_bdev_error_delete(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)131ef78704fSSeth Howell rpc_bdev_error_delete(struct spdk_jsonrpc_request *request,
13207fe6a43SSeth Howell 		      const struct spdk_json_val *params)
13307fe6a43SSeth Howell {
13407fe6a43SSeth Howell 	struct rpc_delete_error req = {NULL};
13507fe6a43SSeth Howell 
13607fe6a43SSeth Howell 	if (spdk_json_decode_object(params, rpc_delete_error_decoders,
13707fe6a43SSeth Howell 				    SPDK_COUNTOF(rpc_delete_error_decoders),
13807fe6a43SSeth Howell 				    &req)) {
13907fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
14007fe6a43SSeth Howell 						 "spdk_json_decode_object failed");
14107fe6a43SSeth Howell 		goto cleanup;
14207fe6a43SSeth Howell 	}
14307fe6a43SSeth Howell 
1444573e4ccSShuhei Matsumoto 	vbdev_error_delete(req.name, rpc_bdev_error_delete_cb, request);
14507fe6a43SSeth Howell 
14607fe6a43SSeth Howell cleanup:
14707fe6a43SSeth Howell 	free_rpc_delete_error(&req);
14807fe6a43SSeth Howell }
149ef78704fSSeth Howell SPDK_RPC_REGISTER("bdev_error_delete", rpc_bdev_error_delete, SPDK_RPC_RUNTIME)
15007fe6a43SSeth Howell 
15107fe6a43SSeth Howell struct rpc_error_information {
15207fe6a43SSeth Howell 	char *name;
153ffee98ddSShuhei Matsumoto 	struct vbdev_error_inject_opts opts;
15407fe6a43SSeth Howell };
15507fe6a43SSeth Howell 
15607fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_error_information_decoders[] = {
15707fe6a43SSeth Howell 	{"name", offsetof(struct rpc_error_information, name), spdk_json_decode_string},
158ffee98ddSShuhei Matsumoto 	{"io_type", offsetof(struct rpc_error_information, opts.io_type), rpc_error_bdev_decode_io_type},
159ffee98ddSShuhei Matsumoto 	{"error_type", offsetof(struct rpc_error_information, opts.error_type), rpc_error_bdev_decode_error_type},
160ffee98ddSShuhei Matsumoto 	{"num", offsetof(struct rpc_error_information, opts.error_num), spdk_json_decode_uint32, true},
1614dacace1SArtur Paszkiewicz 	{"queue_depth", offsetof(struct rpc_error_information, opts.error_qd), spdk_json_decode_uint64, true},
1623d2a3ee4SShuhei Matsumoto 	{"corrupt_offset", offsetof(struct rpc_error_information, opts.corrupt_offset), spdk_json_decode_uint64, true},
1633d2a3ee4SShuhei Matsumoto 	{"corrupt_value", offsetof(struct rpc_error_information, opts.corrupt_value), spdk_json_decode_uint8, true},
16407fe6a43SSeth Howell };
16507fe6a43SSeth Howell 
16607fe6a43SSeth Howell static void
free_rpc_error_information(struct rpc_error_information * p)16707fe6a43SSeth Howell free_rpc_error_information(struct rpc_error_information *p)
16807fe6a43SSeth Howell {
16907fe6a43SSeth Howell 	free(p->name);
17007fe6a43SSeth Howell }
17107fe6a43SSeth Howell 
17207fe6a43SSeth Howell static void
rpc_bdev_error_inject_error(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)173ef78704fSSeth Howell rpc_bdev_error_inject_error(struct spdk_jsonrpc_request *request,
17407fe6a43SSeth Howell 			    const struct spdk_json_val *params)
17507fe6a43SSeth Howell {
176ffee98ddSShuhei Matsumoto 	struct rpc_error_information req = {.opts.error_num = 1};
17707fe6a43SSeth Howell 	int rc = 0;
17807fe6a43SSeth Howell 
17907fe6a43SSeth Howell 	if (spdk_json_decode_object(params, rpc_error_information_decoders,
18007fe6a43SSeth Howell 				    SPDK_COUNTOF(rpc_error_information_decoders),
18107fe6a43SSeth Howell 				    &req)) {
18207fe6a43SSeth Howell 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
18307fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
18407fe6a43SSeth Howell 						 "spdk_json_decode_object failed");
18507fe6a43SSeth Howell 		goto cleanup;
18607fe6a43SSeth Howell 	}
18707fe6a43SSeth Howell 
188ffee98ddSShuhei Matsumoto 	rc = vbdev_error_inject_error(req.name, &req.opts);
18907fe6a43SSeth Howell 	if (rc) {
19007fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
19107fe6a43SSeth Howell 		goto cleanup;
19207fe6a43SSeth Howell 	}
19307fe6a43SSeth Howell 
194d73077b8Syidong0635 	spdk_jsonrpc_send_bool_response(request, true);
19507fe6a43SSeth Howell 
19607fe6a43SSeth Howell cleanup:
19707fe6a43SSeth Howell 	free_rpc_error_information(&req);
19807fe6a43SSeth Howell }
199ef78704fSSeth Howell SPDK_RPC_REGISTER("bdev_error_inject_error", rpc_bdev_error_inject_error, SPDK_RPC_RUNTIME)
200