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>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
1f4390d825
commit
a8fcbd269b
@@ -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])
|
||||
|
Reference in New Issue
Block a user