'\" t .\" Title: libtracefs .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 10/08/2022 .\" Manual: libtracefs Manual .\" Source: libtracefs 1.5.0 .\" Language: English .\" .TH "LIBTRACEFS" "3" "10/08/2022" "libtracefs 1\&.5\&.0" "libtracefs Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" tracefs_filter_string_append, tracefs_filter_string_verify, tracefs_event_filter_apply, tracefs_event_filter_clear \- Add, verify and apply event filters .SH "SYNOPSIS" .sp .nf \fB#include \fR int \fBtracefs_filter_string_append\fR(struct tep_event *\fIevent\fR, char **\fIfilter\fR, struct tracefs_filter \fItype\fR, const char *\fIfield\fR, enum tracefs_synth_compare \fIcompare\fR, const char *\fIval\fR); int \fBtracefs_filter_string_verify\fR(struct tep_event *\fIevent\fR, const char *\fIfilter\fR, char **\fIerr\fR); int \fBtracefs_event_filter_apply\fR(struct tracefs_instance *\fIinstance\fR, struct tep_event *\fIevent\fR, const char *\fIfilter\fR); int \fBtracefs_event_filter_clear\fR(struct tracefs_instance *\fIinstance\fR, struct tep_event *\fIevent\fR); .fi .SH "DESCRIPTION" .sp \fBtracefs_filter_string_append\fR() is a way to create and verify event filters for a given event\&. It will verify that the \fIfield\fR belongs to the event and that the \fIcompare\fR option that is used is valid for the type of the field, as well as \fIval\fR\&. For the \fItype\fR that is not of \fBTRACEFS_FILTER_COMPARE\fR, it will build the logical string and also make sure that the syntax is correct\&. For example, there are no more close parenthesis than open parenthesis\&. An AND (&&) or OR (||) is not misplaced, etc\&. .sp \fBtracefs_synth_append_start_filter\fR() creates a filter or appends to it for the starting event\&. Depending on \fItype\fR, it will build a string of tokens for parenthesis or logic statemens, or it may add a comparison of \fIfield\fR to \fIval\fR based on \fIcompare\fR\&. .sp If \fItype\fR is: \fBTRACEFS_FILTER_COMPARE\fR \- See below \fBTRACEFS_FILTER_AND\fR \- Append "&&" to the filter \fBTRACEFS_FILTER_OR\fR \- Append "||" to the filter \fBTRACEFS_FILTER_NOT\fR \- Append "!" to the filter \fBTRACEFS_FILTER_OPEN_PAREN\fR \- Append "(" to the filter \fBTRACEFS_FILTER_CLOSE_PAREN\fR \- Append ")" to the filter .sp \fIfield\fR, \fIcompare\fR, and \fIval\fR are ignored unless \fItype\fR is equal to \fBTRACEFS_FILTER_COMPARE\fR, then _compare will be used for the following: .sp \fBTRACEFS_COMPARE_EQ\fR \- \fIfield\fR == \fIval\fR .sp \fBTRACEFS_COMPARE_NE\fR \- \fIfield\fR != \fIval\fR .sp \fBTRACEFS_COMPARE_GT\fR \- \fIfield\fR > \fIval\fR .sp \fBTRACEFS_COMPARE_GE\fR \- \fIfield\fR >= \fIval\fR .sp \fBTRACEFS_COMPARE_LT\fR \- \fIfield\fR < \fIval\fR .sp \fBTRACEFS_COMPARE_LE\fR \- \fIfield\fR <= \fIval\fR .sp \fBTRACEFS_COMPARE_RE\fR \- \fIfield\fR ~ "\fIval\fR" : where \fIfield\fR is a string\&. .sp \fBTRACEFS_COMPARE_AND\fR \- \fIfield\fR & \fIval\fR : where \fIfield\fR is a flags field\&. .sp \fBtracefs_filter_string_verify\fR() will parse \fIfilter\fR to make sure that the fields are for the \fIevent\fR, and that the syntax is correct\&. If there\(cqs an error in the syntax, and \fIerr\fR is not NULL, then it will be allocated with an error message stating what was found wrong with the filter\&. \fIerr\fR must be freed with \fBfree\fR()\&. .sp \fBtracefs_event_filter_apply\fR() applies given \fIfilter\fR string on \fIevent\fR in given \fIinstance\fR\&. .sp \fBtracefs_event_filter_clear\fR() clear all filters on \fIevent\fR in given \fIinstance\fR\&. .SH "RETURN VALUE" .sp \fBtracefs_filter_string_append\fR() returns 0 on success and \-1 on error\&. .sp \fBtracefs_filter_string_verify\fR() returns 0 on success and \-1 on error\&. if there is an error, and \fIerrno\fR is not \fBENOMEM\fR, then \fIerr\fR is allocated and will contain a string describing what was found wrong with \fIfilter\fR\&. \fIerr\fR must be freed with \fBfree\fR()\&. .sp \fBtracefs_event_filter_apply\fR() returns 0 on success and \-1 on error\&. .sp \fBtracefs_event_filter_clear\fR() returns 0 on success and \-1 on error\&. .SH "EXAMPLE" .sp .if n \{\ .RS 4 .\} .nf #include #include #include #include static void usage(char **argv) { fprintf(stderr, "usage: %s [system] event filter\en", argv[0]); exit(\-1); } int main (int argc, char **argv) { struct tep_handle *tep; struct tep_event *event; const char *system = NULL; const char *event_name; const char *filter; char *new_filter = NULL; char *err = NULL; int i; if (argc < 3) usage(argv); if (argc < 4) { event_name = argv[1]; filter = argv[2]; } else { system = argv[1]; event_name = argv[2]; filter = argv[3]; } /* Load all events from the system */ tep = tracefs_local_events(NULL); if (!tep) { perror("tep"); exit(\-1); } event = tep_find_event_by_name(tep, system, event_name); if (!event) { fprintf(stderr, "Event %s%s%s not found\en", system ? system : "" , system ? " " : "", event_name); exit(\-1); } if (tracefs_filter_string_verify(event, filter, &err) < 0) { perror("tracecfs_event_verify_filter"); if (err) fprintf(stderr, "%s", err); free(err); exit(\-1); } for (i = 0; filter[i]; i++) { char buf[strlen(filter)]; char *field = NULL; char *val = NULL; enum tracefs_filter type; enum tracefs_compare compare = 0; int start_i, n; int quote; bool backslash; while (isspace(filter[i])) i++; switch(filter[i]) { case \*(Aq(\*(Aq: type = TRACEFS_FILTER_OPEN_PAREN; break; case \*(Aq)\*(Aq: type = TRACEFS_FILTER_CLOSE_PAREN; break; case \*(Aq!\*(Aq: type = TRACEFS_FILTER_NOT; break; case \*(Aq&\*(Aq: type = TRACEFS_FILTER_AND; i++; break; case \*(Aq|\*(Aq: type = TRACEFS_FILTER_OR; i++; break; default: type = TRACEFS_FILTER_COMPARE; while (isspace(filter[i])) i++; start_i = i; for (; filter[i]; i++) { switch(filter[i]) { case \*(Aqa\*(Aq \&.\&.\&. \*(Aqz\*(Aq: case \*(AqA\*(Aq \&.\&.\&. \*(AqZ\*(Aq: case \*(Aq0\*(Aq \&.\&.\&. \*(Aq9\*(Aq: case \*(Aq_\*(Aq: continue; } break; } n = i \- start_i; field = buf; strncpy(field, filter + start_i, n); field[n++] = \*(Aq\e0\*(Aq; val = buf + n; while (isspace(filter[i])) i++; start_i = i; switch(filter[i++]) { case \*(Aq>\*(Aq: compare = TRACEFS_COMPARE_GT; if (filter[i] == \*(Aq=\*(Aq) { i++; compare = TRACEFS_COMPARE_GE; } break; case \*(Aq<\*(Aq: compare = TRACEFS_COMPARE_LT; if (filter[i] == \*(Aq=\*(Aq) { i++; compare = TRACEFS_COMPARE_LE; } break; case \*(Aq=\*(Aq: compare = TRACEFS_COMPARE_EQ; i++; break; case \*(Aq!\*(Aq: compare = TRACEFS_COMPARE_NE; i++; break; case \*(Aq~\*(Aq: compare = TRACEFS_COMPARE_RE; break; case \*(Aq&\*(Aq: compare = TRACEFS_COMPARE_AND; break; } while (isspace(filter[i])) i++; quote = 0; backslash = false; start_i = i; for (; filter[i]; i++) { if (quote) { if (backslash) backslash = false; else if (filter[i] == \*(Aq\e\e\*(Aq) backslash = true; else if (filter[i] == quote) quote = 0; continue; } switch(filter[i]) { case \*(Aq"\*(Aq: case \*(Aq\e\*(Aq\*(Aq: quote = filter[i]; continue; case \*(Aqa\*(Aq \&.\&.\&. \*(Aqz\*(Aq: case \*(AqA\*(Aq \&.\&.\&. \*(AqZ\*(Aq: case \*(Aq0\*(Aq \&.\&.\&. \*(Aq9\*(Aq: case \*(Aq_\*(Aq: continue; } break; } n = i \- start_i; strncpy(val, filter + start_i, n); val[n] = \*(Aq\e0\*(Aq; break; } n = tracefs_filter_string_append(event, &new_filter, type, field, compare, val); if (n < 0) { fprintf(stderr, "Failed making new filter:\en\*(Aq%s\*(Aq\en", new_filter ? new_filter : "(null)"); exit(\-1); } } if (tracefs_event_filter_apply(NULL, event, new_filter)) fprintf(stderr, "Failed to apply filter on event"); tep_free(tep); printf("Created new filter: \*(Aq%s\*(Aq\en", new_filter); free(new_filter); exit(0); } .fi .if n \{\ .RE .\} .SH "FILES" .sp .if n \{\ .RS 4 .\} .nf \fBtracefs\&.h\fR Header file to include in order to have access to the library APIs\&. \fB\-ltracefs\fR Linker switch to add when building a program that uses the library\&. .fi .if n \{\ .RE .\} .SH "SEE ALSO" .sp \fBlibtracefs\fR(3), \fBlibtraceevent\fR(3), \fBtrace\-cmd\fR(1), \fBtracefs_hist_alloc\fR(3), \fBtracefs_hist_alloc_2d\fR(3), \fBtracefs_hist_alloc_nd\fR(3), \fBtracefs_hist_free\fR(3), \fBtracefs_hist_add_key\fR(3), \fBtracefs_hist_add_value\fR(3), \fBtracefs_hist_add_name\fR(3), \fBtracefs_hist_start\fR(3), \fBtracefs_hist_destory\fR(3), \fBtracefs_hist_add_sort_key\fR(3), \fBtracefs_hist_sort_key_direction\fR(3) .SH "AUTHOR" .sp .if n \{\ .RS 4 .\} .nf \fBSteven Rostedt\fR <\m[blue]\fBrostedt@goodmis\&.org\fR\m[]\&\s-2\u[1]\d\s+2> \fBTzvetomir Stoyanov\fR <\m[blue]\fBtz\&.stoyanov@gmail\&.com\fR\m[]\&\s-2\u[2]\d\s+2> \fBsameeruddin shaik\fR <\m[blue]\fBsameeruddin\&.shaik8@gmail\&.com\fR\m[]\&\s-2\u[3]\d\s+2> .fi .if n \{\ .RE .\} .SH "REPORTING BUGS" .sp Report bugs to <\m[blue]\fBlinux\-trace\-devel@vger\&.kernel\&.org\fR\m[]\&\s-2\u[4]\d\s+2> .SH "LICENSE" .sp libtracefs is Free Software licensed under the GNU LGPL 2\&.1 .SH "RESOURCES" .sp \m[blue]\fBhttps://git\&.kernel\&.org/pub/scm/libs/libtrace/libtracefs\&.git/\fR\m[] .SH "COPYING" .sp Copyright (C) 2020 VMware, Inc\&. Free use of this software is granted under the terms of the GNU Public License (GPL)\&. .SH "NOTES" .IP " 1." 4 rostedt@goodmis.org .RS 4 \%mailto:rostedt@goodmis.org .RE .IP " 2." 4 tz.stoyanov@gmail.com .RS 4 \%mailto:tz.stoyanov@gmail.com .RE .IP " 3." 4 sameeruddin.shaik8@gmail.com .RS 4 \%mailto:sameeruddin.shaik8@gmail.com .RE .IP " 4." 4 linux-trace-devel@vger.kernel.org .RS 4 \%mailto:linux-trace-devel@vger.kernel.org .RE