From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> Add tracefs_function_notrace() to set the functions not to trace. Create a per instance pthread mutex lock. [ This is actually the first time I'm sending patches via git send-email! Hopefully I dont' screw it up ;-) ] Steven Rostedt (VMware) (3): libtracefs: Move most functionality into helper function for tracefs_function_filter() libtracefs: Add tracefs_function_notrace() API libtracefs: Add a pthread_mutex per instance Documentation/libtracefs-function-filter.txt | 19 ++- include/tracefs-local.h | 12 +- include/tracefs.h | 3 + src/tracefs-instance.c | 6 + src/tracefs-tools.c | 152 ++++++++++++------- 5 files changed, 131 insertions(+), 61 deletions(-) -- 2.29.2
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> In order to share the code of tracefs_function_filter() for tracefs_function_notrace(), move all its functionality out of tracefs_function_filter() and into a new helper function called update_filter(). Then pass in the filter file and the pointer to the file descriptor to the set_ftrace_filter, such that tracefs_function_notrace() could do the same with set_ftrace_notrace file. Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> --- src/tracefs-tools.c | 111 ++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c index cb07b6f..21a9bd3 100644 --- a/src/tracefs-tools.c +++ b/src/tracefs-tools.c @@ -744,54 +744,17 @@ static int write_func_list(int fd, struct func_list *list) return 0; } -/** - * tracefs_function_filter - filter the functions that are traced - * @instance: ftrace instance, can be NULL for top tracing instance. - * @filter: The filter to filter what functions are to be traced - * @module: Module to be traced or NULL if all functions are to be examined. - * @flags: flags on modifying the filter file - * - * @filter may be a full function name, a glob, or a regex. It will be - * considered a regex, if there's any characters that are not normally in - * function names or "*" or "?" for a glob. - * - * @flags: - * TRACEFS_FL_RESET - will clear the functions in the filter file - * before applying the @filter. This will error with -1 - * and errno of EBUSY if this flag is set and a previous - * call had the same instance and TRACEFS_FL_CONTINUE set. - * TRACEFS_FL_CONTINUE - will keep the filter file open on return. - * The filter is updated on closing of the filter file. - * With this flag set, the file is not closed, and more filters - * may be added before they take effect. The last call of this - * function must be called without this flag for the filter - * to take effect. - * TRACEFS_FL_FUTURE - only applicable if "module" is set. If no match - * is made, and the module is not yet loaded, it will still attempt - * to write the filter plus the module; "<filter>:mod:<module>" - * to the filter file. Starting with Linux kernels 4.13, it is possible - * to load the filter file with module functions for a module that - * is not yet loaded, and when the module is loaded, it will then - * activate the module. - * - * Returns 0 on success, 1 if there was an error but the filtering has not - * yet started, -1 if there was an error but the filtering has started. - * If -1 is returned and TRACEFS_FL_CONTINUE was set, then this function - * needs to be called again without the TRACEFS_FL_CONTINUE flag to commit - * the changes and close the filter file. - */ -int tracefs_function_filter(struct tracefs_instance *instance, const char *filter, - const char *module, unsigned int flags) +static int update_filter(const char *filter_path, int *fd, + struct tracefs_instance *instance, const char *filter, + const char *module, unsigned int flags) { struct func_filter func_filter; struct func_list *func_list = NULL; - char *ftrace_filter_path; bool reset = flags & TRACEFS_FL_RESET; bool cont = flags & TRACEFS_FL_CONTINUE; bool future = flags & TRACEFS_FL_FUTURE; int open_flags; int ret = 1; - int *fd; /* future flag is only applicable to modules */ if (future && !module) { @@ -800,10 +763,6 @@ int tracefs_function_filter(struct tracefs_instance *instance, const char *filte } pthread_mutex_lock(&filter_lock); - if (instance) - fd = &instance->ftrace_filter_fd; - else - fd = &ftrace_filter_fd; /* RESET is only allowed if the file is not opened yet */ if (reset && *fd >= 0) { @@ -846,20 +805,15 @@ int tracefs_function_filter(struct tracefs_instance *instance, const char *filte open_file: ret = 1; - ftrace_filter_path = tracefs_instance_get_file(instance, TRACE_FILTER); - if (!ftrace_filter_path) - goto out_free; open_flags = reset ? O_TRUNC : O_APPEND; if (*fd < 0) - *fd = open(ftrace_filter_path, O_WRONLY | open_flags); - tracefs_put_tracing_file(ftrace_filter_path); + *fd = open(filter_path, O_WRONLY | open_flags); if (*fd < 0) goto out_free; errno = 0; - ret = 0; if (filter) { @@ -887,3 +841,60 @@ int tracefs_function_filter(struct tracefs_instance *instance, const char *filte return ret; } + +/** + * tracefs_function_filter - filter the functions that are traced + * @instance: ftrace instance, can be NULL for top tracing instance. + * @filter: The filter to filter what functions are to be traced + * @module: Module to be traced or NULL if all functions are to be examined. + * @flags: flags on modifying the filter file + * + * @filter may be a full function name, a glob, or a regex. It will be + * considered a regex, if there's any characters that are not normally in + * function names or "*" or "?" for a glob. + * + * @flags: + * TRACEFS_FL_RESET - will clear the functions in the filter file + * before applying the @filter. This will error with -1 + * and errno of EBUSY if this flag is set and a previous + * call had the same instance and TRACEFS_FL_CONTINUE set. + * TRACEFS_FL_CONTINUE - will keep the filter file open on return. + * The filter is updated on closing of the filter file. + * With this flag set, the file is not closed, and more filters + * may be added before they take effect. The last call of this + * function must be called without this flag for the filter + * to take effect. + * TRACEFS_FL_FUTURE - only applicable if "module" is set. If no match + * is made, and the module is not yet loaded, it will still attempt + * to write the filter plus the module; "<filter>:mod:<module>" + * to the filter file. Starting with Linux kernels 4.13, it is possible + * to load the filter file with module functions for a module that + * is not yet loaded, and when the module is loaded, it will then + * activate the module. + * + * Returns 0 on success, 1 if there was an error but the filtering has not + * yet started, -1 if there was an error but the filtering has started. + * If -1 is returned and TRACEFS_FL_CONTINUE was set, then this function + * needs to be called again without the TRACEFS_FL_CONTINUE flag to commit + * the changes and close the filter file. + */ +int tracefs_function_filter(struct tracefs_instance *instance, const char *filter, + const char *module, unsigned int flags) +{ + char *filter_path; + int *fd; + int ret; + + filter_path = tracefs_instance_get_file(instance, TRACE_FILTER); + if (!filter_path) + return -1; + + if (instance) + fd = &instance->ftrace_filter_fd; + else + fd = &ftrace_filter_fd; + + ret = update_filter(filter_path, fd, instance, filter, module, flags); + tracefs_put_tracing_file(filter_path); + return ret; +} -- 2.29.2
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> Add the API of tracefs_function_notrace() that is identical to how tracefs_function_filter() works, but will work with the set_ftrace_notrace filter file. Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> --- Documentation/libtracefs-function-filter.txt | 19 ++++++++--- include/tracefs-local.h | 1 + include/tracefs.h | 3 ++ src/tracefs-instance.c | 1 + src/tracefs-tools.c | 33 ++++++++++++++++++++ 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/Documentation/libtracefs-function-filter.txt b/Documentation/libtracefs-function-filter.txt index ccf20e9..746be37 100644 --- a/Documentation/libtracefs-function-filter.txt +++ b/Documentation/libtracefs-function-filter.txt @@ -4,6 +4,7 @@ libtracefs(3) NAME ---- tracefs_function_filter - Function to limit kernel functions that are traced +tracefs_function_notrace - Function to filter kernel functions that not to be traced SYNOPSIS -------- @@ -12,15 +13,18 @@ SYNOPSIS *#include <tracefs.h>* int *tracefs_function_filter*(struct tracefs_instance pass:[*]_instance_, const char pass:[*]_filter_, const char pass:[*]_module_, int _flags_); +int *tracefs_function_notrace*(struct tracefs_instance pass:[*]_instance_, const char pass:[*]_filter_, const char pass:[*]_module_, int _flags_); -- DESCRIPTION ----------- -This function can be used to limit the Linux kernel functions that would be -traced by the function and function-graph tracers +*tracefs_function_filter* and *tracefs_function_notrace* can be used to limit the +Linux kernel functions that would be traced by the function and function-graph tracers. +The *tracefs_function_filter* defines a list of functions that can be traced. +The *tracefs_function_notrace* defines a list of functions that will not be traced. +If a function is in both lists, it will not be traced. -It will take an -_instance_ , that can be NULL for the top level tracing, +They take an _instance_ , that can be NULL for the top level tracing, _filter_, a string that represents a filter that should be applied to define what functions are to be traced, _module_, to limit the filtering on a specific module (or NULL to filter on all functions), @@ -125,6 +129,13 @@ int main(int argc, char *argv[]) /* Error creating new trace instance */ } + /* Do not trace any function with the word "lock" in it */ + ret = tracefs_function_notrace(inst, "*lock*", NULL, TRACEFS_FL_RESET); + if (ret) { + printf("Failed to set the notrace filter\n"); + goto out; + } + /* First reset the filter */ ret = tracefs_function_filter(inst, NULL, NULL, TRACEFS_FL_RESET | TRACEFS_FL_CONTINUE); diff --git a/include/tracefs-local.h b/include/tracefs-local.h index 73ec113..060de7e 100644 --- a/include/tracefs-local.h +++ b/include/tracefs-local.h @@ -19,6 +19,7 @@ struct tracefs_instance { char *name; int flags; int ftrace_filter_fd; + int ftrace_notrace_fd; }; /* Can be overridden */ diff --git a/include/tracefs.h b/include/tracefs.h index befcc48..70b7ebe 100644 --- a/include/tracefs.h +++ b/include/tracefs.h @@ -160,4 +160,7 @@ enum { int tracefs_function_filter(struct tracefs_instance *instance, const char *filter, const char *module, unsigned int flags); +int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter, + const char *module, unsigned int flags); + #endif /* _TRACE_FS_H */ diff --git a/src/tracefs-instance.c b/src/tracefs-instance.c index bf2fabf..9f45624 100644 --- a/src/tracefs-instance.c +++ b/src/tracefs-instance.c @@ -44,6 +44,7 @@ static struct tracefs_instance *instance_alloc(const char *trace_dir, const char } instance->ftrace_filter_fd = -1; + instance->ftrace_notrace_fd = -1; return instance; diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c index 21a9bd3..b41806b 100644 --- a/src/tracefs-tools.c +++ b/src/tracefs-tools.c @@ -21,10 +21,12 @@ #define TRACE_CTRL "tracing_on" #define TRACE_FILTER "set_ftrace_filter" +#define TRACE_NOTRACE "set_ftrace_notrace" #define TRACE_FILTER_LIST "available_filter_functions" /* File descriptor for Top level set_ftrace_filter */ static int ftrace_filter_fd = -1; +static int ftrace_notrace_fd = -1; static pthread_mutex_t filter_lock = PTHREAD_MUTEX_INITIALIZER; static const char * const options_map[] = { @@ -898,3 +900,34 @@ int tracefs_function_filter(struct tracefs_instance *instance, const char *filte tracefs_put_tracing_file(filter_path); return ret; } + +/** + * tracefs_function_notrace - filter the functions that are not to be traced + * @instance: ftrace instance, can be NULL for top tracing instance. + * @filter: The filter to filter what functions are not to be traced + * @module: Module to be traced or NULL if all functions are to be examined. + * @flags: flags on modifying the filter file + * + * See tracefs_function_filter, as this has the same functionality but + * for adding to the "notrace" filter. + */ +int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter, + const char *module, unsigned int flags) +{ + char *filter_path; + int *fd; + int ret; + + filter_path = tracefs_instance_get_file(instance, TRACE_NOTRACE); + if (!filter_path) + return -1; + + if (instance) + fd = &instance->ftrace_notrace_fd; + else + fd = &ftrace_notrace_fd; + + ret = update_filter(filter_path, fd, instance, filter, module, flags); + tracefs_put_tracing_file(filter_path); + return ret; +} -- 2.29.2
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> Add a pthread_mutex per instance such that modifications being done on specific instances do not interfere with each other. This also includes a new "toplevel_lock" that is to be used when modifying the toplevel instance. Convert the filter_mutex over to the toplevel/instance locking. Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> --- include/tracefs-local.h | 13 ++++++++----- src/tracefs-instance.c | 5 +++++ src/tracefs-tools.c | 8 +++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/tracefs-local.h b/include/tracefs-local.h index 060de7e..6865611 100644 --- a/include/tracefs-local.h +++ b/include/tracefs-local.h @@ -15,13 +15,16 @@ do { if (!(1/!(cond))) { } } while (0) struct tracefs_instance { - char *trace_dir; - char *name; - int flags; - int ftrace_filter_fd; - int ftrace_notrace_fd; + char *trace_dir; + char *name; + pthread_mutex_t lock; + int flags; + int ftrace_filter_fd; + int ftrace_notrace_fd; }; +extern pthread_mutex_t toplevel_lock; + /* Can be overridden */ void warning(const char *fmt, ...); diff --git a/src/tracefs-instance.c b/src/tracefs-instance.c index 9f45624..599c3a7 100644 --- a/src/tracefs-instance.c +++ b/src/tracefs-instance.c @@ -15,6 +15,7 @@ #include <fcntl.h> #include <dirent.h> #include <limits.h> +#include <pthread.h> #include "tracefs.h" #include "tracefs-local.h" @@ -43,6 +44,9 @@ static struct tracefs_instance *instance_alloc(const char *trace_dir, const char goto error; } + if (pthread_mutex_init(&instance->lock, NULL) < 0) + goto error; + instance->ftrace_filter_fd = -1; instance->ftrace_notrace_fd = -1; @@ -69,6 +73,7 @@ void tracefs_instance_free(struct tracefs_instance *instance) return; free(instance->trace_dir); free(instance->name); + pthread_mutex_destroy(&instance->lock); free(instance); } diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c index b41806b..d48062c 100644 --- a/src/tracefs-tools.c +++ b/src/tracefs-tools.c @@ -19,6 +19,8 @@ #include "tracefs.h" #include "tracefs-local.h" +__hidden pthread_mutex_t toplevel_lock = PTHREAD_MUTEX_INITIALIZER; + #define TRACE_CTRL "tracing_on" #define TRACE_FILTER "set_ftrace_filter" #define TRACE_NOTRACE "set_ftrace_notrace" @@ -27,7 +29,6 @@ /* File descriptor for Top level set_ftrace_filter */ static int ftrace_filter_fd = -1; static int ftrace_notrace_fd = -1; -static pthread_mutex_t filter_lock = PTHREAD_MUTEX_INITIALIZER; static const char * const options_map[] = { "unknown", @@ -755,6 +756,7 @@ static int update_filter(const char *filter_path, int *fd, bool reset = flags & TRACEFS_FL_RESET; bool cont = flags & TRACEFS_FL_CONTINUE; bool future = flags & TRACEFS_FL_FUTURE; + pthread_mutex_t *lock = instance ? &instance->lock : &toplevel_lock; int open_flags; int ret = 1; @@ -764,7 +766,7 @@ static int update_filter(const char *filter_path, int *fd, return 1; } - pthread_mutex_lock(&filter_lock); + pthread_mutex_lock(lock); /* RESET is only allowed if the file is not opened yet */ if (reset && *fd >= 0) { @@ -839,7 +841,7 @@ static int update_filter(const char *filter_path, int *fd, out_free: free_func_list(func_list); out: - pthread_mutex_unlock(&filter_lock); + pthread_mutex_unlock(lock); return ret; } -- 2.29.2
On Wed, 7 Apr 2021 16:21:23 -0400 Steven Rostedt <rostedt@goodmis.org> wrote: > From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> > > Add tracefs_function_notrace() to set the functions not to trace. > Create a per instance pthread mutex lock. > > [ This is actually the first time I'm sending patches via > git send-email! Hopefully I dont' screw it up ;-) ] Hmm, as I found that my gitconfig uses vmware's smtp server, and the Receive-SPF does not match. It may be blocked by the mailing lists. I may try a second time. :-/ -- Steve > > Steven Rostedt (VMware) (3): > libtracefs: Move most functionality into helper function for > tracefs_function_filter() > libtracefs: Add tracefs_function_notrace() API > libtracefs: Add a pthread_mutex per instance > > Documentation/libtracefs-function-filter.txt | 19 ++- > include/tracefs-local.h | 12 +- > include/tracefs.h | 3 + > src/tracefs-instance.c | 6 + > src/tracefs-tools.c | 152 ++++++++++++------- > 5 files changed, 131 insertions(+), 61 deletions(-) >
On Thu, Apr 8, 2021 at 1:02 AM Steven Rostedt <rostedt@goodmis.org> wrote: > > From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> > > Add the API of tracefs_function_notrace() that is identical to how > tracefs_function_filter() works, but will work with the set_ftrace_notrace > filter file. > > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> > --- > Documentation/libtracefs-function-filter.txt | 19 ++++++++--- > include/tracefs-local.h | 1 + > include/tracefs.h | 3 ++ > src/tracefs-instance.c | 1 + > src/tracefs-tools.c | 33 ++++++++++++++++++++ > 5 files changed, 53 insertions(+), 4 deletions(-) > > diff --git a/Documentation/libtracefs-function-filter.txt b/Documentation/libtracefs-function-filter.txt > index ccf20e9..746be37 100644 > --- a/Documentation/libtracefs-function-filter.txt > +++ b/Documentation/libtracefs-function-filter.txt > @@ -4,6 +4,7 @@ libtracefs(3) > NAME > ---- > tracefs_function_filter - Function to limit kernel functions that are traced > +tracefs_function_notrace - Function to filter kernel functions that not to be traced > > SYNOPSIS > -------- > @@ -12,15 +13,18 @@ SYNOPSIS > *#include <tracefs.h>* > > int *tracefs_function_filter*(struct tracefs_instance pass:[*]_instance_, const char pass:[*]_filter_, const char pass:[*]_module_, int _flags_); > +int *tracefs_function_notrace*(struct tracefs_instance pass:[*]_instance_, const char pass:[*]_filter_, const char pass:[*]_module_, int _flags_); > -- > > DESCRIPTION > ----------- > -This function can be used to limit the Linux kernel functions that would be > -traced by the function and function-graph tracers > +*tracefs_function_filter* and *tracefs_function_notrace* can be used to limit the > +Linux kernel functions that would be traced by the function and function-graph tracers. > +The *tracefs_function_filter* defines a list of functions that can be traced. > +The *tracefs_function_notrace* defines a list of functions that will not be traced. > +If a function is in both lists, it will not be traced. > > -It will take an > -_instance_ , that can be NULL for the top level tracing, > +They take an _instance_ , that can be NULL for the top level tracing, > _filter_, a string that represents a filter that should > be applied to define what functions are to be traced, > _module_, to limit the filtering on a specific module (or NULL to filter on all functions), > @@ -125,6 +129,13 @@ int main(int argc, char *argv[]) > /* Error creating new trace instance */ > } > > + /* Do not trace any function with the word "lock" in it */ > + ret = tracefs_function_notrace(inst, "*lock*", NULL, TRACEFS_FL_RESET); > + if (ret) { > + printf("Failed to set the notrace filter\n"); > + goto out; > + } > + > /* First reset the filter */ > ret = tracefs_function_filter(inst, NULL, NULL, > TRACEFS_FL_RESET | TRACEFS_FL_CONTINUE); > diff --git a/include/tracefs-local.h b/include/tracefs-local.h > index 73ec113..060de7e 100644 > --- a/include/tracefs-local.h > +++ b/include/tracefs-local.h > @@ -19,6 +19,7 @@ struct tracefs_instance { > char *name; > int flags; > int ftrace_filter_fd; > + int ftrace_notrace_fd; > }; > > /* Can be overridden */ > diff --git a/include/tracefs.h b/include/tracefs.h > index befcc48..70b7ebe 100644 > --- a/include/tracefs.h > +++ b/include/tracefs.h > @@ -160,4 +160,7 @@ enum { > > int tracefs_function_filter(struct tracefs_instance *instance, const char *filter, > const char *module, unsigned int flags); > +int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter, > + const char *module, unsigned int flags); > + > #endif /* _TRACE_FS_H */ > diff --git a/src/tracefs-instance.c b/src/tracefs-instance.c > index bf2fabf..9f45624 100644 > --- a/src/tracefs-instance.c > +++ b/src/tracefs-instance.c > @@ -44,6 +44,7 @@ static struct tracefs_instance *instance_alloc(const char *trace_dir, const char > } > > instance->ftrace_filter_fd = -1; > + instance->ftrace_notrace_fd = -1; These descriptors should be closed in tracefs_instance_free(), as part of the instance cleanup. > > return instance; > > diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c > index 21a9bd3..b41806b 100644 > --- a/src/tracefs-tools.c > +++ b/src/tracefs-tools.c > @@ -21,10 +21,12 @@ > > #define TRACE_CTRL "tracing_on" > #define TRACE_FILTER "set_ftrace_filter" > +#define TRACE_NOTRACE "set_ftrace_notrace" > #define TRACE_FILTER_LIST "available_filter_functions" > > /* File descriptor for Top level set_ftrace_filter */ > static int ftrace_filter_fd = -1; > +static int ftrace_notrace_fd = -1; > static pthread_mutex_t filter_lock = PTHREAD_MUTEX_INITIALIZER; I'm wondering if we should free these global resources somehow. A cleanup API for the whole library can be implemented using __attribute__((destructor)), or some other way ? > > static const char * const options_map[] = { > @@ -898,3 +900,34 @@ int tracefs_function_filter(struct tracefs_instance *instance, const char *filte > tracefs_put_tracing_file(filter_path); > return ret; > } > + > +/** > + * tracefs_function_notrace - filter the functions that are not to be traced > + * @instance: ftrace instance, can be NULL for top tracing instance. > + * @filter: The filter to filter what functions are not to be traced > + * @module: Module to be traced or NULL if all functions are to be examined. > + * @flags: flags on modifying the filter file > + * > + * See tracefs_function_filter, as this has the same functionality but > + * for adding to the "notrace" filter. > + */ > +int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter, > + const char *module, unsigned int flags) > +{ > + char *filter_path; > + int *fd; > + int ret; > + > + filter_path = tracefs_instance_get_file(instance, TRACE_NOTRACE); > + if (!filter_path) > + return -1; > + > + if (instance) > + fd = &instance->ftrace_notrace_fd; > + else > + fd = &ftrace_notrace_fd; > + > + ret = update_filter(filter_path, fd, instance, filter, module, flags); > + tracefs_put_tracing_file(filter_path); > + return ret; > +} > -- > 2.29.2 > -- Tzvetomir (Ceco) Stoyanov VMware Open Source Technology Center
On Thu, 8 Apr 2021 07:25:20 +0300 Tzvetomir Stoyanov <tz.stoyanov@gmail.com> wrote: > > diff --git a/src/tracefs-instance.c b/src/tracefs-instance.c > > index bf2fabf..9f45624 100644 > > --- a/src/tracefs-instance.c > > +++ b/src/tracefs-instance.c > > @@ -44,6 +44,7 @@ static struct tracefs_instance *instance_alloc(const char *trace_dir, const char > > } > > > > instance->ftrace_filter_fd = -1; > > + instance->ftrace_notrace_fd = -1; > > These descriptors should be closed in tracefs_instance_free(), as part > of the instance cleanup. Good point. I'll add a patch on top of this one to close both of them. > > > > > return instance; > > > > diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c > > index 21a9bd3..b41806b 100644 > > --- a/src/tracefs-tools.c > > +++ b/src/tracefs-tools.c > > @@ -21,10 +21,12 @@ > > > > #define TRACE_CTRL "tracing_on" > > #define TRACE_FILTER "set_ftrace_filter" > > +#define TRACE_NOTRACE "set_ftrace_notrace" > > #define TRACE_FILTER_LIST "available_filter_functions" > > > > /* File descriptor for Top level set_ftrace_filter */ > > static int ftrace_filter_fd = -1; > > +static int ftrace_notrace_fd = -1; > > static pthread_mutex_t filter_lock = PTHREAD_MUTEX_INITIALIZER; > > I'm wondering if we should free these global resources somehow. A > cleanup API for the whole library can be implemented using > __attribute__((destructor)), or some other way ? No need. The OS will close them for you when the application exits. All file descriptors that are opened will be closed by the OS. That said, we should probably add O_CLOEXEC in the open for them such that they don't stay open if the application does an exec() system call. -- Steve