Make listeners plugins.

Signed-off-by: Lon Hohberger <lhh@redhat.com>
This commit is contained in:
Lon Hohberger 2009-09-01 16:22:30 -04:00
parent d6b557a407
commit c6bf2d297a
5 changed files with 152 additions and 54 deletions

View File

@ -1,16 +1,16 @@
/* */
#include <uuid/uuid.h>
#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,
typedef int (*backend_init_fn)(backend_context_t *c,
config_object_t *config);
typedef int (*fence_cleanup_callback)(backend_context_t c);
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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;