[RFC PATCH v2 36/37] tools perf: generate event argv.

From: Wang Nan
Date: Fri May 15 2015 - 03:55:04 EST


bpf_load_gen_argv() generates argc and argv which will be passed to
other commands like cmd_record(). The generated arguments utilized
previous introduced '|' syntax to pass file descriptor of bpf
programs.

Signed-off-by: Wang Nan <wangnan0@xxxxxxxxxx>
---
tools/perf/util/bpf-loader.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/bpf-loader.h | 8 ++++
2 files changed, 95 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 7295a3b..a75b0b7 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -215,6 +215,93 @@ int bpf_probe(void)
return err < 0 ? err : 0;
}

+int bpf_load_gen_argv(int *pargc, const char ***pargv,
+ int old_argc, const char **old_argv,
+ const char *arg0)
+{
+ const char **argv = NULL;
+ int i, argc, pos, err;
+
+ if (!pargc || !pargv)
+ return -EINVAL;
+ if (!old_argv && old_argc)
+ return -EINVAL;
+
+ /*
+ * <arg0> <new args> <old args> NIL
+ * Omit the last NIL in argc.
+ */
+ argc = 1 + params.nr_progs * 2 + old_argc;
+ argv = malloc(sizeof(const char *) * (argc + 1));
+ if (!argv) {
+ pr_err("No enough memory\n");
+ return -ENOMEM;
+ }
+ bzero(argv, sizeof(char *) * (argc + 1));
+
+ pos = 0;
+
+ if (arg0)
+ argv[pos++] = strdup(arg0);
+
+ for (i = 0; i < (int)params.nr_progs; i++) {
+ struct bpf_prog_handler *prog =
+ params.progs[i].prog;
+ struct perf_probe_event *pevent =
+ params.progs[i].pevent;
+ int cmd_size, fd;
+ char *event_str;
+
+ err = bpf_prog_get_fd(prog, &fd);
+ if (err) {
+ pr_err("Unable to get program fd\n");
+ goto errout;
+ }
+
+ cmd_size = snprintf(NULL, 0,
+ "%s:%s|bpf_fd=%d|", pevent->group,
+ pevent->event, fd);
+
+ event_str = malloc(cmd_size + 1);
+ if (!event_str) {
+ pr_err("No enough menory\n");
+ goto errout;
+ }
+
+ snprintf(event_str, cmd_size + 1, "%s:%s|bpf_fd=%d|",
+ pevent->group, pevent->event, fd);
+
+ argv[pos++] = strdup("-e");
+ if (!argv[pos - 1]) {
+ pr_err("No enough memory\n");
+ goto errout;
+ }
+
+ argv[pos++] = event_str;
+
+ pr_debug("event: -e %s\n", event_str);
+ }
+
+ for (i = 0; i < old_argc; i++) {
+ argv[pos++] = strdup(old_argv[i]);
+ if (!argv[pos - 1]) {
+ pr_err("No enough memory\n");
+ goto errout;
+ }
+ }
+
+ *pargc = pos;
+ *pargv = argv;
+ return 0;
+errout:
+ for (i = 0; (int)i < argc; i++) {
+ if (argv[i])
+ free((void *)argv[i]);
+ }
+ free(argv);
+ return err;
+}
+
int bpf_load(void)
{
size_t i;
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 1ccebdf..eea45f4 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -13,4 +13,12 @@ int bpf_load(void);

int bpf_unprobe(void);
void bpf_clear(void);
+
+/*
+ * Generates argv like '-e my_event|bpf_fd=5|' for wrapping other
+ * commands.
+ */
+int bpf_load_gen_argv(int *pargc, const char ***pargv,
+ int old_argc, const char **old_argv,
+ const char *arg0);
#endif
--
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/