From e7a30a794455f82dd13ecbf16c507b7a13ac2486 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Thu, 19 Nov 2015 15:40:43 +0000 Subject: [PATCH] Overhaul monitor_common functions and move into monitor.c --- server/core/monitor.c | 353 +++++++++++++++ server/include/def_monitor_event.h | 36 ++ server/include/monitor.h | 55 +++ server/modules/monitor/galeramon.h | 1 - server/modules/monitor/mmmon.h | 1 - server/modules/monitor/monitor_common.c | 558 ------------------------ server/modules/monitor/monitor_common.h | 87 ---- server/modules/monitor/mysqlmon.h | 1 - server/modules/monitor/ndbclustermon.h | 1 - 9 files changed, 444 insertions(+), 649 deletions(-) create mode 100644 server/include/def_monitor_event.h delete mode 100644 server/modules/monitor/monitor_common.c delete mode 100644 server/modules/monitor/monitor_common.h diff --git a/server/core/monitor.c b/server/core/monitor.c index afad7d7da..4f14ff876 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -41,6 +41,7 @@ #include #include #include +#include #include static MONITOR *allMonitors = NULL; @@ -549,3 +550,355 @@ void monitorAddParameters(MONITOR *monitor, CONFIG_PARAMETER *params) params = params->next; } } + +/** + * Set a pending status bit in the monitor server + * + * @param server The server to update + * @param bit The bit to clear for the server + */ +void +monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit) +{ + ptr->pending_status |= bit; +} + +/** + * Clear a pending status bit in the monitor server + * + * @param server The server to update + * @param bit The bit to clear for the server + */ +void +monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit) +{ + ptr->pending_status &= ~bit; +} + +/* + * Determine a monitor event, defined by the difference between the old + * status of a server and the new status. + * + * @param node The monitor server data for a particular server + * @result monitor_event_t A monitor event (enum) + */ +monitor_event_t +mon_get_event_type(MONITOR_SERVERS* node) +{ + typedef enum { + DOWN_EVENT, + UP_EVENT, + LOSS_EVENT, + NEW_EVENT + } general_event_type; + general_event_type event_type; + + unsigned int prev = node->mon_prev_status + & (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB); + unsigned int present = node->server->status + & (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB); + + if (prev == present) + { + /* No change in the bits we're interested in */ + return UNDEFINED_MONITOR_EVENT; + } + + if ((prev & SERVER_RUNNING) == 0) + { + /* The server was not running previously */ + if ((present & SERVER_RUNNING) != 0) + { + event_type = UP_EVENT; + } + } + else + { + /* Previous state must have been running */ + if ((present & SERVER_RUNNING) == 0) + { + event_type = DOWN_EVENT; + } + else + { + /* Was running and still is */ + if (prev && (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB)) + { + /* We used to know what kind of server it was */ + event_type = LOSS_EVENT; + } + else + { + /* We didn't know what kind of server it was, now we do*/ + event_type = NEW_EVENT; + } + } + } + + switch (event_type) + { + case UP_EVENT: + return (present & SERVER_MASTER) ? MASTER_UP_EVENT : + (present & SERVER_SLAVE) ? SLAVE_UP_EVENT : + (present & SERVER_JOINED) ? SYNCED_UP_EVENT : + (present & SERVER_NDB) ? NDB_UP_EVENT : + SERVER_UP_EVENT; + case DOWN_EVENT: + return (present & SERVER_MASTER) ? MASTER_DOWN_EVENT : + (present & SERVER_SLAVE) ? SLAVE_DOWN_EVENT : + (present & SERVER_JOINED) ? SYNCED_DOWN_EVENT : + (present & SERVER_NDB) ? NDB_DOWN_EVENT : + SERVER_DOWN_EVENT; + case LOSS_EVENT: + return (prev & SERVER_MASTER) ? LOST_MASTER_EVENT : + (prev & SERVER_SLAVE) ? LOST_SLAVE_EVENT : + (prev & SERVER_JOINED) ? LOST_SYNCED_EVENT : + LOST_NDB_EVENT; + case NEW_EVENT: + return (present & SERVER_MASTER) ? NEW_MASTER_EVENT : + (present & SERVER_SLAVE) ? NEW_SLAVE_EVENT : + (present & SERVER_JOINED) ? NEW_SYNCED_EVENT : + NEW_NDB_EVENT; + default: + /* This should be impossible */ + return UNDEFINED_MONITOR_EVENT; + } +} + +/* + * Given a monitor event (enum) provide a text string equivalent + * @param node The monitor server data whose event is wanted + * @result string The name of the monitor event for the server + */ +char* +mon_get_event_name(MONITOR_SERVERS* node) +{ + return monitor_event_definitions[mon_get_event_type(node)].name; +} + +/* + * Given the text version of a monitor event, determine the event (enum) + * + * @param event_name String containing the event name + * @result monitor_event_t Monitor event corresponding to name + */ +monitor_event_t +mon_name_to_event (char *event_name) +{ + monitor_event_t event; + + for (event = 0; event < MAX_MONITOR_EVENT; event++) + { + if (0 == strcasecmp(monitor_event_definitions[event].name, event_name)) + { + return event; + } + } + return UNDEFINED_MONITOR_EVENT; +} + +/** + * Create a list of running servers + * + * @param servers Monitored servers + * @param dest Destination where the string is appended, must be null terminated + * @param len Length of @c dest + */ +void +mon_append_node_names(MONITOR_SERVERS* servers, char* dest, int len) +{ + char *separator = ""; + char arr[MAX_SERVER_NAME_LEN + 32]; // Some extra space for port + + while (servers && strlen(dest) < (len - strlen(separator))) + { + if (SERVER_IS_RUNNING(servers->server)) + { + strcat(dest, separator, len); + separator = ","; + snprintf(arr, sizeof(arr), "%s:%d", servers->server->name, servers->server->port); + strncat(dest, arr, len - strlen(dest) - 1); + } + servers = servers->next; + } +} + +/** + * Check if current monitored server status has changed + * + * @param mon_srv The monitored server + * @return true if status has changed or false + */ +bool +mon_status_changed(MONITOR_SERVERS* mon_srv) +{ + /* Previous status is -1 if not yet set */ + return (mon_srv->mon_prev_status != -1 + && mon_srv->mon_prev_status != mon_srv->server->status); +} + +/** + * Check if current monitored server has a loggable failure status + * + * @param mon_srv The monitored server + * @return true if failed status can be logged or false + */ +bool +mon_print_fail_status(MONITOR_SERVERS* mon_srv) +{ + return (SERVER_IS_DOWN(mon_srv->server) && mon_srv->mon_err_count == 0); +} + +/** + * Launch a script + * @param mon Owning monitor + * @param ptr The server which has changed state + * @param script Script to execute + */ +void +monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) +{ + char nodelist[PATH_MAX + MON_ARG_MAX + 1] = {'\0'}; + char initiator[strlen(ptr->server->name) + 24]; // Extra space for port + + snprintf(initiator, sizeof(initiator), "%s:%d", ptr->server->name, ptr->server->port); + mon_append_node_names(mon->databases, nodelist, PATH_MAX + MON_ARG_MAX); + + EXTERNCMD* cmd = externcmd_allocate(script); + + if (cmd == NULL) + { + MXS_ERROR("Failed to initialize script: %s", script); + return; + } + + externcmd_substitute_arg(cmd, "[$]INITIATOR", initiator); + externcmd_substitute_arg(cmd, "[$]EVENT", mon_get_event_name(ptr)); + externcmd_substitute_arg(cmd, "[$]NODELIST", nodelist); + + if (externcmd_execute(cmd)) + { + MXS_ERROR("Failed to execute script " + "'%s' on server state change event %s.", + script, mon_get_event_name(ptr)); + } + externcmd_free(cmd); +} + +/** + * Parse a string of event names to an array with enabled events. + * @param events Pointer to an array of boolean values + * @param count Size of the array + * @param string String to parse + * @return 0 on success. 1 when an error has occurred or an unexpected event was + * found. + */ +int +mon_parse_event_string(bool* events, size_t count, char* string) +{ + char *tok, *saved; + monitor_event_t event; + + tok = strtok_r(string, ",| ", &saved); + + if (tok == NULL) + { + return -1; + } + + while (tok) + { + event = mon_name_to_event(tok); + if (event == UNDEFINED_MONITOR_EVENT) + { + MXS_ERROR("Invalid event name %s", tok); + return -1; + } + events[event] = true; + tok = strtok_r(NULL, ",| ", &saved); + } + + return 0; +} + +/** + * Connect to a database. This will always leave a valid database handle in the + * database->con pointer. This allows the user to call MySQL C API functions to + * find out the reason of the failure. + * @param mon Monitor + * @param database Monitored database + * @return MONITOR_CONN_OK if the connection is OK else the reason for the failure + */ +connect_result_t +mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database) +{ + connect_result_t rval = MONITOR_CONN_OK; + + /** Return if the connection is OK */ + if (database->con && mysql_ping(database->con) == 0) + { + return rval; + } + + int connect_timeout = mon->connect_timeout; + int read_timeout = mon->read_timeout; + int write_timeout = mon->write_timeout; + char *uname = database->server->monuser ? database->server->monuser : mon->user; + char *passwd = database->server->monpw ? database->server->monpw : mon->password; + char *dpwd = decryptPassword(passwd); + + if (database->con) + { + mysql_close(database->con); + } + database->con = mysql_init(NULL); + + mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *) &connect_timeout); + mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *) &read_timeout); + mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *) &write_timeout); + + time_t start = time(NULL); + bool result = (mysql_real_connect(database->con, + database->server->name, + uname, + dpwd, + NULL, + database->server->port, + NULL, + 0) != NULL); + time_t end = time(NULL); + + if (!result) + { + if ((int) difftime(end, start) >= connect_timeout) + { + rval = MONITOR_CONN_TIMEOUT; + } + else + { + rval = MONITOR_CONN_REFUSED; + } + } + + free(dpwd); + return rval; +} + +/** + * Log an error about the failure to connect to a backend server + * and why it happened. + * @param database Backend database + * @param rval Return value of mon_connect_to_db + */ +void +mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval) +{ + MXS_ERROR(rval == MONITOR_CONN_TIMEOUT ? + "Monitor timed out when connecting to " + "server %s:%d : \"%s\"" : + "Monitor was unable to connect to " + "server %s:%d : \"%s\"", + database->server->name, + database->server->port, + mysql_error(database->con)); +} diff --git a/server/include/def_monitor_event.h b/server/include/def_monitor_event.h new file mode 100644 index 000000000..b8d594bb0 --- /dev/null +++ b/server/include/def_monitor_event.h @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: def_event.h + * Author: mbrampton + * + * Created on 18 November 2015, 15:21 + */ + +ADDITEM( UNDEFINED_MONITOR_EVENT, undefined ), +ADDITEM( MASTER_DOWN_EVENT, master_down ), +ADDITEM( MASTER_UP_EVENT, master_up ), +ADDITEM( SLAVE_DOWN_EVENT, slave_down ), +ADDITEM( SLAVE_UP_EVENT, slave_up ), +ADDITEM( SERVER_DOWN_EVENT, server_down ), +ADDITEM( SERVER_UP_EVENT, server_up ), +ADDITEM( SYNCED_DOWN_EVENT, synced_down ), +ADDITEM( SYNCED_UP_EVENT, synced_up ), +ADDITEM( DONOR_DOWN_EVENT, donor_down ), +ADDITEM( DONOR_UP_EVENT, donor_up ), +ADDITEM( NDB_DOWN_EVENT, ndb_down ), +ADDITEM( NDB_UP_EVENT, ndb_up ), +ADDITEM( LOST_MASTER_EVENT, lost_master ), +ADDITEM( LOST_SLAVE_EVENT, lost_slave ), +ADDITEM( LOST_SYNCED_EVENT, lost_synced ), +ADDITEM( LOST_DONOR_EVENT, lost_donor ), +ADDITEM( LOST_NDB_EVENT, lost_ndb ), +ADDITEM( NEW_MASTER_EVENT, new_master ), +ADDITEM( NEW_SLAVE_EVENT, new_slave ), +ADDITEM( NEW_SYNCED_EVENT, new_synced ), +ADDITEM( NEW_DONOR_EVENT, new_donor ), +ADDITEM( NEW_NDB_EVENT, new_ndb ), diff --git a/server/include/monitor.h b/server/include/monitor.h index 5c2bb1f69..e5da23e0f 100644 --- a/server/include/monitor.h +++ b/server/include/monitor.h @@ -20,8 +20,11 @@ #include #include #include +#include #include #include +#include +#include /** * @file monitor.h The interface to the monitor module @@ -39,6 +42,8 @@ * 30/10/14 Massimiliano Pinto Addition of disableMasterFailback * 07/11/14 Massimiliano Pinto Addition of setNetworkTimeout * 19/02/15 Mark Riddoch Addition of monitorGetList + * 19/11/15 Martin Brampton Automation of event and name declaration, absorption + * of what was formerly monitor_common.h * * @endverbatim */ @@ -105,6 +110,18 @@ typedef enum MONITOR_WRITE_TIMEOUT = 2 } monitor_timeouts_t; +/* + * Results of attempt at database connection for monitoring + */ +typedef enum +{ + MONITOR_CONN_OK, + MONITOR_CONN_REFUSED, + MONITOR_CONN_TIMEOUT +} connect_result_t; + +#define MON_ARG_MAX 8192 + #define DEFAULT_CONNECT_TIMEOUT 3 #define DEFAULT_READ_TIMEOUT 1 #define DEFAULT_WRITE_TIMEOUT 2 @@ -118,6 +135,31 @@ typedef enum #define MONITOR_DEFAULT_ID 1UL // unsigned long value #define MONITOR_MAX_NUM_SLAVES 20 //number of MySQL slave servers associated to a MySQL master server +/* + * Create declarations of the enum for monitor events and also the array of + * structs containing the matching names. The data is taken from def_monitor_event.h + */ +#undef ADDITEM +#define ADDITEM( _event_type, _event_name ) _event_type +typedef enum +{ +#include "def_monitor_event.h" + MAX_MONITOR_EVENT +} monitor_event_t; +#undef ADDITEM + +typedef struct monitor_def_s +{ + char name[30]; +} monitor_def_t; + +#undef ADDITEM +#define ADDITEM( _event_type, _event_name ) { #_event_name } +static const monitor_def_t monitor_event_definitions[MAX_MONITOR_EVENT] = +{ +#include "def_monitor_event.h" +}; +#undef ADDITEM /** * The linked list of servers that are being monitored by the monitor module. @@ -175,4 +217,17 @@ extern void monitorSetNetworkTimeout(MONITOR *, int, int); extern RESULTSET *monitorGetList(); bool check_monitor_permissions(MONITOR* monitor); +monitor_event_t mon_name_to_event(char* tok); +void mon_append_node_names(MONITOR_SERVERS* start, char* str, int len); +monitor_event_t mon_get_event_type(MONITOR_SERVERS* node); +char* mon_get_event_name(MONITOR_SERVERS* node); +void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit); +void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit); +bool mon_status_changed(MONITOR_SERVERS* mon_srv); +bool mon_print_fail_status(MONITOR_SERVERS* mon_srv); +void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script); +int mon_parse_event_string(bool* events, size_t count, char* string); +connect_result_t mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database); +void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval); + #endif diff --git a/server/modules/monitor/galeramon.h b/server/modules/monitor/galeramon.h index b92e97015..d4cf3b94c 100644 --- a/server/modules/monitor/galeramon.h +++ b/server/modules/monitor/galeramon.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/server/modules/monitor/mmmon.h b/server/modules/monitor/mmmon.h index 9e1f4d962..923a4b182 100644 --- a/server/modules/monitor/mmmon.h +++ b/server/modules/monitor/mmmon.h @@ -32,7 +32,6 @@ #include #include #include -#include #include /** diff --git a/server/modules/monitor/monitor_common.c b/server/modules/monitor/monitor_common.c deleted file mode 100644 index 4a56056ba..000000000 --- a/server/modules/monitor/monitor_common.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * This file is distributed as part of the MariaDB Corporation 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 MariaDB Corporation Ab 2013-2015 - */ - -#include -#include - -monitor_event_t mon_name_to_event(char* tok); - -/** - * Set a pending status bit in the monitor server - * - * @param server The server to update - * @param bit The bit to clear for the server - */ -void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit) -{ - ptr->pending_status |= bit; -} - -/** - * Clear a pending status bit in the monitor server - * - * @param server The server to update - * @param bit The bit to clear for the server - */ -void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit) -{ - ptr->pending_status &= ~bit; -} - -monitor_event_t mon_get_event_type(MONITOR_SERVERS* node) -{ - unsigned int prev = node->mon_prev_status; - - if ((prev & (SERVER_MASTER | SERVER_RUNNING)) == (SERVER_MASTER | SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) - { - return MASTER_DOWN_EVENT; - } - if ((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_MASTER(node->server)) - { - return MASTER_UP_EVENT; - } - if ((prev & (SERVER_SLAVE | SERVER_RUNNING)) == (SERVER_SLAVE | SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) - { - return SLAVE_DOWN_EVENT; - } - if ((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_SLAVE(node->server)) - { - return SLAVE_UP_EVENT; - } - - /** Galera specific events */ - if ((prev & (SERVER_JOINED | SERVER_RUNNING)) == (SERVER_JOINED | SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) - { - return SYNCED_DOWN_EVENT; - } - if ((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_JOINED(node->server)) - { - return SYNCED_UP_EVENT; - } - - /** NDB events*/ - if ((prev & (SERVER_NDB | SERVER_RUNNING)) == (SERVER_NDB | SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) - { - return NDB_DOWN_EVENT; - } - if ((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_NDB(node->server)) - { - return NDB_UP_EVENT; - } - - if ((prev & (SERVER_RUNNING)) == SERVER_RUNNING && - SERVER_IS_RUNNING(node->server) && SERVER_IS_MASTER(node->server)) - { - return NEW_MASTER_EVENT; - } - if ((prev & (SERVER_RUNNING)) == SERVER_RUNNING && - SERVER_IS_RUNNING(node->server) && SERVER_IS_SLAVE(node->server)) - { - return NEW_SLAVE_EVENT; - } - - /** Status loss events */ - if ((prev & (SERVER_RUNNING | SERVER_MASTER)) == (SERVER_RUNNING | SERVER_MASTER) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_MASTER(node->server)) - { - return LOST_MASTER_EVENT; - } - if ((prev & (SERVER_RUNNING | SERVER_SLAVE)) == (SERVER_RUNNING | SERVER_SLAVE) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_SLAVE(node->server)) - { - return LOST_SLAVE_EVENT; - } - if ((prev & (SERVER_RUNNING | SERVER_JOINED)) == (SERVER_RUNNING | SERVER_JOINED) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_JOINED(node->server)) - { - return LOST_SYNCED_EVENT; - } - if ((prev & (SERVER_RUNNING | SERVER_NDB)) == (SERVER_RUNNING | SERVER_NDB) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_NDB(node->server)) - { - return LOST_NDB_EVENT; - } - - - /** Generic server failure */ - if ((prev & SERVER_RUNNING) == 0 && - SERVER_IS_RUNNING(node->server)) - { - return SERVER_UP_EVENT; - } - if ((prev & SERVER_RUNNING) == SERVER_RUNNING && - SERVER_IS_DOWN(node->server)) - { - return SERVER_DOWN_EVENT; - } - - /** Something else, most likely a state that does not matter. - * For example SERVER_DOWN -> SERVER_MASTER|SERVER_DOWN still results in a - * server state equal to not running.*/ - return UNDEFINED_MONITOR_EVENT; -} - -char* mon_get_event_name(MONITOR_SERVERS* node) -{ - switch (mon_get_event_type(node)) - { - case UNDEFINED_MONITOR_EVENT: - return "undefined"; - - case MASTER_DOWN_EVENT: - return "master_down"; - - case MASTER_UP_EVENT: - return "master_up"; - - case SLAVE_DOWN_EVENT: - return "slave_down"; - - case SLAVE_UP_EVENT: - return "slave_up"; - - case SERVER_DOWN_EVENT: - return "server_down"; - - case SERVER_UP_EVENT: - return "server_up"; - - case SYNCED_DOWN_EVENT: - return "synced_down"; - - case SYNCED_UP_EVENT: - return "synced_up"; - - case DONOR_DOWN_EVENT: - return "donor_down"; - - case DONOR_UP_EVENT: - return "donor_up"; - - case NDB_DOWN_EVENT: - return "ndb_down"; - - case NDB_UP_EVENT: - return "ndb_up"; - - case LOST_MASTER_EVENT: - return "lost_master"; - - case LOST_SLAVE_EVENT: - return "lost_slave"; - - case LOST_SYNCED_EVENT: - return "lost_synced"; - - case LOST_DONOR_EVENT: - return "lost_donor"; - - case LOST_NDB_EVENT: - return "lost_ndb"; - - case NEW_MASTER_EVENT: - return "new_master"; - - case NEW_SLAVE_EVENT: - return "new_slave"; - - case NEW_SYNCED_EVENT: - return "new_synced"; - - case NEW_DONOR_EVENT: - return "new_donor"; - - case NEW_NDB_EVENT: - return "new_ndb"; - - default: - return "MONITOR_EVENT_FAILURE"; - - } - - -} - -/** - * Create a list of running servers - * @param start Monitored servers - * @param dest Destination where the string is formed - * @param len Length of @c dest - */ -void mon_append_node_names(MONITOR_SERVERS* start, char* dest, int len) -{ - MONITOR_SERVERS* ptr = start; - bool first = true; - int slen = strlen(dest); - char arr[MAX_SERVER_NAME_LEN + 32]; // Some extra space for port - while (ptr && slen < len) - { - if (SERVER_IS_RUNNING(ptr->server)) - { - if (!first) - { - strncat(dest, ",", len); - } - first = false; - snprintf(arr, sizeof(arr), "%s:%d", ptr->server->name, ptr->server->port); - strncat(dest, arr, len); - slen = strlen(dest); - } - ptr = ptr->next; - } -} - -/** - * Check if current monitored server status has changed - * - * @param mon_srv The monitored server - * @return true if status has changed or false - */ -bool mon_status_changed( - MONITOR_SERVERS* mon_srv) -{ - bool succp; - - /** This is the first time the server was set with a status*/ - if (mon_srv->mon_prev_status == -1) - { - return false; - } - - if (mon_srv->mon_prev_status != mon_srv->server->status) - { - succp = true; - } - else - { - succp = false; - } - return succp; -} - -/** - * Check if current monitored server has a loggable failure status - * - * @param mon_srv The monitored server - * @return true if failed status can be logged or false - */ -bool mon_print_fail_status( - MONITOR_SERVERS* mon_srv) -{ - bool succp; - int errcount = mon_srv->mon_err_count; - - if (SERVER_IS_DOWN(mon_srv->server) && errcount == 0) - { - succp = true; - } - else - { - succp = false; - } - return succp; -} - -/** - * Launch a script - * @param mon Owning monitor - * @param ptr The server which has changed state - * @param script Script to execute - */ -void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) -{ - char nodelist[PATH_MAX + MON_ARG_MAX + 1] = {'\0'}; - char initiator[strlen(ptr->server->name) + 24]; // Extra space for port - - snprintf(initiator, sizeof(initiator), "%s:%d", ptr->server->name, ptr->server->port); - mon_append_node_names(mon->databases, nodelist, PATH_MAX + MON_ARG_MAX); - - EXTERNCMD* cmd = externcmd_allocate(script); - - if (cmd == NULL) - { - MXS_ERROR("Failed to initialize script: %s", script); - return; - } - - externcmd_substitute_arg(cmd, "[$]INITIATOR", initiator); - externcmd_substitute_arg(cmd, "[$]EVENT", mon_get_event_name(ptr)); - externcmd_substitute_arg(cmd, "[$]NODELIST", nodelist); - - if (externcmd_execute(cmd)) - { - MXS_ERROR("Failed to execute script " - "'%s' on server state change event %s.", - script, mon_get_event_name(ptr)); - } - externcmd_free(cmd); -} - -/** - * Parse a string of event names to an array with enabled events. - * @param events Pointer to an array of boolean values - * @param count Size of the array - * @param string String to parse - * @return 0 on success. 1 when an error has occurred or an unexpected event was - * found. - */ -int mon_parse_event_string(bool* events, size_t count, char* string) -{ - char *tok, *saved; - monitor_event_t event; - - tok = strtok_r(string, ",| ", &saved); - - if (tok == NULL) - { - return -1; - } - - while (tok) - { - event = mon_name_to_event(tok); - if (event == UNDEFINED_MONITOR_EVENT) - { - MXS_ERROR("Invalid event name %s", tok); - return -1; - } - events[event] = true; - tok = strtok_r(NULL, ",| ", &saved); - } - - return 0; -} - -monitor_event_t mon_name_to_event(char* tok) -{ - if (!strcasecmp("master_down", tok)) - { - return MASTER_DOWN_EVENT; - } - else if (!strcasecmp("master_up", tok)) - { - return MASTER_UP_EVENT; - } - else if (!strcasecmp("slave_down", tok)) - { - return SLAVE_DOWN_EVENT; - } - else if (!strcasecmp("slave_up", tok)) - { - return SLAVE_UP_EVENT; - } - else if (!strcasecmp("server_down", tok)) - { - return SERVER_DOWN_EVENT; - } - else if (!strcasecmp("server_up", tok)) - { - return SERVER_UP_EVENT; - } - else if (!strcasecmp("synced_down", tok)) - { - return SYNCED_DOWN_EVENT; - } - else if (!strcasecmp("synced_up", tok)) - { - return SYNCED_UP_EVENT; - } - else if (!strcasecmp("donor_down", tok)) - { - return DONOR_DOWN_EVENT; - } - else if (!strcasecmp("donor_up", tok)) - { - return DONOR_UP_EVENT; - } - else if (!strcasecmp("ndb_down", tok)) - { - return NDB_DOWN_EVENT; - } - else if (!strcasecmp("ndb_up", tok)) - { - return NDB_UP_EVENT; - } - else if (!strcasecmp("lost_master", tok)) - { - return LOST_MASTER_EVENT; - } - else if (!strcasecmp("lost_slave", tok)) - { - return LOST_SLAVE_EVENT; - } - else if (!strcasecmp("lost_synced", tok)) - { - return LOST_SYNCED_EVENT; - } - else if (!strcasecmp("lost_donor", tok)) - { - return LOST_DONOR_EVENT; - } - else if (!strcasecmp("lost_ndb", tok)) - { - return LOST_NDB_EVENT; - } - else if (!strcasecmp("new_master", tok)) - { - return NEW_MASTER_EVENT; - } - else if (!strcasecmp("new_slave", tok)) - { - return NEW_SLAVE_EVENT; - } - else if (!strcasecmp("new_synced", tok)) - { - return NEW_SYNCED_EVENT; - } - else if (!strcasecmp("new_donor", tok)) - { - return NEW_DONOR_EVENT; - } - else if (!strcasecmp("new_ndb", tok)) - { - return NEW_NDB_EVENT; - } - - return UNDEFINED_MONITOR_EVENT; -} - -/** - * Connect to a database. This will always leave a valid database handle in the - * database->con pointer. This allows the user to call MySQL C API functions to - * find out the reason of the failure. - * @param mon Monitor - * @param database Monitored database - * @return MONITOR_CONN_OK if the connection is OK else the reason for the failure - */ -connect_result_t mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database) -{ - connect_result_t rval = MONITOR_CONN_OK; - - /** Return if the connection is OK */ - if (database->con && mysql_ping(database->con) == 0) - { - return rval; - } - - int connect_timeout = mon->connect_timeout; - int read_timeout = mon->read_timeout; - int write_timeout = mon->write_timeout; - char *uname = database->server->monuser ? database->server->monuser : mon->user; - char *passwd = database->server->monpw ? database->server->monpw : mon->password; - char *dpwd = decryptPassword(passwd); - - if (database->con) - { - mysql_close(database->con); - } - database->con = mysql_init(NULL); - - mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *) &connect_timeout); - mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *) &read_timeout); - mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *) &write_timeout); - - time_t start = time(NULL); - bool result = (mysql_real_connect(database->con, - database->server->name, - uname, - dpwd, - NULL, - database->server->port, - NULL, - 0) != NULL); - time_t end = time(NULL); - - if (!result) - { - if ((int) difftime(end, start) >= connect_timeout) - { - rval = MONITOR_CONN_TIMEOUT; - } - else - { - rval = MONITOR_CONN_REFUSED; - } - } - - free(dpwd); - return rval; -} - -/** - * Log an error about the failure to connect to a backend server - * and why it happened. - * @param database Backend database - * @param rval Return value of mon_connect_to_db - */ -void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval) -{ - if (rval == MONITOR_CONN_TIMEOUT) - { - MXS_ERROR("Monitor timed out when connecting to " - "server %s:%d : \"%s\"", - database->server->name, - database->server->port, - mysql_error(database->con)); - } - else - { - MXS_ERROR("Monitor was unable to connect to " - "server %s:%d : \"%s\"", - database->server->name, - database->server->port, - mysql_error(database->con)); - } -} diff --git a/server/modules/monitor/monitor_common.h b/server/modules/monitor/monitor_common.h deleted file mode 100644 index 13b191001..000000000 --- a/server/modules/monitor/monitor_common.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _MONITOR_COMMON_HG -#define _MONITOR_COMMON_HG -/* - * This file is distributed as part of the MariaDB Corporation 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 MariaDB Corporation Ab 2013-2015 - */ - -#include -#include -#include -#include -#include -#include -/** - * @file monitor_common.h - The generic monitor structures all monitors use - * - * Revision History - * - * Date Who Description - * 07/05/15 Markus Makela Initial Implementation - * @endverbatim - */ - -#define MON_ARG_MAX 8192 - -/** Monitor events that are caused by servers moving from - * one state to another.*/ -typedef enum -{ - UNDEFINED_MONITOR_EVENT, - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - SYNCED_DOWN_EVENT, - SYNCED_UP_EVENT, - DONOR_DOWN_EVENT, - DONOR_UP_EVENT, - NDB_DOWN_EVENT, - NDB_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - LOST_SYNCED_EVENT, - LOST_DONOR_EVENT, - LOST_NDB_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - NEW_SYNCED_EVENT, - NEW_DONOR_EVENT, - NEW_NDB_EVENT, - MAX_MONITOR_EVENT -} monitor_event_t; - -typedef enum -{ - MONITOR_CONN_OK, - MONITOR_CONN_REFUSED, - MONITOR_CONN_TIMEOUT -} connect_result_t; - -void mon_append_node_names(MONITOR_SERVERS* start, char* str, int len); -monitor_event_t mon_get_event_type(MONITOR_SERVERS* node); -char* mon_get_event_name(MONITOR_SERVERS* node); -void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit); -void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit); -bool mon_status_changed(MONITOR_SERVERS* mon_srv); -bool mon_print_fail_status(MONITOR_SERVERS* mon_srv); -void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script); -int mon_parse_event_string(bool* events, size_t count, char* string); -connect_result_t mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database); -void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval); -#endif diff --git a/server/modules/monitor/mysqlmon.h b/server/modules/monitor/mysqlmon.h index eaa640a94..b23877aa8 100644 --- a/server/modules/monitor/mysqlmon.h +++ b/server/modules/monitor/mysqlmon.h @@ -32,7 +32,6 @@ #include #include #include -#include #include /** diff --git a/server/modules/monitor/ndbclustermon.h b/server/modules/monitor/ndbclustermon.h index 90798fb87..e6d6e9575 100644 --- a/server/modules/monitor/ndbclustermon.h +++ b/server/modules/monitor/ndbclustermon.h @@ -32,7 +32,6 @@ #include #include #include -#include #include /**