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 0 : free_rpc_update_latency(struct rpc_update_latency *req)
27 : {
28 0 : free(req->delay_bdev_name);
29 0 : free(req->latency_type);
30 0 : }
31 :
32 : static void
33 0 : rpc_bdev_delay_update_latency(struct spdk_jsonrpc_request *request,
34 : const struct spdk_json_val *params)
35 : {
36 0 : struct rpc_update_latency req = {NULL};
37 : enum delay_io_type latency_type;
38 0 : int rc = 0;
39 :
40 0 : 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 0 : if (!strncmp(req.latency_type, "avg_read", 9)) {
50 0 : latency_type = DELAY_AVG_READ;
51 0 : } else if (!strncmp(req.latency_type, "p99_read", 9)) {
52 0 : latency_type = DELAY_P99_READ;
53 0 : } else if (!strncmp(req.latency_type, "avg_write", 10)) {
54 0 : latency_type = DELAY_AVG_WRITE;
55 0 : } else if (!strncmp(req.latency_type, "p99_write", 10)) {
56 0 : 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 0 : rc = vbdev_delay_update_latency_value(req.delay_bdev_name, req.latency_us, latency_type);
64 :
65 0 : 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 0 : } 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 0 : } else if (rc) {
74 0 : SPDK_UNREACHABLE();
75 : }
76 :
77 0 : spdk_jsonrpc_send_bool_response(request, true);
78 :
79 0 : cleanup:
80 0 : free_rpc_update_latency(&req);
81 0 : }
82 0 : 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 0 : free_rpc_construct_delay(struct rpc_construct_delay *r)
96 : {
97 0 : free(r->base_bdev_name);
98 0 : free(r->name);
99 0 : }
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 0 : rpc_bdev_delay_create(struct spdk_jsonrpc_request *request,
113 : const struct spdk_json_val *params)
114 : {
115 0 : struct rpc_construct_delay req = {NULL};
116 : struct spdk_json_write_ctx *w;
117 : int rc;
118 :
119 0 : 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 0 : 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 0 : if (rc != 0) {
132 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
133 0 : goto cleanup;
134 : }
135 :
136 0 : w = spdk_jsonrpc_begin_result(request);
137 0 : spdk_json_write_string(w, req.name);
138 0 : spdk_jsonrpc_end_result(request, w);
139 :
140 0 : cleanup:
141 0 : free_rpc_construct_delay(&req);
142 0 : }
143 0 : 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 0 : SPDK_RPC_REGISTER("bdev_delay_delete", rpc_bdev_delay_delete, SPDK_RPC_RUNTIME)
|