1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/rpc.h" 7 #include "spdk/util.h" 8 9 #include "spdk/log.h" 10 11 struct rpc_log_flag { 12 char *flag; 13 }; 14 15 struct rpc_log_level { 16 char *level; 17 }; 18 19 static void 20 free_rpc_log_flag(struct rpc_log_flag *p) 21 { 22 free(p->flag); 23 } 24 25 static void 26 free_rpc_log_level(struct rpc_log_level *p) 27 { 28 free(p->level); 29 } 30 31 static const struct spdk_json_object_decoder rpc_log_flag_decoders[] = { 32 {"flag", offsetof(struct rpc_log_flag, flag), spdk_json_decode_string}, 33 }; 34 35 static const struct spdk_json_object_decoder rpc_log_level_decoders[] = { 36 {"level", offsetof(struct rpc_log_level, level), spdk_json_decode_string}, 37 }; 38 39 static int 40 _parse_log_level(char *level) 41 { 42 if (!strcasecmp(level, "ERROR")) { 43 return SPDK_LOG_ERROR; 44 } else if (!strcasecmp(level, "WARNING")) { 45 return SPDK_LOG_WARN; 46 } else if (!strcasecmp(level, "NOTICE")) { 47 return SPDK_LOG_NOTICE; 48 } else if (!strcasecmp(level, "INFO")) { 49 return SPDK_LOG_INFO; 50 } else if (!strcasecmp(level, "DEBUG")) { 51 return SPDK_LOG_DEBUG; 52 } 53 return -1; 54 } 55 56 static const char * 57 _log_get_level_name(int level) 58 { 59 if (level == SPDK_LOG_ERROR) { 60 return "ERROR"; 61 } else if (level == SPDK_LOG_WARN) { 62 return "WARNING"; 63 } else if (level == SPDK_LOG_NOTICE) { 64 return "NOTICE"; 65 } else if (level == SPDK_LOG_INFO) { 66 return "INFO"; 67 } else if (level == SPDK_LOG_DEBUG) { 68 return "DEBUG"; 69 } 70 return NULL; 71 } 72 73 static void 74 rpc_log_set_print_level(struct spdk_jsonrpc_request *request, 75 const struct spdk_json_val *params) 76 { 77 struct rpc_log_level req = {}; 78 int level; 79 80 if (spdk_json_decode_object(params, rpc_log_level_decoders, 81 SPDK_COUNTOF(rpc_log_level_decoders), &req)) { 82 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 83 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 84 "spdk_json_decode_object failed"); 85 goto end; 86 } 87 88 level = _parse_log_level(req.level); 89 if (level == -1) { 90 SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n"); 91 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 92 "invalid log level"); 93 goto end; 94 } 95 96 spdk_log_set_print_level(level); 97 spdk_jsonrpc_send_bool_response(request, true); 98 end: 99 free_rpc_log_level(&req); 100 } 101 SPDK_RPC_REGISTER("log_set_print_level", rpc_log_set_print_level, 102 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 103 104 static void 105 rpc_log_get_print_level(struct spdk_jsonrpc_request *request, 106 const struct spdk_json_val *params) 107 { 108 struct spdk_json_write_ctx *w; 109 int level; 110 const char *name; 111 112 if (params != NULL) { 113 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 114 "log_get_print_level requires no parameters"); 115 return; 116 } 117 118 level = spdk_log_get_print_level(); 119 name = _log_get_level_name(level); 120 if (name == NULL) { 121 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 122 "invalid log level"); 123 return; 124 } 125 126 w = spdk_jsonrpc_begin_result(request); 127 spdk_json_write_string(w, name); 128 129 spdk_jsonrpc_end_result(request, w); 130 } 131 SPDK_RPC_REGISTER("log_get_print_level", rpc_log_get_print_level, 132 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 133 134 static void 135 rpc_log_set_level(struct spdk_jsonrpc_request *request, 136 const struct spdk_json_val *params) 137 { 138 struct rpc_log_level req = {}; 139 int level; 140 141 if (spdk_json_decode_object(params, rpc_log_level_decoders, 142 SPDK_COUNTOF(rpc_log_level_decoders), &req)) { 143 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 144 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 145 "spdk_json_decode_object failed"); 146 goto end; 147 } 148 149 level = _parse_log_level(req.level); 150 if (level == -1) { 151 SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n"); 152 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 153 "invalid log level"); 154 goto end; 155 } 156 157 158 spdk_log_set_level(level); 159 spdk_jsonrpc_send_bool_response(request, true); 160 end: 161 free_rpc_log_level(&req); 162 } 163 SPDK_RPC_REGISTER("log_set_level", rpc_log_set_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 164 165 static void 166 rpc_log_get_level(struct spdk_jsonrpc_request *request, 167 const struct spdk_json_val *params) 168 { 169 struct spdk_json_write_ctx *w; 170 int level; 171 const char *name; 172 173 if (params != NULL) { 174 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 175 "log_get_level requires no parameters"); 176 return; 177 } 178 179 level = spdk_log_get_level(); 180 name = _log_get_level_name(level); 181 if (name == NULL) { 182 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 183 "invalid log level"); 184 return; 185 } 186 187 w = spdk_jsonrpc_begin_result(request); 188 spdk_json_write_string(w, name); 189 190 spdk_jsonrpc_end_result(request, w); 191 } 192 SPDK_RPC_REGISTER("log_get_level", rpc_log_get_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 193 194 static void 195 rpc_log_set_flag(struct spdk_jsonrpc_request *request, 196 const struct spdk_json_val *params) 197 { 198 struct rpc_log_flag req = {}; 199 200 if (spdk_json_decode_object(params, rpc_log_flag_decoders, 201 SPDK_COUNTOF(rpc_log_flag_decoders), &req)) { 202 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 203 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 204 "spdk_json_decode_object failed"); 205 goto end; 206 } 207 208 if (req.flag == 0) { 209 SPDK_DEBUGLOG(log_rpc, "invalid flag 0\n"); 210 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 211 "invalid flag 0"); 212 goto end; 213 } 214 215 if (spdk_log_set_flag(req.flag) != 0) { 216 SPDK_DEBUGLOG(log_rpc, "tried to set invalid log flag\n"); 217 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 218 "invalid log flag"); 219 goto end; 220 } 221 222 spdk_jsonrpc_send_bool_response(request, true); 223 end: 224 free_rpc_log_flag(&req); 225 } 226 SPDK_RPC_REGISTER("log_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 227 228 static void 229 rpc_log_clear_flag(struct spdk_jsonrpc_request *request, 230 const struct spdk_json_val *params) 231 { 232 struct rpc_log_flag req = {}; 233 234 if (spdk_json_decode_object(params, rpc_log_flag_decoders, 235 SPDK_COUNTOF(rpc_log_flag_decoders), &req)) { 236 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 237 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 238 "spdk_json_decode_object failed"); 239 goto end; 240 } 241 242 if (req.flag == 0) { 243 SPDK_DEBUGLOG(log_rpc, "Invalid flag 0\n"); 244 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 245 "invalid flag 0"); 246 goto end; 247 } 248 249 if (spdk_log_clear_flag(req.flag) != 0) { 250 SPDK_DEBUGLOG(log_rpc, "tried to clear invalid log flag\n"); 251 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 252 "invalid log flag"); 253 goto end; 254 } 255 256 spdk_jsonrpc_send_bool_response(request, true); 257 end: 258 free_rpc_log_flag(&req); 259 } 260 SPDK_RPC_REGISTER("log_clear_flag", rpc_log_clear_flag, 261 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 262 263 static void 264 rpc_log_get_flags(struct spdk_jsonrpc_request *request, 265 const struct spdk_json_val *params) 266 { 267 struct spdk_json_write_ctx *w; 268 struct spdk_log_flag *flag; 269 270 if (params != NULL) { 271 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 272 "log_get_flags requires no parameters"); 273 return; 274 } 275 276 w = spdk_jsonrpc_begin_result(request); 277 spdk_json_write_object_begin(w); 278 flag = spdk_log_get_first_flag(); 279 while (flag) { 280 spdk_json_write_name(w, flag->name); 281 spdk_json_write_bool(w, flag->enabled); 282 flag = spdk_log_get_next_flag(flag); 283 } 284 spdk_json_write_object_end(w); 285 spdk_jsonrpc_end_result(request, w); 286 } 287 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 288 289 struct rpc_log_enable_timestamps { 290 bool enabled; 291 }; 292 293 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = { 294 {"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool}, 295 }; 296 297 static void 298 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request, 299 const struct spdk_json_val *params) 300 { 301 struct rpc_log_enable_timestamps req = {}; 302 303 if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders, 304 SPDK_COUNTOF(rpc_log_enable_timestamps_decoders), 305 &req)) { 306 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 307 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 308 "spdk_json_decode_object failed"); 309 return; 310 } 311 312 spdk_log_enable_timestamps(req.enabled); 313 314 spdk_jsonrpc_send_bool_response(request, true); 315 } 316 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME) 317 SPDK_LOG_REGISTER_COMPONENT(log_rpc) 318