summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-probe.c
diff options
context:
space:
mode:
authorKrister Johansen <kjlx@templeofstupid.com>2017-07-06 03:48:10 +0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-07-19 04:14:10 +0200
commit544abd44c7064c8a58a6bd2073d757f6b91d98c5 (patch)
treefaa9e5d4c4b86067f4b5cd9f8200010a726a314d /tools/perf/builtin-probe.c
parentperf maps: Lookup maps in both intitial mountns and inner mountns. (diff)
downloadlinux-544abd44c7064c8a58a6bd2073d757f6b91d98c5.tar.xz
linux-544abd44c7064c8a58a6bd2073d757f6b91d98c5.zip
perf probe: Allow placing uprobes in alternate namespaces.
Teaches perf how to place a uprobe on a file that's in a different mount namespace. The user must add the probe using the --target-ns argument to perf probe. Once it has been placed, it may be recorded against without further namespace-specific commands. Signed-off-by: Krister Johansen <kjlx@templeofstupid.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> [ PPC build fixed by Ravi: ] Link: http://lkml.kernel.org/r/1500287542-6219-1-git-send-email-ravi.bangoria@linux.vnet.ibm.com Cc: Thomas-Mich Richter <tmricht@linux.vnet.ibm.com> [ Fix !HAVE_DWARF_SUPPORT build ] Link: http://lkml.kernel.org/r/1499305693-1599-4-git-send-email-kjlx@templeofstupid.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-probe.c')
-rw-r--r--tools/perf/builtin-probe.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index cf9f9e9c2fc0..3fb98d59cd27 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -58,6 +58,7 @@ static struct {
struct line_range line_range;
char *target;
struct strfilter *filter;
+ struct nsinfo *nsi;
} params;
/* Parse an event definition. Note that any error must die. */
@@ -80,6 +81,9 @@ static int parse_probe_event(const char *str)
params.target_used = true;
}
+ if (params.nsi)
+ pev->nsi = nsinfo__get(params.nsi);
+
/* Parse a perf-probe command into event */
ret = parse_perf_probe_command(str, pev);
pr_debug("%d arguments\n", pev->nargs);
@@ -189,7 +193,7 @@ static int opt_set_target(const struct option *opt, const char *str,
/* Expand given path to absolute path, except for modulename */
if (params.uprobes || strchr(str, '/')) {
- tmp = realpath(str, NULL);
+ tmp = nsinfo__realpath(str, params.nsi);
if (!tmp) {
pr_warning("Failed to get the absolute path of %s: %m\n", str);
return ret;
@@ -208,6 +212,34 @@ static int opt_set_target(const struct option *opt, const char *str,
return ret;
}
+static int opt_set_target_ns(const struct option *opt __maybe_unused,
+ const char *str, int unset __maybe_unused)
+{
+ int ret = -ENOENT;
+ pid_t ns_pid;
+ struct nsinfo *nsip;
+
+ if (str) {
+ errno = 0;
+ ns_pid = (pid_t)strtol(str, NULL, 10);
+ if (errno != 0) {
+ ret = -errno;
+ pr_warning("Failed to parse %s as a pid: %s\n", str,
+ strerror(errno));
+ return ret;
+ }
+ nsip = nsinfo__new(ns_pid);
+ if (nsip && nsip->need_setns)
+ params.nsi = nsinfo__get(nsip);
+ nsinfo__put(nsip);
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
/* Command option callbacks */
#ifdef HAVE_DWARF_SUPPORT
@@ -299,6 +331,7 @@ static void cleanup_params(void)
line_range__clear(&params.line_range);
free(params.target);
strfilter__delete(params.filter);
+ nsinfo__put(params.nsi);
memset(&params, 0, sizeof(params));
}
@@ -554,6 +587,8 @@ __cmd_probe(int argc, const char **argv)
OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
+ OPT_CALLBACK(0, "target-ns", NULL, "pid",
+ "target pid for namespace contexts", opt_set_target_ns),
OPT_END()
};
int ret;
@@ -634,15 +669,15 @@ __cmd_probe(int argc, const char **argv)
pr_err_with_code(" Error: Failed to show event list.", ret);
return ret;
case 'F':
- ret = show_available_funcs(params.target, params.filter,
- params.uprobes);
+ ret = show_available_funcs(params.target, params.nsi,
+ params.filter, params.uprobes);
if (ret < 0)
pr_err_with_code(" Error: Failed to show functions.", ret);
return ret;
#ifdef HAVE_DWARF_SUPPORT
case 'L':
ret = show_line_range(&params.line_range, params.target,
- params.uprobes);
+ params.nsi, params.uprobes);
if (ret < 0)
pr_err_with_code(" Error: Failed to show lines.", ret);
return ret;