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