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