aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c82
1 files changed, 9 insertions, 73 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index fff985cf3852..2990570b5c6d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -61,11 +61,6 @@ static void __handle_on_exit_funcs(void)
61} 61}
62#endif 62#endif
63 63
64enum write_mode_t {
65 WRITE_FORCE,
66 WRITE_APPEND
67};
68
69struct perf_record { 64struct perf_record {
70 struct perf_tool tool; 65 struct perf_tool tool;
71 struct perf_record_opts opts; 66 struct perf_record_opts opts;
@@ -77,12 +72,9 @@ struct perf_record {
77 int output; 72 int output;
78 unsigned int page_size; 73 unsigned int page_size;
79 int realtime_prio; 74 int realtime_prio;
80 enum write_mode_t write_mode;
81 bool no_buildid; 75 bool no_buildid;
82 bool no_buildid_cache; 76 bool no_buildid_cache;
83 bool force; 77 bool force;
84 bool file_new;
85 bool append_file;
86 long samples; 78 long samples;
87 off_t post_processing_offset; 79 off_t post_processing_offset;
88}; 80};
@@ -200,25 +192,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
200 signal(signr, SIG_DFL); 192 signal(signr, SIG_DFL);
201} 193}
202 194
203static bool perf_evlist__equal(struct perf_evlist *evlist,
204 struct perf_evlist *other)
205{
206 struct perf_evsel *pos, *pair;
207
208 if (evlist->nr_entries != other->nr_entries)
209 return false;
210
211 pair = perf_evlist__first(other);
212
213 list_for_each_entry(pos, &evlist->entries, node) {
214 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
215 return false;
216 pair = perf_evsel__next(pair);
217 }
218
219 return true;
220}
221
222static int perf_record__open(struct perf_record *rec) 195static int perf_record__open(struct perf_record *rec)
223{ 196{
224 char msg[512]; 197 char msg[512];
@@ -273,16 +246,7 @@ try_again:
273 goto out; 246 goto out;
274 } 247 }
275 248
276 if (rec->file_new) 249 session->evlist = evlist;
277 session->evlist = evlist;
278 else {
279 if (!perf_evlist__equal(session->evlist, evlist)) {
280 fprintf(stderr, "incompatible append\n");
281 rc = -1;
282 goto out;
283 }
284 }
285
286 perf_session__set_id_hdr_size(session); 250 perf_session__set_id_hdr_size(session);
287out: 251out:
288 return rc; 252 return rc;
@@ -415,23 +379,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
415 if (!strcmp(output_name, "-")) 379 if (!strcmp(output_name, "-"))
416 opts->pipe_output = true; 380 opts->pipe_output = true;
417 else if (!stat(output_name, &st) && st.st_size) { 381 else if (!stat(output_name, &st) && st.st_size) {
418 if (rec->write_mode == WRITE_FORCE) { 382 char oldname[PATH_MAX];
419 char oldname[PATH_MAX]; 383 snprintf(oldname, sizeof(oldname), "%s.old",
420 snprintf(oldname, sizeof(oldname), "%s.old", 384 output_name);
421 output_name); 385 unlink(oldname);
422 unlink(oldname); 386 rename(output_name, oldname);
423 rename(output_name, oldname);
424 }
425 } else if (rec->write_mode == WRITE_APPEND) {
426 rec->write_mode = WRITE_FORCE;
427 } 387 }
428 } 388 }
429 389
430 flags = O_CREAT|O_RDWR; 390 flags = O_CREAT|O_RDWR|O_TRUNC;
431 if (rec->write_mode == WRITE_APPEND)
432 rec->file_new = 0;
433 else
434 flags |= O_TRUNC;
435 391
436 if (opts->pipe_output) 392 if (opts->pipe_output)
437 output = STDOUT_FILENO; 393 output = STDOUT_FILENO;
@@ -445,7 +401,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
445 rec->output = output; 401 rec->output = output;
446 402
447 session = perf_session__new(output_name, O_WRONLY, 403 session = perf_session__new(output_name, O_WRONLY,
448 rec->write_mode == WRITE_FORCE, false, NULL); 404 true, false, NULL);
449 if (session == NULL) { 405 if (session == NULL) {
450 pr_err("Not enough memory for reading perf file header\n"); 406 pr_err("Not enough memory for reading perf file header\n");
451 return -1; 407 return -1;
@@ -465,12 +421,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
465 if (!rec->opts.branch_stack) 421 if (!rec->opts.branch_stack)
466 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 422 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
467 423
468 if (!rec->file_new) {
469 err = perf_session__read_header(session, output);
470 if (err < 0)
471 goto out_delete_session;
472 }
473
474 if (forks) { 424 if (forks) {
475 err = perf_evlist__prepare_workload(evsel_list, &opts->target, 425 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
476 argv, opts->pipe_output, 426 argv, opts->pipe_output,
@@ -498,7 +448,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
498 err = perf_header__write_pipe(output); 448 err = perf_header__write_pipe(output);
499 if (err < 0) 449 if (err < 0)
500 goto out_delete_session; 450 goto out_delete_session;
501 } else if (rec->file_new) { 451 } else {
502 err = perf_session__write_header(session, evsel_list, 452 err = perf_session__write_header(session, evsel_list,
503 output, false); 453 output, false);
504 if (err < 0) 454 if (err < 0)
@@ -869,8 +819,6 @@ static struct perf_record record = {
869 .uses_mmap = true, 819 .uses_mmap = true,
870 }, 820 },
871 }, 821 },
872 .write_mode = WRITE_FORCE,
873 .file_new = true,
874}; 822};
875 823
876#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: " 824#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
@@ -906,8 +854,6 @@ const struct option record_options[] = {
906 "collect raw sample records from all opened counters"), 854 "collect raw sample records from all opened counters"),
907 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 855 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
908 "system-wide collection from all CPUs"), 856 "system-wide collection from all CPUs"),
909 OPT_BOOLEAN('A', "append", &record.append_file,
910 "append to the output file to do incremental profiling"),
911 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 857 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
912 "list of cpus to monitor"), 858 "list of cpus to monitor"),
913 OPT_BOOLEAN('f', "force", &record.force, 859 OPT_BOOLEAN('f', "force", &record.force,
@@ -977,16 +923,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
977 if (!argc && perf_target__none(&rec->opts.target)) 923 if (!argc && perf_target__none(&rec->opts.target))
978 usage_with_options(record_usage, record_options); 924 usage_with_options(record_usage, record_options);
979 925
980 if (rec->force && rec->append_file) {
981 ui__error("Can't overwrite and append at the same time."
982 " You need to choose between -f and -A");
983 usage_with_options(record_usage, record_options);
984 } else if (rec->append_file) {
985 rec->write_mode = WRITE_APPEND;
986 } else {
987 rec->write_mode = WRITE_FORCE;
988 }
989
990 if (nr_cgroups && !rec->opts.target.system_wide) { 926 if (nr_cgroups && !rec->opts.target.system_wide) {
991 ui__error("cgroup monitoring only available in" 927 ui__error("cgroup monitoring only available in"
992 " system-wide mode\n"); 928 " system-wide mode\n");