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 132 static void 133 rpc_log_get_print_level(struct spdk_jsonrpc_request *request, 134 const struct spdk_json_val *params) 135 { 136 struct spdk_json_write_ctx *w; 137 int level; 138 const char *name; 139 140 if (params != NULL) { 141 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 142 "log_get_print_level requires no parameters"); 143 return; 144 } 145 146 level = spdk_log_get_print_level(); 147 name = _log_get_level_name(level); 148 if (name == NULL) { 149 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 150 "invalid log level"); 151 return; 152 } 153 154 w = spdk_jsonrpc_begin_result(request); 155 spdk_json_write_string(w, name); 156 157 spdk_jsonrpc_end_result(request, w); 158 } 159 SPDK_RPC_REGISTER("log_get_print_level", rpc_log_get_print_level, 160 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 161 162 static void 163 rpc_log_set_level(struct spdk_jsonrpc_request *request, 164 const struct spdk_json_val *params) 165 { 166 struct rpc_log_level req = {}; 167 int level; 168 169 if (spdk_json_decode_object(params, rpc_log_level_decoders, 170 SPDK_COUNTOF(rpc_log_level_decoders), &req)) { 171 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 172 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 173 "spdk_json_decode_object failed"); 174 goto end; 175 } 176 177 level = _parse_log_level(req.level); 178 if (level == -1) { 179 SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n"); 180 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 181 "invalid log level"); 182 goto end; 183 } 184 185 186 spdk_log_set_level(level); 187 spdk_jsonrpc_send_bool_response(request, true); 188 end: 189 free_rpc_log_level(&req); 190 } 191 SPDK_RPC_REGISTER("log_set_level", rpc_log_set_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 192 193 static void 194 rpc_log_get_level(struct spdk_jsonrpc_request *request, 195 const struct spdk_json_val *params) 196 { 197 struct spdk_json_write_ctx *w; 198 int level; 199 const char *name; 200 201 if (params != NULL) { 202 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 203 "log_get_level requires no parameters"); 204 return; 205 } 206 207 level = spdk_log_get_level(); 208 name = _log_get_level_name(level); 209 if (name == NULL) { 210 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 211 "invalid log level"); 212 return; 213 } 214 215 w = spdk_jsonrpc_begin_result(request); 216 spdk_json_write_string(w, name); 217 218 spdk_jsonrpc_end_result(request, w); 219 } 220 SPDK_RPC_REGISTER("log_get_level", rpc_log_get_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 221 222 static void 223 rpc_log_set_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_set_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_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 249 250 static void 251 rpc_log_clear_flag(struct spdk_jsonrpc_request *request, 252 const struct spdk_json_val *params) 253 { 254 struct rpc_log_flag req = {}; 255 256 if (spdk_json_decode_object(params, rpc_log_flag_decoders, 257 SPDK_COUNTOF(rpc_log_flag_decoders), &req)) { 258 SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n"); 259 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 260 "spdk_json_decode_object failed"); 261 goto end; 262 } 263 264 if (req.flag == 0) { 265 SPDK_DEBUGLOG(log_rpc, "Invalid flag 0\n"); 266 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 267 "invalid flag 0"); 268 goto end; 269 } 270 271 spdk_log_clear_flag(req.flag); 272 spdk_jsonrpc_send_bool_response(request, true); 273 end: 274 free_rpc_log_flag(&req); 275 } 276 SPDK_RPC_REGISTER("log_clear_flag", rpc_log_clear_flag, 277 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 278 279 static void 280 rpc_log_get_flags(struct spdk_jsonrpc_request *request, 281 const struct spdk_json_val *params) 282 { 283 struct spdk_json_write_ctx *w; 284 struct spdk_log_flag *flag; 285 286 if (params != NULL) { 287 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 288 "log_get_flags requires no parameters"); 289 return; 290 } 291 292 w = spdk_jsonrpc_begin_result(request); 293 spdk_json_write_object_begin(w); 294 flag = spdk_log_get_first_flag(); 295 while (flag) { 296 spdk_json_write_name(w, flag->name); 297 spdk_json_write_bool(w, flag->enabled); 298 flag = spdk_log_get_next_flag(flag); 299 } 300 spdk_json_write_object_end(w); 301 spdk_jsonrpc_end_result(request, w); 302 } 303 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 304 305 struct rpc_log_enable_timestamps { 306 bool enabled; 307 }; 308 309 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = { 310 {"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool}, 311 }; 312 313 static void 314 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request, 315 const struct spdk_json_val *params) 316 { 317 struct rpc_log_enable_timestamps req = {}; 318 319 if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders, 320 SPDK_COUNTOF(rpc_log_enable_timestamps_decoders), 321 &req)) { 322 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 323 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 324 "spdk_json_decode_object failed"); 325 return; 326 } 327 328 spdk_log_enable_timestamps(req.enabled); 329 330 spdk_jsonrpc_send_bool_response(request, true); 331 } 332 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME) 333 SPDK_LOG_REGISTER_COMPONENT(log_rpc) 334