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
|
TARGETS=fence_virt fence_xvm
|
||||||
|
|
||||||
@ -21,8 +22,7 @@ INCLUDES=-I../include\
|
|||||||
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
||||||
-I/usr/include/libvirt
|
-I/usr/include/libvirt
|
||||||
|
|
||||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" \
|
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\"
|
||||||
-Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE
|
|
||||||
|
|
||||||
LIBS+=-L../../../cman/lib -L../../../ccs/lib -L${libdir}/openais \
|
LIBS+=-L../../../cman/lib -L../../../ccs/lib -L${libdir}/openais \
|
||||||
-L../../../dlm/lib -lnss3 -lxml2
|
-L../../../dlm/lib -lnss3 -lxml2
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
include ../Makefile.top
|
||||||
|
|
||||||
TARGETS=libfence_virt.a
|
TARGETS=libfence_virt.a
|
||||||
|
|
||||||
@ -22,8 +23,7 @@ INCLUDES=-I../include \
|
|||||||
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
-I../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
||||||
-I/usr/include/libvirt
|
-I/usr/include/libvirt
|
||||||
|
|
||||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" \
|
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\"
|
||||||
-Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE
|
|
||||||
|
|
||||||
LIBS+=-L../../../cman/lib -L../../../ccs/lib -L${libdir}/openais \
|
LIBS+=-L../../../cman/lib -L../../../ccs/lib -L${libdir}/openais \
|
||||||
-L../../../dlm/lib -lnss3 -lxml2
|
-L../../../dlm/lib -lnss3 -lxml2
|
||||||
|
@ -33,7 +33,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MODE_MULTICAST = 0,
|
MODE_MULTICAST = 0,
|
||||||
//MODE_BROADCAST = 1,
|
/*MODE_BROADCAST = 1,*/
|
||||||
MODE_SERIAL = 2,
|
MODE_SERIAL = 2,
|
||||||
MODE_VMCHANNEL = 3
|
MODE_VMCHANNEL = 3
|
||||||
} client_mode_t;
|
} client_mode_t;
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
#include <uuid/uuid.h>
|
#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;
|
typedef void * srv_context_t;
|
||||||
|
|
||||||
/* These callbacks hand requests off to the
|
/* These callbacks hand requests off to the
|
||||||
@ -56,10 +69,11 @@ typedef struct _backend_plugin {
|
|||||||
fence_cleanup_callback cleanup;
|
fence_cleanup_callback cleanup;
|
||||||
} plugin_t;
|
} plugin_t;
|
||||||
|
|
||||||
#ifndef _USE_MODULES
|
int plugin_register(const plugin_t *plugin);
|
||||||
void plugin_register(const plugin_t *plugin);
|
|
||||||
const plugin_t *plugin_find(const char *name);
|
const plugin_t *plugin_find(const char *name);
|
||||||
void plugin_dump(void);
|
void plugin_dump(void);
|
||||||
|
#ifdef _MODULE
|
||||||
|
int plugin_load(const char *libpath);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ typedef enum {
|
|||||||
AUTH_NONE = 0x0, /* Plain TCP */
|
AUTH_NONE = 0x0, /* Plain TCP */
|
||||||
AUTH_SHA1 = 0x1, /* Challenge-response (SHA1) */
|
AUTH_SHA1 = 0x1, /* Challenge-response (SHA1) */
|
||||||
AUTH_SHA256 = 0x2, /* Challenge-response (SHA256) */
|
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 */
|
/* AUTH_SSL_X509 = 0x10 SSL X509 certificates */
|
||||||
} fence_auth_type_t;
|
} 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\
|
INCLUDES=-I../include\
|
||||||
-I/usr/include/openais -I/usr/include/libvirt \
|
-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../../../cman/lib -I../../../ccs/lib -I/usr/include/libxml2 \
|
||||||
-I/usr/include/libvirt
|
-I/usr/include/libvirt
|
||||||
|
|
||||||
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" \
|
CFLAGS+=-DFENCE_RELEASE_NAME=\"devel\" -D_MODULE
|
||||||
-Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE
|
|
||||||
|
|
||||||
LIBS+=-L/usr/lib64/openais -lnss3 -lxml2 -lSaCkpt -lccs -lvirt -lcman \
|
LIBS+=-L/usr/lib64/openais -lnss3 -lxml2 -lSaCkpt -lccs -lvirt -lcman \
|
||||||
-L../common -lfence_virt
|
-L../common -lfence_virt
|
||||||
@ -32,6 +35,9 @@ all: ${TARGETS}
|
|||||||
fence_virtd: ${fence_virtd_SOURCES:.c=.o}
|
fence_virtd: ${fence_virtd_SOURCES:.c=.o}
|
||||||
gcc -o $@ $^ $(LIBS) -L../common -lfence_virt
|
gcc -o $@ $^ $(LIBS) -L../common -lfence_virt
|
||||||
|
|
||||||
|
libvirt.so: ${libvirt_so_SOURCES:.c=.o}
|
||||||
|
gcc -o $@ $^ $(LIBS) -shared -L../common -lvirt
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
gcc $(CFLAGS) -c -o $@ $^ $(INCLUDES)
|
gcc $(CFLAGS) -c -o $@ $^ $(INCLUDES)
|
||||||
|
|
||||||
|
@ -305,14 +305,6 @@ static fence_callbacks_t libvirt_callbacks = {
|
|||||||
.devstatus = libvirt_devstatus
|
.devstatus = libvirt_devstatus
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MODULE
|
|
||||||
fence_callbacks_t *
|
|
||||||
plugin_callbacks(void)
|
|
||||||
{
|
|
||||||
return &libvirt_callbacks;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
static plugin_t libvirt_plugin = {
|
static plugin_t libvirt_plugin = {
|
||||||
.name = NAME,
|
.name = NAME,
|
||||||
.version = VERSION,
|
.version = VERSION,
|
||||||
@ -321,8 +313,22 @@ static plugin_t libvirt_plugin = {
|
|||||||
.cleanup = libvirt_shutdown,
|
.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))
|
static void __attribute__((constructor))
|
||||||
initialize_plugin(void)
|
libvirt_register_plugin(void)
|
||||||
{
|
{
|
||||||
plugin_register(&libvirt_plugin);
|
plugin_register(&libvirt_plugin);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,11 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
dset(99);
|
dset(99);
|
||||||
|
|
||||||
|
#ifdef _MODULE
|
||||||
|
if (plugin_load("./libvirt.so") < 0) {
|
||||||
|
printf("Doom\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
plugin_dump();
|
plugin_dump();
|
||||||
|
|
||||||
p = plugin_find(plugin_name);
|
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 <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <server_plugin.h>
|
#include <server_plugin.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@ -12,17 +41,18 @@ typedef struct _plugin_list {
|
|||||||
|
|
||||||
static plugin_list_t *server_plugins = NULL;
|
static plugin_list_t *server_plugins = NULL;
|
||||||
|
|
||||||
void
|
int
|
||||||
plugin_register(const plugin_t *plugin)
|
plugin_register(const plugin_t *plugin)
|
||||||
{
|
{
|
||||||
plugin_list_t *newplug;
|
plugin_list_t *newplug;
|
||||||
|
|
||||||
newplug = malloc(sizeof(*newplug));
|
newplug = malloc(sizeof(*newplug));
|
||||||
if (!newplug)
|
if (!newplug)
|
||||||
return;
|
return -1;
|
||||||
memset(newplug, 0, sizeof(*newplug));
|
memset(newplug, 0, sizeof(*newplug));
|
||||||
newplug->plugin = plugin;
|
newplug->plugin = plugin;
|
||||||
list_insert(&server_plugins, newplug);
|
list_insert(&server_plugins, newplug);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -64,4 +94,101 @@ plugin_shutdown(const plugin_t *p, srv_context_t c)
|
|||||||
return p->cleanup(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