diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2020-09-02 13:57:07 +0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2020-09-04 14:38:15 -0300 |
commit | a8fcbd269b4340c36dbf99b4453bcbfe128d93fb (patch) | |
tree | cae1fe729dd0558552f4956691a529ec21cbab94 /tools/perf/util/evlist.c | |
parent | 1f4390d825cc04e91a276c78f984dd2d7fe01e62 (diff) | |
download | linux-stable-a8fcbd269b4340c36dbf99b4453bcbfe128d93fb.tar.gz linux-stable-a8fcbd269b4340c36dbf99b4453bcbfe128d93fb.tar.bz2 linux-stable-a8fcbd269b4340c36dbf99b4453bcbfe128d93fb.zip |
perf tools: Add FIFO file names as alternative options to --control
Enable the --control option to accept file names as an alternative to
file descriptors.
Example:
$ mkfifo perf.control
$ mkfifo perf.ack
$ cat perf.ack &
[1] 6808
$ perf record --control fifo:perf.control,perf.ack -- sleep 300 &
[2] 6810
$ echo disable > perf.control
$ Events disabled
ack
$ echo enable > perf.control
$ Events enabled
ack
$ echo disable > perf.control
$ Events disabled
ack
$ kill %2
[ perf record: Woken up 4 times to write data ]
$ [ perf record: Captured and wrote 0.018 MB perf.data (7 samples) ]
[1]- Done cat perf.ack
[2]+ Terminated perf record --control fifo:perf.control,perf.ack -- sleep 300
$
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lore.kernel.org/lkml/20200902105707.11491-1-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/evlist.c')
-rw-r--r-- | tools/perf/util/evlist.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 47d1045a19af..00593e5f2a9d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1727,12 +1727,63 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, return leader; } -int evlist__parse_control(const char *str, int *ctl_fd, int *ctl_fd_ack) +static int evlist__parse_control_fifo(const char *str, int *ctl_fd, int *ctl_fd_ack, bool *ctl_fd_close) +{ + char *s, *p; + int ret = 0, fd; + + if (strncmp(str, "fifo:", 5)) + return -EINVAL; + + str += 5; + if (!*str || *str == ',') + return -EINVAL; + + s = strdup(str); + if (!s) + return -ENOMEM; + + p = strchr(s, ','); + if (p) + *p = '\0'; + + /* + * O_RDWR avoids POLLHUPs which is necessary to allow the other + * end of a FIFO to be repeatedly opened and closed. + */ + fd = open(s, O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (fd < 0) { + pr_err("Failed to open '%s'\n", s); + ret = -errno; + goto out_free; + } + *ctl_fd = fd; + *ctl_fd_close = true; + + if (p && *++p) { + /* O_RDWR | O_NONBLOCK means the other end need not be open */ + fd = open(p, O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (fd < 0) { + pr_err("Failed to open '%s'\n", p); + ret = -errno; + goto out_free; + } + *ctl_fd_ack = fd; + } + +out_free: + free(s); + return ret; +} + +int evlist__parse_control(const char *str, int *ctl_fd, int *ctl_fd_ack, bool *ctl_fd_close) { char *comma = NULL, *endptr = NULL; + *ctl_fd_close = false; + if (strncmp(str, "fd:", 3)) - return -EINVAL; + return evlist__parse_control_fifo(str, ctl_fd, ctl_fd_ack, ctl_fd_close); *ctl_fd = strtoul(&str[3], &endptr, 0); if (endptr == &str[3]) |