Implement new traceevent plugin API, which can be used to add new plugins directories: enum tep_plugin_load_priority { TEP_PLUGIN_FIRST, TEP_PLUGIN_LAST, }; int tep_add_plugin_path(struct tep_handle *tep, char *path, enum tep_plugin_load_priority prio); It adds the "path" as new plugin directory, in the context of the handler "tep". The tep_load_plugins() API searches for plugins in this new location. Depending of the priority "prio", the plugins from this directory are loaded before (TEP_PLUGIN_FIRST) or after (TEP_PLUGIN_LAST) the ordinary libtraceevent plugin locations. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx> --- include/traceevent/event-parse.h | 7 +++ lib/traceevent/event-parse-local.h | 5 ++- lib/traceevent/event-parse.c | 1 + lib/traceevent/event-plugin.c | 70 ++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/include/traceevent/event-parse.h b/include/traceevent/event-parse.h index 5dff952..d66647b 100644 --- a/include/traceevent/event-parse.h +++ b/include/traceevent/event-parse.h @@ -379,6 +379,13 @@ struct tep_plugin_list; #define INVALID_PLUGIN_LIST_OPTION ((char **)((unsigned long)-1)) +enum tep_plugin_load_priority { + TEP_PLUGIN_FIRST, + TEP_PLUGIN_LAST, +}; + +int tep_add_plugin_path(struct tep_handle *tep, char *path, + enum tep_plugin_load_priority prio); struct tep_plugin_list *tep_load_plugins(struct tep_handle *tep); void tep_unload_plugins(struct tep_plugin_list *plugin_list, struct tep_handle *tep); diff --git a/lib/traceevent/event-parse-local.h b/lib/traceevent/event-parse-local.h index 6e58ee1..abaeadf 100644 --- a/lib/traceevent/event-parse-local.h +++ b/lib/traceevent/event-parse-local.h @@ -13,6 +13,7 @@ struct func_map; struct func_list; struct event_handler; struct func_resolver; +struct tep_plugins_dir; struct tep_handle { int ref_count; @@ -47,7 +48,6 @@ struct tep_handle { struct printk_list *printklist; unsigned int printk_count; - struct tep_event **events; int nr_events; struct tep_event **sort_events; @@ -83,10 +83,13 @@ struct tep_handle { struct tep_event *last_event; char *trace_clock; + + struct tep_plugins_dir *plugins_dir; }; void tep_free_event(struct tep_event *event); void tep_free_format_field(struct tep_format_field *field); +void tep_free_plugin_paths(struct tep_handle *tep); unsigned short tep_data2host2(struct tep_handle *tep, unsigned short data); unsigned int tep_data2host4(struct tep_handle *tep, unsigned int data); diff --git a/lib/traceevent/event-parse.c b/lib/traceevent/event-parse.c index 7fbbbcc..b92e52c 100644 --- a/lib/traceevent/event-parse.c +++ b/lib/traceevent/event-parse.c @@ -7063,6 +7063,7 @@ void tep_free(struct tep_handle *tep) free(tep->events); free(tep->sort_events); free(tep->func_resolver); + tep_free_plugin_paths(tep); free(tep); } diff --git a/lib/traceevent/event-plugin.c b/lib/traceevent/event-plugin.c index 6ea4ac0..30c1526 100644 --- a/lib/traceevent/event-plugin.c +++ b/lib/traceevent/event-plugin.c @@ -39,6 +39,12 @@ struct tep_plugin_list { void *handle; }; +struct tep_plugins_dir { + struct tep_plugins_dir *next; + char *path; + enum tep_plugin_load_priority prio; +}; + static void lower_case(char *str) { if (!str) @@ -545,6 +551,7 @@ void tep_load_plugins_hook(struct tep_handle *tep, const char *suffix, void *data), void *data) { + struct tep_plugins_dir *dir = NULL; char *home; char *path; char *envdir; @@ -553,6 +560,15 @@ void tep_load_plugins_hook(struct tep_handle *tep, const char *suffix, if (tep && tep->flags & TEP_DISABLE_PLUGINS) return; + if (tep) + dir = tep->plugins_dir; + while (dir) { + if (dir->prio == TEP_PLUGIN_FIRST) + load_plugins_dir(tep, suffix, dir->path, + load_plugin, data); + dir = dir->next; + } + /* * If a system plugin directory was defined, * check that first. @@ -587,6 +603,15 @@ void tep_load_plugins_hook(struct tep_handle *tep, const char *suffix, load_plugins_dir(tep, suffix, path, load_plugin, data); + if (tep) + dir = tep->plugins_dir; + while (dir) { + if (dir->prio == TEP_PLUGIN_LAST) + load_plugins_dir(tep, suffix, dir->path, + load_plugin, data); + dir = dir->next; + } + free(path); } @@ -599,6 +624,51 @@ tep_load_plugins(struct tep_handle *tep) return list; } +/** + * tep_add_plugin_path - Add a new plugin directory. + * @tep: Trace event handler. + * @path: Path to a directory. All files with extension .so in that + * directory will be loaded as plugins. + *@prio: Load priority of the plugins in that directory. + * + * Returns -1 in case of an error, 0 otherwise. + */ +int tep_add_plugin_path(struct tep_handle *tep, char *path, + enum tep_plugin_load_priority prio) +{ + struct tep_plugins_dir *dir; + + if (!tep || !path) + return -1; + + dir = calloc(1, sizeof(*dir)); + if (!dir) + return -1; + + dir->path = strdup(path); + dir->prio = prio; + dir->next = tep->plugins_dir; + tep->plugins_dir = dir; + + return 0; +} + +void tep_free_plugin_paths(struct tep_handle *tep) +{ + struct tep_plugins_dir *dir; + + if (!tep) + return; + + dir = tep->plugins_dir; + while (dir) { + tep->plugins_dir = tep->plugins_dir->next; + free(dir->path); + free(dir); + dir = tep->plugins_dir; + } +} + void tep_unload_plugins(struct tep_plugin_list *plugin_list, struct tep_handle *tep) { -- 2.21.0
![]() |