From 4089b6b6fd66bf15139de66b00f6d8fb64e71b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 6 Feb 2018 08:31:16 +0200 Subject: [PATCH] MXS-1647: Detect API version mismatch If the API versions do not match, MaxScale will treat this as an error. The API versioning would allow backwards compatible changes but the functionality to handle that is not implemented in MaxScale. Updated API versions based on changes done to module APIs in 2.2. --- include/maxscale/filter.h | 2 +- include/maxscale/monitor.h | 2 +- include/maxscale/query_classifier.h | 2 +- include/maxscale/router.h | 2 +- .../qc_mysqlembedded/qc_mysqlembedded.cc | 2 +- query_classifier/qc_sqlite/qc_sqlite.cc | 2 +- server/core/load_utils.cc | 62 +++++++++++++++++++ 7 files changed, 68 insertions(+), 6 deletions(-) diff --git a/include/maxscale/filter.h b/include/maxscale/filter.h index 4a7c84020..5aae90767 100644 --- a/include/maxscale/filter.h +++ b/include/maxscale/filter.h @@ -214,7 +214,7 @@ typedef struct mxs_filter_object * is changed these values must be updated in line with the rules in the * file modinfo.h. */ -#define MXS_FILTER_VERSION {2, 2, 0} +#define MXS_FILTER_VERSION {3, 0, 0} /** * MXS_FILTER_DEF represents a filter definition from the configuration file. diff --git a/include/maxscale/monitor.h b/include/maxscale/monitor.h index b8d9450d8..7b5a66916 100644 --- a/include/maxscale/monitor.h +++ b/include/maxscale/monitor.h @@ -95,7 +95,7 @@ typedef struct mxs_monitor_object * The monitor API version number. Any change to the monitor module API * must change these versions using the rules defined in modinfo.h */ -#define MXS_MONITOR_VERSION {3, 0, 0} +#define MXS_MONITOR_VERSION {3, 1, 0} /** * Specifies capabilities specific for monitor. diff --git a/include/maxscale/query_classifier.h b/include/maxscale/query_classifier.h index 34396ba09..fce557878 100644 --- a/include/maxscale/query_classifier.h +++ b/include/maxscale/query_classifier.h @@ -17,7 +17,7 @@ MXS_BEGIN_DECLS -#define QUERY_CLASSIFIER_VERSION {1, 1, 0} +#define MXS_QUERY_CLASSIFIER_VERSION {2, 0, 0} /** * qc_init_kind_t specifies what kind of initialization should be performed. diff --git a/include/maxscale/router.h b/include/maxscale/router.h index 92df7af60..a545d3597 100644 --- a/include/maxscale/router.h +++ b/include/maxscale/router.h @@ -218,7 +218,7 @@ typedef struct mxs_router_object * must update these versions numbers in accordance with the rules in * modinfo.h. */ -#define MXS_ROUTER_VERSION { 2, 0, 0 } +#define MXS_ROUTER_VERSION { 3, 0, 0 } /** * Specifies capabilities specific for routers. Common capabilities diff --git a/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc b/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc index e398a343d..4298ff604 100644 --- a/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc +++ b/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc @@ -3526,7 +3526,7 @@ extern "C" { MXS_MODULE_API_QUERY_CLASSIFIER, MXS_MODULE_IN_DEVELOPMENT, - QUERY_CLASSIFIER_VERSION, + MXS_QUERY_CLASSIFIER_VERSION, "Query classifier based upon MySQL Embedded", "V1.0.0", MXS_NO_MODULE_CAPABILITIES, diff --git a/query_classifier/qc_sqlite/qc_sqlite.cc b/query_classifier/qc_sqlite/qc_sqlite.cc index 3e982e120..40804f179 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.cc +++ b/query_classifier/qc_sqlite/qc_sqlite.cc @@ -5037,7 +5037,7 @@ MXS_MODULE* MXS_CREATE_MODULE() { MXS_MODULE_API_QUERY_CLASSIFIER, MXS_MODULE_BETA_RELEASE, - QUERY_CLASSIFIER_VERSION, + MXS_QUERY_CLASSIFIER_VERSION, "Query classifier using sqlite.", "V1.0.0", MXS_NO_MODULE_CAPABILITIES, diff --git a/server/core/load_utils.cc b/server/core/load_utils.cc index 8e851bde1..d21522e0c 100644 --- a/server/core/load_utils.cc +++ b/server/core/load_utils.cc @@ -32,6 +32,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "internal/modules.h" #include "internal/config.h" @@ -78,6 +84,56 @@ static LOADED_MODULE* register_module(const char *module, MXS_MODULE *mod_info); static void unregister_module(const char *module); +static bool api_version_mismatch(const MXS_MODULE *mod_info, const char* module) +{ + bool rval = false; + MXS_MODULE_VERSION api = {}; + + switch (mod_info->modapi) + { + case MXS_MODULE_API_PROTOCOL: + api = MXS_PROTOCOL_VERSION; + break; + + case MXS_MODULE_API_AUTHENTICATOR: + api = MXS_AUTHENTICATOR_VERSION; + break; + + case MXS_MODULE_API_ROUTER: + api = MXS_ROUTER_VERSION; + break; + + case MXS_MODULE_API_MONITOR: + api = MXS_MONITOR_VERSION; + break; + + case MXS_MODULE_API_FILTER: + api = MXS_FILTER_VERSION; + break; + + case MXS_MODULE_API_QUERY_CLASSIFIER: + api = MXS_QUERY_CLASSIFIER_VERSION; + break; + + default: + MXS_ERROR("Unknown module type: 0x%02hhx", mod_info->modapi); + ss_dassert(!true); + break; + } + + if (api.major != mod_info->api_version.major || + api.minor != mod_info->api_version.minor || + api.patch != mod_info->api_version.patch) + { + MXS_ERROR("API version mismatch for '%s': Need version %d.%d.%d, have %d.%d.%d", + module, api.major, api.minor, api.patch, mod_info->api_version.major, + mod_info->api_version.minor, mod_info->api_version.patch); + rval = true; + } + + return rval; +} + static bool check_module(const MXS_MODULE *mod_info, const char *type, const char *module) { bool success = true; @@ -118,6 +174,12 @@ static bool check_module(const MXS_MODULE *mod_info, const char *type, const cha MXS_ERROR("Module '%s' does not implement the query classifier API.", module); success = false; } + + if (api_version_mismatch(mod_info, module)) + { + success = false; + } + if (mod_info->version == NULL) { MXS_ERROR("Module '%s' does not define a version string", module);