tracing/kprobe: Add per-probe delete from event
Allow user to delete a probe from event. This is done by head match. For example, if we have 2 probes on an event $ cat kprobe_events p:kprobes/testprobe _do_fork r1=%ax r2=%dx p:kprobes/testprobe idle_fork r1=%ax r2=%cx Then you can remove one of them by passing the head of definition which identify the probe. $ echo "-:kprobes/testprobe idle_fork" >> kprobe_events Link: http://lkml.kernel.org/r/156095688848.28024.15798690082378432435.stgit@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
41af3cf587
commit
eb5bf81330
|
@ -137,13 +137,36 @@ static bool trace_kprobe_is_busy(struct dyn_event *ev)
|
|||
return trace_probe_is_enabled(&tk->tp);
|
||||
}
|
||||
|
||||
static bool trace_kprobe_match_command_head(struct trace_kprobe *tk,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
char buf[MAX_ARGSTR_LEN + 1];
|
||||
|
||||
if (!argc)
|
||||
return true;
|
||||
|
||||
if (!tk->symbol)
|
||||
snprintf(buf, sizeof(buf), "0x%p", tk->rp.kp.addr);
|
||||
else if (tk->rp.kp.offset)
|
||||
snprintf(buf, sizeof(buf), "%s+%u",
|
||||
trace_kprobe_symbol(tk), tk->rp.kp.offset);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%s", trace_kprobe_symbol(tk));
|
||||
if (strcmp(buf, argv[0]))
|
||||
return false;
|
||||
argc--; argv++;
|
||||
|
||||
return trace_probe_match_command_args(&tk->tp, argc, argv);
|
||||
}
|
||||
|
||||
static bool trace_kprobe_match(const char *system, const char *event,
|
||||
int argc, const char **argv, struct dyn_event *ev)
|
||||
{
|
||||
struct trace_kprobe *tk = to_trace_kprobe(ev);
|
||||
|
||||
return strcmp(trace_probe_name(&tk->tp), event) == 0 &&
|
||||
(!system || strcmp(trace_probe_group_name(&tk->tp), system) == 0);
|
||||
(!system || strcmp(trace_probe_group_name(&tk->tp), system) == 0) &&
|
||||
trace_kprobe_match_command_head(tk, argc, argv);
|
||||
}
|
||||
|
||||
static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
|
||||
|
|
|
@ -1047,3 +1047,21 @@ int trace_probe_compare_arg_type(struct trace_probe *a, struct trace_probe *b)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool trace_probe_match_command_args(struct trace_probe *tp,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
char buf[MAX_ARGSTR_LEN + 1];
|
||||
int i;
|
||||
|
||||
if (tp->nr_args < argc)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
snprintf(buf, sizeof(buf), "%s=%s",
|
||||
tp->args[i].name, tp->args[i].comm);
|
||||
if (strcmp(buf, argv[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -332,6 +332,8 @@ int trace_probe_remove_file(struct trace_probe *tp,
|
|||
struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp,
|
||||
struct trace_event_file *file);
|
||||
int trace_probe_compare_arg_type(struct trace_probe *a, struct trace_probe *b);
|
||||
bool trace_probe_match_command_args(struct trace_probe *tp,
|
||||
int argc, const char **argv);
|
||||
|
||||
#define trace_probe_for_each_link(pos, tp) \
|
||||
list_for_each_entry(pos, &(tp)->event->files, list)
|
||||
|
|
Loading…
Reference in New Issue