aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/trace-event-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/trace-event-info.c')
-rw-r--r--tools/perf/util/trace-event-info.c112
1 files changed, 88 insertions, 24 deletions
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 3403f814ad72..2d530cf74f43 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -196,7 +196,8 @@ static void record_file(const char *file, size_t hdr_sz)
196 die("Can't read '%s'", file); 196 die("Can't read '%s'", file);
197 197
198 /* put in zeros for file size, then fill true size later */ 198 /* put in zeros for file size, then fill true size later */
199 write_or_die(&size, hdr_sz); 199 if (hdr_sz)
200 write_or_die(&size, hdr_sz);
200 201
201 do { 202 do {
202 r = read(fd, buf, BUFSIZ); 203 r = read(fd, buf, BUFSIZ);
@@ -212,7 +213,7 @@ static void record_file(const char *file, size_t hdr_sz)
212 if (bigendian()) 213 if (bigendian())
213 sizep += sizeof(u64) - hdr_sz; 214 sizep += sizeof(u64) - hdr_sz;
214 215
215 if (pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) 216 if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0)
216 die("writing to %s", output_file); 217 die("writing to %s", output_file);
217} 218}
218 219
@@ -428,6 +429,19 @@ get_tracepoints_path(struct list_head *pattrs)
428 return nr_tracepoints > 0 ? path.next : NULL; 429 return nr_tracepoints > 0 ? path.next : NULL;
429} 430}
430 431
432static void
433put_tracepoints_path(struct tracepoint_path *tps)
434{
435 while (tps) {
436 struct tracepoint_path *t = tps;
437
438 tps = tps->next;
439 free(t->name);
440 free(t->system);
441 free(t);
442 }
443}
444
431bool have_tracepoints(struct list_head *pattrs) 445bool have_tracepoints(struct list_head *pattrs)
432{ 446{
433 struct perf_evsel *pos; 447 struct perf_evsel *pos;
@@ -439,19 +453,11 @@ bool have_tracepoints(struct list_head *pattrs)
439 return false; 453 return false;
440} 454}
441 455
442int read_tracing_data(int fd, struct list_head *pattrs) 456static void tracing_data_header(void)
443{ 457{
444 char buf[BUFSIZ]; 458 char buf[20];
445 struct tracepoint_path *tps = get_tracepoints_path(pattrs);
446
447 /*
448 * What? No tracepoints? No sense writing anything here, bail out.
449 */
450 if (tps == NULL)
451 return -1;
452
453 output_fd = fd;
454 459
460 /* just guessing this is someone's birthday.. ;) */
455 buf[0] = 23; 461 buf[0] = 23;
456 buf[1] = 8; 462 buf[1] = 8;
457 buf[2] = 68; 463 buf[2] = 68;
@@ -476,28 +482,86 @@ int read_tracing_data(int fd, struct list_head *pattrs)
476 /* save page_size */ 482 /* save page_size */
477 page_size = sysconf(_SC_PAGESIZE); 483 page_size = sysconf(_SC_PAGESIZE);
478 write_or_die(&page_size, 4); 484 write_or_die(&page_size, 4);
485}
486
487struct tracing_data *tracing_data_get(struct list_head *pattrs,
488 int fd, bool temp)
489{
490 struct tracepoint_path *tps;
491 struct tracing_data *tdata;
492
493 output_fd = fd;
494
495 tps = get_tracepoints_path(pattrs);
496 if (!tps)
497 return NULL;
479 498
499 tdata = malloc_or_die(sizeof(*tdata));
500 tdata->temp = temp;
501 tdata->size = 0;
502
503 if (temp) {
504 int temp_fd;
505
506 snprintf(tdata->temp_file, sizeof(tdata->temp_file),
507 "/tmp/perf-XXXXXX");
508 if (!mkstemp(tdata->temp_file))
509 die("Can't make temp file");
510
511 temp_fd = open(tdata->temp_file, O_RDWR);
512 if (temp_fd < 0)
513 die("Can't read '%s'", tdata->temp_file);
514
515 /*
516 * Set the temp file the default output, so all the
517 * tracing data are stored into it.
518 */
519 output_fd = temp_fd;
520 }
521
522 tracing_data_header();
480 read_header_files(); 523 read_header_files();
481 read_ftrace_files(tps); 524 read_ftrace_files(tps);
482 read_event_files(tps); 525 read_event_files(tps);
483 read_proc_kallsyms(); 526 read_proc_kallsyms();
484 read_ftrace_printk(); 527 read_ftrace_printk();
485 528
486 return 0; 529 /*
530 * All tracing data are stored by now, we can restore
531 * the default output file in case we used temp file.
532 */
533 if (temp) {
534 tdata->size = lseek(output_fd, 0, SEEK_CUR);
535 close(output_fd);
536 output_fd = fd;
537 }
538
539 put_tracepoints_path(tps);
540 return tdata;
487} 541}
488 542
489ssize_t read_tracing_data_size(int fd, struct list_head *pattrs) 543void tracing_data_put(struct tracing_data *tdata)
490{ 544{
491 ssize_t size; 545 if (tdata->temp) {
492 int err = 0; 546 record_file(tdata->temp_file, 0);
547 unlink(tdata->temp_file);
548 }
493 549
494 calc_data_size = 1; 550 free(tdata);
495 err = read_tracing_data(fd, pattrs); 551}
496 size = calc_data_size - 1;
497 calc_data_size = 0;
498 552
499 if (err < 0) 553int read_tracing_data(int fd, struct list_head *pattrs)
500 return err; 554{
555 struct tracing_data *tdata;
501 556
502 return size; 557 /*
558 * We work over the real file, so we can write data
559 * directly, no temp file is needed.
560 */
561 tdata = tracing_data_get(pattrs, fd, false);
562 if (!tdata)
563 return -ENOMEM;
564
565 tracing_data_put(tdata);
566 return 0;
503} 567}