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 | |
| 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')
| -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) |
