xref: /spdk/lib/event/log_rpc.c (revision d8d29ec0b1a116941bdead09bedd58f456317566)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/rpc.h"
35 #include "spdk/util.h"
36 
37 #include "spdk/log.h"
38 
39 struct rpc_log_flag {
40 	char *flag;
41 };
42 
43 struct rpc_log_level {
44 	char *level;
45 };
46 
47 static void
48 free_rpc_log_flag(struct rpc_log_flag *p)
49 {
50 	free(p->flag);
51 }
52 
53 static void
54 free_rpc_log_level(struct rpc_log_level *p)
55 {
56 	free(p->level);
57 }
58 
59 static const struct spdk_json_object_decoder rpc_log_flag_decoders[] = {
60 	{"flag", offsetof(struct rpc_log_flag, flag), spdk_json_decode_string},
61 };
62 
63 static const struct spdk_json_object_decoder rpc_log_level_decoders[] = {
64 	{"level", offsetof(struct rpc_log_level, level), spdk_json_decode_string},
65 };
66 
67 static int
68 _parse_log_level(char *level)
69 {
70 	if (!strcasecmp(level, "ERROR")) {
71 		return SPDK_LOG_ERROR;
72 	} else if (!strcasecmp(level, "WARNING")) {
73 		return SPDK_LOG_WARN;
74 	} else if (!strcasecmp(level, "NOTICE")) {
75 		return SPDK_LOG_NOTICE;
76 	} else if (!strcasecmp(level, "INFO")) {
77 		return SPDK_LOG_INFO;
78 	} else if (!strcasecmp(level, "DEBUG")) {
79 		return SPDK_LOG_DEBUG;
80 	}
81 	return -1;
82 }
83 
84 static const char *
85 _log_get_level_name(int level)
86 {
87 	if (level == SPDK_LOG_ERROR) {
88 		return "ERROR";
89 	} else if (level == SPDK_LOG_WARN) {
90 		return "WARNING";
91 	} else if (level == SPDK_LOG_NOTICE) {
92 		return "NOTICE";
93 	} else if (level == SPDK_LOG_INFO) {
94 		return "INFO";
95 	} else if (level == SPDK_LOG_DEBUG) {
96 		return "DEBUG";
97 	}
98 	return NULL;
99 }
100 
101 static void
102 rpc_log_set_print_level(struct spdk_jsonrpc_request *request,
103 			const struct spdk_json_val *params)
104 {
105 	struct rpc_log_level req = {};
106 	int level;
107 
108 	if (spdk_json_decode_object(params, rpc_log_level_decoders,
109 				    SPDK_COUNTOF(rpc_log_level_decoders), &req)) {
110 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
111 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
112 						 "spdk_json_decode_object failed");
113 		goto end;
114 	}
115 
116 	level = _parse_log_level(req.level);
117 	if (level == -1) {
118 		SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n");
119 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
120 						 "invalid log level");
121 		goto end;
122 	}
123 
124 	spdk_log_set_print_level(level);
125 	spdk_jsonrpc_send_bool_response(request, true);
126 end:
127 	free_rpc_log_level(&req);
128 }
129 SPDK_RPC_REGISTER("log_set_print_level", rpc_log_set_print_level,
130 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
131 
132 static void
133 rpc_log_get_print_level(struct spdk_jsonrpc_request *request,
134 			const struct spdk_json_val *params)
135 {
136 	struct spdk_json_write_ctx *w;
137 	int level;
138 	const char *name;
139 
140 	if (params != NULL) {
141 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
142 						 "log_get_print_level requires no parameters");
143 		return;
144 	}
145 
146 	level = spdk_log_get_print_level();
147 	name = _log_get_level_name(level);
148 	if (name == NULL) {
149 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
150 						 "invalid log level");
151 		return;
152 	}
153 
154 	w = spdk_jsonrpc_begin_result(request);
155 	spdk_json_write_string(w, name);
156 
157 	spdk_jsonrpc_end_result(request, w);
158 }
159 SPDK_RPC_REGISTER("log_get_print_level", rpc_log_get_print_level,
160 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
161 
162 static void
163 rpc_log_set_level(struct spdk_jsonrpc_request *request,
164 		  const struct spdk_json_val *params)
165 {
166 	struct rpc_log_level req = {};
167 	int level;
168 
169 	if (spdk_json_decode_object(params, rpc_log_level_decoders,
170 				    SPDK_COUNTOF(rpc_log_level_decoders), &req)) {
171 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
172 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
173 						 "spdk_json_decode_object failed");
174 		goto end;
175 	}
176 
177 	level = _parse_log_level(req.level);
178 	if (level == -1) {
179 		SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n");
180 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
181 						 "invalid log level");
182 		goto end;
183 	}
184 
185 
186 	spdk_log_set_level(level);
187 	spdk_jsonrpc_send_bool_response(request, true);
188 end:
189 	free_rpc_log_level(&req);
190 }
191 SPDK_RPC_REGISTER("log_set_level", rpc_log_set_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
192 
193 static void
194 rpc_log_get_level(struct spdk_jsonrpc_request *request,
195 		  const struct spdk_json_val *params)
196 {
197 	struct spdk_json_write_ctx *w;
198 	int level;
199 	const char *name;
200 
201 	if (params != NULL) {
202 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
203 						 "log_get_level requires no parameters");
204 		return;
205 	}
206 
207 	level = spdk_log_get_level();
208 	name = _log_get_level_name(level);
209 	if (name == NULL) {
210 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
211 						 "invalid log level");
212 		return;
213 	}
214 
215 	w = spdk_jsonrpc_begin_result(request);
216 	spdk_json_write_string(w, name);
217 
218 	spdk_jsonrpc_end_result(request, w);
219 }
220 SPDK_RPC_REGISTER("log_get_level", rpc_log_get_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
221 
222 static void
223 rpc_log_set_flag(struct spdk_jsonrpc_request *request,
224 		 const struct spdk_json_val *params)
225 {
226 	struct rpc_log_flag req = {};
227 
228 	if (spdk_json_decode_object(params, rpc_log_flag_decoders,
229 				    SPDK_COUNTOF(rpc_log_flag_decoders), &req)) {
230 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
231 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
232 						 "spdk_json_decode_object failed");
233 		goto end;
234 	}
235 
236 	if (req.flag == 0) {
237 		SPDK_DEBUGLOG(log_rpc, "invalid flag 0\n");
238 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
239 						 "invalid flag 0");
240 		goto end;
241 	}
242 
243 	spdk_log_set_flag(req.flag);
244 	spdk_jsonrpc_send_bool_response(request, true);
245 end:
246 	free_rpc_log_flag(&req);
247 }
248 SPDK_RPC_REGISTER("log_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
249 
250 static void
251 rpc_log_clear_flag(struct spdk_jsonrpc_request *request,
252 		   const struct spdk_json_val *params)
253 {
254 	struct rpc_log_flag req = {};
255 
256 	if (spdk_json_decode_object(params, rpc_log_flag_decoders,
257 				    SPDK_COUNTOF(rpc_log_flag_decoders), &req)) {
258 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
259 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
260 						 "spdk_json_decode_object failed");
261 		goto end;
262 	}
263 
264 	if (req.flag == 0) {
265 		SPDK_DEBUGLOG(log_rpc, "Invalid flag 0\n");
266 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
267 						 "invalid flag 0");
268 		goto end;
269 	}
270 
271 	spdk_log_clear_flag(req.flag);
272 	spdk_jsonrpc_send_bool_response(request, true);
273 end:
274 	free_rpc_log_flag(&req);
275 }
276 SPDK_RPC_REGISTER("log_clear_flag", rpc_log_clear_flag,
277 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
278 
279 static void
280 rpc_log_get_flags(struct spdk_jsonrpc_request *request,
281 		  const struct spdk_json_val *params)
282 {
283 	struct spdk_json_write_ctx *w;
284 	struct spdk_log_flag *flag;
285 
286 	if (params != NULL) {
287 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
288 						 "log_get_flags requires no parameters");
289 		return;
290 	}
291 
292 	w = spdk_jsonrpc_begin_result(request);
293 	spdk_json_write_object_begin(w);
294 	flag = spdk_log_get_first_flag();
295 	while (flag) {
296 		spdk_json_write_name(w, flag->name);
297 		spdk_json_write_bool(w, flag->enabled);
298 		flag = spdk_log_get_next_flag(flag);
299 	}
300 	spdk_json_write_object_end(w);
301 	spdk_jsonrpc_end_result(request, w);
302 }
303 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
304 
305 struct rpc_log_enable_timestamps {
306 	bool enabled;
307 };
308 
309 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = {
310 	{"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool},
311 };
312 
313 static void
314 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request,
315 			  const struct spdk_json_val *params)
316 {
317 	struct rpc_log_enable_timestamps req = {};
318 
319 	if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders,
320 				    SPDK_COUNTOF(rpc_log_enable_timestamps_decoders),
321 				    &req)) {
322 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
323 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
324 						 "spdk_json_decode_object failed");
325 		return;
326 	}
327 
328 	spdk_log_enable_timestamps(req.enabled);
329 
330 	spdk_jsonrpc_send_bool_response(request, true);
331 }
332 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME)
333 SPDK_LOG_REGISTER_COMPONENT(log_rpc)
334