Hi Steve,

2014-05-16 (금), 10:02 -0400, Steven Rostedt:

> From: "Steven Rostedt (Red Hat)" <rost...@goodmis.org>
> 
> The traceevent plugins allows developers to have their events print out
> information that is more advanced than what can be achieved by the
> trace event format files.
> 
> As these plugins are used on the userspace side of the tracing tools, it
> is only logical that the tools should be able to produce different types
> of output for the events. The types of events still need to be defined by
> the plugins thus we need a way to pass information from the tool to the
> plugin to specify what type of information to be shown.
> 
> Not only does the information need to be passed by the tool to plugin, but
> the plugin also requires a way to notify the tool of what options it can
> provide.
> 
> This builds the plugin option infrastructure that is taken from trace-cmd
> that is used to allow plugins to produce different output based on the
> options specified by the tool.
> 
> Signed-off-by: Steven Rostedt <rost...@goodmis.org>
> ---
>  tools/lib/traceevent/event-parse.h  |  16 ++-
>  tools/lib/traceevent/event-plugin.c | 197 
> ++++++++++++++++++++++++++++++++++++
>  2 files changed, 209 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/lib/traceevent/event-parse.h 
> b/tools/lib/traceevent/event-parse.h
> index a68ec3d8289f..d6c610a66006 100644
> --- a/tools/lib/traceevent/event-parse.h
> +++ b/tools/lib/traceevent/event-parse.h
> @@ -107,8 +107,8 @@ typedef int (*pevent_event_handler_func)(struct trace_seq 
> *s,
>  typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
>  typedef int (*pevent_plugin_unload_func)(struct pevent *pevent);
>  
> -struct plugin_option {
> -     struct plugin_option            *next;
> +struct pevent_plugin_option {
> +     struct pevent_plugin_option     *next;

Hmm.. this name change reminds me that it might be better if this plugin
and option list belong to a pevent..


>       void                            *handle;
>       char                            *file;
>       char                            *name;
> @@ -135,7 +135,7 @@ struct plugin_option {
>   * PEVENT_PLUGIN_OPTIONS:  (optional)
>   *   Plugin options that can be set before loading
>   *
> - *   struct plugin_option PEVENT_PLUGIN_OPTIONS[] = {
> + *   struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = {
>   *   {
>   *           .name = "option-name",
>   *           .plugin_alias = "overide-file-name", (optional)
> @@ -355,7 +355,7 @@ enum pevent_func_arg_type {
>  enum pevent_flag {
>       PEVENT_NSEC_OUTPUT              = 1,    /* output in NSECS */
>       PEVENT_DISABLE_SYS_PLUGINS      = 1 << 1,
> -     PEVENT_DISABLE_PLUGINS          = 1 << 2,
> +     PEVENT_DISABLE_PLUGINS          = 1 << 2

Unnecessary change?


>  };
>  
>  #define PEVENT_ERRORS                                                        
>       \
> @@ -415,6 +415,14 @@ struct plugin_list;
>  struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
>  void traceevent_unload_plugins(struct plugin_list *plugin_list,
>                              struct pevent *pevent);
> +char **traceevent_plugin_list_options(void);
> +void traceevent_plugin_free_options_list(char **list);
> +int traceevent_plugin_add_options(const char *name,
> +                               struct pevent_plugin_option *options);
> +void traceevent_plugin_remove_options(struct pevent_plugin_option *options);
> +void traceevent_print_plugins(struct trace_seq *s,
> +                           const char *prefix, const char *suffix,
> +                           const struct plugin_list *list);
>  
>  struct cmdline;
>  struct cmdline_list;
> diff --git a/tools/lib/traceevent/event-plugin.c 
> b/tools/lib/traceevent/event-plugin.c
> index 317466bd1a37..a24479426d58 100644
> --- a/tools/lib/traceevent/event-plugin.c
> +++ b/tools/lib/traceevent/event-plugin.c
> @@ -18,6 +18,7 @@
>   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   */
>  
> +#include <stdio.h>
>  #include <string.h>
>  #include <dlfcn.h>
>  #include <stdlib.h>
> @@ -30,12 +31,208 @@
>  
>  #define LOCAL_PLUGIN_DIR ".traceevent/plugins"
>  
> +static struct registered_plugin_options {
> +     struct registered_plugin_options        *next;
> +     struct pevent_plugin_option             *options;
> +} *registered_options;
> +
> +static struct trace_plugin_options {
> +     struct trace_plugin_options     *next;
> +     char                            *plugin;
> +     char                            *option;
> +     char                            *value;
> +} *trace_plugin_options;
> +
>  struct plugin_list {
>       struct plugin_list      *next;
>       char                    *name;
>       void                    *handle;
>  };
>  
> +/**
> + * traceevent_plugin_list_options - get list of plugin options
> + *
> + * Returns an array of char strings that list the currently registered
> + * plugin options in the format of <plugin>:<option>. This list can be
> + * used by toggling the option.
> + *
> + * Returns NULL if there's no options registered. On error it returns
> + * an (char **)-1 (must check for that)

What about making it a macro like INVALID_OPTION_LIST?

> + *
> + * Must be freed with traceevent_plugin_free_options_list().
> + */
> +char **traceevent_plugin_list_options(void)
> +{
> +     struct registered_plugin_options *reg;
> +     struct pevent_plugin_option *op;
> +     char **list = NULL;
> +     char *name;
> +     int count = 0;
> +
> +     for (reg = registered_options; reg; reg = reg->next) {
> +             for (op = reg->options; op->name; op++) {
> +                     char *alias = op->plugin_alias ? op->plugin_alias : 
> op->file;
> +
> +                     name = malloc(strlen(op->name) + strlen(alias) + 2);
> +                     if (!name)
> +                             goto err;
> +
> +                     sprintf(name, "%s:%s", alias, op->name);
> +                     list = realloc(list, count + 2);
> +                     if (!list) {

This will lost the original list pointer.  Please use a temp variable.


> +                             free(name);
> +                             goto err;
> +                     }
> +                     list[count++] = name;
> +                     list[count] = NULL;
> +             }
> +     }
> +     if (!count)
> +             return NULL;
> +     return list;

Isn't it enough to simply return the list?

> +
> + err:
> +     while (--count > 0)

Shouldn't it be >= instead of > ?

Thanks,
Namhyung


> +             free(list[count]);
> +     free(list);
> +
> +     return (char **)((unsigned long)-1);
> +}


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to