user_events: Handle matching arguments from dyn_events
Ensures that when dynamic events requests a match with arguments that they match what is in the user_event. Link: https://lkml.kernel.org/r/20220118204326.2169-4-beaub@linux.microsoft.com Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
parent
aa3b2b4c66
commit
9aed4e157d
|
@ -39,6 +39,7 @@
|
|||
#define MAX_EVENT_DESC 512
|
||||
#define EVENT_NAME(user_event) ((user_event)->tracepoint.name)
|
||||
#define MAX_FIELD_ARRAY_SIZE 1024
|
||||
#define MAX_FIELD_ARG_NAME 256
|
||||
|
||||
static char *register_page_data;
|
||||
|
||||
|
@ -700,13 +701,87 @@ static int user_event_free(struct dyn_event *ev)
|
|||
return destroy_user_event(user);
|
||||
}
|
||||
|
||||
static bool user_field_match(struct ftrace_event_field *field, int argc,
|
||||
const char **argv, int *iout)
|
||||
{
|
||||
char *field_name, *arg_name;
|
||||
int len, pos, i = *iout;
|
||||
bool colon = false, match = false;
|
||||
|
||||
if (i >= argc)
|
||||
return false;
|
||||
|
||||
len = MAX_FIELD_ARG_NAME;
|
||||
field_name = kmalloc(len, GFP_KERNEL);
|
||||
arg_name = kmalloc(len, GFP_KERNEL);
|
||||
|
||||
if (!arg_name || !field_name)
|
||||
goto out;
|
||||
|
||||
pos = 0;
|
||||
|
||||
for (; i < argc; ++i) {
|
||||
if (i != *iout)
|
||||
pos += snprintf(arg_name + pos, len - pos, " ");
|
||||
|
||||
pos += snprintf(arg_name + pos, len - pos, argv[i]);
|
||||
|
||||
if (strchr(argv[i], ';')) {
|
||||
++i;
|
||||
colon = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
|
||||
pos += snprintf(field_name + pos, len - pos, field->type);
|
||||
pos += snprintf(field_name + pos, len - pos, " ");
|
||||
pos += snprintf(field_name + pos, len - pos, field->name);
|
||||
|
||||
if (colon)
|
||||
pos += snprintf(field_name + pos, len - pos, ";");
|
||||
|
||||
*iout = i;
|
||||
|
||||
match = strcmp(arg_name, field_name) == 0;
|
||||
out:
|
||||
kfree(arg_name);
|
||||
kfree(field_name);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static bool user_fields_match(struct user_event *user, int argc,
|
||||
const char **argv)
|
||||
{
|
||||
struct ftrace_event_field *field, *next;
|
||||
struct list_head *head = &user->fields;
|
||||
int i = 0;
|
||||
|
||||
list_for_each_entry_safe_reverse(field, next, head, link)
|
||||
if (!user_field_match(field, argc, argv, &i))
|
||||
return false;
|
||||
|
||||
if (i != argc)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool user_event_match(const char *system, const char *event,
|
||||
int argc, const char **argv, struct dyn_event *ev)
|
||||
{
|
||||
struct user_event *user = container_of(ev, struct user_event, devent);
|
||||
bool match;
|
||||
|
||||
return strcmp(EVENT_NAME(user), event) == 0 &&
|
||||
match = strcmp(EVENT_NAME(user), event) == 0 &&
|
||||
(!system || strcmp(system, USER_EVENTS_SYSTEM) == 0);
|
||||
|
||||
if (match && argc > 0)
|
||||
match = user_fields_match(user, argc, argv);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static struct dyn_event_operations user_event_dops = {
|
||||
|
|
Loading…
Reference in New Issue