From 334e71b079c5646bc611e73fc54aeb61845ce51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 8 Feb 2017 16:42:35 +0200 Subject: [PATCH 01/11] Initialize random number generator in main The random number generator can be initialized when MaxScale's other systems are being initialized. This removes the need to initialized it when the function is used for the first time. --- include/maxscale/random_jkiss.h | 16 +++++- server/core/gateway.cc | 4 ++ server/core/random_jkiss.c | 88 ++++++++++++--------------------- 3 files changed, 50 insertions(+), 58 deletions(-) diff --git a/include/maxscale/random_jkiss.h b/include/maxscale/random_jkiss.h index 852c05ce7..07b0c07f0 100644 --- a/include/maxscale/random_jkiss.h +++ b/include/maxscale/random_jkiss.h @@ -16,6 +16,20 @@ MXS_BEGIN_DECLS -extern unsigned int random_jkiss(void); +/** + * @brief Initialize the random number generator + * + * Uses /dev/urandom if available, and warms the generator up with 1000 iterations. + */ +void random_jkiss_init(void); + +/** + * @brief Return a pseudo-random number + * + * Return a pseudo-random number that satisfies major tests for random sequences. + * + * @return A random number + */ +unsigned int random_jkiss(void); MXS_END_DECLS diff --git a/server/core/gateway.cc b/server/core/gateway.cc index bd06fdd89..48160314c 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -67,6 +67,7 @@ #include #include #include +#include #include "maxscale/config.h" #include "maxscale/maxscale.h" @@ -1666,6 +1667,9 @@ int main(int argc, char **argv) goto return_main; } + /** Initialize the random number generator */ + random_jkiss_init(); + if (!utils_init()) { const char* logerr = "Failed to initialise utility library."; diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index b21ce42f4..846f561ad 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -16,14 +16,6 @@ * * See http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf for discussion of random * number generators (RNGs). - * - * @verbatim - * Revision History - * - * Date Who Description - * 26/08/15 Martin Brampton Initial implementation - * - * @endverbatim */ #include @@ -32,6 +24,7 @@ #include #include #include +#include /* Public domain code for JKISS RNG - Comment header added */ @@ -41,28 +34,12 @@ static unsigned int x = 123456789, y = 987654321, z = 43219876, c = 6543217; /* Seed variables */ static bool init = false; -static unsigned int random_jkiss_devrand(void); -static void random_init_jkiss(void); - -/*** - * - * Return a pseudo-random number that satisfies major tests for random sequences - * - * @return uint Random number - * - */ -unsigned int -random_jkiss(void) +unsigned int random_jkiss(void) { unsigned long long t; unsigned int result; + ss_dassert(init); - if (!init) - { - /* Must set init first because initialisation calls this function */ - init = true; - random_init_jkiss(); - } x = 314527869 * x + 1234567; y ^= y << 5; y ^= y >> 7; @@ -83,8 +60,7 @@ random_jkiss(void) * @return uint Random number * */ -static unsigned int -random_jkiss_devrand(void) +static unsigned int random_jkiss_devrand(void) { int fn; unsigned int r; @@ -102,40 +78,38 @@ random_jkiss_devrand(void) return r; } -/*** - * - * Initialise the generator using /dev/urandom if available, and warm up - * with 1000 iterations - * - */ -static void -random_init_jkiss(void) +void random_jkiss_init(void) { - int newrand, i; - - if ((newrand = random_jkiss_devrand()) != 0) + if (!init) { - x = newrand; - } + int newrand, i; - if ((newrand = random_jkiss_devrand()) != 0) - { - y = newrand; - } + if ((newrand = random_jkiss_devrand()) != 0) + { + x = newrand; + } - if ((newrand = random_jkiss_devrand()) != 0) - { - z = newrand; - } + if ((newrand = random_jkiss_devrand()) != 0) + { + y = newrand; + } - if ((newrand = random_jkiss_devrand()) != 0) - { - c = newrand % 698769068 + 1; /* Should be less than 698769069 */ - } + if ((newrand = random_jkiss_devrand()) != 0) + { + z = newrand; + } - /* "Warm up" our random number generator */ - for (i = 0; i < 100; i++) - { - random_jkiss(); + if ((newrand = random_jkiss_devrand()) != 0) + { + c = newrand % 698769068 + 1; /* Should be less than 698769069 */ + } + + /* "Warm up" our random number generator */ + for (i = 0; i < 100; i++) + { + random_jkiss(); + } + + init = true; } } From a2727ea7e0783ef26204f48706f698fe7010b7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Feb 2017 13:33:51 +0200 Subject: [PATCH 02/11] Generate documentation from the public headers The Doxygen documentation is generated from the public headers. This should make it easier to read for module developers. --- etc/doxygate.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/etc/doxygate.in b/etc/doxygate.in index 00e20b168..433f679c1 100644 --- a/etc/doxygate.in +++ b/etc/doxygate.in @@ -568,8 +568,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @CMAKE_SOURCE_DIR@/README @CMAKE_SOURCE_DIR@/server/core @CMAKE_SOURCE_DIR@/server/modules @CMAKE_SOURCE_DIR@/server/include \ - @CMAKE_SOURCE_DIR@/log_manager @CMAKE_SOURCE_DIR@/query_classifier @CMAKE_SOURCE_DIR@/utils +INPUT = @CMAKE_SOURCE_DIR@/include/maxscale # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -586,7 +585,7 @@ INPUT_ENCODING = UTF-8 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = *.c *.h +FILE_PATTERNS = *.h *.hh # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. From 0200a353a199731bdcf036236dd1d3fac69249a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Feb 2017 13:38:01 +0200 Subject: [PATCH 03/11] Add more filter API documentation The member functions are now documentated. The routeQuery and clientReply entry points should be documented in more detail. --- include/maxscale/filter.h | 109 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/include/maxscale/filter.h b/include/maxscale/filter.h index 265562dc9..9ae004622 100644 --- a/include/maxscale/filter.h +++ b/include/maxscale/filter.h @@ -68,17 +68,126 @@ typedef void *MXS_FILTER_SESSION; */ typedef struct mxs_filter_object { + + /** + * @brief Create a new instance of the filter + * + * This function is called when a new filter instance is created. The return + * value of this function will be passed as the first parameter to the + * other API functions. + * + * @param name Name of the filter instance + * @param options Filter options + * @param params Filter parameters + * + * @return New filter instance on NULL on error + */ MXS_FILTER *(*createInstance)(const char *name, char **options, MXS_CONFIG_PARAMETER *params); + + /** + * Called to create a new user session within the filter + * + * This function is called when a new filter session is created for a client. + * The return value of this function will be passed as the second parameter + * to the @c routeQuery, @c clientReply, @c closeSession, @c freeSession, + * @c setDownstream and @c setUpstream functions. + * + * @param instance Filter instance + * @param session Client SESSION object + * + * @return New filter session or NULL on error + */ MXS_FILTER_SESSION *(*newSession)(MXS_FILTER *instance, MXS_SESSION *session); + + /** + * @brief Called when a session is closed + * + * The filter should close all objects but not free any memory. + * + * @param instance Filter instance + * @param fsession Filter session + */ void (*closeSession)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession); + + /** + * @brief Called when a session is freed + * + * The session should free all allocated memory in this function. + * + * @param instance Filter instance + * @param fsession Filter session + */ void (*freeSession)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession); + + /** + * @brief Sets the downstream component of the filter pipeline + * + * @param instance Filter instance + * @param fsession Filter session + */ void (*setDownstream)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); + + /** + * @brief Sets the upstream component of the filter pipeline + * + * @param instance Filter instance + * @param fsession Filter session + */ void (*setUpstream)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *downstream); + + /** + * @brief Called on each query that requires routing + * + * TODO: Document how routeQuery should be used + * + * @param instance Filter instance + * @param fsession Filter session + * @param queue Request from the client + * + * @return If successful, the function returns 1. If an error occurs + * and the session should be closed, the function returns 0. + */ int32_t (*routeQuery)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); + + /** + * @brief Called for each reply packet + * + * TODO: Document how clientReply should be used + * + * @param instance Filter instance + * @param fsession Filter session + * @param queue Response from the server + * + * @return If successful, the function returns 1. If an error occurs + * and the session should be closed, the function returns 0. + */ int32_t (*clientReply)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); + + /** + * @brief Called for diagnostic output + * + * @param instance Filter instance + * @param fsession Filter session, NULL if general information about the filter is queried + * @param dcb DCB where the diagnostic information should be written + */ void (*diagnostics)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); + + /** + * @brief Called to obtain the capabilities of the filter + * + * @return Zero or more bitwise-or'd values from the mxs_routing_capability_t enum + * + * @see routing.h + */ uint64_t (*getCapabilities)(void); + + /** + * @brief Called for destroying a filter instance + * + * @param instance Filter instance + */ void (*destroyInstance)(MXS_FILTER *instance); + } MXS_FILTER_OBJECT; /** From 04b2475553659686253b9c31d440d7c39499ad91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Feb 2017 14:17:54 +0200 Subject: [PATCH 04/11] Fix random_jkiss initialization The initialization function used another function which expected initialization to be done. --- server/core/random_jkiss.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index 846f561ad..a9ba7a886 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -104,12 +104,6 @@ void random_jkiss_init(void) c = newrand % 698769068 + 1; /* Should be less than 698769069 */ } - /* "Warm up" our random number generator */ - for (i = 0; i < 100; i++) - { - random_jkiss(); - } - init = true; } } From d2c3be8728a4b1baca206f837fadd6a63b84921c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Feb 2017 17:19:46 +0200 Subject: [PATCH 05/11] Fix compiler flag usage The compiler flags overwrote the default values that CMake generates instead of appending to them. --- CMakeLists.txt | 28 ++++++------------- include/maxscale/debug.h | 2 +- server/core/log_manager.cc | 3 +- server/modules/routing/avrorouter/avro_file.c | 12 ++------ 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f199135f..c97c221a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,16 +146,6 @@ if(CMAKE_VERSION VERSION_GREATER 2.6) endif() endif() - -IF(DEFINED OLEVEL) - if((OLEVEL GREATER -1) AND (OLEVEL LESS 4) ) - set(FLAGS "${FLAGS} -O${OLEVEL}" CACHE STRING "Compilation flags" FORCE) - message(STATUS "Optimization level at: ${OLEVEL}") - else() - message(WARNING "Optimization level was set to a bad value, ignoring it. (Valid values are 0-3)") - endif() -endif() - if(GCOV) set(FLAGS "${FLAGS} -fprofile-arcs -ftest-coverage" CACHE STRING "Compilation flags" FORCE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") @@ -168,19 +158,19 @@ endif() if(USE_C99) message(STATUS "Using C99 standard") - set(CMAKE_C_FLAGS "-std=c99 -D_GNU_SOURCE=1 ${FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -D_GNU_SOURCE=1 ${FLAGS}") else() - set(CMAKE_C_FLAGS "${FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}") endif() -set(CMAKE_C_FLAGS_DEBUG "${DEBUG_FLAGS} -DSS_DEBUG -DLOG_ASSERT") -set(CMAKE_C_FLAGS_RELEASE "") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "-ggdb") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEBUG_FLAGS} -DSS_DEBUG -DLOG_ASSERT") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-uninitialized") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -Wno-uninitialized") -set(CMAKE_CXX_FLAGS "${FLAGS} -Wno-deprecated-declarations") -set(CMAKE_CXX_FLAGS_DEBUG "${DEBUG_FLAGS} -DSS_DEBUG -DLOG_ASSERT -Wno-deprecated-declarations") -set(CMAKE_CXX_FLAGS_RELEASE "-Wno-deprecated-declarations") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-ggdb -Wno-deprecated-declarations") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS} -Wno-deprecated-declarations") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS} -DSS_DEBUG -DLOG_ASSERT -Wno-deprecated-declarations") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wno-deprecated-declarations -Wno-uninitialized") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ggdb -Wno-deprecated-declarations -Wno-uninitialized") include_directories(include) include_directories(server/inih) diff --git a/include/maxscale/debug.h b/include/maxscale/debug.h index 21cf887d3..31c9dd1ec 100644 --- a/include/maxscale/debug.h +++ b/include/maxscale/debug.h @@ -264,7 +264,7 @@ typedef enum skygw_chk_t (SERVER_IS_SLAVE(s) ? "RUNNING SLAVE" : \ (SERVER_IS_JOINED(s) ? "RUNNING JOINED" : \ (SERVER_IS_NDB(s) ? "RUNNING NDB" : \ - ((SERVER_IS_RUNNING(s) && SERVER_IN_MAINT(s)) ? "RUNNING MAINTENANCE" : \ + ((!SERVER_IS_DOWN(s) && SERVER_IN_MAINT(s)) ? "RUNNING MAINTENANCE" : \ (SERVER_IS_RELAY_SERVER(s) ? "RUNNING RELAY" : \ (SERVER_IS_RUNNING(s) ? "RUNNING (only)" : \ (SERVER_IS_DOWN(s) ? "DOWN" : "UNKNOWN STATUS")))))))) diff --git a/server/core/log_manager.cc b/server/core/log_manager.cc index 1c6903acf..bb6f85467 100644 --- a/server/core/log_manager.cc +++ b/server/core/log_manager.cc @@ -3020,7 +3020,8 @@ int mxs_log_message(int priority, assert(!true); } - assert(len == augmentation_len); + (void)len; + ss_dassert(len == augmentation_len); } va_start(valist, format); diff --git a/server/modules/routing/avrorouter/avro_file.c b/server/modules/routing/avrorouter/avro_file.c index 324aa2c0d..db542697d 100644 --- a/server/modules/routing/avrorouter/avro_file.c +++ b/server/modules/routing/avrorouter/avro_file.c @@ -630,7 +630,6 @@ avro_binlog_end_t avro_read_all_events(AVRO_INSTANCE *router) { int event_header_length; int event_header_ntypes; - int n_events; /** Extract the event header lengths */ event_header_length = ptr[2 + 50 + 4]; @@ -653,15 +652,10 @@ avro_binlog_end_t avro_read_all_events(AVRO_INSTANCE *router) break; } - n_events = hdr.event_size - event_header_length - (2 + 50 + 4 + 1); - - if (event_header_ntypes < n_events) + uint8_t *checksum = ptr + hdr.event_size - event_header_length - event_header_ntypes; + if (checksum[0] == 1) { - uint8_t *checksum = ptr + hdr.event_size - event_header_length - event_header_ntypes; - if (checksum[0] == 1) - { - found_chksum = true; - } + found_chksum = true; } } /* Decode CLOSE/STOP Event */ From cf63e4cb9e1d08a7719d5d9f66f3d9799474b5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Feb 2017 18:49:22 +0200 Subject: [PATCH 06/11] Remove false debug assertion If MaxScale is started without the appropriate permissions to the paths pointed by default values, the debug assertion fails even though the parameter is valid but not usable. --- server/core/config.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/core/config.c b/server/core/config.c index 99953c2d8..ba614aa4b 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -2512,9 +2512,6 @@ void config_add_defaults(CONFIG_CONTEXT *ctx, const MXS_MODULE_PARAM *params) if (params[i].default_value && config_get_param(ctx->parameters, params[i].name) == NULL) { - ss_dassert(config_param_is_valid(params, params[i].name, - params[i].default_value, ctx)); - bool rv = config_add_param(ctx, params[i].name, params[i].default_value); MXS_ABORT_IF_FALSE(rv); } From eb1e163bdf627dade3fb67d754f69d7918c8e741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Sat, 11 Feb 2017 12:48:07 +0200 Subject: [PATCH 07/11] Only update index file if file is flushed to disk There's no point in indexing the file if it hasn't been synced to disk. Any attempts to index the file will fail if the file still has an open data block. --- server/modules/routing/avrorouter/avro_file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/modules/routing/avrorouter/avro_file.c b/server/modules/routing/avrorouter/avro_file.c index db542697d..7341d671a 100644 --- a/server/modules/routing/avrorouter/avro_file.c +++ b/server/modules/routing/avrorouter/avro_file.c @@ -886,7 +886,10 @@ void avro_flush_all_tables(AVRO_INSTANCE *router, enum avrorouter_file_op flush) } /** Update the GTID index */ - avro_update_index(router); + if (flush == AVROROUTER_FLUSH) + { + avro_update_index(router); + } } /** From acd66b4eb39ca4f4d760927b39ec2c2c1cb141bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Feb 2017 11:41:58 +0200 Subject: [PATCH 08/11] Fix compiler warnings Added missing checks for return values of various function calls. Fixed binlogrouter strerror_r usage and wrong buffer sizes. --- client/maxadmin.c | 5 ++- server/core/adminusers.c | 10 ++++-- server/core/gateway.cc | 20 +++++++++--- server/core/hashtable.c | 15 +++++++-- server/core/monitor.c | 16 +++++++--- .../modules/routing/binlogrouter/blr_file.c | 32 ++++++++++++------- .../modules/routing/binlogrouter/blr_slave.c | 7 +++- 7 files changed, 78 insertions(+), 27 deletions(-) diff --git a/client/maxadmin.c b/client/maxadmin.c index 1b1a894ed..900637426 100644 --- a/client/maxadmin.c +++ b/client/maxadmin.c @@ -994,7 +994,10 @@ bool getPassword(char *passwd, size_t len) if (tcsetattr(STDIN_FILENO, 0, &tty_attr) == 0) { printf("Password: "); - fgets(passwd, len, stdin); + if (fgets(passwd, len, stdin) == NULL) + { + printf("Failed to read password\n"); + } tty_attr.c_lflag = c_lflag; diff --git a/server/core/adminusers.c b/server/core/adminusers.c index 5ef2e0c1e..34bc14b0c 100644 --- a/server/core/adminusers.c +++ b/server/core/adminusers.c @@ -260,8 +260,14 @@ static const char* admin_remove_user(USERS *users, const char* fname, /** one step back */ MXS_ERROR("Unable to set stream position. "); } - fgets(line, LINELEN, fp); - fputs(line, fp_tmp); + if (fgets(line, LINELEN, fp)) + { + fputs(line, fp_tmp); + } + else + { + MXS_ERROR("Failed to read line from admin users file"); + } } if (fgetpos(fp, &rpos) != 0) diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 48160314c..fa681b583 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -304,7 +304,10 @@ static void sigterm_handler(int i) if (n_shutdowns == 1) { - write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1); + if (write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1) == -1) + { + printf("Failed to write shutdown message!\n"); + } } else { @@ -320,11 +323,17 @@ sigint_handler(int i) if (n_shutdowns == 1) { - write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1); + if (write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1) == -1) + { + printf("Failed to write shutdown message!\n"); + } } else if (n_shutdowns == 2) { - write(STDERR_FILENO, patience_msg, sizeof(patience_msg) - 1); + if (write(STDERR_FILENO, patience_msg, sizeof(patience_msg) - 1) == -1) + { + printf("Failed to write shutdown message!\n"); + } } else { @@ -2621,7 +2630,10 @@ static int set_user(const char* user) void write_child_exit_code(int fd, int code) { /** Notify the parent process that an error has occurred */ - write(fd, &code, sizeof (int)); + if (write(fd, &code, sizeof (int)) == -1) + { + printf("Failed to write child process message!\n"); + } close(fd); } diff --git a/server/core/hashtable.c b/server/core/hashtable.c index 30975784b..495a0bb20 100644 --- a/server/core/hashtable.c +++ b/server/core/hashtable.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -741,7 +742,12 @@ hashtable_save(HASHTABLE *table, const char *filename, close(fd); return -1; } - write(fd, &rval, sizeof(rval)); // Write zero counter, will be overrwriten at end + if (write(fd, &rval, sizeof(rval)) == -1) // Write zero counter, will be overrwriten at end + { + char err[MXS_STRERROR_BUFLEN]; + MXS_ERROR("Failed to write hashtable item count: %d, %s", errno, + strerror_r(errno, err, sizeof(err))); + } if ((iter = hashtable_iterator(table)) != NULL) { while ((key = hashtable_next(iter)) != NULL) @@ -766,7 +772,12 @@ hashtable_save(HASHTABLE *table, const char *filename, /* Now go back and write the count of entries */ if (lseek(fd, 7L, SEEK_SET) != -1) { - write(fd, &rval, sizeof(rval)); + if (write(fd, &rval, sizeof(rval)) == -1) + { + char err[MXS_STRERROR_BUFLEN]; + MXS_ERROR("Failed to write hashtable item count: %d, %s", errno, + strerror_r(errno, err, sizeof(err))); + } } close(fd); diff --git a/server/core/monitor.c b/server/core/monitor.c index 25b371df9..695a6ab7b 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -958,17 +958,23 @@ static const char* mon_get_event_name(MXS_MONITOR_SERVERS* node) static void mon_append_node_names(MXS_MONITOR_SERVERS* servers, char* dest, int len, int status) { char *separator = ""; - char arr[MAX_SERVER_NAME_LEN + 32]; // Some extra space for port + char arr[MAX_SERVER_NAME_LEN + 64]; // Some extra space for port and separator dest[0] = '\0'; - while (servers && strlen(dest) < (len - strlen(separator))) + while (servers && len) { if (status == 0 || servers->server->status & status) { - strncat(dest, separator, len); + snprintf(arr, sizeof(arr), "%s%s:%d", separator, servers->server->name, + servers->server->port); separator = ","; - snprintf(arr, sizeof(arr), "%s:%d", servers->server->name, servers->server->port); - strncat(dest, arr, len - strlen(dest) - 1); + int arrlen = strlen(arr); + + if (arrlen < len) + { + strcat(dest, arr); + len -= arrlen; + } } servers = servers->next; } diff --git a/server/modules/routing/binlogrouter/blr_file.c b/server/modules/routing/binlogrouter/blr_file.c index 4e8f2231a..05ea9834a 100644 --- a/server/modules/routing/binlogrouter/blr_file.c +++ b/server/modules/routing/binlogrouter/blr_file.c @@ -1197,8 +1197,12 @@ blr_cache_response(ROUTER_INSTANCE *router, char *response, GWBUF *buf) { return; } - write(fd, GWBUF_DATA(buf), GWBUF_LENGTH(buf)); - // TODO: Check result. + if (write(fd, GWBUF_DATA(buf), GWBUF_LENGTH(buf)) == -1) + { + char err[MXS_STRERROR_BUFLEN]; + MXS_ERROR("Failed to write cached response: %d, %s", + errno, strerror_r(errno, err, sizeof(err))); + } close(fd); } @@ -1251,7 +1255,12 @@ blr_cache_read_response(ROUTER_INSTANCE *router, char *response) close(fd); return NULL; } - read(fd, GWBUF_DATA(buf), statb.st_size); + if (read(fd, GWBUF_DATA(buf), statb.st_size) == -1) + { + char err[MXS_STRERROR_BUFLEN]; + MXS_ERROR("Failed to read cached response: %d, %s", + errno, strerror_r(errno, err, sizeof(err))); + } close(fd); return buf; } @@ -1421,11 +1430,10 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug) break; case -1: { - char err_msg[BLRM_STRERROR_R_MSG_SIZE + 1] = ""; - strerror_r(errno, err_msg, BLRM_STRERROR_R_MSG_SIZE); + char err[MXS_STRERROR_BUFLEN]; MXS_ERROR("Failed to read binlog file %s at position %llu" - " (%s).", router->binlog_name, - pos, err_msg); + " (%s).", router->binlog_name, pos, + strerror_r(errno, err, sizeof(err))); if (errno == EBADF) { @@ -1533,7 +1541,7 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug) } else { - char errmsg[BLRM_STRERROR_R_MSG_SIZE + 1] = ""; + char errmsg[BINLOG_ERROR_MSG_LEN + 1] = ""; /* fill replication header struct */ hdr.timestamp = EXTRACT32(hdbuf); hdr.event_type = hdbuf[4]; @@ -1641,12 +1649,12 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug) { if (n == -1) { - char err_msg[BLRM_STRERROR_R_MSG_SIZE + 1] = ""; - strerror_r(errno, err_msg, BLRM_STRERROR_R_MSG_SIZE); + char err[MXS_STRERROR_BUFLEN]; MXS_ERROR("Error reading the event at %llu in %s. " "%s, expected %d bytes.", pos, router->binlog_name, - err_msg, hdr.event_size - BINLOG_EVENT_HDR_LEN); + strerror_r(errno, err, sizeof(err)), + hdr.event_size - BINLOG_EVENT_HDR_LEN); } else { @@ -1709,7 +1717,7 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug) uint32_t event_size = EXTRACT32(hdbuf + BINLOG_EVENT_LEN_OFFSET); uint8_t *decrypt_ptr; unsigned long next_pos; - char errmsg[BLRM_STRERROR_R_MSG_SIZE + 1] = ""; + char errmsg[BINLOG_ERROR_MSG_LEN + 1] = ""; /** * Events are encrypted. diff --git a/server/modules/routing/binlogrouter/blr_slave.c b/server/modules/routing/binlogrouter/blr_slave.c index 7c72215dc..919097d7b 100644 --- a/server/modules/routing/binlogrouter/blr_slave.c +++ b/server/modules/routing/binlogrouter/blr_slave.c @@ -3556,7 +3556,12 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) router->prevbinlog, router->last_safe_pos); /* Truncate previous binlog file to last_safe pos */ - truncate(file, router->last_safe_pos); + if (truncate(file, router->last_safe_pos) == -1) + { + char err[MXS_STRERROR_BUFLEN]; + MXS_ERROR("Failed to truncate file: %d, %s", + errno, strerror_r(errno, err, sizeof(err))); + } /* Log it */ MXS_WARNING("A transaction is still opened at pos %lu" From 7e2378936448f5392844130bb7b325834ab06e4e Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Mon, 13 Feb 2017 14:46:43 +0200 Subject: [PATCH 09/11] Fix one last compilation error Fix one ignored return value in Avro, caused compilation to fail. --- server/modules/routing/avrorouter/avro_file.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/modules/routing/avrorouter/avro_file.c b/server/modules/routing/avrorouter/avro_file.c index 7341d671a..1bcf3a2aa 100644 --- a/server/modules/routing/avrorouter/avro_file.c +++ b/server/modules/routing/avrorouter/avro_file.c @@ -519,10 +519,9 @@ avro_binlog_end_t avro_read_all_events(AVRO_INSTANCE *router) case -1: { char err_msg[BLRM_STRERROR_R_MSG_SIZE + 1] = ""; - strerror_r(errno, err_msg, BLRM_STRERROR_R_MSG_SIZE); - MXS_ERROR("Failed to read binlog file %s at position %llu" - " (%s).", router->binlog_name, - pos, err_msg); + MXS_ERROR("Failed to read binlog file %s at position %llu (%s).", + router->binlog_name, pos, + strerror_r(errno, err_msg, sizeof(err_msg))); if (errno == EBADF) MXS_ERROR("Bad file descriptor in read binlog for file %s" From 2a49cd6451bb608c0a063a881f28d357f62ceec2 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 14 Feb 2017 13:17:56 +0200 Subject: [PATCH 10/11] getCapabilities now get the instance as argument Allows the capabilities to be different depending on how the filter/router has been configured. --- include/maxscale/filter.h | 2 +- include/maxscale/filter.hh | 8 +++++--- include/maxscale/router.h | 2 +- server/core/service.c | 6 ++++-- server/modules/filter/cache/cachefilter.cc | 1 - server/modules/filter/cache/cachefilter.hh | 2 +- server/modules/filter/ccrfilter/ccrfilter.c | 4 ++-- server/modules/filter/dbfwfilter/dbfwfilter.c | 4 ++-- server/modules/filter/hintfilter/hintfilter.c | 4 ++-- server/modules/filter/insertstream/insertstream.c | 4 ++-- server/modules/filter/masking/maskingfilter.hh | 2 +- server/modules/filter/maxrows/maxrows.c | 4 ++-- server/modules/filter/mqfilter/mqfilter.c | 4 ++-- .../modules/filter/namedserverfilter/namedserverfilter.c | 4 ++-- server/modules/filter/nullfilter/nullfilter.cc | 1 - server/modules/filter/nullfilter/nullfilter.hh | 2 +- server/modules/filter/qlafilter/qlafilter.c | 4 ++-- server/modules/filter/regexfilter/regexfilter.c | 4 ++-- server/modules/filter/tee/tee.c | 4 ++-- server/modules/filter/testfilter/testfilter.c | 4 ++-- server/modules/filter/topfilter/topfilter.c | 4 ++-- server/modules/filter/tpmfilter/tpmfilter.c | 4 ++-- server/modules/routing/avrorouter/avro.c | 4 ++-- server/modules/routing/binlogrouter/blr.c | 4 ++-- server/modules/routing/cli/cli.c | 4 ++-- server/modules/routing/debugcli/debugcli.c | 4 ++-- server/modules/routing/maxinfo/maxinfo.c | 4 ++-- server/modules/routing/readconnroute/readconnroute.c | 4 ++-- server/modules/routing/readwritesplit/readwritesplit.c | 4 ++-- server/modules/routing/schemarouter/schemarouter.c | 4 ++-- server/modules/routing/testroute/testroute.c | 4 ++-- 31 files changed, 58 insertions(+), 56 deletions(-) diff --git a/include/maxscale/filter.h b/include/maxscale/filter.h index 9ae004622..a211db7e0 100644 --- a/include/maxscale/filter.h +++ b/include/maxscale/filter.h @@ -179,7 +179,7 @@ typedef struct mxs_filter_object * * @see routing.h */ - uint64_t (*getCapabilities)(void); + uint64_t (*getCapabilities)(MXS_FILTER *instance); /** * @brief Called for destroying a filter instance diff --git a/include/maxscale/filter.hh b/include/maxscale/filter.hh index de9890c3b..95214991d 100644 --- a/include/maxscale/filter.hh +++ b/include/maxscale/filter.hh @@ -183,7 +183,7 @@ protected: * MyFilterSession* newSession(MXS_SESSION* pSession); * * void diagnostics(DCB* pDcb); - * static uint64_t getCapabilities(); + * uint64_t getCapabilities(); * }; * @endcode * @@ -290,11 +290,13 @@ public: } } - static uint64_t getCapabilities(void) + static uint64_t getCapabilities(MXS_FILTER* pInstance) { uint64_t rv = 0; - MXS_EXCEPTION_GUARD(rv = FilterType::getCapabilities()); + FilterType* pFilter = reinterpret_cast(pInstance); + + MXS_EXCEPTION_GUARD(rv = pFilter->getCapabilities()); return rv; } diff --git a/include/maxscale/router.h b/include/maxscale/router.h index fbfa0aaed..7e5398271 100644 --- a/include/maxscale/router.h +++ b/include/maxscale/router.h @@ -79,7 +79,7 @@ typedef struct mxs_router_object DCB* backend_dcb, mxs_error_action_t action, bool* succp); - uint64_t (*getCapabilities)(void); + uint64_t (*getCapabilities)(MXS_ROUTER *instance); void (*destroyInstance)(MXS_ROUTER *instance); } MXS_ROUTER_OBJECT; diff --git a/server/core/service.c b/server/core/service.c index b80ec8843..fd60479aa 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -142,7 +142,7 @@ SERVICE* service_alloc(const char *name, const char *router) return NULL; } - service->capabilities = service->router->getCapabilities(); + service->capabilities = 0; service->client_count = 0; service->n_dbref = 0; service->name = my_name; @@ -485,6 +485,8 @@ int serviceInitialize(SERVICE *service) if ((service->router_instance = service->router->createInstance(service, router_options))) { + service->capabilities |= service->router->getCapabilities(service->router_instance); + if (!config_get_global_options()->config_check) { listeners = serviceStartAllPorts(service); @@ -1237,7 +1239,7 @@ serviceSetFilters(SERVICE *service, char *filters) { if (filter_load(flist[n - 1])) { - capabilities |= flist[n - 1]->obj->getCapabilities(); + capabilities |= flist[n - 1]->obj->getCapabilities(flist[n - 1]->filter); } else { diff --git a/server/modules/filter/cache/cachefilter.cc b/server/modules/filter/cache/cachefilter.cc index 5d795c9f4..031cf5f70 100644 --- a/server/modules/filter/cache/cachefilter.cc +++ b/server/modules/filter/cache/cachefilter.cc @@ -271,7 +271,6 @@ void CacheFilter::diagnostics(DCB* pDcb) m_sCache->show(pDcb); } -// static uint64_t CacheFilter::getCapabilities() { return RCAP_TYPE_TRANSACTION_TRACKING; diff --git a/server/modules/filter/cache/cachefilter.hh b/server/modules/filter/cache/cachefilter.hh index 06394e70b..c314facba 100644 --- a/server/modules/filter/cache/cachefilter.hh +++ b/server/modules/filter/cache/cachefilter.hh @@ -39,7 +39,7 @@ public: void diagnostics(DCB* pDcb); - static uint64_t getCapabilities(); + uint64_t getCapabilities(); private: CacheFilter(); diff --git a/server/modules/filter/ccrfilter/ccrfilter.c b/server/modules/filter/ccrfilter/ccrfilter.c index 73e2892f2..64d0855a2 100644 --- a/server/modules/filter/ccrfilter/ccrfilter.c +++ b/server/modules/filter/ccrfilter/ccrfilter.c @@ -56,7 +56,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); #define CCR_DEFAULT_TIME "60" @@ -386,7 +386,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.c b/server/modules/filter/dbfwfilter/dbfwfilter.c index fba24b945..6b640595a 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter/dbfwfilter.c @@ -102,7 +102,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); /** * Rule types @@ -2505,7 +2505,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_STMT_INPUT; } diff --git a/server/modules/filter/hintfilter/hintfilter.c b/server/modules/filter/hintfilter/hintfilter.c index 65ad7c755..07536d6ce 100644 --- a/server/modules/filter/hintfilter/hintfilter.c +++ b/server/modules/filter/hintfilter/hintfilter.c @@ -33,7 +33,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); /** * The module entry point routine. It is this routine that @@ -238,7 +238,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/insertstream/insertstream.c b/server/modules/filter/insertstream/insertstream.c index 8620dd483..ea2eb8605 100644 --- a/server/modules/filter/insertstream/insertstream.c +++ b/server/modules/filter/insertstream/insertstream.c @@ -38,7 +38,7 @@ static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MX static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *session, MXS_UPSTREAM *upstream); static int32_t routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER *instance); static int32_t clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION *session, GWBUF *reply); static bool extract_insert_target(GWBUF *buffer, char* target, int len); static GWBUF* create_load_data_command(const char *target); @@ -517,7 +517,7 @@ static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB * * * @return Filter capabilities */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_TRANSACTION_TRACKING; } diff --git a/server/modules/filter/masking/maskingfilter.hh b/server/modules/filter/masking/maskingfilter.hh index 9281e085e..8d4b4f9eb 100644 --- a/server/modules/filter/masking/maskingfilter.hh +++ b/server/modules/filter/masking/maskingfilter.hh @@ -35,7 +35,7 @@ public: void diagnostics(DCB* pDcb); - static uint64_t getCapabilities(); + uint64_t getCapabilities(); void reload(DCB* pOut); diff --git a/server/modules/filter/maxrows/maxrows.c b/server/modules/filter/maxrows/maxrows.c index 92076797b..f88163af5 100644 --- a/server/modules/filter/maxrows/maxrows.c +++ b/server/modules/filter/maxrows/maxrows.c @@ -55,7 +55,7 @@ static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *sdata, MXS_ static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *sdata, GWBUF *queue); static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *sdata, GWBUF *queue); static void diagnostics(MXS_FILTER *instance, MXS_FILTER_SESSION *sdata, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER *instance); /* Global symbols of the Module */ @@ -419,7 +419,7 @@ static void diagnostics(MXS_FILTER *instance, MXS_FILTER_SESSION *sdata, DCB *dc * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_STMT_INPUT | RCAP_TYPE_STMT_OUTPUT; } diff --git a/server/modules/filter/mqfilter/mqfilter.c b/server/modules/filter/mqfilter/mqfilter.c index 19e5c24cb..234810a6b 100644 --- a/server/modules/filter/mqfilter/mqfilter.c +++ b/server/modules/filter/mqfilter/mqfilter.c @@ -95,7 +95,7 @@ static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_ static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER *instance); /** *Structure used to store messages and their properties. @@ -1510,7 +1510,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/namedserverfilter/namedserverfilter.c b/server/modules/filter/namedserverfilter/namedserverfilter.c index f54ee3302..862abeeac 100644 --- a/server/modules/filter/namedserverfilter/namedserverfilter.c +++ b/server/modules/filter/namedserverfilter/namedserverfilter.c @@ -50,7 +50,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); typedef struct source_host { @@ -378,7 +378,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/nullfilter/nullfilter.cc b/server/modules/filter/nullfilter/nullfilter.cc index 07e2b662f..b51b4f95f 100644 --- a/server/modules/filter/nullfilter/nullfilter.cc +++ b/server/modules/filter/nullfilter/nullfilter.cc @@ -121,7 +121,6 @@ void NullFilter::diagnostics(DCB* pDcb) dcb_printf(pDcb, "Hello, World!\n"); } -// static uint64_t NullFilter::getCapabilities() { if (!this_unit.capabilities_set) diff --git a/server/modules/filter/nullfilter/nullfilter.hh b/server/modules/filter/nullfilter/nullfilter.hh index 459a1bcff..ceb7baf60 100644 --- a/server/modules/filter/nullfilter/nullfilter.hh +++ b/server/modules/filter/nullfilter/nullfilter.hh @@ -26,7 +26,7 @@ public: void diagnostics(DCB* pDcb); - static uint64_t getCapabilities(); + uint64_t getCapabilities(); private: NullFilter(const char* zName); diff --git a/server/modules/filter/qlafilter/qlafilter.c b/server/modules/filter/qlafilter/qlafilter.c index ab8c8f525..ae45d52be 100644 --- a/server/modules/filter/qlafilter/qlafilter.c +++ b/server/modules/filter/qlafilter/qlafilter.c @@ -82,7 +82,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); /** * A instance structure, the assumption is that the option passed @@ -619,7 +619,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/regexfilter/regexfilter.c b/server/modules/filter/regexfilter/regexfilter.c index 05044dfe4..b06103edf 100644 --- a/server/modules/filter/regexfilter/regexfilter.c +++ b/server/modules/filter/regexfilter/regexfilter.c @@ -49,7 +49,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); static char *regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *study, const char *replace); @@ -490,7 +490,7 @@ void log_nomatch(REGEX_INSTANCE* inst, char* re, char* old) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/tee/tee.c b/server/modules/filter/tee/tee.c index 3bcb6cc25..e53e4ee3c 100644 --- a/server/modules/filter/tee/tee.c +++ b/server/modules/filter/tee/tee.c @@ -107,7 +107,7 @@ static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_ static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); /** * The instance structure for the TEE filter - this holds the configuration @@ -753,7 +753,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/testfilter/testfilter.c b/server/modules/filter/testfilter/testfilter.c index 0cf525d36..c7e3429c9 100644 --- a/server/modules/filter/testfilter/testfilter.c +++ b/server/modules/filter/testfilter/testfilter.c @@ -37,7 +37,7 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session); static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream); static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); static void destroyInstance(MXS_FILTER *instance); @@ -243,7 +243,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_NONE; } diff --git a/server/modules/filter/topfilter/topfilter.c b/server/modules/filter/topfilter/topfilter.c index 0ca5a2468..6478f57ac 100644 --- a/server/modules/filter/topfilter/topfilter.c +++ b/server/modules/filter/topfilter/topfilter.c @@ -59,7 +59,7 @@ static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_ static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); /** * A instance structure, the assumption is that the option passed @@ -628,7 +628,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/filter/tpmfilter/tpmfilter.c b/server/modules/filter/tpmfilter/tpmfilter.c index 3fa1ff0b2..07ecffa68 100644 --- a/server/modules/filter/tpmfilter/tpmfilter.c +++ b/server/modules/filter/tpmfilter/tpmfilter.c @@ -86,7 +86,7 @@ static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue); static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_FILTER* instance); static void checkNamedPipe(void *args); /** @@ -602,7 +602,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) * * @return The capabilities of the filter. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_FILTER* instance) { return RCAP_TYPE_CONTIGUOUS_INPUT; } diff --git a/server/modules/routing/avrorouter/avro.c b/server/modules/routing/avrorouter/avro.c index 0104c8b58..58b28a972 100644 --- a/server/modules/routing/avrorouter/avro.c +++ b/server/modules/routing/avrorouter/avro.c @@ -81,7 +81,7 @@ static void clientReply(MXS_ROUTER *instance, void *router_session, GWBUF *queue DCB *backend_dcb); static void errorReply(MXS_ROUTER *instance, void *router_session, GWBUF *message, DCB *backend_dcb, mxs_error_action_t action, bool *succp); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); extern int MaxScaleUptime(); extern void avro_get_used_tables(AVRO_INSTANCE *router, DCB *dcb); void converter_func(void* data); @@ -998,7 +998,7 @@ errorReply(MXS_ROUTER *instance, void *router_session, GWBUF *message, DCB *back ss_dassert(false); } -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return RCAP_TYPE_NO_RSESSION; } diff --git a/server/modules/routing/binlogrouter/blr.c b/server/modules/routing/binlogrouter/blr.c index 5cc5f90bd..cf7d3d09d 100644 --- a/server/modules/routing/binlogrouter/blr.c +++ b/server/modules/routing/binlogrouter/blr.c @@ -106,7 +106,7 @@ static void errorReply(MXS_ROUTER *instance, mxs_error_action_t action, bool *succp); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); static int blr_handler_config(void *userdata, const char *section, const char *name, const char *value); static int blr_handle_config_item(const char *name, const char *value, ROUTER_INSTANCE *inst); static int blr_load_dbusers(const ROUTER_INSTANCE *router); @@ -1900,7 +1900,7 @@ static void rses_end_locked_router_action(ROUTER_SLAVE *rses) } -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return RCAP_TYPE_NO_RSESSION | RCAP_TYPE_CONTIGUOUS_OUTPUT | RCAP_TYPE_RESULTSET_OUTPUT; } diff --git a/server/modules/routing/cli/cli.c b/server/modules/routing/cli/cli.c index e24154a67..ec02d96ee 100644 --- a/server/modules/routing/cli/cli.c +++ b/server/modules/routing/cli/cli.c @@ -49,7 +49,7 @@ static void closeSession(MXS_ROUTER *instance, void *router_session); static void freeSession(MXS_ROUTER *instance, void *router_session); static int execute(MXS_ROUTER *instance, void *router_session, GWBUF *queue); static void diagnostics(MXS_ROUTER *instance, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); extern int execute_cmd(CLI_SESSION *cli); @@ -288,7 +288,7 @@ diagnostics(MXS_ROUTER *instance, DCB *dcb) return; /* Nothing to do currently */ } -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER *instance) { return 0; } diff --git a/server/modules/routing/debugcli/debugcli.c b/server/modules/routing/debugcli/debugcli.c index bbcec1786..962647e92 100644 --- a/server/modules/routing/debugcli/debugcli.c +++ b/server/modules/routing/debugcli/debugcli.c @@ -48,7 +48,7 @@ static void closeSession(MXS_ROUTER *instance, void *router_session); static void freeSession(MXS_ROUTER *instance, void *router_session); static int execute(MXS_ROUTER *instance, void *router_session, GWBUF *queue); static void diagnostics(MXS_ROUTER *instance, DCB *dcb); -static uint64_t getCapabilities (); +static uint64_t getCapabilities(MXS_ROUTER* instance); extern int execute_cmd(CLI_SESSION *cli); @@ -293,7 +293,7 @@ diagnostics(MXS_ROUTER *instance, DCB *dcb) return; /* Nothing to do currently */ } -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return 0; } diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index c4c18a3f6..889d3dfc6 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -70,7 +70,7 @@ static void closeSession(MXS_ROUTER *instance, void *router_session); static void freeSession(MXS_ROUTER *instance, void *router_session); static int execute(MXS_ROUTER *instance, void *router_session, GWBUF *queue); static void diagnostics(MXS_ROUTER *instance, DCB *dcb); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); static void handleError(MXS_ROUTER *instance, void *router_session, GWBUF *errbuf, @@ -392,7 +392,7 @@ diagnostics(MXS_ROUTER *instance, DCB *dcb) * Not used for the maxinfo router */ static uint64_t -getCapabilities(void) +getCapabilities(MXS_ROUTER* instance) { return 0; } diff --git a/server/modules/routing/readconnroute/readconnroute.c b/server/modules/routing/readconnroute/readconnroute.c index 77ca1e23f..70f4ed516 100644 --- a/server/modules/routing/readconnroute/readconnroute.c +++ b/server/modules/routing/readconnroute/readconnroute.c @@ -98,7 +98,7 @@ static void clientReply(MXS_ROUTER *instance, void *router_session, GWBUF *queue DCB *backend_dcb); static void handleError(MXS_ROUTER *instance, void *router_session, GWBUF *errbuf, DCB *problem_dcb, mxs_error_action_t action, bool *succp); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses); static void rses_end_locked_router_action(ROUTER_CLIENT_SES* rses); static SERVER_REF *get_root_master(SERVER_REF *servers); @@ -785,7 +785,7 @@ static void rses_end_locked_router_action(ROUTER_CLIENT_SES* rses) spinlock_release(&rses->rses_lock); } -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return RCAP_TYPE_NONE; } diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 5f700c5e8..48b925644 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -79,7 +79,7 @@ static void clientReply(MXS_ROUTER *instance, void *router_session, GWBUF *queue static void handleError(MXS_ROUTER *instance, void *router_session, GWBUF *errmsgbuf, DCB *backend_dcb, mxs_error_action_t action, bool *succp); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); /* * End of the API functions; now the module structure that links to them. @@ -864,7 +864,7 @@ lock_failed: * * @return RCAP_TYPE_STMT_INPUT. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return RCAP_TYPE_STMT_INPUT | RCAP_TYPE_TRANSACTION_TRACKING; } diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 809251d69..2a6a54bf5 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -81,7 +81,7 @@ static route_target_t get_shard_route_target(qc_query_type_t qtype, bool trx_active, HINT* hint); -static uint64_t getCapabilities(void); +static uint64_t getCapabilities(MXS_ROUTER* instance); static bool connect_backend_servers(backend_ref_t* backend_ref, int router_nservers, @@ -3320,7 +3320,7 @@ static rses_property_t* mysql_sescmd_get_property(mysql_sescmd_t* scmd) /** * Return RCAP_TYPE_STMT_INPUT. */ -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return RCAP_TYPE_STMT_INPUT; } diff --git a/server/modules/routing/testroute/testroute.c b/server/modules/routing/testroute/testroute.c index faac7e4ca..14b35c725 100644 --- a/server/modules/routing/testroute/testroute.c +++ b/server/modules/routing/testroute/testroute.c @@ -22,7 +22,7 @@ static void freeSession(MXS_ROUTER *instance, void *session); static int routeQuery(MXS_ROUTER *instance, void *session, GWBUF *queue); static void clientReply(MXS_ROUTER *instance, void *session, GWBUF *queue, DCB*); static void diagnostic(MXS_ROUTER *instance, DCB *dcb); -static uint64_t getCapabilities (); +static uint64_t getCapabilities(MXS_ROUTER* instance); static void handleError(MXS_ROUTER *instance, void *router_session, GWBUF *errbuf, @@ -150,7 +150,7 @@ diagnostic(MXS_ROUTER *instance, DCB *dcb) { } -static uint64_t getCapabilities(void) +static uint64_t getCapabilities(MXS_ROUTER* instance) { return 0; } From 3a3b31ebb48e10c6e311a0ef58b883de7e7e8a66 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 14 Feb 2017 13:43:48 +0200 Subject: [PATCH 11/11] NullFilter capabilities are now instance specific There can now in one configuration be multiple Null filters, each with its own set of capabilities. --- .../modules/filter/nullfilter/nullfilter.cc | 31 +++---------------- .../modules/filter/nullfilter/nullfilter.hh | 5 ++- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/server/modules/filter/nullfilter/nullfilter.cc b/server/modules/filter/nullfilter/nullfilter.cc index b51b4f95f..33aec2605 100644 --- a/server/modules/filter/nullfilter/nullfilter.cc +++ b/server/modules/filter/nullfilter/nullfilter.cc @@ -36,16 +36,6 @@ MXS_ENUM_VALUE capability_values[] = { NULL, 0 } }; -struct unit_variables -{ - uint64_t capabilities; - bool capabilities_set; -} this_unit = -{ - 0, - false -}; - } // @@ -81,7 +71,8 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE() // NullFilter // -NullFilter::NullFilter(const char* zName) +NullFilter::NullFilter(const char* zName, uint64_t capabilities) + : m_capabilities(capabilities) { MXS_NOTICE("Null filter [%s] created.", zName); } @@ -97,16 +88,7 @@ NullFilter* NullFilter::create(const char* zName, char**, MXS_CONFIG_PARAMETER* uint64_t capabilities = config_get_enum(pParams, CAPABILITIES_PARAM, capability_values); - if (this_unit.capabilities_set) - { - MXS_WARNING("The capabilities reported by NullFilter are currently global, " - "and not specific for a particular NullFilter instance."); - } - - this_unit.capabilities = capabilities; - this_unit.capabilities_set = true; - - return new NullFilter(zName); + return new NullFilter(zName, capabilities); } @@ -123,10 +105,5 @@ void NullFilter::diagnostics(DCB* pDcb) uint64_t NullFilter::getCapabilities() { - if (!this_unit.capabilities_set) - { - MXS_ERROR("getCapabilities() called before they have been set."); - } - - return this_unit.capabilities; + return m_capabilities; } diff --git a/server/modules/filter/nullfilter/nullfilter.hh b/server/modules/filter/nullfilter/nullfilter.hh index ceb7baf60..6bb909379 100644 --- a/server/modules/filter/nullfilter/nullfilter.hh +++ b/server/modules/filter/nullfilter/nullfilter.hh @@ -29,8 +29,11 @@ public: uint64_t getCapabilities(); private: - NullFilter(const char* zName); + NullFilter(const char* zName, uint64_t m_capabilities); NullFilter(const NullFilter&); NullFilter& operator = (const NullFilter&); + +private: + uint64_t m_capabilities; };