Make libvirt a built-in plugin
Signed-off-by: Lon Hohberger <lhh@redhat.com>
This commit is contained in:
parent
e08f8eb7c9
commit
214f9b65bf
94
include/list.h
Normal file
94
include/list.h
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef _LIST_H
|
||||
#define _LIST_H
|
||||
|
||||
/**
|
||||
Simple list handlig macros.
|
||||
Needs rewrite or inclusion of /usr/include/linux/list.h as a replacement.
|
||||
*/
|
||||
|
||||
/* Must be first if structure is going to use it. */
|
||||
struct list_entry {
|
||||
struct list_entry *le_next, *le_prev;
|
||||
};
|
||||
|
||||
#define list_head() struct list_entry _list_head
|
||||
|
||||
#define le(p) (&((*p)._list_head))
|
||||
|
||||
#define list_insert(list, newnode) \
|
||||
do { \
|
||||
if (!(*list)) { \
|
||||
le(newnode)->le_next = \
|
||||
le(newnode)->le_prev = le(newnode); \
|
||||
*list = (void *)le(newnode); \
|
||||
} else { \
|
||||
le(*list)->le_prev->le_next = le(newnode); \
|
||||
le(newnode)->le_next = le(*list); \
|
||||
le(newnode)->le_prev = le(*list)->le_prev; \
|
||||
le(*list)->le_prev = le(newnode); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define list_prepend(list, newnode) \
|
||||
do { \
|
||||
list_insert(list, newnode); \
|
||||
*list = newnode; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define list_remove(list, oldnode) \
|
||||
do { \
|
||||
if (le(oldnode) == le(*list)) { \
|
||||
*list = (void *)le(*list)->le_next; \
|
||||
} \
|
||||
if (le(oldnode) == le(*list)) { \
|
||||
le(oldnode)->le_next = NULL; \
|
||||
le(oldnode)->le_prev = NULL; \
|
||||
*list = NULL; \
|
||||
} else { \
|
||||
le(oldnode)->le_next->le_prev = le(oldnode)->le_prev; \
|
||||
le(oldnode)->le_prev->le_next = le(oldnode)->le_next; \
|
||||
le(oldnode)->le_prev = NULL; \
|
||||
le(oldnode)->le_next = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
list_do(list, node) {
|
||||
stuff;
|
||||
} while (!list_done(list, node));
|
||||
*/
|
||||
#define list_do(list, curr) \
|
||||
if (*list && (curr = *list)) do
|
||||
|
||||
#define list_done(list, curr) \
|
||||
(curr && (((curr = (void *)le(curr)->le_next)) && (curr == *list)))
|
||||
|
||||
/*
|
||||
* list_for(list, tmp, counter) {
|
||||
* stuff;
|
||||
* }
|
||||
*
|
||||
* counter = # of items in list when done.
|
||||
* * sets cnt to 0 before even checking list;
|
||||
* * checks for valid list
|
||||
* * traverses list, incrementing counter. If we get to the for loop,
|
||||
* there must be at least one item in the list
|
||||
* * cnt ends up being the number of items in the list.
|
||||
*/
|
||||
#define list_for(list, curr, cnt) \
|
||||
if (!(cnt=0) && (list != NULL) && (*list != NULL)) \
|
||||
for (curr = *list; \
|
||||
(cnt == 0) || (curr != *list); \
|
||||
curr = (void*)le(curr)->le_next, \
|
||||
cnt++)
|
||||
|
||||
#define list_for_rev(list, curr, cnt) \
|
||||
if (!(cnt=0) && list && *list) \
|
||||
for (curr = (void *)(le(*list)->le_prev); \
|
||||
(cnt == 0) || ((void *)curr != le(*list)->le_prev); \
|
||||
curr = (void*)(le(curr)->le_prev), \
|
||||
cnt++)
|
||||
|
||||
#endif
|
@ -36,6 +36,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)(srv_context_t *c);
|
||||
typedef int (*fence_cleanup_callback)(srv_context_t c);
|
||||
|
||||
typedef struct _fence_callbacks {
|
||||
fence_null_callback null;
|
||||
fence_off_callback off;
|
||||
@ -45,10 +48,19 @@ typedef struct _fence_callbacks {
|
||||
fence_devstatus_callback devstatus;
|
||||
} fence_callbacks_t;
|
||||
|
||||
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;
|
||||
|
||||
extern fence_callbacks_t libvirt_callbacks;
|
||||
int libvirt_init(srv_context_t *c);
|
||||
int libvirt_shutdown(srv_context_t c);
|
||||
#ifndef _USE_MODULES
|
||||
void plugin_register(const plugin_t *plugin);
|
||||
const plugin_t *plugin_find(const char *name);
|
||||
void plugin_dump(void);
|
||||
#endif
|
||||
|
||||
|
||||
/* TODO: make these 'plugins' instead of static uses */
|
||||
@ -73,7 +85,7 @@ typedef struct {
|
||||
unsigned int auth;
|
||||
} mcast_options;
|
||||
|
||||
int mcast_init(srv_context_t *, fence_callbacks_t *,
|
||||
int mcast_init(srv_context_t *, const fence_callbacks_t *,
|
||||
mcast_options *, void *priv);
|
||||
int mcast_dispatch(srv_context_t, struct timeval *timeout);
|
||||
int mcast_shutdown(srv_context_t);
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
TARGETS=fence_virtd
|
||||
|
||||
fence_virtd_SOURCES = mcast.c libvirt.c main.c
|
||||
fence_virtd_SOURCES = mcast.c libvirt.c main.c plugin.c
|
||||
|
||||
INCLUDES=-I../include\
|
||||
-I/usr/include/openais -I/usr/include/libvirt \
|
||||
|
@ -57,6 +57,9 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#define NAME "libvirt"
|
||||
#define VERSION "0.1"
|
||||
|
||||
static inline int
|
||||
wait_domain(const char *vm_name, virConnectPtr vp, int timeout)
|
||||
{
|
||||
@ -273,7 +276,7 @@ libvirt_reboot(const char *vm_name, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
libvirt_init(srv_context_t *c)
|
||||
{
|
||||
virConnectPtr vp;
|
||||
@ -286,14 +289,14 @@ libvirt_init(srv_context_t *c)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
libvirt_shutdown(srv_context_t c)
|
||||
{
|
||||
return virConnectClose((virConnectPtr)c);
|
||||
}
|
||||
|
||||
|
||||
fence_callbacks_t libvirt_callbacks = {
|
||||
static fence_callbacks_t libvirt_callbacks = {
|
||||
.null = libvirt_null,
|
||||
.off = libvirt_off,
|
||||
.on = libvirt_on,
|
||||
@ -301,3 +304,26 @@ fence_callbacks_t libvirt_callbacks = {
|
||||
.status = libvirt_status,
|
||||
.devstatus = libvirt_devstatus
|
||||
};
|
||||
|
||||
#ifdef _MODULE
|
||||
fence_callbacks_t *
|
||||
plugin_callbacks(void)
|
||||
{
|
||||
return &libvirt_callbacks;
|
||||
}
|
||||
#else
|
||||
|
||||
static plugin_t libvirt_plugin = {
|
||||
.name = NAME,
|
||||
.version = VERSION,
|
||||
.callbacks = &libvirt_callbacks,
|
||||
.init = libvirt_init,
|
||||
.cleanup = libvirt_shutdown,
|
||||
};
|
||||
|
||||
static void __attribute__((constructor))
|
||||
initialize_plugin(void)
|
||||
{
|
||||
plugin_register(&libvirt_plugin);
|
||||
}
|
||||
#endif
|
||||
|
@ -14,21 +14,28 @@ extern fence_callbacks_t libvirt_callbacks; /* should be in a header */
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *plugin_name = "libvirt";
|
||||
const plugin_t *p;
|
||||
srv_context_t mcast_context;
|
||||
srv_context_t libvirt_context; /*XXX these should be differently
|
||||
named context types */
|
||||
|
||||
dset(99);
|
||||
|
||||
/* Only backend we have right now is basic libvirt */
|
||||
plugin_dump();
|
||||
|
||||
if (libvirt_init(&libvirt_context) < 0) {
|
||||
printf("Libvirt failed to initialize\n");
|
||||
p = plugin_find(plugin_name);
|
||||
if (!p) {
|
||||
printf("Could not find plugin \"%s\n", plugin_name);
|
||||
}
|
||||
|
||||
if (p->init(&libvirt_context) < 0) {
|
||||
printf("%s failed to initialize\n", plugin_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* only client we have now is mcast (fence_xvm behavior) */
|
||||
if (mcast_init(&mcast_context, &libvirt_callbacks, NULL,
|
||||
if (mcast_init(&mcast_context, p->callbacks, NULL,
|
||||
libvirt_context) < 0) {
|
||||
printf("Failed initialization!\n");
|
||||
return 1;
|
||||
@ -37,7 +44,7 @@ main(int argc, char **argv)
|
||||
while (mcast_dispatch(mcast_context, NULL) >= 0);
|
||||
|
||||
mcast_shutdown(mcast_context);
|
||||
libvirt_shutdown(libvirt_context);
|
||||
p->cleanup(libvirt_context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ typedef struct _mcast_info {
|
||||
void *priv;
|
||||
char key[MAX_KEY_LEN];
|
||||
mcast_options *args;
|
||||
fence_callbacks_t *cb;
|
||||
const fence_callbacks_t *cb;
|
||||
ssize_t key_len;
|
||||
int mc_sock;
|
||||
int need_kill;
|
||||
@ -280,7 +280,7 @@ mcast_dispatch(srv_context_t c, struct timeval *timeout)
|
||||
|
||||
|
||||
int
|
||||
mcast_init(srv_context_t *c, fence_callbacks_t *cb,
|
||||
mcast_init(srv_context_t *c, const fence_callbacks_t *cb,
|
||||
mcast_options *args, void *priv)
|
||||
{
|
||||
mcast_info *info;
|
||||
|
67
server/plugin.c
Normal file
67
server/plugin.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <stdio.h>
|
||||
#include <list.h>
|
||||
#include <server_plugin.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef struct _plugin_list {
|
||||
list_head();
|
||||
const plugin_t *plugin;
|
||||
} plugin_list_t;
|
||||
|
||||
static plugin_list_t *server_plugins = NULL;
|
||||
|
||||
void
|
||||
plugin_register(const plugin_t *plugin)
|
||||
{
|
||||
plugin_list_t *newplug;
|
||||
|
||||
newplug = malloc(sizeof(*newplug));
|
||||
if (!newplug)
|
||||
return;
|
||||
memset(newplug, 0, sizeof(*newplug));
|
||||
newplug->plugin = plugin;
|
||||
list_insert(&server_plugins, newplug);
|
||||
}
|
||||
|
||||
void
|
||||
plugin_dump(void)
|
||||
{
|
||||
plugin_list_t *p;
|
||||
int x;
|
||||
|
||||
list_for(&server_plugins, p, x) {
|
||||
printf("%s %s\n", p->plugin->name, p->plugin->version);
|
||||
}
|
||||
}
|
||||
|
||||
const plugin_t *
|
||||
plugin_find(const char *name)
|
||||
{
|
||||
plugin_list_t *p;
|
||||
int x;
|
||||
|
||||
list_for(&server_plugins, p, x) {
|
||||
if (!strcasecmp(name, p->plugin->name))
|
||||
return p->plugin;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
plugin_init(const plugin_t *p, srv_context_t *c)
|
||||
{
|
||||
return p->init(c);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
plugin_shutdown(const plugin_t *p, srv_context_t c)
|
||||
{
|
||||
return p->cleanup(c);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user