1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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 spdk_log_set_flag(req.flag); 216 spdk_jsonrpc_send_bool_response(request, true); 217 end: 218 free_rpc_log_flag(&req); 219 } 220 SPDK_RPC_REGISTER("log_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 221 222 static void 223 rpc_log_clear_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_clear_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_clear_flag", rpc_log_clear_flag, 249 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 250 251 static void 252 rpc_log_get_flags(struct spdk_jsonrpc_request *request, 253 const struct spdk_json_val *params) 254 { 255 struct spdk_json_write_ctx *w; 256 struct spdk_log_flag *flag; 257 258 if (params != NULL) { 259 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 260 "log_get_flags requires no parameters"); 261 return; 262 } 263 264 w = spdk_jsonrpc_begin_result(request); 265 spdk_json_write_object_begin(w); 266 flag = spdk_log_get_first_flag(); 267 while (flag) { 268 spdk_json_write_name(w, flag->name); 269 spdk_json_write_bool(w, flag->enabled); 270 flag = spdk_log_get_next_flag(flag); 271 } 272 spdk_json_write_object_end(w); 273 spdk_jsonrpc_end_result(request, w); 274 } 275 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 276 277 struct rpc_log_enable_timestamps { 278 bool enabled; 279 }; 280 281 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = { 282 {"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool}, 283 }; 284 285 static void 286 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request, 287 const struct spdk_json_val *params) 288 { 289 struct rpc_log_enable_timestamps req = {}; 290 291 if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders, 292 SPDK_COUNTOF(rpc_log_enable_timestamps_decoders), 293 &req)) { 294 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 295 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 296 "spdk_json_decode_object failed"); 297 return; 298 } 299 300 spdk_log_enable_timestamps(req.enabled); 301 302 spdk_jsonrpc_send_bool_response(request, true); 303 } 304 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME) 305 SPDK_LOG_REGISTER_COMPONENT(log_rpc) 306