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 (spdk_log_set_flag(req.flag) != 0) { 209 SPDK_DEBUGLOG(log_rpc, "tried to set invalid log flag\n"); 210 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 211 "invalid log flag"); 212 goto end; 213 } 214 215 spdk_jsonrpc_send_bool_response(request, true); 216 end: 217 free_rpc_log_flag(&req); 218 } 219 SPDK_RPC_REGISTER("log_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 220 221 static void 222 rpc_log_clear_flag(struct spdk_jsonrpc_request *request, 223 const struct spdk_json_val *params) 224 { 225 struct rpc_log_flag req = {}; 226 227 if (spdk_json_decode_object(params, rpc_log_flag_decoders, 228 SPDK_COUNTOF(rpc_log_flag_decoders), &req)) { 229 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 230 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 231 "spdk_json_decode_object failed"); 232 goto end; 233 } 234 235 if (spdk_log_clear_flag(req.flag) != 0) { 236 SPDK_DEBUGLOG(log_rpc, "tried to clear invalid log flag\n"); 237 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 238 "invalid log flag"); 239 goto end; 240 } 241 242 spdk_jsonrpc_send_bool_response(request, true); 243 end: 244 free_rpc_log_flag(&req); 245 } 246 SPDK_RPC_REGISTER("log_clear_flag", rpc_log_clear_flag, 247 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 248 249 static void 250 rpc_log_get_flags(struct spdk_jsonrpc_request *request, 251 const struct spdk_json_val *params) 252 { 253 struct spdk_json_write_ctx *w; 254 struct spdk_log_flag *flag; 255 256 if (params != NULL) { 257 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 258 "log_get_flags requires no parameters"); 259 return; 260 } 261 262 w = spdk_jsonrpc_begin_result(request); 263 spdk_json_write_object_begin(w); 264 flag = spdk_log_get_first_flag(); 265 while (flag) { 266 spdk_json_write_name(w, flag->name); 267 spdk_json_write_bool(w, flag->enabled); 268 flag = spdk_log_get_next_flag(flag); 269 } 270 spdk_json_write_object_end(w); 271 spdk_jsonrpc_end_result(request, w); 272 } 273 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 274 275 struct rpc_log_enable_timestamps { 276 bool enabled; 277 }; 278 279 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = { 280 {"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool}, 281 }; 282 283 static void 284 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request, 285 const struct spdk_json_val *params) 286 { 287 struct rpc_log_enable_timestamps req = {}; 288 289 if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders, 290 SPDK_COUNTOF(rpc_log_enable_timestamps_decoders), 291 &req)) { 292 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 293 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 294 "spdk_json_decode_object failed"); 295 return; 296 } 297 298 spdk_log_enable_timestamps(req.enabled); 299 300 spdk_jsonrpc_send_bool_response(request, true); 301 } 302 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME) 303 SPDK_LOG_REGISTER_COMPONENT(log_rpc) 304