aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-01-04 19:53:23 -0500
committerSteven Rostedt <rostedt@goodmis.org>2011-01-04 19:53:23 -0500
commit3de68e3ec662285bbd612c923308dbdc953420ac (patch)
tree55304afe3e02636dec2e70a761da3e3f2ae7abad
parent4fe00fac471549047589f62db7b32020821b3634 (diff)
trace-cmd: Only record the formats of the events being recorded
No need to record all event formats when only a few are being recorded. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-cmd.c11
-rw-r--r--trace-cmd.h9
-rw-r--r--trace-output.c363
3 files changed, 269 insertions, 114 deletions
diff --git a/trace-cmd.c b/trace-cmd.c
index f8992a8..a8e99de 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -116,6 +116,7 @@ struct event_list {
116}; 116};
117 117
118static struct event_list *event_selection; 118static struct event_list *event_selection;
119struct tracecmd_event_list *listed_events;
119 120
120struct events { 121struct events {
121 struct events *sibling; 122 struct events *sibling;
@@ -1292,7 +1293,8 @@ static void record_data(void)
1292 for (i = 0; i < cpu_count; i++) 1293 for (i = 0; i < cpu_count; i++)
1293 temp_files[i] = get_temp_file(i); 1294 temp_files[i] = get_temp_file(i);
1294 1295
1295 handle = tracecmd_create_file(output_file, cpu_count, temp_files); 1296 handle = tracecmd_create_file_glob(output_file, cpu_count,
1297 temp_files, listed_events);
1296 1298
1297 for (i = 0; i < cpu_count; i++) 1299 for (i = 0; i < cpu_count; i++)
1298 put_temp_file(temp_files[i]); 1300 put_temp_file(temp_files[i]);
@@ -1416,6 +1418,7 @@ int main (int argc, char **argv)
1416 const char *option; 1418 const char *option;
1417 struct event_list *event; 1419 struct event_list *event;
1418 struct event_list *last_event; 1420 struct event_list *last_event;
1421 struct tracecmd_event_list *list;
1419 struct trace_seq s; 1422 struct trace_seq s;
1420 int disable = 0; 1423 int disable = 0;
1421 int plug = 0; 1424 int plug = 0;
@@ -1471,6 +1474,12 @@ int main (int argc, char **argv)
1471 event_selection = event; 1474 event_selection = event;
1472 event->filter = NULL; 1475 event->filter = NULL;
1473 last_event = event; 1476 last_event = event;
1477
1478 list = malloc_or_die(sizeof(*list));
1479 list->next = listed_events;
1480 list->glob = optarg;
1481 listed_events = list;
1482
1474 break; 1483 break;
1475 case 'f': 1484 case 'f':
1476 if (!last_event) 1485 if (!last_event)
diff --git a/trace-cmd.h b/trace-cmd.h
index 59d9d54..ec59e98 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -160,9 +160,18 @@ extern __thread struct tracecmd_input *tracecmd_curr_thread_handle;
160 160
161/* --- Creating and Writing the trace.dat file --- */ 161/* --- Creating and Writing the trace.dat file --- */
162 162
163struct tracecmd_event_list {
164 struct tracecmd_event_list *next;
165 const char *glob;
166};
167
163struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, int cpus); 168struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, int cpus);
164struct tracecmd_output *tracecmd_create_file(const char *output_file, 169struct tracecmd_output *tracecmd_create_file(const char *output_file,
165 int cpus, char * const *cpu_data_files); 170 int cpus, char * const *cpu_data_files);
171struct tracecmd_output *
172tracecmd_create_file_glob(const char *output_file,
173 int cpus, char * const *cpu_data_files,
174 struct tracecmd_event_list *event_globs);
166struct tracecmd_output *tracecmd_create_init_fd(int fd); 175struct tracecmd_output *tracecmd_create_init_fd(int fd);
167struct tracecmd_output *tracecmd_create_init_file(const char *output_file); 176struct tracecmd_output *tracecmd_create_init_file(const char *output_file);
168void tracecmd_output_close(struct tracecmd_output *handle); 177void tracecmd_output_close(struct tracecmd_output *handle);
diff --git a/trace-output.c b/trace-output.c
index 943ed84..8837aa0 100644
--- a/trace-output.c
+++ b/trace-output.c
@@ -35,10 +35,16 @@
35#include <unistd.h> 35#include <unistd.h>
36#include <ctype.h> 36#include <ctype.h>
37#include <errno.h> 37#include <errno.h>
38#include <glob.h>
38 39
39#include "trace-cmd-local.h" 40#include "trace-cmd-local.h"
40#include "version.h" 41#include "version.h"
41 42
43static struct tracecmd_event_list all_event_list = {
44 .next = NULL,
45 .glob = "all"
46};
47
42struct tracecmd_option { 48struct tracecmd_option {
43 unsigned short id; 49 unsigned short id;
44 int size; 50 int size;
@@ -56,6 +62,18 @@ struct tracecmd_output {
56 struct tracecmd_option *options; 62 struct tracecmd_option *options;
57}; 63};
58 64
65struct list_event {
66 struct list_event *next;
67 char *name;
68 char *file;
69};
70
71struct list_event_system {
72 struct list_event_system *next;
73 struct list_event *events;
74 char *name;
75};
76
59static int 77static int
60do_write_check(struct tracecmd_output *handle, void *data, int size) 78do_write_check(struct tracecmd_output *handle, void *data, int size)
61{ 79{
@@ -309,51 +327,26 @@ static int read_header_files(struct tracecmd_output *handle)
309 return -1; 327 return -1;
310} 328}
311 329
312static int copy_event_system(struct tracecmd_output *handle, const char *sys) 330static int copy_event_system(struct tracecmd_output *handle,
331 struct list_event_system *slist)
313{ 332{
333 struct list_event *elist;
314 unsigned long long size, check_size, endian8; 334 unsigned long long size, check_size, endian8;
315 struct dirent *dent;
316 struct stat st; 335 struct stat st;
317 char *format; 336 char *format;
318 DIR *dir;
319 int endian4; 337 int endian4;
320 int count = 0; 338 int count = 0;
321 int ret; 339 int ret;
322 340
323 dir = opendir(sys); 341 for (elist = slist->events; elist; elist = elist->next)
324 if (!dir) {
325 warning("can't read directory '%s'", sys);
326 return -1;
327 }
328
329 while ((dent = readdir(dir))) {
330 if (strcmp(dent->d_name, ".") == 0 ||
331 strcmp(dent->d_name, "..") == 0)
332 continue;
333 format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
334 if (!format)
335 return -1;
336 sprintf(format, "%s/%s/format", sys, dent->d_name);
337 ret = stat(format, &st);
338 free(format);
339 if (ret < 0)
340 continue;
341 count++; 342 count++;
342 }
343 343
344 endian4 = convert_endian_4(handle, count); 344 endian4 = convert_endian_4(handle, count);
345 if (do_write_check(handle, &endian4, 4)) 345 if (do_write_check(handle, &endian4, 4))
346 return -1; 346 return -1;
347 347
348 rewinddir(dir); 348 for (elist = slist->events; elist; elist = elist->next) {
349 while ((dent = readdir(dir))) { 349 format = elist->file;
350 if (strcmp(dent->d_name, ".") == 0 ||
351 strcmp(dent->d_name, "..") == 0)
352 continue;
353 format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
354 if (!format)
355 return -1;
356 sprintf(format, "%s/%s/format", sys, dent->d_name);
357 ret = stat(format, &st); 350 ret = stat(format, &st);
358 351
359 if (ret >= 0) { 352 if (ret >= 0) {
@@ -361,115 +354,248 @@ static int copy_event_system(struct tracecmd_output *handle, const char *sys)
361 size = get_size(format); 354 size = get_size(format);
362 endian8 = convert_endian_8(handle, size); 355 endian8 = convert_endian_8(handle, size);
363 if (do_write_check(handle, &endian8, 8)) 356 if (do_write_check(handle, &endian8, 8))
364 goto out_free; 357 return -1;
365 check_size = copy_file(handle, format); 358 check_size = copy_file(handle, format);
366 if (size != check_size) { 359 if (size != check_size) {
367 warning("error in size of file '%s'", format); 360 warning("error in size of file '%s'", format);
368 goto out_free; 361 return -1;
369 } 362 }
370 } 363 }
371
372 free(format);
373 } 364 }
374 365
375 return 0; 366 return 0;
367}
376 368
377 out_free: 369static void add_list_event_system(struct list_event_system **systems,
378 free(format); 370 const char *system,
379 return -1; 371 const char *event,
372 const char *path)
373{
374 struct list_event_system *slist;
375 struct list_event *elist;
376
377 for (slist = *systems; slist; slist = slist->next)
378 if (strcmp(slist->name, system) == 0)
379 break;
380
381 if (!slist) {
382 slist = malloc_or_die(sizeof(*slist));
383 slist->name = strdup(system);
384 slist->next = *systems;
385 slist->events = NULL;
386 *systems = slist;
387 }
388
389 for (elist = slist->events; elist; elist = elist->next)
390 if (strcmp(elist->name, event) == 0)
391 break;
392
393 if (!elist) {
394 elist = malloc_or_die(sizeof(*elist));
395 elist->name = strdup(event);
396 elist->file = strdup(path);
397 elist->next = slist->events;
398 slist->events = elist;
399 }
380} 400}
381 401
382static int read_ftrace_files(struct tracecmd_output *handle) 402static void free_list_events(struct list_event_system *list)
383{ 403{
404 struct list_event_system *slist;
405 struct list_event *elist;
406
407 while (list) {
408 slist = list;
409 list = list->next;
410 while (slist->events) {
411 elist = slist->events;
412 slist->events = elist->next;
413 free(elist->name);
414 free(elist->file);
415 free(elist);
416 }
417 free(slist->name);
418 free(slist);
419 }
420}
421
422static void glob_events(struct tracecmd_output *handle,
423 struct list_event_system **systems,
424 const char *str)
425{
426 glob_t globbuf;
427 char *events_path;
428 char *system;
429 char *event;
384 char *path; 430 char *path;
431 char *file;
432 char *ptr;
433 int do_ftrace = 0;
434 int events_len;
385 int ret; 435 int ret;
436 int i;
386 437
387 path = get_tracing_file(handle, "events/ftrace"); 438 if (strncmp(str, "ftrace/", 7) == 0)
388 if (!path) 439 do_ftrace = 1;
389 return -1;
390 440
391 ret = copy_event_system(handle, path); 441 events_path = get_tracing_file(handle, "events");
442 events_len = strlen(events_path);
392 443
393 put_tracing_file(path); 444 path = malloc_or_die(events_len + strlen(str) +
445 strlen("/format") + 2);
446 path[0] = '\0';
447 strcat(path, events_path);
448 strcat(path, "/");
449 strcat(path, str);
450 strcat(path, "/format");
451
452 globbuf.gl_offs = 0;
453 ret = glob(path, 0, NULL, &globbuf);
454 if (ret < 0)
455 return;
456
457 for (i = 0; i < globbuf.gl_pathc; i++) {
458 file = globbuf.gl_pathv[i];
459 system = strdup(file + events_len + 1);
460 system = strtok_r(system, "/", &ptr);
461 if (!ptr) {
462 /* ?? should we warn? */
463 free(system);
464 continue;
465 }
466
467 if (!do_ftrace && strcmp(system, "ftrace") == 0) {
468 free(system);
469 continue;
470 }
471
472 event = strtok_r(NULL, "/", &ptr);
473 if (!ptr) {
474 /* ?? should we warn? */
475 free(system);
476 continue;
477 }
478
479 add_list_event_system(systems, system, event, file);
480 free(system);
481 }
482}
483
484static void
485create_event_list_item(struct tracecmd_output *handle,
486 struct list_event_system **systems,
487 struct tracecmd_event_list *list)
488{
489 char *ptr;
490 char *str;
491
492 str = strdup(list->glob);
493 if (!str)
494 die("strdup - no memory");
495
496 /* system and event names are separated by a ':' */
497 ptr = strchr(str, ':');
498 if (ptr)
499 *ptr = '/';
500 else
501 /* system and event may also be separated by a '/' */
502 ptr = strchr(str, '/');
503
504 if (ptr) {
505 glob_events(handle, systems, str);
506 free(str);
507 return;
508 }
509
510 ptr = str;
511 str = malloc_or_die(strlen(ptr) + 3);
512 str[0] = '\0';
513 strcat(str, ptr);
514 strcat(str, "/*");
515 glob_events(handle, systems, str);
516
517 str[0] = '\0';
518 strcat(str, "*/");
519 strcat(str, ptr);
520 glob_events(handle, systems, str);
521
522 free(str);
523}
524
525static int read_ftrace_files(struct tracecmd_output *handle)
526{
527 struct list_event_system *systems = NULL;
528 struct tracecmd_event_list list = { .glob = "ftrace/*" };
529 int ret;
530
531 create_event_list_item(handle, &systems, &list);
532
533 ret = copy_event_system(handle, systems);
534
535 free_list_events(systems);
394 536
395 return ret; 537 return ret;
396} 538}
397 539
398static int read_event_files(struct tracecmd_output *handle) 540static struct list_event_system *
541create_event_list(struct tracecmd_output *handle,
542 struct tracecmd_event_list *event_list)
399{ 543{
400 struct dirent *dent; 544 struct list_event_system *systems = NULL;
401 struct stat st; 545 struct tracecmd_event_list *list;
402 char *path; 546
403 char *sys; 547 for (list = event_list; list; list = list->next)
404 DIR *dir; 548 create_event_list_item(handle, &systems, list);
549
550 return systems;
551}
552
553static int read_event_files(struct tracecmd_output *handle,
554 struct tracecmd_event_list *event_list)
555{
556 struct list_event_system *systems;
557 struct list_event_system *slist;
558 struct tracecmd_event_list *list;
559 struct tracecmd_event_list all_events = { .glob = "*/*" };
405 int count = 0; 560 int count = 0;
406 int endian4; 561 int endian4;
407 int ret; 562 int ret;
408 563
409 path = get_tracing_file(handle, "events"); 564 /*
410 if (!path) 565 * If any of the list is the special keyword "all" then
411 return -1; 566 * just do all files.
567 */
568 for (list = event_list; list; list = list->next) {
569 if (strcmp(list->glob, "all") == 0)
570 break;
571 }
572 /* all events are listed, use a global glob */
573 if (list)
574 event_list = &all_events;
412 575
413 dir = opendir(path); 576 systems = create_event_list(handle, event_list);
414 if (!dir)
415 die("can't read directory '%s'", path);
416 577
417 while ((dent = readdir(dir))) { 578 for (slist = systems; slist; slist = slist->next)
418 if (strcmp(dent->d_name, ".") == 0 || 579 count++;
419 strcmp(dent->d_name, "..") == 0 ||
420 strcmp(dent->d_name, "ftrace") == 0)
421 continue;
422 ret = -1;
423 sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
424 if (!sys)
425 goto out_close_dir;
426 sprintf(sys, "%s/%s", path, dent->d_name);
427 ret = stat(sys, &st);
428 free(sys);
429 if (ret < 0)
430 continue;
431 if (S_ISDIR(st.st_mode))
432 count++;
433 }
434 580
435 ret = -1; 581 ret = -1;
436 endian4 = convert_endian_4(handle, count); 582 endian4 = convert_endian_4(handle, count);
437 if (do_write_check(handle, &endian4, 4)) 583 if (do_write_check(handle, &endian4, 4))
438 goto out_close_dir; 584 goto out_free;
439 585
440 rewinddir(dir); 586 ret = 0;
441 while ((dent = readdir(dir))) { 587 for (slist = systems; !ret && slist; slist = slist->next) {
442 if (strcmp(dent->d_name, ".") == 0 || 588 if (do_write_check(handle, slist->name,
443 strcmp(dent->d_name, "..") == 0 || 589 strlen(slist->name) + 1)) {
444 strcmp(dent->d_name, "ftrace") == 0) 590 ret = -1;
445 continue; 591 continue;
446 ret = -1;
447 sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
448 if (!sys)
449 goto out_close_dir;
450
451 sprintf(sys, "%s/%s", path, dent->d_name);
452 ret = stat(sys, &st);
453 if (ret >= 0) {
454 if (S_ISDIR(st.st_mode)) {
455 if (do_write_check(handle, dent->d_name,
456 strlen(dent->d_name) + 1)) {
457 free(sys);
458 ret = -1;
459 goto out_close_dir;
460 }
461 copy_event_system(handle, sys);
462 }
463 } 592 }
464 free(sys); 593 ret = copy_event_system(handle, slist);
465 } 594 }
466 595
467 put_tracing_file(path); 596 out_free:
468 597 free_list_events(systems);
469 ret = 0;
470 598
471 out_close_dir:
472 closedir(dir);
473 return ret; 599 return ret;
474} 600}
475 601
@@ -538,7 +664,8 @@ static int read_ftrace_printk(struct tracecmd_output *handle)
538} 664}
539 665
540static struct tracecmd_output * 666static struct tracecmd_output *
541create_file_fd(int fd, struct tracecmd_input *ihandle) 667create_file_fd(int fd, struct tracecmd_input *ihandle,
668 struct tracecmd_event_list *list)
542{ 669{
543 struct tracecmd_output *handle; 670 struct tracecmd_output *handle;
544 unsigned long long endian8; 671 unsigned long long endian8;
@@ -607,7 +734,7 @@ create_file_fd(int fd, struct tracecmd_input *ihandle)
607 goto out_free; 734 goto out_free;
608 if (read_ftrace_files(handle)) 735 if (read_ftrace_files(handle))
609 goto out_free; 736 goto out_free;
610 if (read_event_files(handle)) 737 if (read_event_files(handle, list))
611 goto out_free; 738 goto out_free;
612 if (read_proc_kallsyms(handle)) 739 if (read_proc_kallsyms(handle))
613 goto out_free; 740 goto out_free;
@@ -647,7 +774,8 @@ create_file_fd(int fd, struct tracecmd_input *ihandle)
647} 774}
648 775
649static struct tracecmd_output *create_file(const char *output_file, 776static struct tracecmd_output *create_file(const char *output_file,
650 struct tracecmd_input *ihandle) 777 struct tracecmd_input *ihandle,
778 struct tracecmd_event_list *list)
651{ 779{
652 struct tracecmd_output *handle; 780 struct tracecmd_output *handle;
653 int fd; 781 int fd;
@@ -656,7 +784,7 @@ static struct tracecmd_output *create_file(const char *output_file,
656 if (fd < 0) 784 if (fd < 0)
657 return NULL; 785 return NULL;
658 786
659 handle = create_file_fd(fd, ihandle); 787 handle = create_file_fd(fd, ihandle, list);
660 if (!handle) { 788 if (!handle) {
661 close(fd); 789 close(fd);
662 unlink(output_file); 790 unlink(output_file);
@@ -742,7 +870,7 @@ struct tracecmd_output *tracecmd_create_file_latency(const char *output_file, in
742 struct tracecmd_output *handle; 870 struct tracecmd_output *handle;
743 char *path; 871 char *path;
744 872
745 handle = create_file(output_file, NULL); 873 handle = create_file(output_file, NULL, &all_event_list);
746 if (!handle) 874 if (!handle)
747 return NULL; 875 return NULL;
748 876
@@ -915,12 +1043,14 @@ int tracecmd_attach_cpu_data(char *file, int cpus, char * const *cpu_data_files)
915 return tracecmd_attach_cpu_data_fd(fd, cpus, cpu_data_files); 1043 return tracecmd_attach_cpu_data_fd(fd, cpus, cpu_data_files);
916} 1044}
917 1045
918struct tracecmd_output *tracecmd_create_file(const char *output_file, 1046struct tracecmd_output *
919 int cpus, char * const *cpu_data_files) 1047tracecmd_create_file_glob(const char *output_file,
1048 int cpus, char * const *cpu_data_files,
1049 struct tracecmd_event_list *list)
920{ 1050{
921 struct tracecmd_output *handle; 1051 struct tracecmd_output *handle;
922 1052
923 handle = create_file(output_file, NULL); 1053 handle = create_file(output_file, NULL, list);
924 if (!handle) 1054 if (!handle)
925 return NULL; 1055 return NULL;
926 1056
@@ -930,14 +1060,21 @@ struct tracecmd_output *tracecmd_create_file(const char *output_file,
930 return handle; 1060 return handle;
931} 1061}
932 1062
1063struct tracecmd_output *tracecmd_create_file(const char *output_file,
1064 int cpus, char * const *cpu_data_files)
1065{
1066 return tracecmd_create_file_glob(output_file, cpus,
1067 cpu_data_files, &all_event_list);
1068}
1069
933struct tracecmd_output *tracecmd_create_init_fd(int fd) 1070struct tracecmd_output *tracecmd_create_init_fd(int fd)
934{ 1071{
935 return create_file_fd(fd, NULL); 1072 return create_file_fd(fd, NULL, &all_event_list);
936} 1073}
937 1074
938struct tracecmd_output *tracecmd_create_init_file(const char *output_file) 1075struct tracecmd_output *tracecmd_create_init_file(const char *output_file)
939{ 1076{
940 return create_file(output_file, NULL); 1077 return create_file(output_file, NULL, &all_event_list);
941} 1078}
942 1079
943/** 1080/**
@@ -954,7 +1091,7 @@ struct tracecmd_output *tracecmd_copy(struct tracecmd_input *ihandle,
954{ 1091{
955 struct tracecmd_output *handle; 1092 struct tracecmd_output *handle;
956 1093
957 handle = create_file(file, ihandle); 1094 handle = create_file(file, ihandle, &all_event_list);
958 if (!handle) 1095 if (!handle)
959 return NULL; 1096 return NULL;
960 1097