Re: [PATCH v1] libtracefs: An API to set the filtering of functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tzvetomir,
Thanks for your review, I will address your comments in the next patch.
steve,
Do you have any other comments on this patch?
Thanks,
sameer.

On Tue, Mar 16, 2021 at 5:07 PM Tzvetomir Stoyanov
<tz.stoyanov@xxxxxxxxx> wrote:
>
> Hi Sameer,
> I think we are almost there, I have a few comments on the error
> handling, that should be addressed before merging the patch.
>
> On Mon, Mar 15, 2021 at 7:49 PM Sameeruddin shaik
> <sameeruddin.shaik8@xxxxxxxxx> wrote:
> >
> > This new API will write the function filters into the
> > set_ftrace_filter file.
> >
> > tracefs_function_filter()
> >
> > https://bugzilla.kernel.org/show_bug.cgi?id=210643
> >
> > Signed-off-by: Sameeruddin shaik <sameeruddin.shaik8@xxxxxxxxx>
> > ---
> > changed snprintf to asprintf for string formation
> > handled the lines over 80 characters
> >
> > diff --git a/include/tracefs.h b/include/tracefs.h
> > index f3eec62..c1f07b0 100644
> > --- a/include/tracefs.h
> > +++ b/include/tracefs.h
> > @@ -145,5 +145,6 @@ bool tracefs_option_is_enabled(struct tracefs_instance *instance, enum tracefs_o
> >  int tracefs_option_enable(struct tracefs_instance *instance, enum tracefs_option_id id);
> >  int tracefs_option_diasble(struct tracefs_instance *instance, enum tracefs_option_id id);
> >  const char *tracefs_option_name(enum tracefs_option_id id);
> > -
> > +int tracefs_function_filter(struct tracefs_instance *instance, const char **filters,
> > +                           const char *module, bool reset, const char ***errs);
> >  #endif /* _TRACE_FS_H */
> > diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c
> > index e2dfc7b..6b33321 100644
> > --- a/src/tracefs-tools.c
> > +++ b/src/tracefs-tools.c
> > @@ -18,6 +18,7 @@
> >  #include "tracefs-local.h"
> >
> >  #define TRACE_CTRL     "tracing_on"
> > +#define TRACE_FILTER   "set_ftrace_filter"
> >
> >  static const char * const options_map[] = {
> >         "unknown",
> > @@ -387,3 +388,93 @@ void tracefs_option_clear(struct tracefs_options_mask *options, enum tracefs_opt
> >         if (options && id > TRACEFS_OPTION_INVALID)
> >                 options->mask &= ~(1ULL << (id - 1));
> >  }
> > +
> > +static int controlled_write(const char *filter_path, const char **filters,
> > +                           const char *module, bool reset, const char ***errs)
> > +{
> > +       int flags = reset ? O_TRUNC : O_APPEND;
> > +       const char **e = NULL;
> > +       char *each_str = NULL;
> > +       int write_size = 0;
> > +       int size = 0;
> > +       int fd = -1;
> > +       int ret = 0;
> > +       int j = 0;
> > +       int i;
> > +
> > +       fd = open(filter_path, O_WRONLY | flags);
> > +       if (fd < 0)
> > +               return 1;
> > +
> > +       for (i = 0; filters[i]; i++) {
> > +               if (module)
> > +                       write_size = asprintf(&each_str, "%s:mod:%s ", filters[i], module);
> > +               else
> > +                       write_size = asprintf(&each_str, "%s ", filters[i]);
> > +               if (write_size < 0)
> > +                       continue;
>
> I think we can consider asprintf() failure as a major problem. There
> are two options - break the loop or goto error label.
>
> > +               size = write(fd, each_str, write_size);
> > +               /* compare written bytes*/
> > +               if (size < write_size) {
> > +                       if (errs) {
> > +                               e = realloc(e, (j + 1) * (sizeof(char *)));
>
> The realloc return value must be checked. In case of an error - break
> the loop or goto error label.
>
> > +                               e[j++] = filters[i];
> > +                               ret -= 1;
> > +                       }
> > +               }
> > +               free(each_str);
>
> Set each_str to NULL after the free, This will help with proper
> resources cleanup, in case of an error.
>
> > +       }
>
> If you choose the option to break the loop in case of an error, check
> here if filters[i] is not NULL, i.e. if the loop exit with an error.
> If there was an error - clean up all internally allocated resources
> (fd, e, each_str) and return error.
> The other option is to add "error" or "out" label at the end of the
> function where to do this resource cleanups.
>
> > +       if (errs) {
> > +               e = realloc(e, (j + 1) * (sizeof(char *)));
>
> Check that realloc return value too.
>
> > +               e[j] = NULL;
> > +               *errs = e;
> > +       }
> > +       close(fd);
>
> Note: in case of an internal error exit, free e and each_str, if they
> were allocated, and do not modify err.
>
> > +       return ret;
> > +}
> > +
> > +/**
> > + * tracefs_function_filter - write to set_ftrace_filter file to trace
> > + * particular functions
> > + * @instance: ftrace instance, can be NULL for top tracing instance
> > + * @filters: An array of function names ending with a NULL pointer
> > + * @module: Module to be traced
> > + * @reset: set to true to reset the file before applying the filter
> > + * @errs: A pointer to array of constant strings that will be allocated
> > + * on negative return of this function, pointing to the filters that
> > + * failed.May be NULL, in which case this field will be ignored.
> > + *
> > + * The @filters is an array of strings, where each string will be used
> > + * to set a function or functions to be traced.
> > + *
> > + * If @reset is true, then all functions in the filter are cleared
> > + * before adding functions from @filters. Otherwise, the functions set
> > + * by @filters will be appended to the filter file
> > + *
> > + * returns -x on filter errors (where x is number of failed filter
> > + * srtings) and if @errs is not NULL will be an allocated string array
> > + * pointing to the strings in @filters that failed and must be freed
> > + * with free().
> > + *
> > + * returns 1 on general errors not realted to setting the filter.
> > + * @errs is not set even if supplied.
> > + *
> > + * return 0 on success and @errs is not set.
> Note: in case of an error exit, free e and each_str, if they were allocated
> > + */
> > +int tracefs_function_filter(struct tracefs_instance *instance, const char **filters,
> > +                           const char *module, bool reset, const char ***errs)
> > +{
> > +       char *ftrace_filter_path;
> > +       int ret = 0;
> > +
> > +       if (!filters)
> > +               return 1;
> > +
> > +       ftrace_filter_path = tracefs_instance_get_file(instance, TRACE_FILTER);
> > +       if (!ftrace_filter_path)
> > +               return 1;
> > +
> > +       ret = controlled_write(ftrace_filter_path, filters, module, reset, errs);
> > +       tracefs_put_tracing_file(ftrace_filter_path);
> > +       return ret;
> > +}
> > --
> > 2.7.4
> >
>
> Thanks, Sameer!
>
> --
> Tzvetomir (Ceco) Stoyanov
> VMware Open Source Technology Center



[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux