ftrace: Support full glob matching
Subsystems (3)
Masami Hiramatsu
maintainerPATCH 1/1 ftrace: Support full glob matching
Use glob_match() to support flexible glob wildcards (*,?) and character classes ([) for ftrace.
Since the full glob matching is slower than the current partial matching routines(*pat, pat*, *pat*), this leaves those routines and just add MATCH_GLOB for complex glob expression.
e.g.
----
[root@localhost tracing]# echo 'sched*group' > set_ftrace_filter [root@localhost tracing]# cat set_ftrace_filter sched_free_groupsched_change_groupsched_create_groupsched_online_groupsched_destroy_groupsched_offline_group
[root@localhost tracing]# echo '[Ss]y[Ss]_*' > set_ftrace_filter [root@localhost tracing]# head set_ftrace_filter sys_arch_prctlsys_rt_sigreturnsys_iopermSyS_ioplsys_modify_ldtSyS_mmapSyS_set_thread_areaSyS_get_thread_areaSyS_set_tid_addresssys_fork
----
--- Documentation/trace/events.txt | 9 +++------ Documentation/trace/ftrace.txt | 9 +++------ kernel/trace/Kconfig | 2 ++ kernel/trace/ftrace.c | 4 ++++ kernel/trace/trace.c | 2 +- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events_filter.c | 17 ++++++++++++++++- 7 files changed, 31 insertions(+), 14 deletions(-)
Documentation/trace/events.txt +3 -6
@@ -189,16 +189,13 @@ And for string fields they are: ==, !=, ~ -The glob (~) only accepts a wild card character (*) at the start and or -end of the string. For example: +The glob (~) accepts a wild card character (*,?) and character classes +([). For example: prev_comm ~ "*sh" prev_comm ~ "sh*" prev_comm ~ "*sh*" - -But does not allow for it to be within the string: - - prev_comm ~ "ba*sh" <-- is invalid + prev_comm ~ "ba*sh" 5.2 Setting filters -------------------
Documentation/trace/ftrace.txt +3 -6
@@ -2218,16 +2218,13 @@ hrtimer_interrupt sys_nanosleep -Perhaps this is not enough. The filters also allow simple wild -cards. Only the following are currently available +Perhaps this is not enough. The filters also allow glob(7) matching. <match>* - will match functions that begin with <match> *<match> - will match functions that end with <match> *<match>* - will match functions that have <match> in it - -These are the only wild cards which are supported. - - <match>*<match> will not work. + <match1>*<match2> - will match functions that begin with + <match1> and end with <match2> Note: It is better to use quotes to enclose the wild cards, otherwise the shell may expand the parameters into names
kernel/trace/Kconfig +2 -0
@@ -70,6 +70,7 @@ config FTRACE_NMI_ENTER config EVENT_TRACING select CONTEXT_SWITCH_TRACER + select GLOB bool config CONTEXT_SWITCH_TRACER
@@ -133,6 +134,7 @@ config FUNCTION_TRACER select KALLSYMS select GENERIC_TRACER select CONTEXT_SWITCH_TRACER + select GLOB help Enable the kernel to trace every kernel function. This is done by using a compiler feature to insert a small, 5-byte No-Operation
kernel/trace/ftrace.c +4 -0
@@ -3493,6 +3493,10 @@ static int ftrace_match(char *str, struct ftrace_glob *g) memcmp(str + slen - g->len, g->search, g->len) == 0) matched =1 ;break ; +case MATCH_GLOB : +if (glob_match (g->search, str)) + matched =1 ; +break ; }return matched;
kernel/trace/trace.c +1 -1
@@ -4065,7 +4065,7 @@ static const char readme_msg[] ="\n available_filter_functions - list of functions that can be filtered on\n" " set_ftrace_filter\t- echo function name in here to only trace these\n" "\t\t\t functions\n" -"\t accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" +"\t accepts: func_full_name or glob-matching-pattern\n" "\t modules: Can select a group via module\n" "\t Format: :mod:<module-name>\n" "\t example: echo :mod:ext3 > set_ftrace_filter\n"
kernel/trace/trace.h +2 -0
@@ -15,6 +15,7 @@#include <linux/trace_events.h> #include <linux/compiler.h> #include <linux/trace_seq.h> +#include <linux/glob.h> #ifdef CONFIG_FTRACE_SYSCALLS #include <asm/unistd.h> /* For NR_SYSCALLS */
@@ -1252,6 +1253,7 @@ enum regex_type {MATCH_FRONT_ONLY ,MATCH_MIDDLE_ONLY ,MATCH_END_ONLY , + MATCH_GLOB, }; struct regex {
kernel/trace/trace_events_filter.c +16 -1
@@ -344,6 +344,12 @@ static int regex_match_end(char *str, struct regex *r, int len)return 0 ; } +static int regex_match_glob (char *str,struct regex *r,int len__maybe_unused ) +{ +if (glob_match (r->pattern, str)) +return 1 ; +return 0 ; +}/** * filter_parse_regex - parse a basic regex * @buff: the raw regex
@@ -380,14 +386,20 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)if (!i) { *search = buff +1 ; type =MATCH_END_ONLY ; - }else { + }else if (i == len -1 ) {if (type ==MATCH_END_ONLY ) type =MATCH_MIDDLE_ONLY ;else type =MATCH_FRONT_ONLY ; buff[i] =0 ;break ; + }else {/* pattern continues, use full glob */ + type =MATCH_GLOB ; +break ; } + }else if (strchr ("[?\\" , buff[i])) { + type =MATCH_GLOB ; +break ; } }
@@ -420,6 +432,9 @@ static void filter_build_regex(struct filter_pred *pred)case MATCH_END_ONLY : r->match = regex_match_end;break ; +case MATCH_GLOB : + r->match = regex_match_glob; +break ; } pred->not ^= not;
Steven Rostedt
maintainerQuoted 31 lines · On Wed, 5 Oct 2016 20:58:15 +0900 Masami Hiramatsu <[email protected]> wrote:
Use
glob_match()to support flexible glob wildcards (*,?) and character classes ([) for ftrace.
Since the full glob matching is slower than the current partial matchingroutines(*pat, pat*, *pat*), this leaves those routines and just addMATCH_GLOBfor complex glob expression.e.g.
----
[root@localhost tracing]# echo 'sched*group' >set_ftrace_filter[root@localhost tracing]# catset_ftrace_filtersched_free_groupsched_change_groupsched_create_groupsched_online_groupsched_destroy_groupsched_offline_group
[root@localhost tracing]# echo '[Ss]y[Ss]_*' >set_ftrace_filter[root@localhost tracing]# headset_ftrace_filtersys_arch_prctlsys_rt_sigreturnsys_iopermSyS_ioplsys_modify_ldtSyS_mmapSyS_set_thread_areaSyS_get_thread_areaSyS_set_tid_addresssys_fork
----
Quoted 1 line
Signed-off-by Masami Hiramatsu <[email protected]>
Nice! Although, I probably wont get to look at this till I get back from Berlin. Please send me a friendly "ping" on the 17th.
I'll still add it to my new "todo" folder. Since, just marking patches in my inbox as todo hasn't been working out for me, I've created a separate folder for ftrace patches.
Thanks!
-- Steve
Masami Hiramatsu
maintainerQuoted 34 lines · On Wed, 5 Oct 2016 09:36:35 -0400 Steven Rostedt <[email protected]> wrote:
Quoted 31 lines · On Wed, 5 Oct 2016 20:58:15 +0900 Masami Hiramatsu <[email protected]> wrote:
Use
glob_match()to support flexible glob wildcards (*,?) and character classes ([) for ftrace.
Since the full glob matching is slower than the current partial matchingroutines(*pat, pat*, *pat*), this leaves those routines and just addMATCH_GLOBfor complex glob expression.e.g.
----
[root@localhost tracing]# echo 'sched*group' >set_ftrace_filter[root@localhost tracing]# catset_ftrace_filtersched_free_groupsched_change_groupsched_create_groupsched_online_groupsched_destroy_groupsched_offline_group
[root@localhost tracing]# echo '[Ss]y[Ss]_*' >set_ftrace_filter[root@localhost tracing]# headset_ftrace_filtersys_arch_prctlsys_rt_sigreturnsys_iopermSyS_ioplsys_modify_ldtSyS_mmapSyS_set_thread_areaSyS_get_thread_areaSyS_set_tid_addresssys_fork
----
Quoted 4 lines
Quoted 1 line
Signed-off-by Masami Hiramatsu <[email protected]>Nice! Although, I probably wont get to look at this till I get back from Berlin. Please send me a friendly "ping" on the 17th.
OK, I'm also considering update ftracetest too for recent features. Maybe I would better make a series including this.
Quoted 3 lines
I'll still add it to my new "todo" folder. Since, just marking patches in my inbox as todo hasn't been working out for me, I've created a separate folder for ftrace patches.
:)
Thanks!
Quoted 4 lines
Thanks!
-- Steve
Signature · 1 line
Masami Hiramatsu <[email protected]>
Hi Masami,
Quoted 31 lines · Masami Hiramatsu
Use
glob_match()to support flexible glob wildcards (*,?) and character classes ([) for ftrace.
Since the full glob matching is slower than the current partial matchingroutines(*pat, pat*, *pat*), this leaves those routines and just addMATCH_GLOBfor complex glob expression.e.g.
----
[root@localhost tracing]# echo 'sched*group' >set_ftrace_filter[root@localhost tracing]# catset_ftrace_filtersched_free_groupsched_change_groupsched_create_groupsched_online_groupsched_destroy_groupsched_offline_group
[root@localhost tracing]# echo '[Ss]y[Ss]_*' >set_ftrace_filter[root@localhost tracing]# headset_ftrace_filtersys_arch_prctlsys_rt_sigreturnsys_iopermSyS_ioplsys_modify_ldtSyS_mmapSyS_set_thread_areaSyS_get_thread_areaSyS_set_tid_addresssys_fork
----
Quoted 1 line
Signed-off-by Masami Hiramatsu <[email protected]>
Nice!
Thanks,
Namhyung
Quoted 176 lines
--- Documentation/trace/events.txt | 9 +++------ Documentation/trace/ftrace.txt | 9 +++------ kernel/trace/Kconfig | 2 ++ kernel/trace/ftrace.c | 4 ++++ kernel/trace/trace.c | 2 +- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events_filter.c | 17 ++++++++++++++++- 7 files changed, 31 insertions(+), 14 deletions(-)Documentation/trace/events.txt +3
-6@@ -189,16 +189,13 @@ And for string fields they are: ==, !=, ~ -The glob (~) only accepts a wild card character (*) at the start and or -end of the string. For example: +The glob (~) accepts a wild card character (*,?) and character classes +([). For example: prev_comm ~ "*sh" prev_comm ~ "sh*" prev_comm ~ "*sh*" - -But does not allow for it to be within the string: - - prev_comm ~ "ba*sh" <-- is invalid + prev_comm ~ "ba*sh" 5.2 Setting filters -------------------Documentation/trace/ftrace.txt +3
-6@@ -2218,16 +2218,13 @@ hrtimer_interrupt sys_nanosleep -Perhaps this is not enough. The filters also allow simple wild -cards. Only the following are currently available +Perhaps this is not enough. The filters also allow glob(7) matching. <match>* - will match functions that begin with <match> *<match> - will match functions that end with <match> *<match>* - will match functions that have <match> in it - -These are the only wild cards which are supported. - - <match>*<match> will not work. + <match1>*<match2> - will match functions that begin with + <match1> and end with <match2> Note: It is better to use quotes to enclose the wild cards, otherwise the shell may expand the parameters into nameskernel/trace/Kconfig +2
-0@@ -70,6 +70,7 @@ config FTRACE_NMI_ENTER config EVENT_TRACING select CONTEXT_SWITCH_TRACER + select GLOB bool config CONTEXT_SWITCH_TRACER@@ -133,6 +134,7 @@ config FUNCTION_TRACER select KALLSYMS select GENERIC_TRACER select CONTEXT_SWITCH_TRACER + select GLOB help Enable the kernel to trace every kernel function. This is done by using a compiler feature to insert a small, 5-byte No-Operationkernel/trace/ftrace.c +4
-0@@ -3493,6 +3493,10 @@ static int ftrace_match(char *str, struct ftrace_glob *g) memcmp(str + slen - g->len, g->search, g->len) == 0) matched =1 ;break ; +case MATCH_GLOB : +if (glob_match (g->search, str)) + matched =1 ; +break ; }return matched;kernel/trace/trace.c +1
-1@@ -4065,7 +4065,7 @@ static const char readme_msg[] ="\n available_filter_functions - list of functions that can be filtered on\n" " set_ftrace_filter\t- echo function name in here to only trace these\n" "\t\t\t functions\n" -"\t accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" +"\t accepts: func_full_name or glob-matching-pattern\n" "\t modules: Can select a group via module\n" "\t Format: :mod:<module-name>\n" "\t example: echo :mod:ext3 > set_ftrace_filter\n" kernel/trace/trace.h +2
-0@@ -15,6 +15,7 @@#include <linux/trace_events.h> #include <linux/compiler.h> #include <linux/trace_seq.h> +#include <linux/glob.h> #ifdef CONFIG_FTRACE_SYSCALLS #include <asm/unistd.h> /* For NR_SYSCALLS */ @@ -1252,6 +1253,7 @@ enum regex_type {MATCH_FRONT_ONLY ,MATCH_MIDDLE_ONLY ,MATCH_END_ONLY , + MATCH_GLOB, }; struct regex {kernel/trace/trace_events_filter.c +16
-1@@ -344,6 +344,12 @@ static int regex_match_end(char *str, struct regex *r, int len)return 0 ; } +static int regex_match_glob (char *str,struct regex *r,int len__maybe_unused ) +{ +if (glob_match (r->pattern, str)) +return 1 ; +return 0 ; +}/** * filter_parse_regex - parse a basic regex * @buff: the raw regex @@ -380,14 +386,20 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)if (!i) { *search = buff +1 ; type =MATCH_END_ONLY ; - }else { + }else if (i == len -1 ) {if (type ==MATCH_END_ONLY ) type =MATCH_MIDDLE_ONLY ;else type =MATCH_FRONT_ONLY ; buff[i] =0 ;break ; + }else {/* pattern continues, use full glob */ + type =MATCH_GLOB ; +break ; } + }else if (strchr ("[?\\" , buff[i])) { + type =MATCH_GLOB ; +break ; } }@@ -420,6 +432,9 @@ static void filter_build_regex(struct filter_pred *pred)case MATCH_END_ONLY : r->match = regex_match_end;break ; +case MATCH_GLOB : + r->match = regex_match_glob; +break ; } pred->not ^= not;
Steven Rostedt
maintainerShuah,
Hi! I'm going to be pulling these patches into my tree, but since they touch selftests, can you take a look at them. They were posted to LKML, but if you need me to bounce them to you too, I can do that as well.
Here's the links of the patches with the selftests:
http://lkml.kernel.org/r/147685282642.8760.554191165644931816.stgit@devbox
http://lkml.kernel.org/r/147685283587.8760.2601950190140526395.stgit@devbox
http://lkml.kernel.org/r/147685284503.8760.3870499047839781698.stgit@devbox
http://lkml.kernel.org/r/147685285432.8760.9114124487704649863.stgit@devbox
I'm still in the process of reviewing them myself.
-- Steve
Quoted 207 lines · On Wed, 5 Oct 2016 20:58:15 +0900 Masami Hiramatsu <[email protected]> wrote:
Use
glob_match()to support flexible glob wildcards (*,?) and character classes ([) for ftrace.
Since the full glob matching is slower than the current partial matchingroutines(*pat, pat*, *pat*), this leaves those routines and just addMATCH_GLOBfor complex glob expression.e.g.
----
[root@localhost tracing]# echo 'sched*group' >set_ftrace_filter[root@localhost tracing]# catset_ftrace_filtersched_free_groupsched_change_groupsched_create_groupsched_online_groupsched_destroy_groupsched_offline_group
[root@localhost tracing]# echo '[Ss]y[Ss]_*' >set_ftrace_filter[root@localhost tracing]# headset_ftrace_filtersys_arch_prctlsys_rt_sigreturnsys_iopermSyS_ioplsys_modify_ldtSyS_mmapSyS_set_thread_areaSyS_get_thread_areaSyS_set_tid_addresssys_fork
----Signed-off-by Masami Hiramatsu <[email protected]>--- Documentation/trace/events.txt | 9 +++------ Documentation/trace/ftrace.txt | 9 +++------ kernel/trace/Kconfig | 2 ++ kernel/trace/ftrace.c | 4 ++++ kernel/trace/trace.c | 2 +- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events_filter.c | 17 ++++++++++++++++- 7 files changed, 31 insertions(+), 14 deletions(-)Documentation/trace/events.txt +3
-6@@ -189,16 +189,13 @@ And for string fields they are: ==, !=, ~ -The glob (~) only accepts a wild card character (*) at the start and or -end of the string. For example: +The glob (~) accepts a wild card character (*,?) and character classes +([). For example: prev_comm ~ "*sh" prev_comm ~ "sh*" prev_comm ~ "*sh*" - -But does not allow for it to be within the string: - - prev_comm ~ "ba*sh" <-- is invalid + prev_comm ~ "ba*sh" 5.2 Setting filters -------------------Documentation/trace/ftrace.txt +3
-6@@ -2218,16 +2218,13 @@ hrtimer_interrupt sys_nanosleep -Perhaps this is not enough. The filters also allow simple wild -cards. Only the following are currently available +Perhaps this is not enough. The filters also allow glob(7) matching. <match>* - will match functions that begin with <match> *<match> - will match functions that end with <match> *<match>* - will match functions that have <match> in it - -These are the only wild cards which are supported. - - <match>*<match> will not work. + <match1>*<match2> - will match functions that begin with + <match1> and end with <match2> Note: It is better to use quotes to enclose the wild cards, otherwise the shell may expand the parameters into nameskernel/trace/Kconfig +2
-0@@ -70,6 +70,7 @@ config FTRACE_NMI_ENTER config EVENT_TRACING select CONTEXT_SWITCH_TRACER + select GLOB bool config CONTEXT_SWITCH_TRACER@@ -133,6 +134,7 @@ config FUNCTION_TRACER select KALLSYMS select GENERIC_TRACER select CONTEXT_SWITCH_TRACER + select GLOB help Enable the kernel to trace every kernel function. This is done by using a compiler feature to insert a small, 5-byte No-Operationkernel/trace/ftrace.c +4
-0@@ -3493,6 +3493,10 @@ static int ftrace_match(char *str, struct ftrace_glob *g) memcmp(str + slen - g->len, g->search, g->len) == 0) matched =1 ;break ; +case MATCH_GLOB : +if (glob_match (g->search, str)) + matched =1 ; +break ; }return matched;kernel/trace/trace.c +1
-1@@ -4065,7 +4065,7 @@ static const char readme_msg[] ="\n available_filter_functions - list of functions that can be filtered on\n" " set_ftrace_filter\t- echo function name in here to only trace these\n" "\t\t\t functions\n" -"\t accepts: func_full_name, *func_end, func_begin*, *func_middle*\n" +"\t accepts: func_full_name or glob-matching-pattern\n" "\t modules: Can select a group via module\n" "\t Format: :mod:<module-name>\n" "\t example: echo :mod:ext3 > set_ftrace_filter\n" kernel/trace/trace.h +2
-0@@ -15,6 +15,7 @@#include <linux/trace_events.h> #include <linux/compiler.h> #include <linux/trace_seq.h> +#include <linux/glob.h> #ifdef CONFIG_FTRACE_SYSCALLS #include <asm/unistd.h> /* For NR_SYSCALLS */ @@ -1252,6 +1253,7 @@ enum regex_type {MATCH_FRONT_ONLY ,MATCH_MIDDLE_ONLY ,MATCH_END_ONLY , + MATCH_GLOB, }; struct regex {kernel/trace/trace_events_filter.c +16
-1@@ -344,6 +344,12 @@ static int regex_match_end(char *str, struct regex *r, int len)return 0 ; } +static int regex_match_glob (char *str,struct regex *r,int len__maybe_unused ) +{ +if (glob_match (r->pattern, str)) +return 1 ; +return 0 ; +}/** * filter_parse_regex - parse a basic regex * @buff: the raw regex @@ -380,14 +386,20 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)if (!i) { *search = buff +1 ; type =MATCH_END_ONLY ; - }else { + }else if (i == len -1 ) {if (type ==MATCH_END_ONLY ) type =MATCH_MIDDLE_ONLY ;else type =MATCH_FRONT_ONLY ; buff[i] =0 ;break ; + }else {/* pattern continues, use full glob */ + type =MATCH_GLOB ; +break ; } + }else if (strchr ("[?\\" , buff[i])) { + type =MATCH_GLOB ; +break ; } }@@ -420,6 +432,9 @@ static void filter_build_regex(struct filter_pred *pred)case MATCH_END_ONLY : r->match = regex_match_end;break ; +case MATCH_GLOB : + r->match = regex_match_glob; +break ; } pred->not ^= not;