diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2010-06-11 13:46:10 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2010-06-11 13:46:10 -0400 |
| commit | f3fbc8c9ef0fb0ab9b017b6711f0ea803effe7eb (patch) | |
| tree | 5eb571cbbd20230f190529a5c38ef8d10187122d | |
| parent | ac22592638b2cab71e8c9b958ef549a81f910d14 (diff) | |
trace-cmd: Add way to retrieve a list of event systems or events
Add tracecmd_event_systems() and tracecmd_system_events() to
retrieve the list of event systems or events under a system
that is in the /debug/tracing/events/* directory.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | trace-cmd.h | 3 | ||||
| -rw-r--r-- | trace-util.c | 185 |
2 files changed, 188 insertions, 0 deletions
diff --git a/trace-cmd.h b/trace-cmd.h index 22b45cc..ea6c356 100644 --- a/trace-cmd.h +++ b/trace-cmd.h | |||
| @@ -35,6 +35,9 @@ struct plugin_list; | |||
| 35 | struct plugin_list *tracecmd_load_plugins(struct pevent *pevent); | 35 | struct plugin_list *tracecmd_load_plugins(struct pevent *pevent); |
| 36 | void tracecmd_unload_plugins(struct plugin_list *list); | 36 | void tracecmd_unload_plugins(struct plugin_list *list); |
| 37 | 37 | ||
| 38 | char **tracecmd_event_systems(const char *tracing_dir); | ||
| 39 | char **tracecmd_system_events(const char *tracing_dir, const char *system); | ||
| 40 | |||
| 38 | enum { | 41 | enum { |
| 39 | RINGBUF_TYPE_PADDING = 29, | 42 | RINGBUF_TYPE_PADDING = 29, |
| 40 | RINGBUF_TYPE_TIME_EXTEND = 30, | 43 | RINGBUF_TYPE_TIME_EXTEND = 30, |
diff --git a/trace-util.c b/trace-util.c index b8b6faf..456687c 100644 --- a/trace-util.c +++ b/trace-util.c | |||
| @@ -227,6 +227,191 @@ char *tracecmd_find_tracing_dir(void) | |||
| 227 | return tracing_dir; | 227 | return tracing_dir; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | static char *append_file(const char *dir, const char *name) | ||
| 231 | { | ||
| 232 | char *file; | ||
| 233 | |||
| 234 | file = malloc_or_die(strlen(dir) + strlen(name) + 2); | ||
| 235 | if (!file) | ||
| 236 | return NULL; | ||
| 237 | |||
| 238 | sprintf(file, "%s/%s", dir, name); | ||
| 239 | return file; | ||
| 240 | } | ||
| 241 | |||
| 242 | static char **add_list(char **list, const char *name, int len) | ||
| 243 | { | ||
| 244 | if (!list) | ||
| 245 | list = malloc_or_die(sizeof(*list) * 2); | ||
| 246 | else { | ||
| 247 | list = realloc(list, sizeof(*list) * (len + 2)); | ||
| 248 | if (!list) | ||
| 249 | die("Can not allocate list"); | ||
| 250 | } | ||
| 251 | |||
| 252 | list[len] = strdup(name); | ||
| 253 | if (!list[len]) | ||
| 254 | die("Can not allocate list"); | ||
| 255 | |||
| 256 | list[len + 1] = NULL; | ||
| 257 | |||
| 258 | return list; | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * tracecmd_event_systems - return list of systems for tracing | ||
| 263 | * @tracing_dir: directory holding the "events" directory | ||
| 264 | * | ||
| 265 | * Returns an allocated list of system names. Both the names and | ||
| 266 | * the list must be freed with free(). | ||
| 267 | * The list returned ends with a "NULL" pointer. | ||
| 268 | */ | ||
| 269 | char **tracecmd_event_systems(const char *tracing_dir) | ||
| 270 | { | ||
| 271 | struct dirent *dent; | ||
| 272 | char **systems = NULL; | ||
| 273 | char *events_dir; | ||
| 274 | struct stat st; | ||
| 275 | DIR *dir; | ||
| 276 | int len = 0; | ||
| 277 | int ret; | ||
| 278 | |||
| 279 | if (!tracing_dir) | ||
| 280 | return NULL; | ||
| 281 | |||
| 282 | events_dir = append_file(tracing_dir, "events"); | ||
| 283 | if (!events_dir) | ||
| 284 | return NULL; | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Search all the directories in the events directory, | ||
| 288 | * and collect the ones that have the "enable" file. | ||
| 289 | */ | ||
| 290 | ret = stat(events_dir, &st); | ||
| 291 | if (ret < 0 || !S_ISDIR(st.st_mode)) | ||
| 292 | goto out_free; | ||
| 293 | |||
| 294 | dir = opendir(events_dir); | ||
| 295 | if (!dir) | ||
| 296 | goto out_free; | ||
| 297 | |||
| 298 | while ((dent = readdir(dir))) { | ||
| 299 | const char *name = dent->d_name; | ||
| 300 | char *enable; | ||
| 301 | char *sys; | ||
| 302 | |||
| 303 | if (strcmp(name, ".") == 0 || | ||
| 304 | strcmp(name, "..") == 0) | ||
| 305 | continue; | ||
| 306 | |||
| 307 | sys = append_file(events_dir, name); | ||
| 308 | ret = stat(sys, &st); | ||
| 309 | if (ret < 0 || !S_ISDIR(st.st_mode)) { | ||
| 310 | free(sys); | ||
| 311 | continue; | ||
| 312 | } | ||
| 313 | |||
| 314 | enable = append_file(sys, "enable"); | ||
| 315 | |||
| 316 | ret = stat(enable, &st); | ||
| 317 | if (ret >= 0) | ||
| 318 | systems = add_list(systems, name, len++); | ||
| 319 | |||
| 320 | free(enable); | ||
| 321 | free(sys); | ||
| 322 | } | ||
| 323 | |||
| 324 | closedir(dir); | ||
| 325 | |||
| 326 | out_free: | ||
| 327 | free(events_dir); | ||
| 328 | return systems; | ||
| 329 | } | ||
| 330 | |||
| 331 | /** | ||
| 332 | * tracecmd_system_events - return list of events for system | ||
| 333 | * @tracing_dir: directory holding the "events" directory | ||
| 334 | * @system: the system to return the events for | ||
| 335 | * | ||
| 336 | * Returns an allocated list of event names. Both the names and | ||
| 337 | * the list must be freed with free(). | ||
| 338 | * The list returned ends with a "NULL" pointer. | ||
| 339 | */ | ||
| 340 | char **tracecmd_system_events(const char *tracing_dir, const char *system) | ||
| 341 | { | ||
| 342 | struct dirent *dent; | ||
| 343 | char **events = NULL; | ||
| 344 | char *events_dir; | ||
| 345 | char *system_dir; | ||
| 346 | struct stat st; | ||
| 347 | DIR *dir; | ||
| 348 | int len = 0; | ||
| 349 | int ret; | ||
| 350 | |||
| 351 | if (!tracing_dir || !system) | ||
| 352 | return NULL; | ||
| 353 | |||
| 354 | events_dir = append_file(tracing_dir, "events"); | ||
| 355 | if (!events_dir) | ||
| 356 | return NULL; | ||
| 357 | |||
| 358 | /* | ||
| 359 | * Search all the directories in the systems directory, | ||
| 360 | * and collect the ones that have the "enable" file. | ||
| 361 | */ | ||
| 362 | ret = stat(events_dir, &st); | ||
| 363 | if (ret < 0 || !S_ISDIR(st.st_mode)) | ||
| 364 | goto out_free; | ||
| 365 | |||
| 366 | system_dir = append_file(events_dir, system); | ||
| 367 | if (!system_dir) | ||
| 368 | goto out_free; | ||
| 369 | |||
| 370 | ret = stat(system_dir, &st); | ||
| 371 | if (ret < 0 || !S_ISDIR(st.st_mode)) | ||
| 372 | goto out_free_sys; | ||
| 373 | |||
| 374 | dir = opendir(system_dir); | ||
| 375 | if (!dir) | ||
| 376 | goto out_free_sys; | ||
| 377 | |||
| 378 | while ((dent = readdir(dir))) { | ||
| 379 | const char *name = dent->d_name; | ||
| 380 | char *enable; | ||
| 381 | char *event; | ||
| 382 | |||
| 383 | if (strcmp(name, ".") == 0 || | ||
| 384 | strcmp(name, "..") == 0) | ||
| 385 | continue; | ||
| 386 | |||
| 387 | event = append_file(system_dir, name); | ||
| 388 | ret = stat(event, &st); | ||
| 389 | if (ret < 0 || !S_ISDIR(st.st_mode)) { | ||
| 390 | free(event); | ||
| 391 | continue; | ||
| 392 | } | ||
| 393 | |||
| 394 | enable = append_file(event, "enable"); | ||
| 395 | |||
| 396 | ret = stat(enable, &st); | ||
| 397 | if (ret >= 0) | ||
| 398 | events = add_list(events, name, len++); | ||
| 399 | |||
| 400 | free(enable); | ||
| 401 | free(event); | ||
| 402 | } | ||
| 403 | |||
| 404 | closedir(dir); | ||
| 405 | |||
| 406 | out_free_sys: | ||
| 407 | free(system_dir); | ||
| 408 | |||
| 409 | out_free: | ||
| 410 | free(events_dir); | ||
| 411 | |||
| 412 | return events; | ||
| 413 | } | ||
| 414 | |||
| 230 | static void | 415 | static void |
| 231 | trace_util_load_plugins_dir(struct pevent *pevent, const char *suffix, | 416 | trace_util_load_plugins_dir(struct pevent *pevent, const char *suffix, |
| 232 | const char *path, | 417 | const char *path, |
