lkml.org 
[lkml]   [2013]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH 04/24] tools list traceevent: Add plugin support
On 9/1/13 4:48 AM, Jiri Olsa wrote:
> Backporting plugin support for traceevent lib.

It would be worthwhile to not where the code is ported from --
repository and as of commit id.

David


>
> It's now possible to use following interface
> to load plugins for 'struct pevent' object:
>
> struct plugin_list*
> traceevent_load_plugins(struct pevent *pevent)
> - loads plusing for 'struct pevent' object and returns
> loaded plugins list
>
> void traceevent_unload_plugins(struct plugin_list *plugin_list);
> - unload plugin list
>
> Adding -ldl dependency for perf which is needed
> due to plugins support.
>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: David Ahern <dsahern@gmail.com>
> ---
> tools/lib/traceevent/Makefile | 2 +-
> tools/lib/traceevent/event-parse.h | 5 +
> tools/lib/traceevent/event-plugin.c | 202 ++++++++++++++++++++++++++++++++++++
> tools/perf/config/Makefile | 2 +-
> 4 files changed, 209 insertions(+), 2 deletions(-)
> create mode 100644 tools/lib/traceevent/event-plugin.c
>
> diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
> index ca6cb77..539f3e5 100644
> --- a/tools/lib/traceevent/Makefile
> +++ b/tools/lib/traceevent/Makefile
> @@ -180,7 +180,7 @@ $(obj)/%.o: $(src)/%.c
> %.o: $(src)/%.c
> $(Q)$(call do_compile)
>
> -PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o
> +PEVENT_LIB_OBJS = event-parse.o event-plugin.o trace-seq.o parse-filter.o parse-utils.o
> PEVENT_LIB_OBJS += kbuffer-parse.o
>
> ALL_OBJS = $(PEVENT_LIB_OBJS)
> diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
> index c37b202..8273c6e 100644
> --- a/tools/lib/traceevent/event-parse.h
> +++ b/tools/lib/traceevent/event-parse.h
> @@ -374,6 +374,11 @@ enum pevent_errno {
> };
> #undef _PE
>
> +struct plugin_list;
> +
> +struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
> +void traceevent_unload_plugins(struct plugin_list *plugin_list);
> +
> struct cmdline;
> struct cmdline_list;
> struct func_map;
> diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c
> new file mode 100644
> index 0000000..d272d87
> --- /dev/null
> +++ b/tools/lib/traceevent/event-plugin.c
> @@ -0,0 +1,202 @@
> +/*
> + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation;
> + * version 2.1 of the License (not later!)
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this program; if not, see <http://www.gnu.org/licenses>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + */
> +
> +#include <string.h>
> +#include <dlfcn.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include "event-parse.h"
> +#include "event-utils.h"
> +
> +#define LOCAL_PLUGIN_DIR ".traceevent/plugins"
> +
> +struct plugin_list {
> + struct plugin_list *next;
> + char *name;
> + void *handle;
> +};
> +
> +static void
> +load_plugin(struct pevent *pevent, const char *path,
> + const char *file, void *data)
> +{
> + struct plugin_list **plugin_list = data;
> + pevent_plugin_load_func func;
> + struct plugin_list *list;
> + const char *alias;
> + char *plugin;
> + void *handle;
> +
> + plugin = malloc_or_die(strlen(path) + strlen(file) + 2);
> +
> + strcpy(plugin, path);
> + strcat(plugin, "/");
> + strcat(plugin, file);
> +
> + handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
> + if (!handle) {
> + warning("could not load plugin '%s'\n%s\n",
> + plugin, dlerror());
> + goto out_free;
> + }
> +
> + alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
> + if (!alias)
> + alias = file;
> +
> + func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
> + if (!func) {
> + warning("could not find func '%s' in plugin '%s'\n%s\n",
> + PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror());
> + goto out_free;
> + }
> +
> + list = malloc_or_die(sizeof(*list));
> + list->next = *plugin_list;
> + list->handle = handle;
> + list->name = plugin;
> + *plugin_list = list;
> +
> + pr_stat("registering plugin: %s", plugin);
> + func(pevent);
> + return;
> +
> + out_free:
> + free(plugin);
> +}
> +
> +static void
> +load_plugins_dir(struct pevent *pevent, const char *suffix,
> + const char *path,
> + void (*load_plugin)(struct pevent *pevent,
> + const char *path,
> + const char *name,
> + void *data),
> + void *data)
> +{
> + struct dirent *dent;
> + struct stat st;
> + DIR *dir;
> + int ret;
> +
> + ret = stat(path, &st);
> + if (ret < 0)
> + return;
> +
> + if (!S_ISDIR(st.st_mode))
> + return;
> +
> + dir = opendir(path);
> + if (!dir)
> + return;
> +
> + while ((dent = readdir(dir))) {
> + const char *name = dent->d_name;
> +
> + if (strcmp(name, ".") == 0 ||
> + strcmp(name, "..") == 0)
> + continue;
> +
> + /* Only load plugins that end in suffix */
> + if (strcmp(name + (strlen(name) - strlen(suffix)), suffix) != 0)
> + continue;
> +
> + load_plugin(pevent, path, name, data);
> + }
> +
> + closedir(dir);
> +}
> +
> +static void
> +load_plugins(struct pevent *pevent, const char *suffix,
> + void (*load_plugin)(struct pevent *pevent,
> + const char *path,
> + const char *name,
> + void *data),
> + void *data)
> +{
> + char *home;
> + char *path;
> + char *envdir;
> +
> + /*
> + * If a system plugin directory was defined,
> + * check that first.
> + */
> +#ifdef PLUGIN_DIR
> + load_plugins_dir(pevent, suffix, PLUGIN_DIR, load_plugin, data);
> +#endif
> +
> + /*
> + * Next let the environment-set plugin directory
> + * override the system defaults.
> + */
> + envdir = getenv("TRACEEVENT_PLUGIN_DIR");
> + if (envdir)
> + load_plugins_dir(pevent, suffix, envdir, load_plugin, data);
> +
> + /*
> + * Now let the home directory override the environment
> + * or system defaults.
> + */
> + home = getenv("HOME");
> + if (!home)
> + return;
> +
> + path = malloc_or_die(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2);
> +
> + strcpy(path, home);
> + strcat(path, "/");
> + strcat(path, LOCAL_PLUGIN_DIR);
> +
> + load_plugins_dir(pevent, suffix, path, load_plugin, data);
> +
> + free(path);
> +}
> +
> +struct plugin_list*
> +traceevent_load_plugins(struct pevent *pevent)
> +{
> + struct plugin_list *list = NULL;
> +
> + load_plugins(pevent, ".so", load_plugin, &list);
> + return list;
> +}
> +
> +void
> +traceevent_unload_plugins(struct plugin_list *plugin_list)
> +{
> + pevent_plugin_unload_func func;
> + struct plugin_list *list;
> +
> + while (plugin_list) {
> + list = plugin_list;
> + plugin_list = list->next;
> + func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
> + if (func)
> + func();
> + dlclose(list->handle);
> + free(list->name);
> + free(list);
> + }
> +}
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index 214e17e..f6d720d 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -87,7 +87,7 @@ CFLAGS += -Wall
> CFLAGS += -Wextra
> CFLAGS += -std=gnu99
>
> -EXTLIBS = -lelf -lpthread -lrt -lm
> +EXTLIBS = -lelf -lpthread -lrt -lm -ldl
>
> ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
> CFLAGS += -fstack-protector-all
>



\
 
 \ /
  Last update: 2013-09-16 06:01    [W:0.159 / U:1.672 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site