forked from altcloud/fence-virt
Create server-side plugin architecture
Signed-off-by: Lon Hohberger <lhh@redhat.com>
This commit is contained in:
parent
aa4d011b75
commit
9ec497ddc6
1
Makefile.top
Normal file
1
Makefile.top
Normal file
@ -0,0 +1 @@
|
||||
CFLAGS=-fPIC -Wall -Wstrict-prototypes -Werror -ggdb -D_GNU_SOURCE
|
@ -10,6 +10,7 @@
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
|
||||
include=../Makefile.top
|
||||
|
||||
TARGETS=fence_virt fence_xvm
|
||||
|
||||
@ -21,8 +22,7 @@ INCLUDES=-I../include\
|
||||
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
||||
-I/usr/include/libvirt
|
||||
|
||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" \
|
||||
-Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE
|
||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\"
|
||||
|
||||
LIBS+=-L../../../cman/lib -L../../../ccs/lib -L${libdir}/openais \
|
||||
-L../../../dlm/lib -lnss3 -lxml2
|
||||
|
@ -10,6 +10,7 @@
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
|
||||
include ../Makefile.top
|
||||
|
||||
TARGETS=libfence_virt.a
|
||||
|
||||
@ -22,8 +23,7 @@ INCLUDES=-I../include \
|
||||
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
||||
-I/usr/include/libvirt
|
||||
|
||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" \
|
||||
-Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE
|
||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\"
|
||||
|
||||
LIBS+=-L../../../cman/lib -L../../../ccs/lib -L${libdir}/openais \
|
||||
-L../../../dlm/lib -lnss3 -lxml2
|
||||
|
@ -33,7 +33,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
MODE_MULTICAST = 0,
|
||||
//MODE_BROADCAST = 1,
|
||||
/*MODE_BROADCAST = 1,*/
|
||||
MODE_SERIAL = 2,
|
||||
MODE_VMCHANNEL = 3
|
||||
} client_mode_t;
|
||||
|
@ -1,8 +1,21 @@
|
||||
|
||||
/* */
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#define PLUGIN_VERSION_FRONTEND ((double)0.1)
|
||||
#define PLUGIN_VERSION_BACKEND ((double)0.1)
|
||||
|
||||
#define FRONTEND_VER_SYM frontend_plugin_version
|
||||
#define BACKEND_VER_SYM backend_plugin_version
|
||||
#define FRONTEND_INFO_SYM frontend_plugin_info
|
||||
#define BACKEND_INFO_SYM backend_plugin_info
|
||||
#define FRONTEND_VER_STR "frontend_plugin_version"
|
||||
#define BACKEND_VER_STR "backend_plugin_version"
|
||||
#define FRONTEND_INFO_STR "frontend_plugin_info"
|
||||
#define BACKEND_INFO_STR "backend_plugin_info"
|
||||
|
||||
|
||||
|
||||
|
||||
typedef void * srv_context_t;
|
||||
|
||||
/* These callbacks hand requests off to the
|
||||
@ -56,10 +69,11 @@ typedef struct _backend_plugin {
|
||||
fence_cleanup_callback cleanup;
|
||||
} plugin_t;
|
||||
|
||||
#ifndef _USE_MODULES
|
||||
void plugin_register(const plugin_t *plugin);
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ typedef enum {
|
||||
AUTH_NONE = 0x0, /* Plain TCP */
|
||||
AUTH_SHA1 = 0x1, /* Challenge-response (SHA1) */
|
||||
AUTH_SHA256 = 0x2, /* Challenge-response (SHA256) */
|
||||
AUTH_SHA512 = 0x3, /* Challenge-response (SHA512) */
|
||||
AUTH_SHA512 = 0x3 /* Challenge-response (SHA512) */
|
||||
/* AUTH_SSL_X509 = 0x10 SSL X509 certificates */
|
||||
} fence_auth_type_t;
|
||||
|
||||
|
@ -10,10 +10,14 @@
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
|
||||
include ../Makefile.top
|
||||
|
||||
TARGETS=fence_virtd
|
||||
|
||||
fence_virtd_SOURCES = mcast.c libvirt.c main.c plugin.c
|
||||
TARGETS=fence_virtd libvirt.so
|
||||
|
||||
fence_virtd_SOURCES = mcast.c main.c plugin.c
|
||||
|
||||
libvirt_so_SOURCES = libvirt.c
|
||||
|
||||
INCLUDES=-I../include\
|
||||
-I/usr/include/openais -I/usr/include/libvirt \
|
||||
@ -21,8 +25,7 @@ INCLUDES=-I../include\
|
||||
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
||||
-I/usr/include/libvirt
|
||||
|
||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" \
|
||||
-Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE
|
||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" -D_MODULE
|
||||
|
||||
LIBS+=-L/usr/lib64/openais -lnss3 -lxml2 -lSaCkpt -lccs -lvirt -lcman \
|
||||
-L../common -lfence_virt
|
||||
@ -32,6 +35,9 @@ all: ${TARGETS}
|
||||
fence_virtd: ${fence_virtd_SOURCES:.c=.o}
|
||||
gcc -o $@ $^ $(LIBS) -L../common -lfence_virt
|
||||
|
||||
libvirt.so: ${libvirt_so_SOURCES:.c=.o}
|
||||
gcc -o $@ $^ $(LIBS) -shared -L../common -lvirt
|
||||
|
||||
%.o: %.c
|
||||
gcc $(CFLAGS) -c -o $@ $^ $(INCLUDES)
|
||||
|
||||
|
@ -305,14 +305,6 @@ static fence_callbacks_t libvirt_callbacks = {
|
||||
.devstatus = libvirt_devstatus
|
||||
};
|
||||
|
||||
#ifdef _MODULE
|
||||
fence_callbacks_t *
|
||||
plugin_callbacks(void)
|
||||
{
|
||||
return &libvirt_callbacks;
|
||||
}
|
||||
#else
|
||||
|
||||
static plugin_t libvirt_plugin = {
|
||||
.name = NAME,
|
||||
.version = VERSION,
|
||||
@ -321,8 +313,22 @@ static plugin_t libvirt_plugin = {
|
||||
.cleanup = libvirt_shutdown,
|
||||
};
|
||||
|
||||
|
||||
#ifdef _MODULE
|
||||
double
|
||||
BACKEND_VER_SYM(void)
|
||||
{
|
||||
return PLUGIN_VERSION_BACKEND;
|
||||
}
|
||||
|
||||
const plugin_t *
|
||||
BACKEND_INFO_SYM(void)
|
||||
{
|
||||
return &libvirt_plugin;
|
||||
}
|
||||
#else
|
||||
static void __attribute__((constructor))
|
||||
initialize_plugin(void)
|
||||
libvirt_register_plugin(void)
|
||||
{
|
||||
plugin_register(&libvirt_plugin);
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ main(int argc, char **argv)
|
||||
|
||||
dset(99);
|
||||
|
||||
#ifdef _MODULE
|
||||
if (plugin_load("./libvirt.so") < 0) {
|
||||
printf("Doom\n");
|
||||
}
|
||||
#endif
|
||||
plugin_dump();
|
||||
|
||||
p = plugin_find(plugin_name);
|
||||
|
131
server/plugin.c
131
server/plugin.c
@ -1,4 +1,33 @@
|
||||
/*
|
||||
Copyright Red Hat, Inc. 2002-2004, 2009
|
||||
|
||||
The Magma Cluster API Library is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The Magma Cluster API Library is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA.
|
||||
*/
|
||||
/** @file
|
||||
* Plugin loading routines
|
||||
*/
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <list.h>
|
||||
#include <server_plugin.h>
|
||||
#include <malloc.h>
|
||||
@ -12,17 +41,18 @@ typedef struct _plugin_list {
|
||||
|
||||
static plugin_list_t *server_plugins = NULL;
|
||||
|
||||
void
|
||||
int
|
||||
plugin_register(const plugin_t *plugin)
|
||||
{
|
||||
plugin_list_t *newplug;
|
||||
|
||||
newplug = malloc(sizeof(*newplug));
|
||||
if (!newplug)
|
||||
return;
|
||||
return -1;
|
||||
memset(newplug, 0, sizeof(*newplug));
|
||||
newplug->plugin = plugin;
|
||||
list_insert(&server_plugins, newplug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -64,4 +94,101 @@ plugin_shutdown(const plugin_t *p, srv_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.
|
||||
*
|
||||
* @param libpath Path to file.
|
||||
* @return NULL on failure, or plugin-specific
|
||||
* (const) plugin_t * structure on
|
||||
* success.
|
||||
*/
|
||||
int
|
||||
plugin_load(const char *libpath)
|
||||
{
|
||||
void *handle = NULL;
|
||||
const plugin_t *plug = NULL;
|
||||
double (*modversion)(void);
|
||||
plugin_t *(*modinfo)(void);
|
||||
struct stat sb;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (!libpath) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stat(libpath, &sb) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
If it's not owner-readable or it's a directory,
|
||||
ignore/fail. Thus, a user may change the permission of
|
||||
a plugin "u-r" and this would then prevent magma apps
|
||||
from loading it.
|
||||
*/
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
errno = EISDIR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(sb.st_mode & S_IRUSR)) {
|
||||
#ifdef DEBUG
|
||||
printf("Ignoring %s (User-readable bit not set)\n",
|
||||
libpath);
|
||||
#endif
|
||||
errno = EPERM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle = dlopen(libpath, RTLD_LAZY);
|
||||
if (!handle) {
|
||||
errno = ELIBACC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
modversion = dlsym(handle, BACKEND_VER_STR);
|
||||
if (!modversion) {
|
||||
#ifdef DEBUG
|
||||
printf("Failed to map %s\n", BACKEND_VER_STR);
|
||||
#endif
|
||||
dlclose(handle);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (modversion() != PLUGIN_VERSION_BACKEND) {
|
||||
#ifdef DEBUG
|
||||
printf("API version mismatch in %s: \n"
|
||||
" %f expected; %f received.\n", libpath,
|
||||
, modversion());
|
||||
#endif
|
||||
dlclose(handle);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
modinfo = dlsym(handle, BACKEND_INFO_STR);
|
||||
if (!modinfo) {
|
||||
#ifdef DEBUG
|
||||
printf("Failed to map %s\n", BACKEND_INFO_STR);
|
||||
#endif
|
||||
dlclose(handle);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
plug = modinfo();
|
||||
if (plugin_register(plug) < 0) {
|
||||
dlclose(handle);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
} else {
|
||||
printf("Registered plugin %s %s\n",
|
||||
plug->name, plug->version);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user