Make libvirt a built-in plugin

Signed-off-by: Lon Hohberger <lhh@redhat.com>
This commit is contained in:
Lon Hohberger 2009-08-12 13:20:50 -04:00
parent e08f8eb7c9
commit 214f9b65bf
7 changed files with 221 additions and 15 deletions

94
include/list.h Normal file
View 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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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);
}