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