diff options
author | Masami Hiramatsu <mhiramat@kernel.org> | 2021-02-01 13:48:11 -0600 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2021-02-09 12:52:15 -0500 |
commit | d262271d04830e4b5009f4a5cc64934d86b49832 (patch) | |
tree | 5f22cea362fec30f4e879f4192bd6aa1c31441d8 /kernel/trace/trace_events_synth.c | |
parent | 33b1d14668859626bf96958e38042b0ed8a22a68 (diff) |
tracing/dynevent: Delegate parsing to create function
Delegate command parsing to each create function so that the
command syntax can be customized.
This requires changes to the kprobe/uprobe/synthetic event handling,
which are also included here.
Link: https://lkml.kernel.org/r/e488726f49cbdbc01568618f8680584306c4c79f.1612208610.git.zanussi@kernel.org
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
[ zanussi@kernel.org: added synthetic event modifications ]
Signed-off-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_events_synth.c')
-rw-r--r-- | kernel/trace/trace_events_synth.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 5a8bc0b421f1..b2588a5650c9 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -62,7 +62,7 @@ static void synth_err(u8 err_type, u8 err_pos) err_type, err_pos); } -static int create_synth_event(int argc, const char **argv); +static int create_synth_event(const char *raw_command); static int synth_event_show(struct seq_file *m, struct dyn_event *ev); static int synth_event_release(struct dyn_event *ev); static bool synth_event_is_busy(struct dyn_event *ev); @@ -1383,18 +1383,30 @@ int synth_event_delete(const char *event_name) } EXPORT_SYMBOL_GPL(synth_event_delete); -static int create_or_delete_synth_event(int argc, char **argv) +static int create_or_delete_synth_event(const char *raw_command) { - const char *name = argv[0]; - int ret; + char **argv, *name = NULL; + int argc = 0, ret = 0; + + argv = argv_split(GFP_KERNEL, raw_command, &argc); + if (!argv) + return -ENOMEM; + + if (!argc) + goto free; + + name = argv[0]; /* trace_run_command() ensures argc != 0 */ if (name[0] == '!') { ret = synth_event_delete(name + 1); - return ret; + goto free; } ret = __create_synth_event(argc - 1, name, (const char **)argv + 1); +free: + argv_free(argv); + return ret == -ECANCELED ? -EINVAL : ret; } @@ -1403,7 +1415,7 @@ static int synth_event_run_command(struct dynevent_cmd *cmd) struct synth_event *se; int ret; - ret = trace_run_command(cmd->seq.buffer, create_or_delete_synth_event); + ret = create_or_delete_synth_event(cmd->seq.buffer); if (ret) return ret; @@ -1939,23 +1951,43 @@ int synth_event_trace_end(struct synth_event_trace_state *trace_state) } EXPORT_SYMBOL_GPL(synth_event_trace_end); -static int create_synth_event(int argc, const char **argv) +static int create_synth_event(const char *raw_command) { - const char *name = argv[0]; - int len; + char **argv, *name; + int len, argc = 0, ret = 0; + + argv = argv_split(GFP_KERNEL, raw_command, &argc); + if (!argv) { + ret = -ENOMEM; + return ret; + } - if (name[0] != 's' || name[1] != ':') - return -ECANCELED; + if (!argc) + goto free; + + name = argv[0]; + + if (name[0] != 's' || name[1] != ':') { + ret = -ECANCELED; + goto free; + } name += 2; /* This interface accepts group name prefix */ if (strchr(name, '/')) { len = str_has_prefix(name, SYNTH_SYSTEM "/"); - if (len == 0) - return -EINVAL; + if (len == 0) { + ret = -EINVAL; + goto free; + } name += len; } - return __create_synth_event(argc - 1, name, argv + 1); + + ret = __create_synth_event(argc - 1, name, (const char **)argv + 1); +free: + argv_free(argv); + + return ret; } static int synth_event_release(struct dyn_event *ev) |