Addition of the module info structure to allow module information to
be extracted from the modules. This gives a way to verify the API that the module provides as well as the version of that API. The hope is that this will make it possible for MaxScale to detect out of date plugins and either adapt to use them or reject loading them. Also added the ability to set a release state on a per module basis. This allows for production ready and non-production ready plugins to be identified.
This commit is contained in:
parent
f026cd9e77
commit
1245fba35b
@ -28,6 +28,7 @@
|
||||
* 14/06/13 Mark Riddoch Updated to add call to ModuleInit if one is
|
||||
* defined in the loaded module.
|
||||
* Also updated to call fixed GetModuleObject
|
||||
* 02/06/14 Mark Riddoch Addition of module info
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -38,6 +39,7 @@
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <modules.h>
|
||||
#include <modinfo.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
@ -47,10 +49,11 @@ static MODULES *registered = NULL;
|
||||
|
||||
static MODULES *find_module(const char *module);
|
||||
static void register_module(const char *module,
|
||||
const char *type,
|
||||
void *dlhandle,
|
||||
char *version,
|
||||
void *modobj);
|
||||
const char *type,
|
||||
void *dlhandle,
|
||||
char *version,
|
||||
void *modobj,
|
||||
MODULE_INFO *info);
|
||||
static void unregister_module(const char *module);
|
||||
|
||||
char* get_maxscale_home(void)
|
||||
@ -76,12 +79,13 @@ char* get_maxscale_home(void)
|
||||
void *
|
||||
load_module(const char *module, const char *type)
|
||||
{
|
||||
char *home, *version;
|
||||
char fname[MAXPATHLEN];
|
||||
void *dlhandle, *sym;
|
||||
char *(*ver)();
|
||||
void *(*ep)(), *modobj;
|
||||
MODULES *mod;
|
||||
char *home, *version;
|
||||
char fname[MAXPATHLEN];
|
||||
void *dlhandle, *sym;
|
||||
char *(*ver)();
|
||||
void *(*ep)(), *modobj;
|
||||
MODULES *mod;
|
||||
MODULE_INFO *mod_info = NULL;
|
||||
|
||||
if ((mod = find_module(module)) == NULL)
|
||||
{
|
||||
@ -141,6 +145,11 @@ MODULES *mod;
|
||||
ModuleInit();
|
||||
}
|
||||
|
||||
if ((sym = dlsym(dlhandle, "info")) != NULL)
|
||||
{
|
||||
mod_info = sym;
|
||||
}
|
||||
|
||||
if ((sym = dlsym(dlhandle, "GetModuleObject")) == NULL)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
@ -161,7 +170,7 @@ MODULES *mod;
|
||||
module,
|
||||
version,
|
||||
fname)));
|
||||
register_module(module, type, dlhandle, version, modobj);
|
||||
register_module(module, type, dlhandle, version, modobj, mod_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -227,7 +236,7 @@ MODULES *mod = registered;
|
||||
* @param modobj The module object
|
||||
*/
|
||||
static void
|
||||
register_module(const char *module, const char *type, void *dlhandle, char *version, void *modobj)
|
||||
register_module(const char *module, const char *type, void *dlhandle, char *version, void *modobj, MODULE_INFO *mod_info)
|
||||
{
|
||||
MODULES *mod;
|
||||
|
||||
@ -239,6 +248,7 @@ MODULES *mod;
|
||||
mod->version = strdup(version);
|
||||
mod->modobj = modobj;
|
||||
mod->next = registered;
|
||||
mod->info = mod_info;
|
||||
registered = mod;
|
||||
}
|
||||
|
||||
@ -303,11 +313,25 @@ dprintAllModules(DCB *dcb)
|
||||
{
|
||||
MODULES *ptr = registered;
|
||||
|
||||
dcb_printf(dcb, "%-15s | %-11s | Version\n", "Module Name", "Module Type");
|
||||
dcb_printf(dcb, "-----------------------------------------------------\n");
|
||||
dcb_printf(dcb, "%-15s | %-11s | Version | API | Status\n", "Module Name", "Module Type");
|
||||
dcb_printf(dcb, "--------------------------------------------------------------------------\n");
|
||||
while (ptr)
|
||||
{
|
||||
dcb_printf(dcb, "%-15s | %-11s | %s\n", ptr->module, ptr->type, ptr->version);
|
||||
dcb_printf(dcb, "%-15s | %-11s | %-7s ", ptr->module, ptr->type, ptr->version);
|
||||
if (ptr->info)
|
||||
dcb_printf(dcb, "| %d.%d.%d | %s",
|
||||
ptr->info->api_version.major,
|
||||
ptr->info->api_version.minor,
|
||||
ptr->info->api_version.patch,
|
||||
ptr->info->status == MODULE_IN_DEVELOPMENT
|
||||
? "In Development"
|
||||
: (ptr->info->status == MODULE_ALPHA_RELEASE
|
||||
? "Alpha"
|
||||
: (ptr->info->status == MODULE_BETA_RELEASE
|
||||
? "Beta"
|
||||
: (ptr->info->status == MODULE_GA
|
||||
? "GA" : "Unknown"))));
|
||||
dcb_printf(dcb, "\n");
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
#include <spinlock.h>
|
||||
#include <buffer.h>
|
||||
#include <modinfo.h>
|
||||
#include <gwbitmask.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <netinet/in.h>
|
||||
@ -93,6 +94,13 @@ typedef struct gw_protocol {
|
||||
int (*session)(struct dcb *, void *);
|
||||
} GWPROTOCOL;
|
||||
|
||||
/**
|
||||
* The GWPROTOCOL version data. The following should be updated whenever
|
||||
* the GWPROTOCOL structure is changed. See the rules defined in modinfo.h
|
||||
* that define how these numbers should change.
|
||||
*/
|
||||
#define GWPROTOCOL_VERSION {1, 0, 0}
|
||||
|
||||
/**
|
||||
* The statitics gathered on a descriptor control block
|
||||
*/
|
||||
|
85
server/include/modinfo.h
Normal file
85
server/include/modinfo.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef _MODINFO_H
|
||||
#define _MODINFO_H
|
||||
/*
|
||||
* This file is distributed as part of MaxScale. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
*
|
||||
* This program 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 General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modinfo.h The module information interface
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 02/06/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/**
|
||||
* The status of the module. This gives some idea of the module
|
||||
* maturity.
|
||||
*/
|
||||
typedef enum {
|
||||
MODULE_IN_DEVELOPMENT = 0,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
MODULE_BETA_RELEASE,
|
||||
MODULE_GA
|
||||
} MODULE_STATUS;
|
||||
|
||||
/**
|
||||
* The API implemented by the module
|
||||
*/
|
||||
typedef enum {
|
||||
MODULE_API_PROTOCOL = 0,
|
||||
MODULE_API_ROUTER,
|
||||
MODULE_API_MONITOR,
|
||||
MODULE_API_FILTER,
|
||||
MODULE_API_AUTHENTICATION
|
||||
} MODULE_API;
|
||||
|
||||
/**
|
||||
* The module version structure.
|
||||
*
|
||||
* The rules for changing these values are:
|
||||
*
|
||||
* Any change that affects an inexisting call in the API in question,
|
||||
* making the new API no longer compatible with the old,
|
||||
* must increment the major version.
|
||||
*
|
||||
* Any change that adds to the API, but does not alter the existing API
|
||||
* calls, must increment the minor version.
|
||||
*
|
||||
* Any change that is purely cosmetic and does not affect the calling
|
||||
* conventions of the API must increment only the patch version number.
|
||||
*/
|
||||
typedef struct {
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
} MODULE_VERSION;
|
||||
|
||||
/**
|
||||
* The module information structure
|
||||
*/
|
||||
typedef struct {
|
||||
MODULE_API modapi;
|
||||
MODULE_STATUS status;
|
||||
MODULE_VERSION api_version;
|
||||
char *description;
|
||||
} MODULE_INFO;
|
||||
#endif
|
@ -18,6 +18,7 @@
|
||||
* Copyright SkySQL Ab 2013
|
||||
*/
|
||||
#include <dcb.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
/**
|
||||
* @file modules.h Utilities for loading modules
|
||||
@ -39,6 +40,8 @@ typedef struct modules {
|
||||
char *version; /**< Module version */
|
||||
void *handle; /**< The handle returned by dlopen */
|
||||
void *modobj; /**< The module "object" this is the set of entry points */
|
||||
MODULE_INFO
|
||||
*info; /**< The module information */
|
||||
struct modules
|
||||
*next; /**< Next module in the linked list */
|
||||
} MODULES;
|
||||
|
@ -72,6 +72,12 @@ typedef struct {
|
||||
void (*replicationHeartbeat)(void *, int);
|
||||
} MONITOR_OBJECT;
|
||||
|
||||
/**
|
||||
* The monitor API version number. Any change to the monitor module API
|
||||
* must change these versions usign the rules defined in modinfo.h
|
||||
*/
|
||||
#define MONITOR_VERSION {1, 0, 0}
|
||||
|
||||
/**
|
||||
* Representation of the running monitor.
|
||||
*/
|
||||
|
@ -78,6 +78,13 @@ typedef struct router_object {
|
||||
uint8_t (*getCapabilities)(ROUTER *instance, void* router_session);
|
||||
} ROUTER_OBJECT;
|
||||
|
||||
/**
|
||||
* The router module API version. Any change that changes the router API
|
||||
* must update these versions numbers in accordance with the rules in
|
||||
* modinfo.h.
|
||||
*/
|
||||
#define ROUTER_VERSION { 1, 0, 0 }
|
||||
|
||||
typedef enum router_capability_t {
|
||||
RCAP_TYPE_UNDEFINED = 0,
|
||||
RCAP_TYPE_STMT_INPUT = (1 << 0),
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <log_manager.h>
|
||||
#include <secrets.h>
|
||||
#include <dcb.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
@ -51,6 +52,13 @@ static void monitorMain(void *);
|
||||
|
||||
static char *version_str = "V1.2.0";
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_MONITOR,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
MONITOR_VERSION,
|
||||
"A Galera cluster monitor"
|
||||
};
|
||||
|
||||
static void *startMonitor(void *);
|
||||
static void stopMonitor(void *);
|
||||
static void registerServer(void *, SERVER *);
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <log_manager.h>
|
||||
#include <secrets.h>
|
||||
#include <dcb.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
@ -55,6 +56,13 @@ static void monitorMain(void *);
|
||||
|
||||
static char *version_str = "V1.2.0";
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_MONITOR,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
MONITOR_VERSION,
|
||||
"A MySQL Master/Slave replication monitor"
|
||||
};
|
||||
|
||||
static void *startMonitor(void *);
|
||||
static void stopMonitor(void *);
|
||||
static void registerServer(void *, SERVER *);
|
||||
|
@ -39,6 +39,14 @@
|
||||
|
||||
#include <httpd.h>
|
||||
#include <gw.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_IN_DEVELOPMENT,
|
||||
GWPROTOCOL_VERSION,
|
||||
"An experimental HTTPD implementation for use in admnistration"
|
||||
};
|
||||
|
||||
#define ISspace(x) isspace((int)(x))
|
||||
#define HTTP_SERVER_STRING "Gateway(c) v.1.0.0"
|
||||
|
@ -43,6 +43,14 @@
|
||||
* 27/09/2013 Massimiliano Pinto Changed in gw_read_backend_event the check for dcb_read(), now is if rc < 0
|
||||
*
|
||||
*/
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
GWPROTOCOL_VERSION,
|
||||
"The MySQL to backend server protocol"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
|
@ -40,6 +40,14 @@
|
||||
#include <log_manager.h>
|
||||
#include <mysql_client_server_protocol.h>
|
||||
#include <gw.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
GWPROTOCOL_VERSION,
|
||||
"The client to MaxScale MySQL protocol implementation"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
|
@ -36,6 +36,14 @@
|
||||
#include <adminusers.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
GWPROTOCOL_VERSION,
|
||||
"A telnet deamon protocol for simple administration interface"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <session.h>
|
||||
#include <router.h>
|
||||
#include <modules.h>
|
||||
#include <modinfo.h>
|
||||
#include <atomic.h>
|
||||
#include <spinlock.h>
|
||||
#include <dcb.h>
|
||||
@ -43,6 +44,14 @@
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_ROUTER,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
ROUTER_VERSION,
|
||||
"The debug user interface"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
static char *version_str = "V1.1.1";
|
||||
|
@ -79,6 +79,7 @@
|
||||
#include <readconnection.h>
|
||||
#include <dcb.h>
|
||||
#include <spinlock.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
#include <skygw_types.h>
|
||||
#include <skygw_utils.h>
|
||||
@ -88,6 +89,13 @@
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_ROUTER,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
ROUTER_VERSION,
|
||||
"A connection based router to load balance based on connections"
|
||||
};
|
||||
|
||||
static char *version_str = "V1.0.2";
|
||||
|
||||
/* The router entry points */
|
||||
|
@ -30,6 +30,15 @@
|
||||
#include <query_classifier.h>
|
||||
#include <dcb.h>
|
||||
#include <spinlock.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_ROUTER,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
ROUTER_VERSION,
|
||||
"A Read/Write splitting router for enhancement read scalability"
|
||||
};
|
||||
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
@ -2450,4 +2459,4 @@ static void rwsplit_process_options(
|
||||
}
|
||||
}
|
||||
} /*< for */
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,17 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <router.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
static char *version_str = "V1.0.0";
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_ROUTER,
|
||||
MODULE_IN_DEVELOPMENT,
|
||||
ROUTER_VERSION,
|
||||
"A test router - not for use in real systems"
|
||||
};
|
||||
|
||||
static ROUTER *createInstance(SERVICE *service, char **options);
|
||||
static void *newSession(ROUTER *instance, SESSION *session);
|
||||
static void closeSession(ROUTER *instance, void *session);
|
||||
@ -145,4 +153,4 @@ static uint8_t getCapabilities(
|
||||
void* router_session)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user