1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/rpc.h" 7 #include "spdk/util.h" 8 #include "spdk/trace.h" 9 #include "spdk/log.h" 10 #include "trace_internal.h" 11 12 struct rpc_tpoint_group { 13 char *name; 14 uint64_t tpoint_mask; 15 }; 16 17 static void 18 free_rpc_tpoint_group(struct rpc_tpoint_group *p) 19 { 20 free(p->name); 21 } 22 23 static const struct spdk_json_object_decoder rpc_tpoint_mask_decoders[] = { 24 {"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string}, 25 {"tpoint_mask", offsetof(struct rpc_tpoint_group, tpoint_mask), spdk_json_decode_uint64, true}, 26 }; 27 28 static void 29 rpc_trace_set_tpoint_mask(struct spdk_jsonrpc_request *request, 30 const struct spdk_json_val *params) 31 { 32 struct rpc_tpoint_group req = {}; 33 uint64_t tpoint_group_mask = 0; 34 35 if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders, 36 SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) { 37 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 38 goto invalid; 39 } 40 41 if (req.name == NULL) { 42 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 43 goto invalid; 44 } 45 46 tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name); 47 if (tpoint_group_mask == 0) { 48 goto invalid; 49 } 50 51 spdk_trace_set_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask); 52 53 free_rpc_tpoint_group(&req); 54 55 spdk_jsonrpc_send_bool_response(request, true); 56 return; 57 58 invalid: 59 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 60 free_rpc_tpoint_group(&req); 61 } 62 SPDK_RPC_REGISTER("trace_set_tpoint_mask", rpc_trace_set_tpoint_mask, 63 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 64 65 static void 66 rpc_trace_clear_tpoint_mask(struct spdk_jsonrpc_request *request, 67 const struct spdk_json_val *params) 68 { 69 struct rpc_tpoint_group req = {}; 70 uint64_t tpoint_group_mask = 0; 71 72 if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders, 73 SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) { 74 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 75 goto invalid; 76 } 77 78 if (req.name == NULL) { 79 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 80 goto invalid; 81 } 82 83 tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name); 84 if (tpoint_group_mask == 0) { 85 goto invalid; 86 } 87 88 spdk_trace_clear_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask); 89 90 free_rpc_tpoint_group(&req); 91 92 spdk_jsonrpc_send_bool_response(request, true); 93 return; 94 95 invalid: 96 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 97 free_rpc_tpoint_group(&req); 98 } 99 SPDK_RPC_REGISTER("trace_clear_tpoint_mask", rpc_trace_clear_tpoint_mask, 100 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 101 102 static const struct spdk_json_object_decoder rpc_tpoint_group_decoders[] = { 103 {"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string}, 104 }; 105 106 static void 107 rpc_trace_enable_tpoint_group(struct spdk_jsonrpc_request *request, 108 const struct spdk_json_val *params) 109 { 110 struct rpc_tpoint_group req = {}; 111 112 if (spdk_json_decode_object(params, rpc_tpoint_group_decoders, 113 SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) { 114 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 115 goto invalid; 116 } 117 118 if (req.name == NULL) { 119 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 120 goto invalid; 121 } 122 123 if (spdk_trace_enable_tpoint_group(req.name)) { 124 goto invalid; 125 } 126 127 free_rpc_tpoint_group(&req); 128 129 spdk_jsonrpc_send_bool_response(request, true); 130 return; 131 132 invalid: 133 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 134 free_rpc_tpoint_group(&req); 135 } 136 SPDK_RPC_REGISTER("trace_enable_tpoint_group", rpc_trace_enable_tpoint_group, 137 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 138 139 static void 140 rpc_trace_disable_tpoint_group(struct spdk_jsonrpc_request *request, 141 const struct spdk_json_val *params) 142 { 143 struct rpc_tpoint_group req = {}; 144 145 if (spdk_json_decode_object(params, rpc_tpoint_group_decoders, 146 SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) { 147 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 148 goto invalid; 149 } 150 151 if (req.name == NULL) { 152 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 153 goto invalid; 154 } 155 156 if (spdk_trace_disable_tpoint_group(req.name)) { 157 goto invalid; 158 } 159 160 free_rpc_tpoint_group(&req); 161 162 spdk_jsonrpc_send_bool_response(request, true); 163 return; 164 165 invalid: 166 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 167 free_rpc_tpoint_group(&req); 168 } 169 SPDK_RPC_REGISTER("trace_disable_tpoint_group", rpc_trace_disable_tpoint_group, 170 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 171 172 static void 173 rpc_trace_get_tpoint_group_mask(struct spdk_jsonrpc_request *request, 174 const struct spdk_json_val *params) 175 { 176 uint64_t tpoint_group_mask; 177 char mask_str[20]; 178 bool enabled; 179 struct spdk_json_write_ctx *w; 180 struct spdk_trace_register_fn *register_fn; 181 182 if (params != NULL) { 183 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 184 "trace_get_tpoint_group_mask requires no parameters"); 185 return; 186 } 187 188 w = spdk_jsonrpc_begin_result(request); 189 tpoint_group_mask = spdk_trace_get_tpoint_group_mask(); 190 191 spdk_json_write_object_begin(w); 192 193 snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask); 194 spdk_json_write_named_string(w, "tpoint_group_mask", mask_str); 195 196 register_fn = spdk_trace_get_first_register_fn(); 197 while (register_fn) { 198 enabled = spdk_trace_get_tpoint_mask(register_fn->tgroup_id) != 0; 199 200 spdk_json_write_named_object_begin(w, register_fn->name); 201 spdk_json_write_named_bool(w, "enabled", enabled); 202 203 snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id)); 204 spdk_json_write_named_string(w, "mask", mask_str); 205 spdk_json_write_object_end(w); 206 207 register_fn = spdk_trace_get_next_register_fn(register_fn); 208 } 209 210 spdk_json_write_object_end(w); 211 spdk_jsonrpc_end_result(request, w); 212 } 213 SPDK_RPC_REGISTER("trace_get_tpoint_group_mask", rpc_trace_get_tpoint_group_mask, 214 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 215 216 static void 217 rpc_trace_get_info(struct spdk_jsonrpc_request *request, 218 const struct spdk_json_val *params) 219 { 220 char shm_path[128]; 221 uint64_t tpoint_group_mask; 222 uint64_t tpoint_mask; 223 char tpoint_mask_str[20]; 224 char mask_str[20]; 225 struct spdk_json_write_ctx *w; 226 struct spdk_trace_register_fn *register_fn; 227 228 if (params != NULL) { 229 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 230 "trace_get_info requires no parameters"); 231 return; 232 } 233 234 snprintf(shm_path, sizeof(shm_path), "/dev/shm%s", trace_get_shm_name()); 235 tpoint_group_mask = spdk_trace_get_tpoint_group_mask(); 236 237 w = spdk_jsonrpc_begin_result(request); 238 spdk_json_write_object_begin(w); 239 spdk_json_write_named_string(w, "tpoint_shm_path", shm_path); 240 241 snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask); 242 spdk_json_write_named_string(w, "tpoint_group_mask", mask_str); 243 244 register_fn = spdk_trace_get_first_register_fn(); 245 while (register_fn) { 246 247 tpoint_mask = spdk_trace_get_tpoint_mask(register_fn->tgroup_id); 248 249 spdk_json_write_named_object_begin(w, register_fn->name); 250 snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id)); 251 spdk_json_write_named_string(w, "mask", mask_str); 252 snprintf(tpoint_mask_str, sizeof(tpoint_mask_str), "0x%lx", tpoint_mask); 253 spdk_json_write_named_string(w, "tpoint_mask", tpoint_mask_str); 254 spdk_json_write_object_end(w); 255 256 register_fn = spdk_trace_get_next_register_fn(register_fn); 257 } 258 259 spdk_json_write_object_end(w); 260 spdk_jsonrpc_end_result(request, w); 261 } 262 SPDK_RPC_REGISTER("trace_get_info", rpc_trace_get_info, 263 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 264