Make listeners plugins.
Signed-off-by: Lon Hohberger <lhh@redhat.com>
This commit is contained in:
parent
d6b557a407
commit
c6bf2d297a
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user