diff --git a/include/maxscale/monitor.h b/include/maxscale/monitor.h index c828ddbd5..f91273ad6 100644 --- a/include/maxscale/monitor.h +++ b/include/maxscale/monitor.h @@ -102,11 +102,10 @@ typedef struct mxs_monitor_api * @param monitor The monitor object * @param params Parameters for this monitor * - * @return Pointer to the monitor specific data. Will be stored - * in @c monitor->handle. + * @return True, if the monitor could be started, false otherwise. */ - MXS_MONITOR_INSTANCE *(*startMonitor)(MXS_MONITOR *monitor, - const MXS_CONFIG_PARAMETER *params); + bool (*startMonitor)(MXS_MONITOR_INSTANCE *monitor, + const MXS_CONFIG_PARAMETER *params); /** * @brief Stop the monitor diff --git a/server/core/monitor.cc b/server/core/monitor.cc index 28f1d5857..9b30c755a 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -105,10 +105,10 @@ MXS_MONITOR* monitor_create(const char *name, const char *module) char *my_module = MXS_STRDUP(module); MXS_MONITOR *mon = (MXS_MONITOR *)MXS_MALLOC(sizeof(MXS_MONITOR)); - if (!my_name || !mon || !my_module) + if (!mon || !my_module || !my_name) { - MXS_FREE(my_name); MXS_FREE(mon); + MXS_FREE(my_name); MXS_FREE(my_module); return NULL; } @@ -116,8 +116,9 @@ MXS_MONITOR* monitor_create(const char *name, const char *module) if ((mon->api = (MXS_MONITOR_API*)load_module(module, MODULE_MONITOR)) == NULL) { MXS_ERROR("Unable to load monitor module '%s'.", my_name); - MXS_FREE(my_name); MXS_FREE(mon); + MXS_FREE(my_module); + MXS_FREE(my_name); return NULL; } mon->active = true; @@ -139,6 +140,16 @@ MXS_MONITOR* monitor_create(const char *name, const char *module) mon->server_pending_changes = false; memset(mon->journal_hash, 0, sizeof(mon->journal_hash)); spinlock_init(&mon->lock); + + if ((mon->instance = mon->api->createInstance(mon)) == NULL) + { + MXS_ERROR("Unable to create monitor instance for '%s', using module '%s'.", + name, module); + MXS_FREE(mon); + MXS_FREE(my_module); + MXS_FREE(my_name); + } + spinlock_acquire(&monLock); mon->next = allMonitors; allMonitors = mon; @@ -204,7 +215,7 @@ monitor_start(MXS_MONITOR *monitor, const MXS_CONFIG_PARAMETER* params) remove_server_journal(monitor); } - if ((monitor->instance = (*monitor->api->startMonitor)(monitor, params))) + if ((*monitor->api->startMonitor)(monitor->instance, params)) { monitor->state = MONITOR_STATE_RUNNING; } diff --git a/server/modules/monitor/auroramon/auroramon.cc b/server/modules/monitor/auroramon/auroramon.cc index 7007f34ac..890e5d75e 100644 --- a/server/modules/monitor/auroramon/auroramon.cc +++ b/server/modules/monitor/auroramon/auroramon.cc @@ -199,8 +199,9 @@ MXS_MONITOR_INSTANCE* createInstance(MXS_MONITOR* mon) static void destroyInstance(MXS_MONITOR_INSTANCE* mon) { AURORA_MONITOR* handle = static_cast(mon); + ss_dassert(!handle->thread); + ss_dassert(!handle->script); - MXS_FREE(handle->script); MXS_FREE(handle); } @@ -213,50 +214,45 @@ static void destroyInstance(MXS_MONITOR_INSTANCE* mon) * @param opt The configuration parameters for this monitor * @return Monitor handle */ -static MXS_MONITOR_INSTANCE * -startMonitor(MXS_MONITOR *mon, const MXS_CONFIG_PARAMETER *params) +static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *params) { - AURORA_MONITOR *handle = static_cast(mon->instance); + bool started = false; - if (handle) + AURORA_MONITOR *handle = static_cast(mon); + ss_dassert(handle); + + if (!handle->checked) { - handle->shutdown = false; - MXS_FREE(handle->script); - } - else - { - if ((handle = (AURORA_MONITOR *) MXS_MALLOC(sizeof(AURORA_MONITOR))) == NULL) - { - return NULL; - } - - handle->shutdown = false; - handle->monitor = mon; - handle->checked = false; - - if (!check_monitor_permissions(mon, "SELECT @@aurora_server_id, server_id FROM " + if (!check_monitor_permissions(handle->monitor, "SELECT @@aurora_server_id, server_id FROM " "information_schema.replica_host_status " "WHERE session_id = 'MASTER_SESSION_ID'")) { MXS_ERROR("Failed to start monitor. See earlier errors for more information."); - auroramon_free(handle); - return NULL; } - - handle->checked = true; + else + { + handle->checked = true; + } } - handle->script = config_copy_string(params, "script"); - handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); - - if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) + if (handle->checked) { - MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); - auroramon_free(handle); - return NULL; + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); + + if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) + { + MXS_ERROR("Failed to start monitor thread for monitor '%s'.", handle->monitor->name); + MXS_FREE(handle->script); + handle->script = NULL; + } + else + { + started = true; + } } - return handle; + return started; } /** @@ -268,9 +264,15 @@ static void stopMonitor(MXS_MONITOR_INSTANCE *mon) { AURORA_MONITOR *handle = static_cast(mon); + ss_dassert(handle->thread); handle->shutdown = true; thread_wait(handle->thread); + handle->thread = 0; + handle->shutdown = false; + + MXS_FREE(handle->script); + handle->script = NULL; } /** diff --git a/server/modules/monitor/galeramon/galeramon.cc b/server/modules/monitor/galeramon/galeramon.cc index 8cbc3e510..c0b9b44a8 100644 --- a/server/modules/monitor/galeramon/galeramon.cc +++ b/server/modules/monitor/galeramon/galeramon.cc @@ -32,8 +32,8 @@ static bool warn_erange_on_local_index = true; static MXS_MONITOR_INSTANCE *createInstance(MXS_MONITOR *mon); static void destroyInstance(MXS_MONITOR_INSTANCE* monitor); -static MXS_MONITOR_INSTANCE *startMonitor(MXS_MONITOR *, - const MXS_CONFIG_PARAMETER *params); +static bool startMonitor(MXS_MONITOR_INSTANCE *, + const MXS_CONFIG_PARAMETER *params); static void stopMonitor(MXS_MONITOR_INSTANCE *); static void diagnostics(const MXS_MONITOR_INSTANCE *, DCB *); static json_t* diagnostics_json(const MXS_MONITOR_INSTANCE *); @@ -168,80 +168,53 @@ static void destroyInstance(MXS_MONITOR_INSTANCE* monitor) * * @return A handle to use when interacting with the monitor */ -static MXS_MONITOR_INSTANCE * -startMonitor(MXS_MONITOR *mon, const MXS_CONFIG_PARAMETER *params) +static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *params) { - GALERA_MONITOR *handle = static_cast(mon->instance); - if (handle != NULL) - { - handle->shutdown = 0; - MXS_FREE(handle->script); - } - else - { - handle = (GALERA_MONITOR *) MXS_MALLOC(sizeof(GALERA_MONITOR)); - HASHTABLE *nodes_info = hashtable_alloc(MAX_NUM_SLAVES, hashtable_item_strhash, hashtable_item_strcmp); + bool started = false; - if (!handle || !nodes_info) + GALERA_MONITOR *handle = static_cast(mon); + + ss_dassert(!handle->shutdown); + ss_dassert(!handle->thread); + ss_dassert(!handle->script); + + if (!handle->checked) + { + if (!check_monitor_permissions(handle->monitor, "SHOW STATUS LIKE 'wsrep_local_state'")) { - hashtable_free(nodes_info); - MXS_FREE(handle); - return NULL; + MXS_ERROR("Failed to start monitor. See earlier errors for more information."); + } + else + { + handle->checked = true; } - - /* Set copy / free routines for hashtable */ - hashtable_memory_fns(nodes_info, - hashtable_item_strdup, - (HASHCOPYFN)nodeval_dup, - hashtable_item_free, - (HASHFREEFN)nodeval_free); - - handle->shutdown = 0; - handle->id = MXS_MONITOR_DEFAULT_ID; - handle->master = NULL; - - /* Initialise cluster nodes hash and Cluster info */ - handle->galera_nodes_info = nodes_info; - handle->cluster_info.c_size = 0; - handle->cluster_info.c_uuid = NULL; - handle->monitor = mon; } - handle->disableMasterFailback = config_get_bool(params, "disable_master_failback"); - handle->availableWhenDonor = config_get_bool(params, "available_when_donor"); - 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"); - handle->script = config_copy_string(params, "script"); - handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); - handle->set_donor_nodes = config_get_bool(params, "set_donor_nodes"); - - /* Reset all data in the hashtable */ - reset_cluster_info(handle); - - - /** SHOW STATUS doesn't require any special permissions */ - if (!check_monitor_permissions(mon, "SHOW STATUS LIKE 'wsrep_local_state'")) + if (handle->checked) { - MXS_ERROR("Failed to start monitor. See earlier errors for more information."); - hashtable_free(handle->galera_nodes_info); - MXS_FREE(handle->script); - MXS_FREE(handle); - return NULL; + handle->disableMasterFailback = config_get_bool(params, "disable_master_failback"); + handle->availableWhenDonor = config_get_bool(params, "available_when_donor"); + 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"); + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); + handle->set_donor_nodes = config_get_bool(params, "set_donor_nodes"); + + /* Reset all data in the hashtable */ + reset_cluster_info(handle); + + if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) + { + MXS_ERROR("Failed to start monitor thread for monitor '%s'.", handle->monitor->name); + } + else + { + started = true; + } } - handle->checked = true; - - if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) - { - MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); - hashtable_free(handle->galera_nodes_info); - MXS_FREE(handle->script); - MXS_FREE(handle); - return NULL; - } - - return handle; + return started; } /** @@ -253,9 +226,15 @@ static void stopMonitor(MXS_MONITOR_INSTANCE *mon) { GALERA_MONITOR *handle = static_cast(mon); + ss_dassert(handle->thread); - handle->shutdown = 1; + handle->shutdown = true; thread_wait(handle->thread); + handle->thread = 0; + handle->shutdown = false; + + MXS_FREE(handle->script); + handle->script = NULL; } /** diff --git a/server/modules/monitor/grmon/grmon.cc b/server/modules/monitor/grmon/grmon.cc index 91f7ea0c9..411125be3 100644 --- a/server/modules/monitor/grmon/grmon.cc +++ b/server/modules/monitor/grmon/grmon.cc @@ -75,27 +75,6 @@ GRMon* GRMon::create(MXS_MONITOR* monitor) return mon; } -GRMon* GRMon::create_and_start(MXS_MONITOR* monitor, const MXS_CONFIG_PARAMETER* params) -{ - GRMon* instance = static_cast(monitor->instance); - - if (!instance) - { - instance = create(monitor); - } - - if (instance) - { - if (!instance->start(params)) - { - delete instance; - instance = NULL; - } - } - - return instance; -} - bool GRMon::start(const MXS_CONFIG_PARAMETER* params) { bool started = false; @@ -122,8 +101,12 @@ void GRMon::main(void* data) void GRMon::stop() { + ss_dassert(m_thread); + atomic_store_int32(&m_shutdown, 1); thread_wait(m_thread); + m_thread = 0; + m_shutdown = 0; } static MXS_MONITOR_INSTANCE* createInstance(MXS_MONITOR *mon) @@ -144,10 +127,9 @@ static void destroyInstance(MXS_MONITOR_INSTANCE* mon) * * @return A handle to use when interacting with the monitor */ -static MXS_MONITOR_INSTANCE * -startMonitor(MXS_MONITOR *mon, const MXS_CONFIG_PARAMETER *params) +static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *params) { - return GRMon::create_and_start(mon, params); + return static_cast(mon)->start(params); } /** @@ -158,9 +140,7 @@ startMonitor(MXS_MONITOR *mon, const MXS_CONFIG_PARAMETER *params) static void stopMonitor(MXS_MONITOR_INSTANCE *mon) { - GRMon *handle = static_cast(mon); - handle->stop(); - delete handle; + static_cast(mon)->stop(); } /** diff --git a/server/modules/monitor/mariadbmon/cluster_manipulation.cc b/server/modules/monitor/mariadbmon/cluster_manipulation.cc index d594b92c9..bbf5136fa 100644 --- a/server/modules/monitor/mariadbmon/cluster_manipulation.cc +++ b/server/modules/monitor/mariadbmon/cluster_manipulation.cc @@ -71,7 +71,8 @@ bool MariaDBMonitor::manual_switchover(SERVER* new_master, SERVER* current_maste if (stopped) { - MariaDBMonitor::create_and_start(m_monitor_base, m_monitor_base->parameters); + // TODO: What if this fails? + start(m_monitor_base->parameters); } return rval; } @@ -105,7 +106,8 @@ bool MariaDBMonitor::manual_failover(json_t** output) if (stopped) { - MariaDBMonitor::create_and_start(m_monitor_base, m_monitor_base->parameters); + // TODO: What if this fails? + start(m_monitor_base->parameters); } return rv; } @@ -178,7 +180,8 @@ bool MariaDBMonitor::manual_rejoin(SERVER* rejoin_server, json_t** output) if (stopped) { - MariaDBMonitor::create_and_start(m_monitor_base, m_monitor_base->parameters); + // TODO: What if this fails? + start(m_monitor_base->parameters); } return rval; } diff --git a/server/modules/monitor/mariadbmon/mariadbmon.cc b/server/modules/monitor/mariadbmon/mariadbmon.cc index ac3b141b2..8a57bc84e 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.cc +++ b/server/modules/monitor/mariadbmon/mariadbmon.cc @@ -134,40 +134,38 @@ MariaDBMonitor* MariaDBMonitor::create(MXS_MONITOR *monitor) return new MariaDBMonitor(monitor); } -MariaDBMonitor* MariaDBMonitor::create_and_start(MXS_MONITOR *monitor, const MXS_CONFIG_PARAMETER* params) +bool MariaDBMonitor::start(const MXS_CONFIG_PARAMETER* params) { bool error = false; - MariaDBMonitor *handle = static_cast(monitor->instance); - if (handle == NULL) - { - handle = new MariaDBMonitor(monitor); - } /* Always reset these values. The server dependent values must be reset as servers could have been * added and removed. */ - handle->m_keep_running = true; - handle->m_master = NULL; - handle->init_server_info(); + m_keep_running = true; + m_master = NULL; + init_server_info(); - if (!handle->load_config_params(params)) + if (!load_config_params(params)) { error = true; } - if (!check_monitor_permissions(monitor, "SHOW SLAVE STATUS")) + if (!error && !m_checked) { - error = true; - } - else - { - handle->m_checked = true; + if (!check_monitor_permissions(m_monitor_base, "SHOW SLAVE STATUS")) + { + error = true; + } + else + { + m_checked = true; + } } if (!error) { - if (thread_start(&handle->m_thread, monitorMain, handle, 0) == NULL) + if (thread_start(&m_thread, monitorMain, this, 0) == NULL) { - MXS_ERROR("Failed to start monitor thread for monitor '%s'.", monitor->name); + MXS_ERROR("Failed to start monitor thread for monitor '%s'.", m_monitor_base->name); error = true; } } @@ -175,10 +173,9 @@ MariaDBMonitor* MariaDBMonitor::create_and_start(MXS_MONITOR *monitor, const MXS if (error) { MXS_ERROR("Failed to start monitor. See earlier errors for more information."); - delete handle; - handle = NULL; } - return handle; + + return !error; } void MariaDBMonitor::destroy(MariaDBMonitor* monitor) @@ -935,12 +932,11 @@ static void destroyInstance(MXS_MONITOR_INSTANCE* monitor) * * @param monitor General monitor data * @param params Configuration parameters - * @return A pointer to MariaDBMonitor specific data. Should be stored in MXS_MONITOR's "handle"-field. + * @return True, if the monitor could be started, false otherwise. */ -static MXS_MONITOR_INSTANCE* startMonitor(MXS_MONITOR *monitor, - const MXS_CONFIG_PARAMETER* params) +static bool startMonitor(MXS_MONITOR_INSTANCE *monitor, const MXS_CONFIG_PARAMETER* params) { - return MariaDBMonitor::create_and_start(monitor, params); + return static_cast(monitor)->start(params); } /** diff --git a/server/modules/monitor/mariadbmon/mariadbmon.hh b/server/modules/monitor/mariadbmon/mariadbmon.hh index de2ed77da..d4b802b68 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.hh +++ b/server/modules/monitor/mariadbmon/mariadbmon.hh @@ -71,14 +71,13 @@ public: static MariaDBMonitor* create(MXS_MONITOR *monitor); /** - * Start the monitor instance and return the instance data, creating it if starting for the first time. + * Start the monitor instance. * This function creates a thread to execute the monitoring. * - * @param monitor General monitor data * @param params Configuration parameters - * @return A pointer to MariaDBMonitor specific data. + * @return True, if the monitor could be started, false otherwise. */ - static MariaDBMonitor* create_and_start(MXS_MONITOR *monitor, const MXS_CONFIG_PARAMETER* params); + bool start(const MXS_CONFIG_PARAMETER* params); /** * Destroyes aka deletes the instance. diff --git a/server/modules/monitor/mmmon/mmmon.cc b/server/modules/monitor/mmmon/mmmon.cc index cb1893f9f..7dc50f7c4 100644 --- a/server/modules/monitor/mmmon/mmmon.cc +++ b/server/modules/monitor/mmmon/mmmon.cc @@ -40,7 +40,7 @@ MXS_MODULE info = static MXS_MONITOR_INSTANCE *createInstance(MXS_MONITOR *); static void destroyInstance(MXS_MONITOR_INSTANCE *); -static MXS_MONITOR_INSTANCE *startMonitor(MXS_MONITOR *, const MXS_CONFIG_PARAMETER *); +static bool startMonitor(MXS_MONITOR_INSTANCE *, const MXS_CONFIG_PARAMETER *); static void stopMonitor(MXS_MONITOR_INSTANCE *); static void diagnostics(const MXS_MONITOR_INSTANCE *, DCB *); static json_t* diagnostics_json(const MXS_MONITOR_INSTANCE *); @@ -132,8 +132,9 @@ static MXS_MONITOR_INSTANCE* createInstance(MXS_MONITOR *mon) static void destroyInstance(MXS_MONITOR_INSTANCE* mon) { MM_MONITOR* handle = static_cast(mon); + ss_dassert(!handle->thread); + ss_dassert(!handle->script); - MXS_FREE(handle->script); MXS_FREE(handle); } @@ -145,51 +146,44 @@ static void destroyInstance(MXS_MONITOR_INSTANCE* mon) * @param arg The current handle - NULL if first start * @return A handle to use when interacting with the monitor */ -static MXS_MONITOR_INSTANCE * -startMonitor(MXS_MONITOR *mon, const MXS_CONFIG_PARAMETER *params) +static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *params) { - MM_MONITOR *handle = static_cast(mon->instance); + bool started = false; - if (handle) + MM_MONITOR *handle = static_cast(mon); + ss_dassert(handle); + + if (!handle->checked) { - handle->shutdown = 0; - MXS_FREE(handle->script); - } - else - { - if ((handle = (MM_MONITOR *) MXS_MALLOC(sizeof(MM_MONITOR))) == NULL) + if (!check_monitor_permissions(handle->monitor, "SHOW SLAVE STATUS")) { - return NULL; + MXS_ERROR("Failed to start monitor. See earlier errors for more information."); + } + else + { + handle->checked = true; } - handle->shutdown = 0; - handle->id = MXS_MONITOR_DEFAULT_ID; - handle->master = NULL; - handle->monitor = mon; } - handle->detectStaleMaster = config_get_bool(params, "detect_stale_master"); - handle->script = config_copy_string(params, "script"); - handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); - - if (!check_monitor_permissions(mon, "SHOW SLAVE STATUS")) + if (handle->checked) { - MXS_ERROR("Failed to start monitor. See earlier errors for more information."); - MXS_FREE(handle->script); - MXS_FREE(handle); - return NULL; + handle->detectStaleMaster = config_get_bool(params, "detect_stale_master"); + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); + + if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) + { + MXS_ERROR("Failed to start monitor thread for monitor '%s'.", handle->monitor->name); + MXS_FREE(handle->script); + handle->script = NULL; + } + else + { + started = true; + } } - handle->checked = true; - - if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) - { - MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); - MXS_FREE(handle->script); - MXS_FREE(handle); - return NULL; - } - - return handle; + return started; } /** @@ -201,9 +195,15 @@ static void stopMonitor(MXS_MONITOR_INSTANCE *mon) { MM_MONITOR *handle = static_cast(mon); + ss_dassert(handle->thread); handle->shutdown = 1; thread_wait(handle->thread); + handle->thread = 0; + handle->shutdown = 0; + + MXS_FREE(handle->script); + handle->script = NULL; } /** diff --git a/server/modules/monitor/ndbclustermon/ndbclustermon.cc b/server/modules/monitor/ndbclustermon/ndbclustermon.cc index 3d6cd3d7f..ccb53d778 100644 --- a/server/modules/monitor/ndbclustermon/ndbclustermon.cc +++ b/server/modules/monitor/ndbclustermon/ndbclustermon.cc @@ -32,8 +32,7 @@ static void monitorMain(void *); static MXS_MONITOR_INSTANCE *createInstance(MXS_MONITOR *); static void destroyInstance(MXS_MONITOR_INSTANCE*); -static MXS_MONITOR_INSTANCE *startMonitor(MXS_MONITOR *, - const MXS_CONFIG_PARAMETER *params); +static bool startMonitor(MXS_MONITOR_INSTANCE *, const MXS_CONFIG_PARAMETER *params); static void stopMonitor(MXS_MONITOR_INSTANCE *); static void diagnostics(const MXS_MONITOR_INSTANCE *, DCB *); static json_t* diagnostics_json(const MXS_MONITOR_INSTANCE *); @@ -125,8 +124,9 @@ static MXS_MONITOR_INSTANCE* createInstance(MXS_MONITOR *mon) void destroyInstance(MXS_MONITOR_INSTANCE* mon) { NDBC_MONITOR* handle = static_cast(mon); + ss_dassert(!handle->thread); + ss_dassert(!handle->script); - MXS_FREE(handle->script); MXS_FREE(handle); } @@ -137,52 +137,42 @@ void destroyInstance(MXS_MONITOR_INSTANCE* mon) * * @return A handle to use when interacting with the monitor */ -static MXS_MONITOR_INSTANCE * -startMonitor(MXS_MONITOR *mon, const MXS_CONFIG_PARAMETER *params) +static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *params) { - NDBC_MONITOR *handle = static_cast(mon->instance); - bool have_events = false, script_error = false; + bool started = false; - if (handle != NULL) + NDBC_MONITOR *handle = static_cast(mon); + + if (!handle->checked) { - handle->shutdown = 0; - MXS_FREE(handle->script); - } - else - { - if ((handle = (NDBC_MONITOR *) MXS_MALLOC(sizeof(NDBC_MONITOR))) == NULL) + if (!check_monitor_permissions(handle->monitor, "SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'")) { - return NULL; + MXS_ERROR("Failed to start monitor. See earlier errors for more information."); + } + else + { + handle->checked = true; } - handle->shutdown = 0; - handle->id = MXS_MONITOR_DEFAULT_ID; - handle->master = NULL; - handle->monitor = mon; } - handle->script = config_copy_string(params, "script"); - handle->events = config_get_enum(params, "events", mxs_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'")) + if (handle->checked) { - MXS_ERROR("Failed to start monitor. See earlier errors for more information."); - MXS_FREE(handle->script); - MXS_FREE(handle); - return NULL; + handle->script = config_copy_string(params, "script"); + handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); + + if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) + { + MXS_ERROR("Failed to start monitor thread for monitor '%s'.", handle->monitor->name); + MXS_FREE(handle->script); + handle->script = NULL; + } + else + { + started = true; + } } - handle->checked = true; - - if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) - { - MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); - MXS_FREE(handle->script); - MXS_FREE(handle); - return NULL; - } - - return handle; + return started; } /** @@ -194,9 +184,15 @@ static void stopMonitor(MXS_MONITOR_INSTANCE *mon) { NDBC_MONITOR *handle = static_cast(mon); + ss_dassert(handle->thread); handle->shutdown = 1; thread_wait(handle->thread); + handle->thread = 0; + handle->shutdown = 0; + + MXS_FREE(handle->script); + handle->script = NULL; } /**