summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-record.txt4
-rw-r--r--tools/perf/builtin-record.c30
-rw-r--r--tools/perf/util/data.c11
-rw-r--r--tools/perf/util/data.h2
4 files changed, 39 insertions, 8 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 8f0c2be34848..8fe4dffcadd0 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -495,6 +495,10 @@ overhead. You can still switch them on with:
495 495
496 --switch-output --no-no-buildid --no-no-buildid-cache 496 --switch-output --no-no-buildid --no-no-buildid-cache
497 497
498--switch-max-files=N::
499
500When rotating perf.data with --switch-output, only keep N files.
501
498--dry-run:: 502--dry-run::
499Parse options then exit. --dry-run can be used to detect errors in cmdline 503Parse options then exit. --dry-run can be used to detect errors in cmdline
500options. 504options.
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a468d882e74f..02d7c40b2d10 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -62,6 +62,9 @@ struct switch_output {
62 unsigned long time; 62 unsigned long time;
63 const char *str; 63 const char *str;
64 bool set; 64 bool set;
65 char **filenames;
66 int num_files;
67 int cur_file;
65}; 68};
66 69
67struct record { 70struct record {
@@ -892,6 +895,7 @@ record__switch_output(struct record *rec, bool at_exit)
892{ 895{
893 struct perf_data *data = &rec->data; 896 struct perf_data *data = &rec->data;
894 int fd, err; 897 int fd, err;
898 char *new_filename;
895 899
896 /* Same Size: "2015122520103046"*/ 900 /* Same Size: "2015122520103046"*/
897 char timestamp[] = "InvalidTimestamp"; 901 char timestamp[] = "InvalidTimestamp";
@@ -912,7 +916,7 @@ record__switch_output(struct record *rec, bool at_exit)
912 916
913 fd = perf_data__switch(data, timestamp, 917 fd = perf_data__switch(data, timestamp,
914 rec->session->header.data_offset, 918 rec->session->header.data_offset,
915 at_exit); 919 at_exit, &new_filename);
916 if (fd >= 0 && !at_exit) { 920 if (fd >= 0 && !at_exit) {
917 rec->bytes_written = 0; 921 rec->bytes_written = 0;
918 rec->session->header.data_size = 0; 922 rec->session->header.data_size = 0;
@@ -922,6 +926,21 @@ record__switch_output(struct record *rec, bool at_exit)
922 fprintf(stderr, "[ perf record: Dump %s.%s ]\n", 926 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
923 data->path, timestamp); 927 data->path, timestamp);
924 928
929 if (rec->switch_output.num_files) {
930 int n = rec->switch_output.cur_file + 1;
931
932 if (n >= rec->switch_output.num_files)
933 n = 0;
934 rec->switch_output.cur_file = n;
935 if (rec->switch_output.filenames[n]) {
936 remove(rec->switch_output.filenames[n]);
937 free(rec->switch_output.filenames[n]);
938 }
939 rec->switch_output.filenames[n] = new_filename;
940 } else {
941 free(new_filename);
942 }
943
925 /* Output tracking events */ 944 /* Output tracking events */
926 if (!at_exit) { 945 if (!at_exit) {
927 record__synthesize(rec, false); 946 record__synthesize(rec, false);
@@ -1973,6 +1992,8 @@ static struct option __record_options[] = {
1973 &record.switch_output.set, "signal,size,time", 1992 &record.switch_output.set, "signal,size,time",
1974 "Switch output when receive SIGUSR2 or cross size,time threshold", 1993 "Switch output when receive SIGUSR2 or cross size,time threshold",
1975 "signal"), 1994 "signal"),
1995 OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files,
1996 "Limit number of switch output generated files"),
1976 OPT_BOOLEAN(0, "dry-run", &dry_run, 1997 OPT_BOOLEAN(0, "dry-run", &dry_run,
1977 "Parse options then exit"), 1998 "Parse options then exit"),
1978#ifdef HAVE_AIO_SUPPORT 1999#ifdef HAVE_AIO_SUPPORT
@@ -2059,6 +2080,13 @@ int cmd_record(int argc, const char **argv)
2059 alarm(rec->switch_output.time); 2080 alarm(rec->switch_output.time);
2060 } 2081 }
2061 2082
2083 if (rec->switch_output.num_files) {
2084 rec->switch_output.filenames = calloc(sizeof(char *),
2085 rec->switch_output.num_files);
2086 if (!rec->switch_output.filenames)
2087 return -EINVAL;
2088 }
2089
2062 /* 2090 /*
2063 * Allow aliases to facilitate the lookup of symbols for address 2091 * Allow aliases to facilitate the lookup of symbols for address
2064 * filters. Refer to auxtrace_parse_filters(). 2092 * filters. Refer to auxtrace_parse_filters().
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index c6b67efea11a..6a64f713710d 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -361,9 +361,9 @@ ssize_t perf_data__write(struct perf_data *data,
361 361
362int perf_data__switch(struct perf_data *data, 362int perf_data__switch(struct perf_data *data,
363 const char *postfix, 363 const char *postfix,
364 size_t pos, bool at_exit) 364 size_t pos, bool at_exit,
365 char **new_filepath)
365{ 366{
366 char *new_filepath;
367 int ret; 367 int ret;
368 368
369 if (check_pipe(data)) 369 if (check_pipe(data))
@@ -371,15 +371,15 @@ int perf_data__switch(struct perf_data *data,
371 if (perf_data__is_read(data)) 371 if (perf_data__is_read(data))
372 return -EINVAL; 372 return -EINVAL;
373 373
374 if (asprintf(&new_filepath, "%s.%s", data->path, postfix) < 0) 374 if (asprintf(new_filepath, "%s.%s", data->path, postfix) < 0)
375 return -ENOMEM; 375 return -ENOMEM;
376 376
377 /* 377 /*
378 * Only fire a warning, don't return error, continue fill 378 * Only fire a warning, don't return error, continue fill
379 * original file. 379 * original file.
380 */ 380 */
381 if (rename(data->path, new_filepath)) 381 if (rename(data->path, *new_filepath))
382 pr_warning("Failed to rename %s to %s\n", data->path, new_filepath); 382 pr_warning("Failed to rename %s to %s\n", data->path, *new_filepath);
383 383
384 if (!at_exit) { 384 if (!at_exit) {
385 close(data->file.fd); 385 close(data->file.fd);
@@ -396,7 +396,6 @@ int perf_data__switch(struct perf_data *data,
396 } 396 }
397 ret = data->file.fd; 397 ret = data->file.fd;
398out: 398out:
399 free(new_filepath);
400 return ret; 399 return ret;
401} 400}
402 401
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h
index 6aef8746469f..259868a39019 100644
--- a/tools/perf/util/data.h
+++ b/tools/perf/util/data.h
@@ -70,7 +70,7 @@ ssize_t perf_data_file__write(struct perf_data_file *file,
70 */ 70 */
71int perf_data__switch(struct perf_data *data, 71int perf_data__switch(struct perf_data *data,
72 const char *postfix, 72 const char *postfix,
73 size_t pos, bool at_exit); 73 size_t pos, bool at_exit, char **new_filepath);
74 74
75int perf_data__create_dir(struct perf_data *data, int nr); 75int perf_data__create_dir(struct perf_data *data, int nr);
76int perf_data__open_dir(struct perf_data *data); 76int perf_data__open_dir(struct perf_data *data);