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