xref: /spdk/lib/trace/trace_rpc.c (revision 12fbe739a31b09aff0d05f354d4f3bbef99afc55)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/rpc.h"
7 #include "spdk/util.h"
8 #include "spdk/trace.h"
9 #include "spdk/log.h"
10 #include "trace_internal.h"
11 
12 struct rpc_tpoint_group {
13 	char *name;
14 	uint64_t tpoint_mask;
15 };
16 
17 static void
18 free_rpc_tpoint_group(struct rpc_tpoint_group *p)
19 {
20 	free(p->name);
21 }
22 
23 static const struct spdk_json_object_decoder rpc_tpoint_mask_decoders[] = {
24 	{"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string},
25 	{"tpoint_mask", offsetof(struct rpc_tpoint_group, tpoint_mask), spdk_json_decode_uint64, true},
26 };
27 
28 static void
29 rpc_trace_set_tpoint_mask(struct spdk_jsonrpc_request *request,
30 			  const struct spdk_json_val *params)
31 {
32 	struct rpc_tpoint_group req = {};
33 	uint64_t tpoint_group_mask = 0;
34 
35 	if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders,
36 				    SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) {
37 		SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
38 		goto invalid;
39 	}
40 
41 	if (req.name == NULL) {
42 		SPDK_DEBUGLOG(trace, "flag was NULL\n");
43 		goto invalid;
44 	}
45 
46 	tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name);
47 	if (tpoint_group_mask == 0) {
48 		goto invalid;
49 	}
50 
51 	spdk_trace_set_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask);
52 
53 	free_rpc_tpoint_group(&req);
54 
55 	spdk_jsonrpc_send_bool_response(request, true);
56 	return;
57 
58 invalid:
59 	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
60 	free_rpc_tpoint_group(&req);
61 }
62 SPDK_RPC_REGISTER("trace_set_tpoint_mask", rpc_trace_set_tpoint_mask,
63 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
64 
65 static void
66 rpc_trace_clear_tpoint_mask(struct spdk_jsonrpc_request *request,
67 			    const struct spdk_json_val *params)
68 {
69 	struct rpc_tpoint_group req = {};
70 	uint64_t tpoint_group_mask = 0;
71 
72 	if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders,
73 				    SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) {
74 		SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
75 		goto invalid;
76 	}
77 
78 	if (req.name == NULL) {
79 		SPDK_DEBUGLOG(trace, "flag was NULL\n");
80 		goto invalid;
81 	}
82 
83 	tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name);
84 	if (tpoint_group_mask == 0) {
85 		goto invalid;
86 	}
87 
88 	spdk_trace_clear_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask);
89 
90 	free_rpc_tpoint_group(&req);
91 
92 	spdk_jsonrpc_send_bool_response(request, true);
93 	return;
94 
95 invalid:
96 	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
97 	free_rpc_tpoint_group(&req);
98 }
99 SPDK_RPC_REGISTER("trace_clear_tpoint_mask", rpc_trace_clear_tpoint_mask,
100 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
101 
102 static const struct spdk_json_object_decoder rpc_tpoint_group_decoders[] = {
103 	{"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string},
104 };
105 
106 static void
107 rpc_trace_enable_tpoint_group(struct spdk_jsonrpc_request *request,
108 			      const struct spdk_json_val *params)
109 {
110 	struct rpc_tpoint_group req = {};
111 
112 	if (spdk_json_decode_object(params, rpc_tpoint_group_decoders,
113 				    SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) {
114 		SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
115 		goto invalid;
116 	}
117 
118 	if (req.name == NULL) {
119 		SPDK_DEBUGLOG(trace, "flag was NULL\n");
120 		goto invalid;
121 	}
122 
123 	if (spdk_trace_enable_tpoint_group(req.name)) {
124 		goto invalid;
125 	}
126 
127 	free_rpc_tpoint_group(&req);
128 
129 	spdk_jsonrpc_send_bool_response(request, true);
130 	return;
131 
132 invalid:
133 	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
134 	free_rpc_tpoint_group(&req);
135 }
136 SPDK_RPC_REGISTER("trace_enable_tpoint_group", rpc_trace_enable_tpoint_group,
137 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
138 
139 static void
140 rpc_trace_disable_tpoint_group(struct spdk_jsonrpc_request *request,
141 			       const struct spdk_json_val *params)
142 {
143 	struct rpc_tpoint_group req = {};
144 
145 	if (spdk_json_decode_object(params, rpc_tpoint_group_decoders,
146 				    SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) {
147 		SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
148 		goto invalid;
149 	}
150 
151 	if (req.name == NULL) {
152 		SPDK_DEBUGLOG(trace, "flag was NULL\n");
153 		goto invalid;
154 	}
155 
156 	if (spdk_trace_disable_tpoint_group(req.name)) {
157 		goto invalid;
158 	}
159 
160 	free_rpc_tpoint_group(&req);
161 
162 	spdk_jsonrpc_send_bool_response(request, true);
163 	return;
164 
165 invalid:
166 	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
167 	free_rpc_tpoint_group(&req);
168 }
169 SPDK_RPC_REGISTER("trace_disable_tpoint_group", rpc_trace_disable_tpoint_group,
170 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
171 
172 static void
173 rpc_trace_get_tpoint_group_mask(struct spdk_jsonrpc_request *request,
174 				const struct spdk_json_val *params)
175 {
176 	uint64_t tpoint_group_mask;
177 	char mask_str[20];
178 	bool enabled;
179 	struct spdk_json_write_ctx *w;
180 	struct spdk_trace_register_fn *register_fn;
181 
182 	if (params != NULL) {
183 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
184 						 "trace_get_tpoint_group_mask requires no parameters");
185 		return;
186 	}
187 
188 	w = spdk_jsonrpc_begin_result(request);
189 	tpoint_group_mask = spdk_trace_get_tpoint_group_mask();
190 
191 	spdk_json_write_object_begin(w);
192 
193 	snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask);
194 	spdk_json_write_named_string(w, "tpoint_group_mask", mask_str);
195 
196 	register_fn = spdk_trace_get_first_register_fn();
197 	while (register_fn) {
198 		enabled = spdk_trace_get_tpoint_mask(register_fn->tgroup_id) != 0;
199 
200 		spdk_json_write_named_object_begin(w, register_fn->name);
201 		spdk_json_write_named_bool(w, "enabled", enabled);
202 
203 		snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id));
204 		spdk_json_write_named_string(w, "mask", mask_str);
205 		spdk_json_write_object_end(w);
206 
207 		register_fn = spdk_trace_get_next_register_fn(register_fn);
208 	}
209 
210 	spdk_json_write_object_end(w);
211 	spdk_jsonrpc_end_result(request, w);
212 }
213 SPDK_RPC_REGISTER("trace_get_tpoint_group_mask", rpc_trace_get_tpoint_group_mask,
214 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
215 
216 static void
217 rpc_trace_get_info(struct spdk_jsonrpc_request *request,
218 		   const struct spdk_json_val *params)
219 {
220 	char shm_path[128];
221 	uint64_t tpoint_group_mask;
222 	uint64_t tpoint_mask;
223 	char tpoint_mask_str[20];
224 	char mask_str[20];
225 	struct spdk_json_write_ctx *w;
226 	struct spdk_trace_register_fn *register_fn;
227 
228 	if (params != NULL) {
229 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
230 						 "trace_get_info requires no parameters");
231 		return;
232 	}
233 
234 	snprintf(shm_path, sizeof(shm_path), "/dev/shm%s", trace_get_shm_name());
235 	tpoint_group_mask = spdk_trace_get_tpoint_group_mask();
236 
237 	w = spdk_jsonrpc_begin_result(request);
238 	spdk_json_write_object_begin(w);
239 	spdk_json_write_named_string(w, "tpoint_shm_path", shm_path);
240 
241 	snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask);
242 	spdk_json_write_named_string(w, "tpoint_group_mask", mask_str);
243 
244 	register_fn = spdk_trace_get_first_register_fn();
245 	while (register_fn) {
246 
247 		tpoint_mask = spdk_trace_get_tpoint_mask(register_fn->tgroup_id);
248 
249 		spdk_json_write_named_object_begin(w, register_fn->name);
250 		snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id));
251 		spdk_json_write_named_string(w, "mask", mask_str);
252 		snprintf(tpoint_mask_str, sizeof(tpoint_mask_str), "0x%lx", tpoint_mask);
253 		spdk_json_write_named_string(w, "tpoint_mask", tpoint_mask_str);
254 		spdk_json_write_object_end(w);
255 
256 		register_fn = spdk_trace_get_next_register_fn(register_fn);
257 	}
258 
259 	spdk_json_write_object_end(w);
260 	spdk_jsonrpc_end_result(request, w);
261 }
262 SPDK_RPC_REGISTER("trace_get_info", rpc_trace_get_info,
263 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
264