From 7356cb9627e941e66dbd90b6cc670a8427c88c5e Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Tue, 28 Apr 2015 06:09:21 +0200 Subject: Initial support for event engines --- pcilib/plugin.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 pcilib/plugin.c (limited to 'pcilib/plugin.c') diff --git a/pcilib/plugin.c b/pcilib/plugin.c new file mode 100644 index 0000000..663bb27 --- /dev/null +++ b/pcilib/plugin.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "model.h" +#include "pci.h" +#include "config.h" + +void *pcilib_plugin_load(const char *name) { + void *plug; + char *fullname; + const char *path; + + path = getenv("PCILIB_PLUGIN_DIR"); + if (!path) path = PCILIB_PLUGIN_DIR; + + fullname = malloc(strlen(path) + strlen(name) + 2); + if (!fullname) return NULL; + + sprintf(fullname, "%s/%s", path, name); + + plug = dlopen(fullname, RTLD_LAZY|RTLD_LOCAL); + free(fullname); + + return plug; +} + +void pcilib_plugin_close(void *plug) { + if (plug) + dlclose(plug); + +} + +void *pcilib_plugin_get_symbol(void *plug, const char *symbol) { + if ((!plug)||(!symbol)) return NULL; + return dlsym(plug, symbol); +} + +const pcilib_model_description_t *pcilib_get_plugin_model(pcilib_t *pcilib, void *plug, unsigned short vendor_id, unsigned short device_id, const char *model) { + void *get_model; + + if (!plug) return NULL; + + get_model = dlsym(plug, "pcilib_get_event_model"); + if (!get_model) return NULL; + + return ((const pcilib_model_description_t *(*)(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model))get_model)(pcilib, vendor_id, device_id, model); +} + +const pcilib_model_description_t *pcilib_find_plugin_model(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model) { + DIR *dir; + const char *path; + struct dirent *entry; + + void *plugin; + const pcilib_model_description_t *model_info = NULL; + + + path = getenv("PCILIB_PLUGIN_DIR"); + if (!path) path = PCILIB_PLUGIN_DIR; + + if (model) { + plugin = pcilib_plugin_load(model); + if (plugin) { + model_info = pcilib_get_plugin_model(pcilib, plugin, vendor_id, device_id, model); + if (model_info) { + pcilib->event_plugin = plugin; + return model_info; + } + pcilib_plugin_close(plugin); + } + } + + dir = opendir(path); + if (!dir) return NULL; + + while ((entry = readdir(dir))) { + const char *suffix = strstr(entry->d_name, ".so"); + if ((!suffix)||(strlen(suffix) != 3)) continue; + + if ((model)&&(!strcmp(entry->d_name, model))) + continue; + + plugin = pcilib_plugin_load(entry->d_name); + if (plugin) { + model_info = pcilib_get_plugin_model(pcilib, plugin, vendor_id, device_id, model); + if (model_info) { + pcilib->event_plugin = plugin; + break; + } + pcilib_plugin_close(plugin); + } + } + + closedir(dir); + return model_info; +} -- cgit v1.2.3