From a196420c2db1bb45ffd1329f5894249d3f45c0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 11 Jan 2017 11:11:11 +0200 Subject: [PATCH] Move monitor script processing and launching into the core This removes parts of the nearly identical code from all monitors. The removal of monitor type specific event checking is done based on the assumption that only the monitor that is monitoring the server can be the cause for a state change. This removes the need to actually check that the state change is relevant for each monitor and allows the event handling to be moved into the core. --- include/maxscale/def_monitor_event.h | 46 ----- include/maxscale/monitor.h | 92 +++++++--- server/core/monitor.c | 107 ++++-------- server/modules/monitor/auroramon/auroramon.c | 116 +++---------- server/modules/monitor/galeramon/galeramon.c | 163 +++--------------- server/modules/monitor/galeramon/galeramon.h | 2 +- server/modules/monitor/mmmon/mmmon.c | 118 +++---------- server/modules/monitor/mmmon/mmmon.h | 2 +- server/modules/monitor/mysqlmon.h | 2 +- server/modules/monitor/mysqlmon/mysql_mon.c | 115 +++--------- .../monitor/ndbclustermon/ndbclustermon.c | 123 +++---------- 11 files changed, 206 insertions(+), 680 deletions(-) delete mode 100644 include/maxscale/def_monitor_event.h diff --git a/include/maxscale/def_monitor_event.h b/include/maxscale/def_monitor_event.h deleted file mode 100644 index 6f0e09393..000000000 --- a/include/maxscale/def_monitor_event.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016 MariaDB Corporation Ab - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file and at www.mariadb.com/bsl. - * - * Change Date: 2019-07-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2 or later of the General - * Public License. - */ - -/** - * @file def_monitor_event.h - * - * @verbatim - * Revision History - * - * Date Who Description - * 01-06-2013 Martin Brampton Initial implementation - */ - -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/include/maxscale/monitor.h b/include/maxscale/monitor.h index 4b3a63092..2d94c211d 100644 --- a/include/maxscale/monitor.h +++ b/include/maxscale/monitor.h @@ -43,6 +43,7 @@ #include #include #include +#include MXS_BEGIN_DECLS @@ -62,14 +63,6 @@ MXS_BEGIN_DECLS * * stopMonitor is responsible for shuting down and destroying a monitor, it is called * with the void * handle that was returned by startMonitor. - * - * registerServer is called to register a server that must be monitored with a running - * monitor. this will be called with the handle returned from the startMonitor call and - * the SERVER structure that the monitor must update and monitor. The SERVER structure - * contains the information required to connect to the monitored server. - * - * unregisterServer is called to remove a server from the set of servers that need to be - * monitored. */ struct monitor; @@ -140,25 +133,66 @@ typedef enum #define MAX_MONITOR_USER_LEN 512 #define MAX_MONITOR_PASSWORD_LEN 512 -/* - * 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 +/** Monitor events */ typedef enum { -#include "def_monitor_event.h" - MAX_MONITOR_EVENT + UNDEFINED_EVENT = 0, + MASTER_DOWN_EVENT = (1 << 0), /**< master_down */ + MASTER_UP_EVENT = (1 << 1), /**< master_up */ + SLAVE_DOWN_EVENT = (1 << 2), /**< slave_down */ + SLAVE_UP_EVENT = (1 << 3), /**< slave_up */ + SERVER_DOWN_EVENT = (1 << 4), /**< server_down */ + SERVER_UP_EVENT = (1 << 5), /**< server_up */ + SYNCED_DOWN_EVENT = (1 << 6), /**< synced_down */ + SYNCED_UP_EVENT = (1 << 7), /**< synced_up */ + DONOR_DOWN_EVENT = (1 << 8), /**< donor_down */ + DONOR_UP_EVENT = (1 << 9), /**< donor_up */ + NDB_DOWN_EVENT = (1 << 10), /**< ndb_down */ + NDB_UP_EVENT = (1 << 11), /**< ndb_up */ + LOST_MASTER_EVENT = (1 << 12), /**< lost_master */ + LOST_SLAVE_EVENT = (1 << 13), /**< lost_slave */ + LOST_SYNCED_EVENT = (1 << 14), /**< lost_synced */ + LOST_DONOR_EVENT = (1 << 15), /**< lost_donor */ + LOST_NDB_EVENT = (1 << 16), /**< lost_ndb */ + NEW_MASTER_EVENT = (1 << 17), /**< new_master */ + NEW_SLAVE_EVENT = (1 << 18), /**< new_slave */ + NEW_SYNCED_EVENT = (1 << 19), /**< new_synced */ + NEW_DONOR_EVENT = (1 << 20), /**< new_donor */ + NEW_NDB_EVENT = (1 << 21), /**< new_ndb */ } monitor_event_t; -#undef ADDITEM -typedef struct monitor_def_s +static const MXS_ENUM_VALUE monitor_event_enum_values[] = { - char name[30]; -} monitor_def_t; + {"master_down", MASTER_DOWN_EVENT}, + {"master_up ", MASTER_UP_EVENT}, + {"slave_down ", SLAVE_DOWN_EVENT}, + {"slave_up ", SLAVE_UP_EVENT}, + {"server_down ", SERVER_DOWN_EVENT}, + {"server_up ", SERVER_UP_EVENT}, + {"synced_down ", SYNCED_DOWN_EVENT}, + {"synced_up ", SYNCED_UP_EVENT}, + {"donor_down ", DONOR_DOWN_EVENT}, + {"donor_up ", DONOR_UP_EVENT}, + {"ndb_down ", NDB_DOWN_EVENT}, + {"ndb_up ", NDB_UP_EVENT}, + {"lost_master ", LOST_MASTER_EVENT}, + {"lost_slave ", LOST_SLAVE_EVENT}, + {"lost_synced ", LOST_SYNCED_EVENT}, + {"lost_donor ", LOST_DONOR_EVENT}, + {"lost_ndb ", LOST_NDB_EVENT}, + {"new_master ", NEW_MASTER_EVENT}, + {"new_slave ", NEW_SLAVE_EVENT}, + {"new_synced ", NEW_SYNCED_EVENT}, + {"new_donor ", NEW_DONOR_EVENT}, + {"new_ndb ", NEW_NDB_EVENT}, + {NULL} +}; -extern const monitor_def_t monitor_event_definitions[]; +/** Default value for the `events` parameter */ +static const char MONITOR_EVENT_DEFAULT_VALUE[] = "master_down,master_up,slave_down," + "slave_up,server_down,server_up,synced_down,synced_up,donor_down,donor_up," + "ndb_down,ndb_up,lost_master,lost_slave,lost_synced,lost_donor,lost_ndb," + "new_master,new_slave,new_synced,new_donor,new_ndb"; /** * The linked list of servers that are being monitored by the monitor module. @@ -226,15 +260,12 @@ extern bool monitorSetNetworkTimeout(MONITOR *, int, int); extern RESULTSET *monitorGetList(); extern bool check_monitor_permissions(MONITOR* monitor, const char* query); -monitor_event_t mon_name_to_event(const char* tok); monitor_event_t mon_get_event_type(MONITOR_SERVERS* node); const 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); void mon_log_state_change(MONITOR_SERVERS *ptr); @@ -242,6 +273,19 @@ void lock_monitor_servers(MONITOR *monitor); void release_monitor_servers(MONITOR *monitor); void servers_status_pending_to_current(MONITOR *monitor); void servers_status_current_to_pending(MONITOR *monitor); + +/** + * @brief Handle state change events + * + * This function should be called by all monitors at the end of each monitoring + * cycle. This will log state changes and execute any scripts that should be executed. + * + * @param monitor Monitor object + * @param script Script to execute or NULL for no script + * @param events Enabled events + */ +void mon_process_state_changes(MONITOR *monitor, const char *script, uint64_t events); + /** * @brief Hangup connections to failed servers * diff --git a/server/core/monitor.c b/server/core/monitor.c index e7db1216a..138f52c31 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -42,20 +42,6 @@ #include #include -/* - * 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_name } -const monitor_def_t monitor_event_definitions[MAX_MONITOR_EVENT] = -{ -#include -}; -#undef ADDITEM - static MONITOR *allMonitors = NULL; static SPINLOCK monLock = SPINLOCK_INIT; @@ -837,7 +823,7 @@ mon_get_event_type(MONITOR_SERVERS* node) if (prev == present) { /* No change in the bits we're interested in */ - return UNDEFINED_MONITOR_EVENT; + return UNDEFINED_EVENT; } if ((prev & SERVER_RUNNING) == 0) @@ -904,7 +890,7 @@ mon_get_event_type(MONITOR_SERVERS* node) (present & SERVER_JOINED) ? NEW_SYNCED_EVENT : NEW_NDB_EVENT; default: - return UNDEFINED_MONITOR_EVENT; + return UNDEFINED_EVENT; } } @@ -916,28 +902,17 @@ mon_get_event_type(MONITOR_SERVERS* node) const char* mon_get_event_name(MONITOR_SERVERS* node) { - return monitor_event_definitions[mon_get_event_type(node)].name; -} + monitor_event_t event = mon_get_event_type(node); -/* - * 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(const char *event_name) -{ - monitor_event_t event; - - for (event = 0; event < MAX_MONITOR_EVENT; event++) + for (int i = 0; monitor_event_enum_values[i].name; i++) { - if (0 == strcasecmp(monitor_event_definitions[event].name, event_name)) + if (monitor_event_enum_values[i].enum_value & event) { - return event; + return monitor_event_enum_values[i].name; } } - return UNDEFINED_MONITOR_EVENT; + + return "undefined_event"; } /** @@ -1001,9 +976,12 @@ mon_print_fail_status(MONITOR_SERVERS* mon_srv) * @param script Script to execute */ void -monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) +monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, const char* script) { - EXTERNCMD* cmd = externcmd_allocate(script); + char arg[strlen(script) + 1]; + strcpy(arg, script); + + EXTERNCMD* cmd = externcmd_allocate(arg); if (cmd == NULL) { @@ -1110,49 +1088,6 @@ monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) 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* given_string) -{ - char *tok, *saved, *string = MXS_STRDUP(given_string); - MXS_ABORT_IF_NULL(string); - monitor_event_t event; - - tok = strtok_r(string, ",| ", &saved); - - if (tok == NULL) - { - MXS_FREE(string); - return -1; - } - - while (tok) - { - event = mon_name_to_event(tok); - if (event == UNDEFINED_MONITOR_EVENT) - { - MXS_ERROR("Invalid event name %s", tok); - MXS_FREE(string); - return -1; - } - if (event < count) - { - events[event] = true; - tok = strtok_r(NULL, ",| ", &saved); - } - } - - MXS_FREE(string); - 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 @@ -1498,3 +1433,19 @@ void servers_status_current_to_pending(MONITOR *monitor) ptr = ptr->next; } } + +void mon_process_state_changes(MONITOR *monitor, const char *script, uint64_t events) +{ + for (MONITOR_SERVERS *ptr = monitor->databases; ptr; ptr = ptr->next) + { + if (mon_status_changed(ptr)) + { + mon_log_state_change(ptr); + + if (script && (events & mon_get_event_type(ptr))) + { + monitor_launch_script(monitor, ptr, script); + } + } + } +} diff --git a/server/modules/monitor/auroramon/auroramon.c b/server/modules/monitor/auroramon/auroramon.c index e2bead57f..2a06a605f 100644 --- a/server/modules/monitor/auroramon/auroramon.c +++ b/server/modules/monitor/auroramon/auroramon.c @@ -27,7 +27,7 @@ typedef struct aurora_monitor bool shutdown; /**< True if the monitor is stopped */ THREAD thread; /**< Monitor thread */ char* script; /**< Launchable script */ - bool events[MAX_MONITOR_EVENT]; /**< Enabled monitor events */ + uint64_t events; /**< Enabled monitor events */ } AURORA_MONITOR; /** @@ -101,39 +101,6 @@ void update_server_status(MONITOR *monitor, MONITOR_SERVERS *database) } } -/** - * @brief Check if this is an event that the Aurora monitor handles - * @param event Event to check - * @return True if the event is monitored, false if it is not - * */ -bool is_aurora_event(monitor_event_t event) -{ - static monitor_event_t aurora_events[] = - { - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - MAX_MONITOR_EVENT - }; - - for (int i = 0; aurora_events[i] != MAX_MONITOR_EVENT; i++) - { - if (event == aurora_events[i]) - { - return true; - } - } - - return false; -} - /** * @brief Main monitoring loop * @@ -170,25 +137,9 @@ monitorMain(void *arg) /** * After updating the status of all servers, check if monitor events * need to be launched. - * - * TODO: Move this functionality into monitor.c, it is duplicated in - * every monitor. */ - for (MONITOR_SERVERS *ptr = monitor->databases; ptr; ptr = ptr->next) - { - if (mon_status_changed(ptr)) - { - monitor_event_t evtype = mon_get_event_type(ptr); - if (is_aurora_event(evtype)) - { - mon_log_state_change(ptr); - if (handle->script && handle->events[evtype]) - { - monitor_launch_script(monitor, ptr, handle->script); - } - } - } - } + mon_process_state_changes(monitor, handle->script, handle->events); + servers_status_current_to_pending(monitor); release_monitor_servers(monitor); @@ -233,12 +184,12 @@ static void auroramon_free(AURORA_MONITOR *handle) static void * startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) { - bool have_events = false, script_error = false; AURORA_MONITOR *handle = mon->handle; if (handle) { handle->shutdown = false; + MXS_FREE(handle->script); } else { @@ -248,35 +199,6 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) } handle->shutdown = false; - handle->script = NULL; - memset(handle->events, false, sizeof(handle->events)); - - while (params) - { - if (strcmp(params->name, "script") == 0) - { - if (externcmd_can_execute(params->value)) - { - handle->script = MXS_STRDUP_A(params->value); - } - else - { - script_error = true; - } - } - else if (strcmp(params->name, "events") == 0) - { - if (mon_parse_event_string(handle->events, sizeof(handle->events), params->value) != 0) - { - script_error = true; - } - else - { - have_events = true; - } - } - params = params->next; - } if (!check_monitor_permissions(mon, "SELECT @@aurora_server_id, server_id FROM " "information_schema.replica_host_status " @@ -286,22 +208,11 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) auroramon_free(handle); return NULL; } - - if (script_error) - { - MXS_ERROR("Errors were found in the script configuration parameters " - "for the monitor '%s'.", mon->name); - auroramon_free(handle); - return NULL; - } - - /** If no specific events are given, enable them all */ - if (!have_events) - { - memset(handle->events, true, sizeof(handle->events)); - } } + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", monitor_event_enum_values); + if (thread_start(&handle->thread, monitorMain, mon) == NULL) { MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); @@ -366,6 +277,19 @@ MXS_MODULE* MXS_CREATE_MODULE() NULL, /* Thread init. */ NULL, /* Thread finish. */ { + { + "script", + MXS_MODULE_PARAM_PATH, + NULL, + MXS_MODULE_OPT_PATH_X_OK + }, + { + "events", + MXS_MODULE_PARAM_ENUM, + MONITOR_EVENT_DEFAULT_VALUE, + MXS_MODULE_OPT_NONE, + monitor_event_enum_values + }, {MXS_END_MODULE_PARAMS} } }; diff --git a/server/modules/monitor/galeramon/galeramon.c b/server/modules/monitor/galeramon/galeramon.c index a7d9f27c4..662a76125 100644 --- a/server/modules/monitor/galeramon/galeramon.c +++ b/server/modules/monitor/galeramon/galeramon.c @@ -88,6 +88,19 @@ MXS_MODULE* MXS_CREATE_MODULE() {"disable_master_role_setting", MXS_MODULE_PARAM_BOOL, "false"}, {"root_node_as_master", MXS_MODULE_PARAM_BOOL, "true"}, {"use_priority", MXS_MODULE_PARAM_BOOL, "false"}, + { + "script", + MXS_MODULE_PARAM_PATH, + NULL, + MXS_MODULE_OPT_PATH_X_OK + }, + { + "events", + MXS_MODULE_PARAM_ENUM, + MONITOR_EVENT_DEFAULT_VALUE, + MXS_MODULE_OPT_NONE, + monitor_event_enum_values + }, {MXS_END_MODULE_PARAMS} } }; @@ -106,10 +119,10 @@ static void * startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) { GALERA_MONITOR *handle = mon->handle; - bool have_events = false, script_error = false; if (handle != NULL) { handle->shutdown = 0; + MXS_FREE(handle->script); } else { @@ -120,8 +133,6 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) handle->shutdown = 0; handle->id = MONITOR_DEFAULT_ID; handle->master = NULL; - handle->script = NULL; - memset(handle->events, false, sizeof(handle->events)); spinlock_init(&handle->lock); } @@ -130,35 +141,8 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) handle->disableMasterRoleSetting = config_get_bool(params, "disable_master_role_setting"); handle->root_node_as_master = config_get_bool(params, "root_node_as_master"); handle->use_priority = config_get_bool(params, "use_priority"); - - while (params) - { - if (!strcmp(params->name, "script")) - { - if (externcmd_can_execute(params->value)) - { - MXS_FREE(handle->script); - handle->script = MXS_STRDUP_A(params->value); - } - else - { - script_error = true; - } - } - else if (!strcmp(params->name, "events")) - { - if (mon_parse_event_string((bool *) handle->events, - sizeof(handle->events), params->value) != 0) - { - script_error = true; - } - else - { - have_events = true; - } - } - params = params->next; - } + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", monitor_event_enum_values); /** SHOW STATUS doesn't require any special permissions */ if (!check_monitor_permissions(mon, "SHOW STATUS LIKE 'wsrep_local_state'")) @@ -169,19 +153,6 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) return NULL; } - if (script_error) - { - MXS_ERROR("Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.", mon->name); - MXS_FREE(handle->script); - handle->script = NULL; - } - /** If no specific events are given, enable them all */ - if (!have_events) - { - memset(handle->events, true, sizeof(handle->events)); - } - if (thread_start(&handle->thread, monitorMain, mon) == NULL) { MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); @@ -551,26 +522,12 @@ monitorMain(void *arg) } } - ptr = mon->databases; - while (ptr) - { - - /** Execute monitor script if a server state has changed */ - if (mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if (isGaleraEvent(evtype)) - { - mon_log_state_change(ptr); - if (handle->script && handle->events[evtype]) - { - monitor_launch_script(mon, ptr, handle->script); - } - } - } - ptr = ptr->next; - } + /** + * After updating the status of all servers, check if monitor events + * need to be launched. + */ + mon_process_state_changes(mon, handle->script, handle->events); mon_hangup_failed_servers(mon); servers_status_current_to_pending(mon); @@ -687,81 +644,3 @@ static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *current_master, MONI } } } - -/** - * Disable/Enable the Master failback in a Galera Cluster. - * - * A restarted / rejoined node may get back the previous 'wsrep_local_index' - * from Cluster: if the value is the lowest in the cluster it will be selected as Master - * This will cause a Master change even if there is no failure. - * The option if set to 1 will avoid this situation, keeping the current Master (if running) available - * - * @param arg The handle allocated by startMonitor - * @param disable To disable it use 1, 0 keeps failback - * - * NOT USED -static void -disableMasterFailback(void *arg, int disable) -{ - GALERA_MONITOR *handle = (GALERA_MONITOR *) arg; - memcpy(&handle->disableMasterFailback, &disable, sizeof(int)); -} -*/ - -/** - * Allow a Galera node to be in sync when Donor. - * - * When enabled, the monitor will check if the node is using xtrabackup or xtrabackup-v2 - * as SST method. In that case, node will stay as synced. - * - * @param arg The handle allocated by startMonitor - * @param disable To allow sync status use 1, 0 for traditional behavior - * NOT USED -static void -availableWhenDonor(void *arg, int disable) -{ - GALERA_MONITOR *handle = (GALERA_MONITOR *) arg; - memcpy(&handle->availableWhenDonor, &disable, sizeof(int)); -} -*/ - -static monitor_event_t galera_events[] = -{ - 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, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - LOST_SYNCED_EVENT, - LOST_DONOR_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - NEW_SYNCED_EVENT, - NEW_DONOR_EVENT, - MAX_MONITOR_EVENT -}; - -/** - * Check if the Galera monitor is monitoring this event type. - * @param event Event to check - * @return True if the event is monitored, false if it is not - * */ -bool isGaleraEvent(monitor_event_t event) -{ - int i; - for (i = 0; galera_events[i] != MAX_MONITOR_EVENT; i++) - { - if (event == galera_events[i]) - { - return true; - } - } - return false; -} diff --git a/server/modules/monitor/galeramon/galeramon.h b/server/modules/monitor/galeramon/galeramon.h index 87cdce692..4640ecf6a 100644 --- a/server/modules/monitor/galeramon/galeramon.h +++ b/server/modules/monitor/galeramon/galeramon.h @@ -61,7 +61,7 @@ typedef struct bool root_node_as_master; /**< Whether we require that the Master should * have a wsrep_local_index of 0 */ bool use_priority; /*< Use server priorities */ - bool events[MAX_MONITOR_EVENT]; /*< enabled events */ + uint64_t events; /*< enabled events */ } GALERA_MONITOR; MXS_END_DECLS diff --git a/server/modules/monitor/mmmon/mmmon.c b/server/modules/monitor/mmmon/mmmon.c index 7515e26cc..ae5b28b5e 100644 --- a/server/modules/monitor/mmmon/mmmon.c +++ b/server/modules/monitor/mmmon/mmmon.c @@ -85,6 +85,19 @@ MXS_MODULE* MXS_CREATE_MODULE() NULL, /* Thread finish. */ { {"detect_stale_master", MXS_MODULE_PARAM_BOOL, "false"}, + { + "script", + MXS_MODULE_PARAM_PATH, + NULL, + MXS_MODULE_OPT_PATH_X_OK + }, + { + "events", + MXS_MODULE_PARAM_ENUM, + MONITOR_EVENT_DEFAULT_VALUE, + MXS_MODULE_OPT_NONE, + monitor_event_enum_values + }, {MXS_END_MODULE_PARAMS} } }; @@ -105,11 +118,11 @@ static void * startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) { MM_MONITOR *handle = mon->handle; - bool have_events = false, script_error = false; if (handle) { handle->shutdown = 0; + MXS_FREE(handle->script); } else { @@ -120,41 +133,12 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) handle->shutdown = 0; handle->id = MONITOR_DEFAULT_ID; handle->master = NULL; - handle->script = NULL; - memset(handle->events, false, sizeof(handle->events)); spinlock_init(&handle->lock); } handle->detectStaleMaster = config_get_bool(params, "detect_stale_master"); - - while (params) - { - if (!strcmp(params->name, "script")) - { - if (externcmd_can_execute(params->value)) - { - MXS_FREE(handle->script); - handle->script = MXS_STRDUP_A(params->value); - } - else - { - script_error = true; - } - } - else if (!strcmp(params->name, "events")) - { - if (mon_parse_event_string((bool *)handle->events, - sizeof(handle->events), params->value) != 0) - { - script_error = true; - } - else - { - have_events = true; - } - } - params = params->next; - } + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", monitor_event_enum_values); if (!check_monitor_permissions(mon, "SHOW SLAVE STATUS")) { @@ -164,19 +148,6 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) return NULL; } - if (script_error) - { - MXS_ERROR("Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.", mon->name); - MXS_FREE(handle->script); - handle->script = NULL; - } - /** If no specific events are given, enable them all */ - if (!have_events) - { - memset(handle->events, true, sizeof(handle->events)); - } - if (thread_start(&handle->thread, monitorMain, mon) == NULL) { MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); @@ -615,24 +586,11 @@ monitorMain(void *arg) ptr = ptr->next; } - ptr = mon->databases; - monitor_event_t evtype; - while (ptr) - { - if (mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if (isMySQLEvent(evtype)) - { - mon_log_state_change(ptr); - if (handle->script && handle->events[evtype]) - { - monitor_launch_script(mon, ptr, handle->script); - } - } - } - ptr = ptr->next; - } + /** + * After updating the status of all servers, check if monitor events + * need to be launched. + */ + mon_process_state_changes(mon, handle->script, handle->events); mon_hangup_failed_servers(mon); servers_status_current_to_pending(mon); @@ -717,37 +675,3 @@ static MONITOR_SERVERS *get_current_master(MONITOR *mon) return NULL; } } - - -static monitor_event_t mysql_events[] = -{ - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - MAX_MONITOR_EVENT -}; - -/** - * Check if the MM monitor is monitoring this event type. - * @param event Event to check - * @return True if the event is monitored, false if it is not - * */ -bool isMySQLEvent(monitor_event_t event) -{ - int i; - for (i = 0; mysql_events[i] != MAX_MONITOR_EVENT; i++) - { - if (event == mysql_events[i]) - { - return true; - } - } - return false; -} diff --git a/server/modules/monitor/mmmon/mmmon.h b/server/modules/monitor/mmmon/mmmon.h index 7c3a6fd9c..70e796aa0 100644 --- a/server/modules/monitor/mmmon/mmmon.h +++ b/server/modules/monitor/mmmon/mmmon.h @@ -49,7 +49,7 @@ typedef struct int detectStaleMaster; /**< Monitor flag for Stale Master detection */ MONITOR_SERVERS *master; /**< Master server for Master/Slave replication */ char* script; /*< Script to call when state changes occur on servers */ - bool events[MAX_MONITOR_EVENT]; /*< enabled events */ + uint64_t events; /*< enabled events */ } MM_MONITOR; MXS_END_DECLS diff --git a/server/modules/monitor/mysqlmon.h b/server/modules/monitor/mysqlmon.h index 753e9c367..a9390d3a6 100644 --- a/server/modules/monitor/mysqlmon.h +++ b/server/modules/monitor/mysqlmon.h @@ -73,7 +73,7 @@ typedef struct bool mysql51_replication; /**< Use MySQL 5.1 replication */ MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ char* script; /*< Script to call when state changes occur on servers */ - bool events[MAX_MONITOR_EVENT]; /*< enabled events */ + uint64_t events; /*< enabled events */ HASHTABLE *server_info; /**< Contains server specific information */ bool failover; /**< If simple failover is enabled */ int failcount; /**< How many monitoring cycles servers must be diff --git a/server/modules/monitor/mysqlmon/mysql_mon.c b/server/modules/monitor/mysqlmon/mysql_mon.c index 944109ebb..603a4f6ff 100644 --- a/server/modules/monitor/mysqlmon/mysql_mon.c +++ b/server/modules/monitor/mysqlmon/mysql_mon.c @@ -125,6 +125,19 @@ MXS_MODULE* MXS_CREATE_MODULE() {"multimaster", MXS_MODULE_PARAM_BOOL, "false"}, {"failover", MXS_MODULE_PARAM_BOOL, "false"}, {"failcount", MXS_MODULE_PARAM_COUNT, "5"}, + { + "script", + MXS_MODULE_PARAM_PATH, + NULL, + MXS_MODULE_OPT_PATH_X_OK + }, + { + "events", + MXS_MODULE_PARAM_ENUM, + MONITOR_EVENT_DEFAULT_VALUE, + MXS_MODULE_OPT_NONE, + monitor_event_enum_values + }, {MXS_END_MODULE_PARAMS} } }; @@ -229,11 +242,11 @@ static void * startMonitor(MONITOR *monitor, const CONFIG_PARAMETER* params) { MYSQL_MONITOR *handle = (MYSQL_MONITOR*) monitor->handle; - bool have_events = false, script_error = false, error = false; if (handle) { handle->shutdown = 0; + MXS_FREE(handle->script); } else { @@ -252,9 +265,7 @@ startMonitor(MONITOR *monitor, const CONFIG_PARAMETER* params) handle->server_info = server_info; handle->shutdown = 0; handle->id = config_get_gateway_id(); - handle->script = NULL; handle->warn_failover = true; - memset(handle->events, false, sizeof(handle->events)); spinlock_init(&handle->lock); } @@ -268,34 +279,10 @@ startMonitor(MONITOR *monitor, const CONFIG_PARAMETER* params) handle->failover = config_get_bool(params, "failover"); handle->failcount = config_get_integer(params, "failcount"); handle->mysql51_replication = config_get_bool(params, "mysql51_replication"); + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", monitor_event_enum_values); - while (params) - { - if (!strcmp(params->name, "script")) - { - if (externcmd_can_execute(params->value)) - { - MXS_FREE(handle->script); - handle->script = MXS_STRDUP_A(params->value); - } - else - { - script_error = true; - } - } - else if (!strcmp(params->name, "events")) - { - if (mon_parse_event_string((bool *)handle->events, sizeof(handle->events), params->value) != 0) - { - script_error = true; - } - else - { - have_events = true; - } - } - params = params->next; - } + bool error = false; if (!check_monitor_permissions(monitor, "SHOW SLAVE STATUS")) { @@ -303,17 +290,6 @@ startMonitor(MONITOR *monitor, const CONFIG_PARAMETER* params) error = true; } - if (script_error) - { - MXS_ERROR("[%s] Errors were found in the script configuration parameters ", monitor->name); - error = true; - } - else if (!have_events) - { - /** If no specific events are given, enable them all */ - memset(handle->events, true, sizeof(handle->events)); - } - if (!init_server_info(handle, monitor->databases)) { error = true; @@ -1330,25 +1306,11 @@ monitorMain(void *arg) } } - ptr = mon->databases; - monitor_event_t evtype; - while (ptr) - { - /** Execute monitor script if a server state has changed */ - if (mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if (isMySQLEvent(evtype)) - { - mon_log_state_change(ptr); - if (handle->script && handle->events[evtype]) - { - monitor_launch_script(mon, ptr, handle->script); - } - } - } - ptr = ptr->next; - } + /** + * After updating the status of all servers, check if monitor events + * need to be launched. + */ + mon_process_state_changes(mon, handle->script, handle->events); /* log master detection failure of first master becomes available after failure */ if (root_master && @@ -1878,39 +1840,6 @@ static int add_slave_to_master(long *slaves_list, int list_size, long node_id) return 0; } -static monitor_event_t mysql_events[] = -{ - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - MAX_MONITOR_EVENT -}; - -/** - * Check if the MySQL monitor is monitoring this event type. - * @param event Event to check - * @return True if the event is monitored, false if it is not - * */ -bool isMySQLEvent(monitor_event_t event) -{ - int i; - for (i = 0; mysql_events[i] != MAX_MONITOR_EVENT; i++) - { - if (event == mysql_events[i]) - { - return true; - } - } - return false; -} - /** * Check if replicate_ignore_table is defined and if maxscale_schema.replication_hearbeat * table is in the list. diff --git a/server/modules/monitor/ndbclustermon/ndbclustermon.c b/server/modules/monitor/ndbclustermon/ndbclustermon.c index 9c3c8db86..789fb4b37 100644 --- a/server/modules/monitor/ndbclustermon/ndbclustermon.c +++ b/server/modules/monitor/ndbclustermon/ndbclustermon.c @@ -77,6 +77,19 @@ MXS_MODULE* MXS_CREATE_MODULE() NULL, /* Thread init. */ NULL, /* Thread finish. */ { + { + "script", + MXS_MODULE_PARAM_PATH, + NULL, + MXS_MODULE_OPT_PATH_X_OK + }, + { + "events", + MXS_MODULE_PARAM_ENUM, + MONITOR_EVENT_DEFAULT_VALUE, + MXS_MODULE_OPT_NONE, + monitor_event_enum_values + }, {MXS_END_MODULE_PARAMS} // No parameters } }; @@ -101,6 +114,7 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) if (handle != NULL) { handle->shutdown = 0; + MXS_FREE(handle->script); } else { @@ -110,39 +124,12 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) } handle->shutdown = 0; handle->id = MONITOR_DEFAULT_ID; - handle->script = NULL; handle->master = NULL; - memset(handle->events, false, sizeof(handle->events)); spinlock_init(&handle->lock); } - while (params) - { - if (!strcmp(params->name, "script")) - { - if (externcmd_can_execute(params->value)) - { - MXS_FREE(handle->script); - handle->script = MXS_STRDUP_A(params->value); - } - else - { - script_error = true; - } - } - else if (!strcmp(params->name, "events")) - { - if (mon_parse_event_string((bool *)handle->events, - sizeof(handle->events), params->value) != 0) - { - script_error = true; - } - else - { - have_events = true; - } - } - params = params->next; - } + + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", monitor_event_enum_values); /** SHOW STATUS doesn't require any special permissions */ if (!check_monitor_permissions(mon, "SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'")) @@ -153,19 +140,6 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params) return NULL; } - if (script_error) - { - MXS_ERROR("Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.", mon->name); - MXS_FREE(handle->script); - handle->script = NULL; - } - /** If no specific events are given, enable them all */ - if (!have_events) - { - memset(handle->events, true, sizeof(handle->events)); - } - if (thread_start(&handle->thread, monitorMain, mon) == NULL) { MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); @@ -382,67 +356,14 @@ monitorMain(void *arg) ptr = ptr->next; } - ptr = mon->databases; - monitor_event_t evtype; - - while (ptr) - { - /** Execute monitor script if a server state has changed */ - if (mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if (isNdbEvent(evtype)) - { - mon_log_state_change(ptr); - if (handle->script && handle->events[evtype]) - { - monitor_launch_script(mon, ptr, handle->script); - } - } - } - ptr = ptr->next; - } + /** + * After updating the status of all servers, check if monitor events + * need to be launched. + */ + mon_process_state_changes(mon, handle->script, handle->events); mon_hangup_failed_servers(mon); servers_status_current_to_pending(mon); release_monitor_servers(mon); } } - - -static monitor_event_t ndb_events[] = -{ - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - NDB_UP_EVENT, - NDB_DOWN_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - LOST_NDB_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - NEW_NDB_EVENT, - MAX_MONITOR_EVENT -}; - -/** - * Check if the event type is one the ndbcustermonitor is interested in. - * @param event Event to check - * @return True if the event is monitored, false if it is not - */ -bool isNdbEvent(monitor_event_t event) -{ - int i; - for (i = 0; ndb_events[i] != MAX_MONITOR_EVENT; i++) - { - if (event == ndb_events[i]) - { - return true; - } - } - return false; -}