tracefs_filter_string_append() is a way to create and verify
event filters for a given event. It will verify that the field
belongs to the event and that the compare option that is used is
valid for the type of the field, as well as val. For the type
that is not of TRACEFS_FILTER_COMPARE, 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.
tracefs_synth_append_start_filter() creates a filter or appends
to it for the starting event. Depending on type, it will build a
string of tokens for parenthesis or logic statemens, or it may
add a comparison of field to val based on compare.
If type is: TRACEFS_FILTER_COMPARE - See below TRACEFS_FILTER_AND
- Append "&&" to the filter TRACEFS_FILTER_OR - Append "||" to
the filter TRACEFS_FILTER_NOT - Append "!" to the filter
TRACEFS_FILTER_OPEN_PAREN - Append "(" to the filter
TRACEFS_FILTER_CLOSE_PAREN - Append ")" to the filter
field, compare, and val are ignored unless type is equal to
TRACEFS_FILTER_COMPARE, then _compare will be used for the
following:
TRACEFS_COMPARE_EQ - field == valTRACEFS_COMPARE_NE - field != valTRACEFS_COMPARE_GT - field > valTRACEFS_COMPARE_GE - field >= valTRACEFS_COMPARE_LT - field < valTRACEFS_COMPARE_LE - field <= valTRACEFS_COMPARE_RE - field ~ "val" : where field is a string.
TRACEFS_COMPARE_AND - field & val : where field is a flags field.
tracefs_filter_string_verify() will parse filter to make sure
that the fields are for the event, and that the syntax is
correct. If there’s an error in the syntax, and err is not NULL,
then it will be allocated with an error message stating what was
found wrong with the filter. err must be freed with free().
tracefs_event_filter_apply() applies given filter string on event
in given instance.
tracefs_event_filter_clear() clear all filters on event in given
instance.
ЗНАЧЕНИЕ, ВОЗВРАЩАЕМОЕ ФУНКЦИЕЙ
tracefs_filter_string_append() returns 0 on success and -1 on
error.
tracefs_filter_string_verify() returns 0 on success and -1 on
error. if there is an error, and errno is not ENOMEM, then err is
allocated and will contain a string describing what was found
wrong with filter. err must be freed with free().
tracefs_event_filter_apply() returns 0 on success and -1 on
error.
tracefs_event_filter_clear() returns 0 on success and -1 on
error.
ПРИМЕР
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <tracefs.h>
static void usage(char **argv)
{
fprintf(stderr, "usage: %s [system] event filter\n", 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\n",
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 '(':
type = TRACEFS_FILTER_OPEN_PAREN;
break;
case ')':
type = TRACEFS_FILTER_CLOSE_PAREN;
break;
case '!':
type = TRACEFS_FILTER_NOT;
break;
case '&':
type = TRACEFS_FILTER_AND;
i++;
break;
case '|':
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 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9':
case '_':
continue;
}
break;
}
n = i - start_i;
field = buf;
strncpy(field, filter + start_i, n);
field[n++] = '\0';
val = buf + n;
while (isspace(filter[i]))
i++;
start_i = i;
switch(filter[i++]) {
case '>':
compare = TRACEFS_COMPARE_GT;
if (filter[i] == '=') {
i++;
compare = TRACEFS_COMPARE_GE;
}
break;
case '<':
compare = TRACEFS_COMPARE_LT;
if (filter[i] == '=') {
i++;
compare = TRACEFS_COMPARE_LE;
}
break;
case '=':
compare = TRACEFS_COMPARE_EQ;
i++;
break;
case '!':
compare = TRACEFS_COMPARE_NE;
i++;
break;
case '~':
compare = TRACEFS_COMPARE_RE;
break;
case '&':
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] == '\\')
backslash = true;
else if (filter[i] == quote)
quote = 0;
continue;
}
switch(filter[i]) {
case '"': case '\'':
quote = filter[i];
continue;
case 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9':
case '_':
continue;
}
break;
}
n = i - start_i;
strncpy(val, filter + start_i, n);
val[n] = '\0';
break;
}
n = tracefs_filter_string_append(event, &new_filter, type,
field, compare, val);
if (n < 0) {
fprintf(stderr, "Failed making new filter:\n'%s'\n",
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: '%s'\n", new_filter);
free(new_filter);
exit(0);
}
ФАЙЛЫ
tracefs.h
Header file to include in order to have access to the library APIs.
-ltracefs
Linker switch to add when building a program that uses the library.
This page is part of the libtracefs (Linux kernel trace file
system library) project. Information about the project can be
found at ⟨https://www.trace-cmd.org/⟩. If you have a bug report
for this manual page, see ⟨https://www.trace-cmd.org/⟩. This
page was obtained from the project's upstream Git repository
⟨https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git⟩ on
2024-06-14. (At that time, the date of the most recent commit
that was found in the repository was 2024-05-17.) If you
discover any rendering problems in this HTML version of the page,
or you believe there is a better or more up-to-date source for
the page, or you have corrections or improvements to the
information in this COLOPHON (which is not part of the original
manual page), send a mail to man-pages@man7.org
libtracefs 1.7.0 12/22/2023 LIBTRACEFS(3)