diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-12-15 10:32:10 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-12-15 14:22:03 -0500 |
commit | bbbb521bc61008b280c72ad6e29a8a7558d3acfa (patch) | |
tree | c4abf43779dd0380cb514b52b0ce0047c5f1cf8e /tools/perf | |
parent | adf365f486280e4577c9eabd7d8e118e5994a03e (diff) |
perf probe: Add glob matching support on --del
Add glob-expression matching support on --del option.
You can use wildcards for specifying deleting events.
e.g.
Clear all probe events:
# perf probe --del '*'
Clear probes on schedule():
# perf probe --del 'schedule*'
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: systemtap <systemtap@sources.redhat.com>
Cc: DLE <dle-develop@lists.sourceforge.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20091215153210.17436.12327.stgit@dhcp-100-2-132.bos.redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/probe-event.c | 52 | ||||
-rw-r--r-- | tools/perf/util/string.c | 25 | ||||
-rw-r--r-- | tools/perf/util/string.h | 2 |
3 files changed, 66 insertions, 13 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 3e30be928101..5e99e52b0179 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -532,26 +532,50 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes) | |||
532 | close(fd); | 532 | close(fd); |
533 | } | 533 | } |
534 | 534 | ||
535 | static void __del_trace_kprobe_event(int fd, struct str_node *ent) | ||
536 | { | ||
537 | char *p; | ||
538 | char buf[128]; | ||
539 | |||
540 | /* Convert from perf-probe event to trace-kprobe event */ | ||
541 | if (e_snprintf(buf, 128, "-:%s", ent->s) < 0) | ||
542 | die("Failed to copy event."); | ||
543 | p = strchr(buf + 2, ':'); | ||
544 | if (!p) | ||
545 | die("Internal error: %s should have ':' but not.", ent->s); | ||
546 | *p = '/'; | ||
547 | |||
548 | write_trace_kprobe_event(fd, buf); | ||
549 | printf("Remove event: %s\n", ent->s); | ||
550 | } | ||
551 | |||
535 | static void del_trace_kprobe_event(int fd, const char *group, | 552 | static void del_trace_kprobe_event(int fd, const char *group, |
536 | const char *event, struct strlist *namelist) | 553 | const char *event, struct strlist *namelist) |
537 | { | 554 | { |
538 | char buf[128]; | 555 | char buf[128]; |
539 | struct str_node *ent; | 556 | struct str_node *ent, *n; |
557 | int found = 0; | ||
540 | 558 | ||
541 | if (e_snprintf(buf, 128, "%s:%s", group, event) < 0) | 559 | if (e_snprintf(buf, 128, "%s:%s", group, event) < 0) |
542 | die("Failed to copy event."); | 560 | die("Failed to copy event."); |
543 | ent = strlist__find(namelist, buf); | ||
544 | if (!ent) { | ||
545 | pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); | ||
546 | return; | ||
547 | } | ||
548 | /* Convert from perf-probe event to trace-kprobe event */ | ||
549 | if (e_snprintf(buf, 128, "-:%s/%s", group, event) < 0) | ||
550 | die("Failed to copy event."); | ||
551 | 561 | ||
552 | write_trace_kprobe_event(fd, buf); | 562 | if (strpbrk(buf, "*?")) { /* Glob-exp */ |
553 | printf("Remove event: %s:%s\n", group, event); | 563 | strlist__for_each_safe(ent, n, namelist) |
554 | strlist__remove(namelist, ent); | 564 | if (strglobmatch(ent->s, buf)) { |
565 | found++; | ||
566 | __del_trace_kprobe_event(fd, ent); | ||
567 | strlist__remove(namelist, ent); | ||
568 | } | ||
569 | } else { | ||
570 | ent = strlist__find(namelist, buf); | ||
571 | if (ent) { | ||
572 | found++; | ||
573 | __del_trace_kprobe_event(fd, ent); | ||
574 | strlist__remove(namelist, ent); | ||
575 | } | ||
576 | } | ||
577 | if (found == 0) | ||
578 | pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); | ||
555 | } | 579 | } |
556 | 580 | ||
557 | void del_trace_kprobe_events(struct strlist *dellist) | 581 | void del_trace_kprobe_events(struct strlist *dellist) |
@@ -570,15 +594,17 @@ void del_trace_kprobe_events(struct strlist *dellist) | |||
570 | str = strdup(ent->s); | 594 | str = strdup(ent->s); |
571 | if (!str) | 595 | if (!str) |
572 | die("Failed to copy event."); | 596 | die("Failed to copy event."); |
597 | pr_debug("Parsing: %s\n", str); | ||
573 | p = strchr(str, ':'); | 598 | p = strchr(str, ':'); |
574 | if (p) { | 599 | if (p) { |
575 | group = str; | 600 | group = str; |
576 | *p = '\0'; | 601 | *p = '\0'; |
577 | event = p + 1; | 602 | event = p + 1; |
578 | } else { | 603 | } else { |
579 | group = PERFPROBE_GROUP; | 604 | group = "*"; |
580 | event = str; | 605 | event = str; |
581 | } | 606 | } |
607 | pr_debug("Group: %s, Event: %s\n", group, event); | ||
582 | del_trace_kprobe_event(fd, group, event, namelist); | 608 | del_trace_kprobe_event(fd, group, event, namelist); |
583 | free(str); | 609 | free(str); |
584 | } | 610 | } |
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index f24a8cc933d5..5352d7dccc61 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -226,3 +226,28 @@ fail: | |||
226 | argv_free(argv); | 226 | argv_free(argv); |
227 | return NULL; | 227 | return NULL; |
228 | } | 228 | } |
229 | |||
230 | /* Glob expression pattern matching */ | ||
231 | bool strglobmatch(const char *str, const char *pat) | ||
232 | { | ||
233 | while (*str && *pat && *pat != '*') { | ||
234 | if (*pat == '?') { | ||
235 | str++; | ||
236 | pat++; | ||
237 | } else | ||
238 | if (*str++ != *pat++) | ||
239 | return false; | ||
240 | } | ||
241 | /* Check wild card */ | ||
242 | if (*pat == '*') { | ||
243 | while (*pat == '*') | ||
244 | pat++; | ||
245 | if (!*pat) /* Tail wild card matches all */ | ||
246 | return true; | ||
247 | while (*str) | ||
248 | if (strglobmatch(str++, pat)) | ||
249 | return true; | ||
250 | } | ||
251 | return !*str && !*pat; | ||
252 | } | ||
253 | |||
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h index bfecec265a1a..02ede58c54b4 100644 --- a/tools/perf/util/string.h +++ b/tools/perf/util/string.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __PERF_STRING_H_ | 1 | #ifndef __PERF_STRING_H_ |
2 | #define __PERF_STRING_H_ | 2 | #define __PERF_STRING_H_ |
3 | 3 | ||
4 | #include <stdbool.h> | ||
4 | #include "types.h" | 5 | #include "types.h" |
5 | 6 | ||
6 | int hex2u64(const char *ptr, u64 *val); | 7 | int hex2u64(const char *ptr, u64 *val); |
@@ -8,6 +9,7 @@ char *strxfrchar(char *s, char from, char to); | |||
8 | s64 perf_atoll(const char *str); | 9 | s64 perf_atoll(const char *str); |
9 | char **argv_split(const char *str, int *argcp); | 10 | char **argv_split(const char *str, int *argcp); |
10 | void argv_free(char **argv); | 11 | void argv_free(char **argv); |
12 | bool strglobmatch(const char *str, const char *pat); | ||
11 | 13 | ||
12 | #define _STR(x) #x | 14 | #define _STR(x) #x |
13 | #define STR(x) _STR(x) | 15 | #define STR(x) _STR(x) |