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.c87
1 files changed, 10 insertions, 77 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index cdf58ecc04b1..ecca62e27b28 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,8 @@ 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;
84 bool file_new;
85 bool append_file;
86 long samples; 77 long samples;
87 off_t post_processing_offset; 78 off_t post_processing_offset;
88}; 79};
@@ -198,26 +189,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
198 return; 189 return;
199 190
200 signal(signr, SIG_DFL); 191 signal(signr, SIG_DFL);
201 kill(getpid(), signr);
202}
203
204static bool perf_evlist__equal(struct perf_evlist *evlist,
205 struct perf_evlist *other)
206{
207 struct perf_evsel *pos, *pair;
208
209 if (evlist->nr_entries != other->nr_entries)
210 return false;
211
212 pair = perf_evlist__first(other);
213
214 list_for_each_entry(pos, &evlist->entries, node) {
215 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
216 return false;
217 pair = perf_evsel__next(pair);
218 }
219
220 return true;
221} 192}
222 193
223static int perf_record__open(struct perf_record *rec) 194static int perf_record__open(struct perf_record *rec)
@@ -274,16 +245,7 @@ try_again:
274 goto out; 245 goto out;
275 } 246 }
276 247
277 if (rec->file_new) 248 session->evlist = evlist;
278 session->evlist = evlist;
279 else {
280 if (!perf_evlist__equal(session->evlist, evlist)) {
281 fprintf(stderr, "incompatible append\n");
282 rc = -1;
283 goto out;
284 }
285 }
286
287 perf_session__set_id_hdr_size(session); 249 perf_session__set_id_hdr_size(session);
288out: 250out:
289 return rc; 251 return rc;
@@ -404,6 +366,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
404 signal(SIGCHLD, sig_handler); 366 signal(SIGCHLD, sig_handler);
405 signal(SIGINT, sig_handler); 367 signal(SIGINT, sig_handler);
406 signal(SIGUSR1, sig_handler); 368 signal(SIGUSR1, sig_handler);
369 signal(SIGTERM, sig_handler);
407 370
408 if (!output_name) { 371 if (!output_name) {
409 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode)) 372 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
@@ -415,23 +378,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
415 if (!strcmp(output_name, "-")) 378 if (!strcmp(output_name, "-"))
416 opts->pipe_output = true; 379 opts->pipe_output = true;
417 else if (!stat(output_name, &st) && st.st_size) { 380 else if (!stat(output_name, &st) && st.st_size) {
418 if (rec->write_mode == WRITE_FORCE) { 381 char oldname[PATH_MAX];
419 char oldname[PATH_MAX]; 382 snprintf(oldname, sizeof(oldname), "%s.old",
420 snprintf(oldname, sizeof(oldname), "%s.old", 383 output_name);
421 output_name); 384 unlink(oldname);
422 unlink(oldname); 385 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 } 386 }
428 } 387 }
429 388
430 flags = O_CREAT|O_RDWR; 389 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 390
436 if (opts->pipe_output) 391 if (opts->pipe_output)
437 output = STDOUT_FILENO; 392 output = STDOUT_FILENO;
@@ -445,7 +400,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
445 rec->output = output; 400 rec->output = output;
446 401
447 session = perf_session__new(output_name, O_WRONLY, 402 session = perf_session__new(output_name, O_WRONLY,
448 rec->write_mode == WRITE_FORCE, false, NULL); 403 true, false, NULL);
449 if (session == NULL) { 404 if (session == NULL) {
450 pr_err("Not enough memory for reading perf file header\n"); 405 pr_err("Not enough memory for reading perf file header\n");
451 return -1; 406 return -1;
@@ -465,12 +420,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
465 if (!rec->opts.branch_stack) 420 if (!rec->opts.branch_stack)
466 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 421 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
467 422
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) { 423 if (forks) {
475 err = perf_evlist__prepare_workload(evsel_list, &opts->target, 424 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
476 argv, opts->pipe_output, 425 argv, opts->pipe_output,
@@ -498,7 +447,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
498 err = perf_header__write_pipe(output); 447 err = perf_header__write_pipe(output);
499 if (err < 0) 448 if (err < 0)
500 goto out_delete_session; 449 goto out_delete_session;
501 } else if (rec->file_new) { 450 } else {
502 err = perf_session__write_header(session, evsel_list, 451 err = perf_session__write_header(session, evsel_list,
503 output, false); 452 output, false);
504 if (err < 0) 453 if (err < 0)
@@ -869,8 +818,6 @@ static struct perf_record record = {
869 .uses_mmap = true, 818 .uses_mmap = true,
870 }, 819 },
871 }, 820 },
872 .write_mode = WRITE_FORCE,
873 .file_new = true,
874}; 821};
875 822
876#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: " 823#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
@@ -906,12 +853,8 @@ const struct option record_options[] = {
906 "collect raw sample records from all opened counters"), 853 "collect raw sample records from all opened counters"),
907 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 854 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
908 "system-wide collection from all CPUs"), 855 "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", 856 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
912 "list of cpus to monitor"), 857 "list of cpus to monitor"),
913 OPT_BOOLEAN('f', "force", &record.force,
914 "overwrite existing data file (deprecated)"),
915 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 858 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
916 OPT_STRING('o', "output", &record.output_name, "file", 859 OPT_STRING('o', "output", &record.output_name, "file",
917 "output file name"), 860 "output file name"),
@@ -977,16 +920,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
977 if (!argc && perf_target__none(&rec->opts.target)) 920 if (!argc && perf_target__none(&rec->opts.target))
978 usage_with_options(record_usage, record_options); 921 usage_with_options(record_usage, record_options);
979 922
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) { 923 if (nr_cgroups && !rec->opts.target.system_wide) {
991 ui__error("cgroup monitoring only available in" 924 ui__error("cgroup monitoring only available in"
992 " system-wide mode\n"); 925 " system-wide mode\n");