aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--trace-cmd.h1
-rw-r--r--trace-util.c182
2 files changed, 183 insertions, 0 deletions
diff --git a/trace-cmd.h b/trace-cmd.h
index ea6c356..b732484 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -37,6 +37,7 @@ void tracecmd_unload_plugins(struct plugin_list *list);
37 37
38char **tracecmd_event_systems(const char *tracing_dir); 38char **tracecmd_event_systems(const char *tracing_dir);
39char **tracecmd_system_events(const char *tracing_dir, const char *system); 39char **tracecmd_system_events(const char *tracing_dir, const char *system);
40struct pevent *tracecmd_local_events(const char *tracing_dir);
40 41
41enum { 42enum {
42 RINGBUF_TYPE_PADDING = 29, 43 RINGBUF_TYPE_PADDING = 29,
diff --git a/trace-util.c b/trace-util.c
index 456687c..6d813c5 100644
--- a/trace-util.c
+++ b/trace-util.c
@@ -26,6 +26,8 @@
26#include <ctype.h> 26#include <ctype.h>
27#include <errno.h> 27#include <errno.h>
28#include <dlfcn.h> 28#include <dlfcn.h>
29#include <fcntl.h>
30#include <unistd.h>
29#include <sys/mount.h> 31#include <sys/mount.h>
30#include <sys/types.h> 32#include <sys/types.h>
31#include <sys/stat.h> 33#include <sys/stat.h>
@@ -412,6 +414,186 @@ char **tracecmd_system_events(const char *tracing_dir, const char *system)
412 return events; 414 return events;
413} 415}
414 416
417static int read_file(const char *file, char **buffer)
418{
419 char *buf;
420 int len = 0;
421 int fd;
422 int r;
423
424 fd = open(file, O_RDONLY);
425 if (fd < 0)
426 return -1;
427
428 buf = malloc_or_die(BUFSIZ);
429
430 while ((r = read(fd, buf + len, BUFSIZ)) > 0) {
431 len += r;
432 buf = realloc(buf, len + BUFSIZ);
433 if (!buf) {
434 len = -1;
435 goto out;
436 }
437 }
438
439 *buffer = buf;
440
441 out:
442 close(fd);
443
444 return len;
445}
446
447static void load_events(struct pevent *pevent, const char *system,
448 const char *sys_dir)
449{
450 struct dirent *dent;
451 struct stat st;
452 DIR *dir;
453 int len = 0;
454 int ret;
455
456 ret = stat(sys_dir, &st);
457 if (ret < 0 || !S_ISDIR(st.st_mode))
458 return;
459
460 dir = opendir(sys_dir);
461 if (!dir)
462 return;
463
464 while ((dent = readdir(dir))) {
465 const char *name = dent->d_name;
466 char *event;
467 char *format;
468 char *buf;
469
470 if (strcmp(name, ".") == 0 ||
471 strcmp(name, "..") == 0)
472 continue;
473
474 event = append_file(sys_dir, name);
475 ret = stat(event, &st);
476 if (ret < 0 || !S_ISDIR(st.st_mode))
477 goto free_event;
478
479 format = append_file(event, "format");
480 ret = stat(format, &st);
481 if (ret < 0)
482 goto free_format;
483
484 len = read_file(format, &buf);
485 if (len < 0)
486 goto free_format;
487
488 pevent_parse_event(pevent, buf, len, system);
489 free(buf);
490 free_format:
491 free(format);
492 free_event:
493 free(event);
494 }
495
496 closedir(dir);
497}
498
499static int read_header(struct pevent *pevent, const char *events_dir)
500{
501 struct stat st;
502 char *header;
503 char *buf;
504 int len;
505 int ret = -1;
506
507 header = append_file(events_dir, "header_page");
508
509 ret = stat(header, &st);
510 if (ret < 0)
511 goto out;
512
513 len = read_file(header, &buf);
514 if (len < 0)
515 goto out;
516
517 pevent_parse_header_page(pevent, buf, len, sizeof(long));
518
519 free(buf);
520
521 ret = 0;
522 out:
523 free(header);
524 return ret;
525}
526
527/**
528 * tracecmd_local_events - create a pevent from the events on system
529 * @tracing_dir: The directory that contains the events.
530 *
531 * Returns a pevent structure that contains the pevents local to
532 * the system.
533 */
534struct pevent *tracecmd_local_events(const char *tracing_dir)
535{
536 struct pevent *pevent = NULL;
537 struct dirent *dent;
538 char *events_dir;
539 struct stat st;
540 DIR *dir;
541 int ret;
542
543 if (!tracing_dir)
544 return NULL;
545
546 events_dir = append_file(tracing_dir, "events");
547 if (!events_dir)
548 return NULL;
549
550 ret = stat(events_dir, &st);
551 if (ret < 0 || !S_ISDIR(st.st_mode))
552 goto out_free;
553
554 dir = opendir(events_dir);
555 if (!dir)
556 goto out_free;
557
558 pevent = pevent_alloc();
559 if (!pevent)
560 goto out_free;
561
562 ret = read_header(pevent, events_dir);
563 if (ret < 0) {
564 pevent_free(pevent);
565 pevent = NULL;
566 goto out_free;
567 }
568
569 while ((dent = readdir(dir))) {
570 const char *name = dent->d_name;
571 char *sys;
572
573 if (strcmp(name, ".") == 0 ||
574 strcmp(name, "..") == 0)
575 continue;
576
577 sys = append_file(events_dir, name);
578 ret = stat(sys, &st);
579 if (ret < 0 || !S_ISDIR(st.st_mode)) {
580 free(sys);
581 continue;
582 }
583
584 load_events(pevent, name, sys);
585
586 free(sys);
587 }
588
589 closedir(dir);
590
591 out_free:
592 free(events_dir);
593
594 return pevent;
595}
596
415static void 597static void
416trace_util_load_plugins_dir(struct pevent *pevent, const char *suffix, 598trace_util_load_plugins_dir(struct pevent *pevent, const char *suffix,
417 const char *path, 599 const char *path,