• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1libtracefs(3)
2=============
3
4NAME
5----
6tracefs_filter_string_append, tracefs_filter_string_verify, tracefs_event_filter_apply, tracefs_event_filter_clear -
7Add, verify and apply event filters
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <tracefs.h>*
14
15int *tracefs_filter_string_append*(struct tep_event pass:[*]_event_, char pass:[**]_filter_,
16				 struct tracefs_filter _type_, const char pass:[*]_field_,
17				 enum tracefs_synth_compare _compare_, const char pass:[*]_val_);
18int *tracefs_filter_string_verify*(struct tep_event pass:[*]_event_, const char pass:[*]_filter_, char pass:[**]_err_);
19int *tracefs_event_filter_apply*(struct tracefs_instance pass:[*]_instance_, struct tep_event pass:[*]_event_, const char pass:[*]_filter_);
20int *tracefs_event_filter_clear*(struct tracefs_instance pass:[*]_instance_, struct tep_event pass:[*]_event_);
21
22--
23
24DESCRIPTION
25-----------
26*tracefs_filter_string_append*() is a way to create and verify event filters for
27a given event. It will verify that the _field_ belongs to the event and that
28the _compare_ option that is used is valid for the type of the field, as well
29as _val_. For the _type_ that is not of *TRACEFS_FILTER_COMPARE*, it will build
30the logical string and also make sure that the syntax is correct. For example,
31there are no more close parenthesis than open parenthesis. An AND (&&) or OR
32(||) is not misplaced, etc.
33
34*tracefs_synth_append_start_filter*() creates a filter or appends to it for the
35starting event. Depending on _type_, it will build a string of tokens for
36parenthesis or logic statemens, or it may add a comparison of _field_
37to _val_ based on _compare_.
38
39If _type_ is:
40*TRACEFS_FILTER_COMPARE*     -  See below
41*TRACEFS_FILTER_AND*         -  Append "&&" to the filter
42*TRACEFS_FILTER_OR*          -  Append "||" to the filter
43*TRACEFS_FILTER_NOT*         -  Append "!" to the filter
44*TRACEFS_FILTER_OPEN_PAREN*  -  Append "(" to the filter
45*TRACEFS_FILTER_CLOSE_PAREN* -  Append ")" to the filter
46
47_field_, _compare_, and _val_ are ignored unless _type_ is equal to
48*TRACEFS_FILTER_COMPARE*, then _compare will be used for the following:
49
50*TRACEFS_COMPARE_EQ* - _field_ == _val_
51
52*TRACEFS_COMPARE_NE* - _field_ != _val_
53
54*TRACEFS_COMPARE_GT* - _field_ > _val_
55
56*TRACEFS_COMPARE_GE* - _field_ >= _val_
57
58*TRACEFS_COMPARE_LT* - _field_ < _val_
59
60*TRACEFS_COMPARE_LE* - _field_ <pass:[=] _val_
61
62*TRACEFS_COMPARE_RE* - _field_ ~ "_val_" : where _field_ is a string.
63
64*TRACEFS_COMPARE_AND* - _field_ & _val_ : where _field_ is a flags field.
65
66*tracefs_filter_string_verify*() will parse _filter_ to make sure that the
67fields are for the _event_, and that the syntax is correct. If there's an
68error in the syntax, and _err_ is not NULL, then it will be allocated with an
69error message stating what was found wrong with the filter. _err_ must be freed
70with *free*().
71
72*tracefs_event_filter_apply*() applies given _filter_ string on _event_ in given _instance_.
73
74*tracefs_event_filter_clear*() clear all filters on _event_ in given _instance_.
75
76RETURN VALUE
77------------
78*tracefs_filter_string_append*() returns 0 on success and -1 on error.
79
80*tracefs_filter_string_verify*() returns 0 on success and -1 on error. if there
81is an error, and _errno_ is not *ENOMEM*, then _err_ is allocated and will
82contain a string describing what was found wrong with _filter_. _err_ must be
83freed with *free*().
84
85*tracefs_event_filter_apply*() returns 0 on success and -1 on error.
86
87*tracefs_event_filter_clear*() returns 0 on success and -1 on error.
88
89EXAMPLE
90-------
91[source,c]
92--
93#include <stdlib.h>
94#include <stdio.h>
95#include <ctype.h>
96#include <tracefs.h>
97
98static void usage(char **argv)
99{
100	fprintf(stderr, "usage: %s [system] event filter\n", argv[0]);
101	exit(-1);
102}
103
104int main (int argc, char **argv)
105{
106	struct tep_handle *tep;
107	struct tep_event *event;
108	const char *system = NULL;
109	const char *event_name;
110	const char *filter;
111	char *new_filter = NULL;
112	char *err = NULL;
113	int i;
114
115	if (argc < 3)
116		usage(argv);
117
118	if (argc < 4) {
119		event_name = argv[1];
120		filter = argv[2];
121	} else {
122		system = argv[1];
123		event_name = argv[2];
124		filter = argv[3];
125	}
126
127	/* Load all events from the system */
128	tep = tracefs_local_events(NULL);
129	if (!tep) {
130		perror("tep");
131		exit(-1);
132	}
133
134	event = tep_find_event_by_name(tep, system, event_name);
135	if (!event) {
136		fprintf(stderr, "Event %s%s%s not found\n",
137			system ? system : "" , system ? " " : "",
138			event_name);
139		exit(-1);
140	}
141
142	if (tracefs_filter_string_verify(event, filter, &err) < 0) {
143		perror("tracecfs_event_verify_filter");
144		if (err)
145			fprintf(stderr, "%s", err);
146		free(err);
147		exit(-1);
148	}
149
150	for (i = 0; filter[i]; i++) {
151		char buf[strlen(filter)];
152		char *field = NULL;
153		char *val = NULL;
154		enum tracefs_filter type;
155		enum tracefs_compare compare = 0;
156		int start_i, n;
157		int quote;
158		bool backslash;
159
160		while (isspace(filter[i]))
161			i++;
162
163		switch(filter[i]) {
164		case '(':
165			type = TRACEFS_FILTER_OPEN_PAREN;
166			break;
167		case ')':
168			type = TRACEFS_FILTER_CLOSE_PAREN;
169			break;
170		case '!':
171			type = TRACEFS_FILTER_NOT;
172			break;
173		case '&':
174			type = TRACEFS_FILTER_AND;
175			i++;
176			break;
177		case '|':
178			type = TRACEFS_FILTER_OR;
179			i++;
180			break;
181		default:
182			type = TRACEFS_FILTER_COMPARE;
183
184			while (isspace(filter[i]))
185				i++;
186
187			start_i = i;
188			for (; filter[i]; i++) {
189				switch(filter[i]) {
190				case 'a' ... 'z':
191				case 'A' ... 'Z':
192				case '0' ... '9':
193				case '_':
194					continue;
195				}
196				break;
197			}
198
199			n = i - start_i;
200			field = buf;
201			strncpy(field, filter + start_i, n);
202			field[n++] = '\0';
203
204			val = buf + n;
205
206			while (isspace(filter[i]))
207				i++;
208
209			start_i = i;
210			switch(filter[i++]) {
211			case '>':
212				compare = TRACEFS_COMPARE_GT;
213				if (filter[i] == '=') {
214					i++;
215					compare = TRACEFS_COMPARE_GE;
216				}
217				break;
218			case '<':
219				compare = TRACEFS_COMPARE_LT;
220				if (filter[i] == '=') {
221					i++;
222					compare = TRACEFS_COMPARE_LE;
223				}
224				break;
225			case '=':
226				compare = TRACEFS_COMPARE_EQ;
227				i++;
228				break;
229			case '!':
230				compare = TRACEFS_COMPARE_NE;
231				i++;
232				break;
233			case '~':
234				compare = TRACEFS_COMPARE_RE;
235				break;
236			case '&':
237				compare = TRACEFS_COMPARE_AND;
238				break;
239			}
240
241			while (isspace(filter[i]))
242				i++;
243
244			quote = 0;
245			backslash = false;
246			start_i = i;
247			for (; filter[i]; i++) {
248				if (quote) {
249					if (backslash)
250						backslash = false;
251					else if (filter[i] == '\\')
252						backslash = true;
253					else if (filter[i] == quote)
254						quote = 0;
255					continue;
256				}
257				switch(filter[i]) {
258				case '"': case '\'':
259					quote = filter[i];
260					continue;
261				case 'a' ... 'z':
262				case 'A' ... 'Z':
263				case '0' ... '9':
264				case '_':
265					continue;
266				}
267				break;
268			}
269			n = i - start_i;
270			strncpy(val, filter + start_i, n);
271			val[n] = '\0';
272			break;
273		}
274		n = tracefs_filter_string_append(event, &new_filter, type,
275						field, compare, val);
276		if (n < 0) {
277			fprintf(stderr, "Failed making new filter:\n'%s'\n",
278				new_filter ? new_filter : "(null)");
279			exit(-1);
280		}
281	}
282
283	if (tracefs_event_filter_apply(NULL, event, new_filter))
284		fprintf(stderr, "Failed to apply filter on event");
285
286	tep_free(tep);
287
288	printf("Created new filter: '%s'\n", new_filter);
289	free(new_filter);
290
291	exit(0);
292}
293--
294
295FILES
296-----
297[verse]
298--
299*tracefs.h*
300	Header file to include in order to have access to the library APIs.
301*-ltracefs*
302	Linker switch to add when building a program that uses the library.
303--
304
305SEE ALSO
306--------
307*libtracefs*(3),
308*libtraceevent*(3),
309*trace-cmd*(1),
310*tracefs_hist_alloc*(3),
311*tracefs_hist_alloc_2d*(3),
312*tracefs_hist_alloc_nd*(3),
313*tracefs_hist_free*(3),
314*tracefs_hist_add_key*(3),
315*tracefs_hist_add_value*(3),
316*tracefs_hist_add_name*(3),
317*tracefs_hist_start*(3),
318*tracefs_hist_destory*(3),
319*tracefs_hist_add_sort_key*(3),
320*tracefs_hist_sort_key_direction*(3)
321
322AUTHOR
323------
324[verse]
325--
326*Steven Rostedt* <rostedt@goodmis.org>
327*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>
328*sameeruddin shaik* <sameeruddin.shaik8@gmail.com>
329--
330REPORTING BUGS
331--------------
332Report bugs to  <linux-trace-devel@vger.kernel.org>
333
334LICENSE
335-------
336libtracefs is Free Software licensed under the GNU LGPL 2.1
337
338RESOURCES
339---------
340https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
341
342COPYING
343-------
344Copyright \(C) 2020 VMware, Inc. Free use of this software is granted under
345the terms of the GNU Public License (GPL).
346