xref: /spdk/lib/event/log_rpc.c (revision 88e3ffd7b6c5ec1ea1a660354d25f02c766092e1)
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 invalid;
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 invalid;
122 	}
123 
124 	spdk_log_set_print_level(level);
125 	free_rpc_log_level(&req);
126 
127 	spdk_jsonrpc_send_bool_response(request, true);
128 	return;
129 
130 invalid:
131 	free_rpc_log_level(&req);
132 }
133 SPDK_RPC_REGISTER("log_set_print_level", rpc_log_set_print_level,
134 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
135 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_set_print_level, set_log_print_level)
136 
137 static void
138 rpc_log_get_print_level(struct spdk_jsonrpc_request *request,
139 			const struct spdk_json_val *params)
140 {
141 	struct spdk_json_write_ctx *w;
142 	int level;
143 	const char *name;
144 
145 	if (params != NULL) {
146 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
147 						 "log_get_print_level requires no parameters");
148 		return;
149 	}
150 
151 	level = spdk_log_get_print_level();
152 	name = _log_get_level_name(level);
153 	if (name == NULL) {
154 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
155 						 "invalid log level");
156 		return;
157 	}
158 
159 	w = spdk_jsonrpc_begin_result(request);
160 	spdk_json_write_string(w, name);
161 
162 	spdk_jsonrpc_end_result(request, w);
163 }
164 SPDK_RPC_REGISTER("log_get_print_level", rpc_log_get_print_level,
165 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
166 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_get_print_level, get_log_print_level)
167 
168 static void
169 rpc_log_set_level(struct spdk_jsonrpc_request *request,
170 		  const struct spdk_json_val *params)
171 {
172 	struct rpc_log_level req = {};
173 	int level;
174 
175 	if (spdk_json_decode_object(params, rpc_log_level_decoders,
176 				    SPDK_COUNTOF(rpc_log_level_decoders), &req)) {
177 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
178 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
179 						 "spdk_json_decode_object failed");
180 		goto invalid;
181 	}
182 
183 	level = _parse_log_level(req.level);
184 	if (level == -1) {
185 		SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n");
186 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
187 						 "invalid log level");
188 		goto invalid;
189 	}
190 
191 
192 	spdk_log_set_level(level);
193 	free_rpc_log_level(&req);
194 
195 	spdk_jsonrpc_send_bool_response(request, true);
196 	return;
197 
198 invalid:
199 	free_rpc_log_level(&req);
200 }
201 SPDK_RPC_REGISTER("log_set_level", rpc_log_set_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
202 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_set_level, set_log_level)
203 
204 static void
205 rpc_log_get_level(struct spdk_jsonrpc_request *request,
206 		  const struct spdk_json_val *params)
207 {
208 	struct spdk_json_write_ctx *w;
209 	int level;
210 	const char *name;
211 
212 	if (params != NULL) {
213 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
214 						 "log_get_level requires no parameters");
215 		return;
216 	}
217 
218 	level = spdk_log_get_level();
219 	name = _log_get_level_name(level);
220 	if (name == NULL) {
221 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
222 						 "invalid log level");
223 		return;
224 	}
225 
226 	w = spdk_jsonrpc_begin_result(request);
227 	spdk_json_write_string(w, name);
228 
229 	spdk_jsonrpc_end_result(request, w);
230 }
231 SPDK_RPC_REGISTER("log_get_level", rpc_log_get_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
232 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_get_level, get_log_level)
233 
234 static void
235 rpc_log_set_flag(struct spdk_jsonrpc_request *request,
236 		 const struct spdk_json_val *params)
237 {
238 	struct rpc_log_flag req = {};
239 
240 	if (spdk_json_decode_object(params, rpc_log_flag_decoders,
241 				    SPDK_COUNTOF(rpc_log_flag_decoders), &req)) {
242 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
243 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
244 						 "spdk_json_decode_object failed");
245 		goto invalid;
246 	}
247 
248 	if (req.flag == 0) {
249 		SPDK_DEBUGLOG(log_rpc, "invalid flag 0\n");
250 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
251 						 "invalid flag 0");
252 		goto invalid;
253 	}
254 
255 	spdk_log_set_flag(req.flag);
256 	free_rpc_log_flag(&req);
257 
258 	spdk_jsonrpc_send_bool_response(request, true);
259 	return;
260 
261 invalid:
262 	free_rpc_log_flag(&req);
263 }
264 SPDK_RPC_REGISTER("log_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
265 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_set_flag, set_log_flag)
266 
267 static void
268 rpc_log_clear_flag(struct spdk_jsonrpc_request *request,
269 		   const struct spdk_json_val *params)
270 {
271 	struct rpc_log_flag req = {};
272 
273 	if (spdk_json_decode_object(params, rpc_log_flag_decoders,
274 				    SPDK_COUNTOF(rpc_log_flag_decoders), &req)) {
275 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
276 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
277 						 "spdk_json_decode_object failed");
278 		goto invalid;
279 	}
280 
281 	if (req.flag == 0) {
282 		SPDK_DEBUGLOG(log_rpc, "Invalid flag 0\n");
283 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
284 						 "invalid flag 0");
285 		goto invalid;
286 	}
287 
288 	spdk_log_clear_flag(req.flag);
289 	free_rpc_log_flag(&req);
290 
291 	spdk_jsonrpc_send_bool_response(request, true);
292 	return;
293 
294 invalid:
295 	free_rpc_log_flag(&req);
296 }
297 SPDK_RPC_REGISTER("log_clear_flag", rpc_log_clear_flag,
298 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
299 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_clear_flag, clear_log_flag)
300 
301 static void
302 rpc_log_get_flags(struct spdk_jsonrpc_request *request,
303 		  const struct spdk_json_val *params)
304 {
305 	struct spdk_json_write_ctx *w;
306 	struct spdk_log_flag *flag;
307 
308 	if (params != NULL) {
309 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
310 						 "log_get_flags requires no parameters");
311 		return;
312 	}
313 
314 	w = spdk_jsonrpc_begin_result(request);
315 	spdk_json_write_object_begin(w);
316 	flag = spdk_log_get_first_flag();
317 	while (flag) {
318 		spdk_json_write_name(w, flag->name);
319 		spdk_json_write_bool(w, flag->enabled);
320 		flag = spdk_log_get_next_flag(flag);
321 	}
322 	spdk_json_write_object_end(w);
323 	spdk_jsonrpc_end_result(request, w);
324 }
325 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
326 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(log_get_flags, get_log_flags)
327 
328 struct rpc_log_enable_timestamps {
329 	bool enabled;
330 };
331 
332 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = {
333 	{"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool},
334 };
335 
336 static void
337 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request,
338 			  const struct spdk_json_val *params)
339 {
340 	struct rpc_log_enable_timestamps req = {};
341 
342 	if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders,
343 				    SPDK_COUNTOF(rpc_log_enable_timestamps_decoders),
344 				    &req)) {
345 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
346 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
347 						 "spdk_json_decode_object failed");
348 		return;
349 	}
350 
351 	spdk_log_enable_timestamps(req.enabled);
352 
353 	spdk_jsonrpc_send_bool_response(request, true);
354 }
355 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME)
356 SPDK_LOG_REGISTER_COMPONENT(log_rpc)
357