@@ -204,6 +204,8 @@ static void trace_events_free(struct trace_events *events)
204204
205205 tevent = tevent -> next ;
206206
207+ if (free_event -> filter )
208+ free (free_event -> filter );
207209 if (free_event -> trigger )
208210 free (free_event -> trigger );
209211 free (free_event -> system );
@@ -237,6 +239,21 @@ struct trace_events *trace_event_alloc(const char *event_string)
237239 return tevent ;
238240}
239241
242+ /*
243+ * trace_event_add_filter - record an event filter
244+ */
245+ int trace_event_add_filter (struct trace_events * event , char * filter )
246+ {
247+ if (event -> filter )
248+ free (event -> filter );
249+
250+ event -> filter = strdup (filter );
251+ if (!event -> filter )
252+ return 1 ;
253+
254+ return 0 ;
255+ }
256+
240257/*
241258 * trace_event_add_trigger - record an event trigger action
242259 */
@@ -252,6 +269,33 @@ int trace_event_add_trigger(struct trace_events *event, char *trigger)
252269 return 0 ;
253270}
254271
272+ /*
273+ * trace_event_disable_filter - disable an event filter
274+ */
275+ static void trace_event_disable_filter (struct trace_instance * instance ,
276+ struct trace_events * tevent )
277+ {
278+ char filter [1024 ];
279+ int retval ;
280+
281+ if (!tevent -> filter )
282+ return ;
283+
284+ if (!tevent -> filter_enabled )
285+ return ;
286+
287+ debug_msg ("Disabling %s:%s filter %s\n" , tevent -> system ,
288+ tevent -> event ? : "*" , tevent -> filter );
289+
290+ snprintf (filter , 1024 , "!%s\n" , tevent -> filter );
291+
292+ retval = tracefs_event_file_write (instance -> inst , tevent -> system ,
293+ tevent -> event , "filter" , filter );
294+ if (retval < 0 )
295+ err_msg ("Error disabling %s:%s filter %s\n" , tevent -> system ,
296+ tevent -> event ? : "*" , tevent -> filter );
297+ }
298+
255299/*
256300 * trace_event_disable_trigger - disable an event trigger
257301 */
@@ -293,6 +337,7 @@ void trace_events_disable(struct trace_instance *instance,
293337 while (tevent ) {
294338 debug_msg ("Disabling event %s:%s\n" , tevent -> system , tevent -> event ? : "*" );
295339 if (tevent -> enabled ) {
340+ trace_event_disable_filter (instance , tevent );
296341 trace_event_disable_trigger (instance , tevent );
297342 tracefs_event_disable (instance -> inst , tevent -> system , tevent -> event );
298343 }
@@ -302,6 +347,41 @@ void trace_events_disable(struct trace_instance *instance,
302347 }
303348}
304349
350+ /*
351+ * trace_event_enable_filter - enable an event filter associated with an event
352+ */
353+ static int trace_event_enable_filter (struct trace_instance * instance ,
354+ struct trace_events * tevent )
355+ {
356+ char filter [1024 ];
357+ int retval ;
358+
359+ if (!tevent -> filter )
360+ return 0 ;
361+
362+ if (!tevent -> event ) {
363+ err_msg ("Filter %s applies only for single events, not for all %s:* events\n" ,
364+ tevent -> filter , tevent -> system );
365+ return 1 ;
366+ }
367+
368+ snprintf (filter , 1024 , "%s\n" , tevent -> filter );
369+
370+ debug_msg ("Enabling %s:%s filter %s\n" , tevent -> system ,
371+ tevent -> event ? : "*" , tevent -> filter );
372+
373+ retval = tracefs_event_file_write (instance -> inst , tevent -> system ,
374+ tevent -> event , "filter" , filter );
375+ if (retval < 0 ) {
376+ err_msg ("Error enabling %s:%s filter %s\n" , tevent -> system ,
377+ tevent -> event ? : "*" , tevent -> filter );
378+ return 1 ;
379+ }
380+
381+ tevent -> filter_enabled = 1 ;
382+ return 0 ;
383+ }
384+
305385/*
306386 * trace_event_enable_trigger - enable an event trigger associated with an event
307387 */
@@ -356,6 +436,9 @@ int trace_events_enable(struct trace_instance *instance,
356436 return 1 ;
357437 }
358438
439+ retval = trace_event_enable_filter (instance , tevent );
440+ if (retval )
441+ return 1 ;
359442
360443 retval = trace_event_enable_trigger (instance , tevent );
361444 if (retval )
0 commit comments