Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "vbdev_delay.h"
7 : : #include "spdk/rpc.h"
8 : : #include "spdk/util.h"
9 : : #include "spdk/string.h"
10 : : #include "spdk/log.h"
11 : : #include "spdk_internal/assert.h"
12 : :
13 : : struct rpc_update_latency {
14 : : char *delay_bdev_name;
15 : : char *latency_type;
16 : : uint64_t latency_us;
17 : : };
18 : :
19 : : static const struct spdk_json_object_decoder rpc_update_latency_decoders[] = {
20 : : {"delay_bdev_name", offsetof(struct rpc_update_latency, delay_bdev_name), spdk_json_decode_string},
21 : : {"latency_type", offsetof(struct rpc_update_latency, latency_type), spdk_json_decode_string},
22 : : {"latency_us", offsetof(struct rpc_update_latency, latency_us), spdk_json_decode_uint64}
23 : : };
24 : :
25 : : static void
26 : 40 : free_rpc_update_latency(struct rpc_update_latency *req)
27 : : {
28 : 40 : free(req->delay_bdev_name);
29 : 40 : free(req->latency_type);
30 : 40 : }
31 : :
32 : : static void
33 : 40 : rpc_bdev_delay_update_latency(struct spdk_jsonrpc_request *request,
34 : : const struct spdk_json_val *params)
35 : : {
36 : 40 : struct rpc_update_latency req = {NULL};
37 : : enum delay_io_type latency_type;
38 : 40 : int rc = 0;
39 : :
40 [ - + ]: 40 : if (spdk_json_decode_object(params, rpc_update_latency_decoders,
41 : : SPDK_COUNTOF(rpc_update_latency_decoders),
42 : : &req)) {
43 [ # # # # ]: 0 : SPDK_DEBUGLOG(vbdev_delay, "spdk_json_decode_object failed\n");
44 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
45 : : "spdk_json_decode_object failed");
46 : 0 : goto cleanup;
47 : : }
48 : :
49 [ - + + + ]: 40 : if (!strncmp(req.latency_type, "avg_read", 9)) {
50 : 10 : latency_type = DELAY_AVG_READ;
51 [ - + + + ]: 30 : } else if (!strncmp(req.latency_type, "p99_read", 9)) {
52 : 10 : latency_type = DELAY_P99_READ;
53 [ - + + + ]: 20 : } else if (!strncmp(req.latency_type, "avg_write", 10)) {
54 : 10 : latency_type = DELAY_AVG_WRITE;
55 [ - + + - ]: 10 : } else if (!strncmp(req.latency_type, "p99_write", 10)) {
56 : 10 : latency_type = DELAY_P99_WRITE;
57 : : } else {
58 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
59 : : "Please specify a valid latency type.");
60 : 0 : goto cleanup;
61 : : }
62 : :
63 : 40 : rc = vbdev_delay_update_latency_value(req.delay_bdev_name, req.latency_us, latency_type);
64 : :
65 [ - + ]: 40 : if (rc == -ENODEV) {
66 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
67 : : "The requested bdev does not exist.");
68 : 0 : goto cleanup;
69 [ - + ]: 40 : } else if (rc == -EINVAL) {
70 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST,
71 : : "The requested bdev is not a delay bdev.");
72 : 0 : goto cleanup;
73 [ - + ]: 40 : } else if (rc) {
74 : 0 : SPDK_UNREACHABLE();
75 : : }
76 : :
77 : 40 : spdk_jsonrpc_send_bool_response(request, true);
78 : :
79 : 40 : cleanup:
80 : 40 : free_rpc_update_latency(&req);
81 : 40 : }
82 : 2038 : SPDK_RPC_REGISTER("bdev_delay_update_latency", rpc_bdev_delay_update_latency, SPDK_RPC_RUNTIME)
83 : :
84 : : struct rpc_construct_delay {
85 : : char *base_bdev_name;
86 : : char *name;
87 : : struct spdk_uuid uuid;
88 : : uint64_t avg_read_latency;
89 : : uint64_t p99_read_latency;
90 : : uint64_t avg_write_latency;
91 : : uint64_t p99_write_latency;
92 : : };
93 : :
94 : : static void
95 : 56 : free_rpc_construct_delay(struct rpc_construct_delay *r)
96 : : {
97 : 56 : free(r->base_bdev_name);
98 : 56 : free(r->name);
99 : 56 : }
100 : :
101 : : static const struct spdk_json_object_decoder rpc_construct_delay_decoders[] = {
102 : : {"base_bdev_name", offsetof(struct rpc_construct_delay, base_bdev_name), spdk_json_decode_string},
103 : : {"name", offsetof(struct rpc_construct_delay, name), spdk_json_decode_string},
104 : : {"uuid", offsetof(struct rpc_construct_delay, uuid), spdk_json_decode_uuid, true},
105 : : {"avg_read_latency", offsetof(struct rpc_construct_delay, avg_read_latency), spdk_json_decode_uint64},
106 : : {"p99_read_latency", offsetof(struct rpc_construct_delay, p99_read_latency), spdk_json_decode_uint64},
107 : : {"avg_write_latency", offsetof(struct rpc_construct_delay, avg_write_latency), spdk_json_decode_uint64},
108 : : {"p99_write_latency", offsetof(struct rpc_construct_delay, p99_write_latency), spdk_json_decode_uint64},
109 : : };
110 : :
111 : : static void
112 : 56 : rpc_bdev_delay_create(struct spdk_jsonrpc_request *request,
113 : : const struct spdk_json_val *params)
114 : : {
115 : 56 : struct rpc_construct_delay req = {NULL};
116 : : struct spdk_json_write_ctx *w;
117 : : int rc;
118 : :
119 [ - + ]: 56 : if (spdk_json_decode_object(params, rpc_construct_delay_decoders,
120 : : SPDK_COUNTOF(rpc_construct_delay_decoders),
121 : : &req)) {
122 [ # # # # ]: 0 : SPDK_DEBUGLOG(vbdev_delay, "spdk_json_decode_object failed\n");
123 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
124 : : "spdk_json_decode_object failed");
125 : 0 : goto cleanup;
126 : : }
127 : :
128 : 56 : rc = create_delay_disk(req.base_bdev_name, req.name, &req.uuid, req.avg_read_latency,
129 : : req.p99_read_latency,
130 : : req.avg_write_latency, req.p99_write_latency);
131 [ - + ]: 56 : if (rc != 0) {
132 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
133 : 0 : goto cleanup;
134 : : }
135 : :
136 : 56 : w = spdk_jsonrpc_begin_result(request);
137 : 56 : spdk_json_write_string(w, req.name);
138 : 56 : spdk_jsonrpc_end_result(request, w);
139 : :
140 : 56 : cleanup:
141 : 56 : free_rpc_construct_delay(&req);
142 : 56 : }
143 : 2038 : SPDK_RPC_REGISTER("bdev_delay_create", rpc_bdev_delay_create, SPDK_RPC_RUNTIME)
144 : :
145 : : struct rpc_delete_delay {
146 : : char *name;
147 : : };
148 : :
149 : : static void
150 : 0 : free_rpc_delete_delay(struct rpc_delete_delay *req)
151 : : {
152 : 0 : free(req->name);
153 : 0 : }
154 : :
155 : : static const struct spdk_json_object_decoder rpc_delete_delay_decoders[] = {
156 : : {"name", offsetof(struct rpc_delete_delay, name), spdk_json_decode_string},
157 : : };
158 : :
159 : : static void
160 : 0 : rpc_bdev_delay_delete_cb(void *cb_arg, int bdeverrno)
161 : : {
162 : 0 : struct spdk_jsonrpc_request *request = cb_arg;
163 : :
164 [ # # ]: 0 : if (bdeverrno == 0) {
165 : 0 : spdk_jsonrpc_send_bool_response(request, true);
166 : : } else {
167 : 0 : spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
168 : : }
169 : 0 : }
170 : :
171 : : static void
172 : 0 : rpc_bdev_delay_delete(struct spdk_jsonrpc_request *request,
173 : : const struct spdk_json_val *params)
174 : : {
175 : 0 : struct rpc_delete_delay req = {NULL};
176 : :
177 [ # # ]: 0 : if (spdk_json_decode_object(params, rpc_delete_delay_decoders,
178 : : SPDK_COUNTOF(rpc_delete_delay_decoders),
179 : : &req)) {
180 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
181 : : "spdk_json_decode_object failed");
182 : 0 : goto cleanup;
183 : : }
184 : :
185 : 0 : delete_delay_disk(req.name, rpc_bdev_delay_delete_cb, request);
186 : :
187 : 0 : cleanup:
188 : 0 : free_rpc_delete_delay(&req);
189 : 0 : }
190 : 2038 : SPDK_RPC_REGISTER("bdev_delay_delete", rpc_bdev_delay_delete, SPDK_RPC_RUNTIME)
|