'\" t
.\" Title: libtracefs
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 01/17/2023
.\" Manual: libtracefs Manual
.\" Source: libtracefs 1.6.4
.\" Language: English
.\"
.TH "LIBTRACEFS" "3" "01/17/2023" "libtracefs 1\&.6\&.4" "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