From c6bf2d297a1207d8944b26ee9fc549898333224a Mon Sep 17 00:00:00 2001 From: Lon Hohberger Date: Tue, 1 Sep 2009 16:22:30 -0400 Subject: [PATCH] Make listeners plugins. Signed-off-by: Lon Hohberger --- include/server_plugin.h | 61 ++++++++++++++++++++++---------- server/libvirt.c | 4 +-- server/main.c | 23 +++++++----- server/mcast.c | 40 +++++++++++++++++++-- server/plugin.c | 78 +++++++++++++++++++++++++++++------------ 5 files changed, 152 insertions(+), 54 deletions(-) diff --git a/include/server_plugin.h b/include/server_plugin.h index 77c05a8..6311d3d 100644 --- a/include/server_plugin.h +++ b/include/server_plugin.h @@ -1,16 +1,16 @@ /* */ #include -#define PLUGIN_VERSION_FRONTEND ((double)0.1) +#define PLUGIN_VERSION_LISTENER ((double)0.1) #define PLUGIN_VERSION_BACKEND ((double)0.1) -#define FRONTEND_VER_SYM frontend_plugin_version +#define LISTENER_VER_SYM listener_plugin_version #define BACKEND_VER_SYM backend_plugin_version -#define FRONTEND_INFO_SYM frontend_plugin_info +#define LISTENER_INFO_SYM listener_plugin_info #define BACKEND_INFO_SYM backend_plugin_info -#define FRONTEND_VER_STR "frontend_plugin_version" +#define LISTENER_VER_STR "listener_plugin_version" #define BACKEND_VER_STR "backend_plugin_version" -#define FRONTEND_INFO_STR "frontend_plugin_info" +#define LISTENER_INFO_STR "listener_plugin_info" #define BACKEND_INFO_STR "backend_plugin_info" @@ -50,9 +50,9 @@ typedef int (*fence_status_callback)(const char *vm_name, is responding to requests. */ typedef int (*fence_devstatus_callback)(void *priv); -typedef int (*fence_init_callback)(backend_context_t *c, - config_object_t *config); -typedef int (*fence_cleanup_callback)(backend_context_t c); +typedef int (*backend_init_fn)(backend_context_t *c, + config_object_t *config); +typedef int (*backend_cleanup_fn)(backend_context_t c); typedef struct _fence_callbacks { fence_null_callback null; @@ -63,16 +63,44 @@ typedef struct _fence_callbacks { fence_devstatus_callback devstatus; } fence_callbacks_t; -typedef struct _backend_plugin { +typedef struct backend_plugin { const char *name; const char *version; const fence_callbacks_t *callbacks; - fence_init_callback init; - fence_cleanup_callback cleanup; -} plugin_t; + backend_init_fn init; + backend_cleanup_fn cleanup; +} backend_plugin_t; + + +typedef int (*listener_init_fn)(listener_context_t *c, + const fence_callbacks_t *cb, + config_object_t *config, + void *priv); +typedef int (*listener_dispatch_fn)(listener_context_t c, + struct timeval *timeout); +typedef int (*listener_cleanup_fn)(listener_context_t c); + + +typedef struct listener_plugin { + const char *name; + const char *version; + listener_init_fn init; + listener_dispatch_fn dispatch; + listener_cleanup_fn cleanup; +} listener_plugin_t; + + +typedef enum { + PLUGIN_NONE = 0, + PLUGIN_LISTENER = 1, + PLUGIN_BACKEND = 2 +} plugin_type_t; + +int plugin_reg_backend(const backend_plugin_t *plugin); +int plugin_reg_listener(const listener_plugin_t *plugin); +const backend_plugin_t *plugin_find_backend(const char *name); +const listener_plugin_t *plugin_find_listener(const char *name); -int plugin_register(const plugin_t *plugin); -const plugin_t *plugin_find(const char *name); void plugin_dump(void); #ifdef _MODULE int plugin_load(const char *libpath); @@ -91,8 +119,3 @@ int serial_init(listener_context_t *, fence_callbacks_t *, int serial_dispatch(listener_context_t, struct timeval *timeout); int serial_shutdown(listener_context_t); -int mcast_init(listener_context_t *, const fence_callbacks_t *, - config_object_t *, void *priv); -int mcast_dispatch(listener_context_t, struct timeval *timeout); -int mcast_shutdown(listener_context_t); - diff --git a/server/libvirt.c b/server/libvirt.c index d1fea4d..757b767 100644 --- a/server/libvirt.c +++ b/server/libvirt.c @@ -412,7 +412,7 @@ static fence_callbacks_t libvirt_callbacks = { .devstatus = libvirt_devstatus }; -static plugin_t libvirt_plugin = { +static backend_plugin_t libvirt_plugin = { .name = NAME, .version = VERSION, .callbacks = &libvirt_callbacks, @@ -428,7 +428,7 @@ BACKEND_VER_SYM(void) return PLUGIN_VERSION_BACKEND; } -const plugin_t * +const backend_plugin_t * BACKEND_INFO_SYM(void) { return &libvirt_plugin; diff --git a/server/main.c b/server/main.c index b983f03..c19ce78 100644 --- a/server/main.c +++ b/server/main.c @@ -20,7 +20,8 @@ main(int argc, char **argv) char backend_name[80]; const char *config_file = DEFAULT_CONFIG_FILE; config_object_t *config; - const plugin_t *p; + const listener_plugin_t *lp; + const backend_plugin_t *p; listener_context_t listener_ctx = NULL; backend_context_t backend_ctx = NULL; int debug_set = 0; @@ -82,27 +83,33 @@ main(int argc, char **argv) #endif plugin_dump(); - p = plugin_find(backend_name); + lp = plugin_find_listener(listener_name); + if (!lp) { + printf("Could not find listener \"%s\"\n", listener_name); + return 1; + } + + p = plugin_find_backend(backend_name); if (!p) { - printf("Could not find plugin \"%s\n", val); + printf("Could not find backend \"%s\n", backend_name); return 1; } if (p->init(&backend_ctx, config) < 0) { - printf("%s failed to initialize\n", val); + printf("%s failed to initialize\n", backend_name); return 1; } /* only client we have now is mcast (fence_xvm behavior) */ - if (mcast_init(&listener_ctx, p->callbacks, config, + if (lp->init(&listener_ctx, p->callbacks, config, backend_ctx) < 0) { - printf("Failed initialization!\n"); + printf("%s failed to initialize\n", listener_name); return 1; } - while (mcast_dispatch(listener_ctx, NULL) >= 0); + while (lp->dispatch(listener_ctx, NULL) >= 0); - mcast_shutdown(listener_ctx); + lp->cleanup(listener_ctx); p->cleanup(backend_ctx); return 0; diff --git a/server/mcast.c b/server/mcast.c index 7886880..8ff676a 100644 --- a/server/mcast.c +++ b/server/mcast.c @@ -54,6 +54,9 @@ #include "tcp.h" #include "debug.h" +#define NAME "multicast" +#define VERSION "1.0" + #define MCAST_MAGIC 0xaabab1b34b911a #define VALIDATE(info) \ @@ -255,7 +258,7 @@ out: } -int +static int mcast_dispatch(listener_context_t c, struct timeval *timeout) { mcast_info *info; @@ -461,7 +464,7 @@ mcast_config(config_object_t *config, mcast_options *args) } -int +static int mcast_init(listener_context_t *c, const fence_callbacks_t *cb, config_object_t *config, void *priv) { @@ -524,7 +527,7 @@ mcast_init(listener_context_t *c, const fence_callbacks_t *cb, } -int +static int mcast_shutdown(listener_context_t c) { mcast_info *info = (mcast_info *)c; @@ -538,3 +541,34 @@ mcast_shutdown(listener_context_t c) return 0; } + + +static listener_plugin_t mcast_plugin = { + .name = NAME, + .version = VERSION, + .init = mcast_init, + .dispatch = mcast_dispatch, + .cleanup = mcast_shutdown, +}; + + +#ifdef _MODULE_FOO +double +LISTENER_VER_SYM(void) +{ + return PLUGIN_VERSION_LISTENER; +} + +const listener_plugin_t * +LISTENER_INFO_SYM(void) +{ + return &mcast_plugin; +} +#else +static void __attribute__((constructor)) +mcast_register_plugin(void) +{ + plugin_reg_listener(&mcast_plugin); +} +#endif + diff --git a/server/plugin.c b/server/plugin.c index 49b61ce..521716f 100644 --- a/server/plugin.c +++ b/server/plugin.c @@ -37,13 +37,15 @@ typedef struct _plugin_list { list_head(); - const plugin_t *plugin; + const listener_plugin_t *listener; + const backend_plugin_t *backend; + plugin_type_t type; } plugin_list_t; static plugin_list_t *server_plugins = NULL; int -plugin_register(const plugin_t *plugin) +plugin_reg_backend(const backend_plugin_t *plugin) { plugin_list_t *newplug; @@ -51,11 +53,31 @@ plugin_register(const plugin_t *plugin) if (!newplug) return -1; memset(newplug, 0, sizeof(*newplug)); - newplug->plugin = plugin; + newplug->backend = plugin; + newplug->type = PLUGIN_BACKEND; + list_insert(&server_plugins, newplug); return 0; } + +int +plugin_reg_listener(const listener_plugin_t *plugin) +{ + plugin_list_t *newplug; + + newplug = malloc(sizeof(*newplug)); + if (!newplug) + return -1; + memset(newplug, 0, sizeof(*newplug)); + newplug->listener = plugin; + newplug->type = PLUGIN_LISTENER; + + list_insert(&server_plugins, newplug); + return 0; +} + + void plugin_dump(void) { @@ -63,54 +85,66 @@ plugin_dump(void) int x; list_for(&server_plugins, p, x) { - printf("%s %s\n", p->plugin->name, p->plugin->version); + if (p->type == PLUGIN_BACKEND) { + printf("backend: %s %s\n", + p->backend->name, p->backend->version); + } else if (p->type == PLUGIN_LISTENER) { + printf("listener: %s %s\n", + p->listener->name, p->listener->version); + } } } -const plugin_t * -plugin_find(const char *name) +const backend_plugin_t * +plugin_find_backend(const char *name) { plugin_list_t *p; int x; list_for(&server_plugins, p, x) { - if (!strcasecmp(name, p->plugin->name)) - return p->plugin; + if (p->type != PLUGIN_BACKEND) + continue; + if (!strcasecmp(name, p->backend->name)) + return p->backend; } return NULL; } -int -plugin_init(const plugin_t *p, backend_context_t *c, config_object_t *config) +const listener_plugin_t * +plugin_find_listener(const char *name) { - return p->init(c, config); + plugin_list_t *p; + int x; + + list_for(&server_plugins, p, x) { + if (p->type != PLUGIN_LISTENER) + continue; + if (!strcasecmp(name, p->listener->name)) + return p->listener; + } + + return NULL; } -int -plugin_shutdown(const plugin_t *p, backend_context_t c) -{ - return p->cleanup(c); -} - /** * Load a cluster plugin .so file and map all the functions - * provided to entries in a plugin_t structure. + * provided to entries in a backend_plugin_t structure. * * @param libpath Path to file. * @return NULL on failure, or plugin-specific - * (const) plugin_t * structure on + * (const) backend_plugin_t * structure on * success. */ int plugin_load(const char *libpath) { void *handle = NULL; - const plugin_t *plug = NULL; + const backend_plugin_t *plug = NULL; double (*modversion)(void); - plugin_t *(*modinfo)(void); + backend_plugin_t *(*modinfo)(void); struct stat sb; errno = 0; @@ -182,7 +216,7 @@ plugin_load(const char *libpath) } plug = modinfo(); - if (plugin_register(plug) < 0) { + if (plugin_reg_backend(plug) < 0) { dlclose(handle); errno = EINVAL; return -1;