aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2009-10-14 23:21:12 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-15 05:35:22 -0400
commitb0f1a59a98d7ac2102e7e4f22904c26d564a5628 (patch)
tree63ee120d7fa1eda7e6c11db3530021634d3ba59b
parentfce29d15b59245597f7f320db4a9f2be0f5fb512 (diff)
tracing/filters: Use a different op for glob match
"==" will always do a full match, and "~" will do a glob match. In the future, we may add "=~" for regex match. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <4AD69528.3050309@cn.fujitsu.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--kernel/trace/trace.h2
-rw-r--r--kernel/trace/trace_events_filter.c59
2 files changed, 29 insertions, 32 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 628614532d16..ffe53ddbe67a 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -702,7 +702,7 @@ typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event,
702typedef int (*regex_match_func)(char *str, struct regex *r, int len); 702typedef int (*regex_match_func)(char *str, struct regex *r, int len);
703 703
704enum regex_type { 704enum regex_type {
705 MATCH_FULL, 705 MATCH_FULL = 0,
706 MATCH_FRONT_ONLY, 706 MATCH_FRONT_ONLY,
707 MATCH_MIDDLE_ONLY, 707 MATCH_MIDDLE_ONLY,
708 MATCH_END_ONLY, 708 MATCH_END_ONLY,
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 9c4f9a0dae2b..273845fce393 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -29,6 +29,7 @@ enum filter_op_ids
29{ 29{
30 OP_OR, 30 OP_OR,
31 OP_AND, 31 OP_AND,
32 OP_GLOB,
32 OP_NE, 33 OP_NE,
33 OP_EQ, 34 OP_EQ,
34 OP_LT, 35 OP_LT,
@@ -46,16 +47,17 @@ struct filter_op {
46}; 47};
47 48
48static struct filter_op filter_ops[] = { 49static struct filter_op filter_ops[] = {
49 { OP_OR, "||", 1 }, 50 { OP_OR, "||", 1 },
50 { OP_AND, "&&", 2 }, 51 { OP_AND, "&&", 2 },
51 { OP_NE, "!=", 4 }, 52 { OP_GLOB, "~", 4 },
52 { OP_EQ, "==", 4 }, 53 { OP_NE, "!=", 4 },
53 { OP_LT, "<", 5 }, 54 { OP_EQ, "==", 4 },
54 { OP_LE, "<=", 5 }, 55 { OP_LT, "<", 5 },
55 { OP_GT, ">", 5 }, 56 { OP_LE, "<=", 5 },
56 { OP_GE, ">=", 5 }, 57 { OP_GT, ">", 5 },
57 { OP_NONE, "OP_NONE", 0 }, 58 { OP_GE, ">=", 5 },
58 { OP_OPEN_PAREN, "(", 0 }, 59 { OP_NONE, "OP_NONE", 0 },
60 { OP_OPEN_PAREN, "(", 0 },
59}; 61};
60 62
61enum { 63enum {
@@ -329,22 +331,18 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
329 return type; 331 return type;
330} 332}
331 333
332static int filter_build_regex(struct filter_pred *pred) 334static void filter_build_regex(struct filter_pred *pred)
333{ 335{
334 struct regex *r = &pred->regex; 336 struct regex *r = &pred->regex;
335 char *search, *dup; 337 char *search;
336 enum regex_type type; 338 enum regex_type type = MATCH_FULL;
337 int not; 339 int not = 0;
338 340
339 type = filter_parse_regex(r->pattern, r->len, &search, &not); 341 if (pred->op == OP_GLOB) {
340 dup = kstrdup(search, GFP_KERNEL); 342 type = filter_parse_regex(r->pattern, r->len, &search, &not);
341 if (!dup) 343 r->len = strlen(search);
342 return -ENOMEM; 344 memmove(r->pattern, search, r->len+1);
343 345 }
344 strcpy(r->pattern, dup);
345 kfree(dup);
346
347 r->len = strlen(r->pattern);
348 346
349 switch (type) { 347 switch (type) {
350 case MATCH_FULL: 348 case MATCH_FULL:
@@ -362,8 +360,6 @@ static int filter_build_regex(struct filter_pred *pred)
362 } 360 }
363 361
364 pred->not ^= not; 362 pred->not ^= not;
365
366 return 0;
367} 363}
368 364
369/* return 1 if event matches, 0 otherwise (discard) */ 365/* return 1 if event matches, 0 otherwise (discard) */
@@ -676,7 +672,10 @@ static bool is_string_field(struct ftrace_event_field *field)
676 672
677static int is_legal_op(struct ftrace_event_field *field, int op) 673static int is_legal_op(struct ftrace_event_field *field, int op)
678{ 674{
679 if (is_string_field(field) && (op != OP_EQ && op != OP_NE)) 675 if (is_string_field(field) &&
676 (op != OP_EQ && op != OP_NE && op != OP_GLOB))
677 return 0;
678 if (!is_string_field(field) && op == OP_GLOB)
680 return 0; 679 return 0;
681 680
682 return 1; 681 return 1;
@@ -761,15 +760,13 @@ static int filter_add_pred(struct filter_parse_state *ps,
761 } 760 }
762 761
763 if (is_string_field(field)) { 762 if (is_string_field(field)) {
764 ret = filter_build_regex(pred); 763 filter_build_regex(pred);
765 if (ret)
766 return ret;
767 764
768 if (field->filter_type == FILTER_STATIC_STRING) { 765 if (field->filter_type == FILTER_STATIC_STRING) {
769 fn = filter_pred_string; 766 fn = filter_pred_string;
770 pred->regex.field_len = field->size; 767 pred->regex.field_len = field->size;
771 } else if (field->filter_type == FILTER_DYN_STRING) 768 } else if (field->filter_type == FILTER_DYN_STRING)
772 fn = filter_pred_strloc; 769 fn = filter_pred_strloc;
773 else { 770 else {
774 fn = filter_pred_pchar; 771 fn = filter_pred_pchar;
775 pred->regex.field_len = strlen(pred->regex.pattern); 772 pred->regex.field_len = strlen(pred->regex.pattern);