Created
November 8, 2016 17:22
-
-
Save nsheridan/ff2002a38dfdbedc3609c24ffb023361 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -urN MaxScale-maxscale-2.0.1.orig/server/include/alloc.h MaxScale-maxscale-2.0.1/server/include/alloc.h | |
--- MaxScale-maxscale-2.0.1.orig/server/include/alloc.h 1970-01-01 00:00:00.000000000 +0000 | |
+++ MaxScale-maxscale-2.0.1/server/include/alloc.h 2016-11-08 11:50:27.787027160 +0000 | |
@@ -0,0 +1,79 @@ | |
+#pragma once | |
+/* | |
+ * 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. | |
+ */ | |
+ | |
+#include <maxscale/cdefs.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+ | |
+MXS_BEGIN_DECLS | |
+ | |
+/* | |
+ * NOTE: Do not use these functions directly, use the macros below. | |
+ */ | |
+ | |
+// "caller" arg temporarily disabled so that existing code | |
+// using the previous version of mxs_alloc etc. will continue | |
+// to compile. | |
+void *mxs_malloc(size_t size/*, const char *caller*/); | |
+void *mxs_calloc(size_t nmemb, size_t size/*, const char *caller*/); | |
+void *mxs_realloc(void *ptr, size_t size/*, const char *caller*/); | |
+void mxs_free(void *ptr/*, const char *caller*/); | |
+ | |
+char *mxs_strdup(const char *s/*, const char *caller*/); | |
+char *mxs_strndup(const char *s, size_t n/*, const char *caller*/); | |
+ | |
+char *mxs_strdup_a(const char *s/*, const char *caller*/); | |
+char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/); | |
+ | |
+ | |
+/* | |
+ * NOTE: USE these macros instead of the functions above. | |
+ */ | |
+#define MXS_MALLOC(size) mxs_malloc(size/*, __func__*/) | |
+#define MXS_CALLOC(nmemb, size) mxs_calloc(nmemb, size/*, __func__*/) | |
+#define MXS_REALLOC(ptr, size) mxs_realloc(ptr, size/*, __func__*/) | |
+#define MXS_FREE(ptr) mxs_free(ptr/*, __func__*/) | |
+ | |
+#define MXS_STRDUP(s) mxs_strdup(s/*, __func__*/) | |
+#define MXS_STRNDUP(s, n) mxs_strndup(s, n/*, __func__*/) | |
+ | |
+#define MXS_STRDUP_A(s) mxs_strdup_a(s/*, __func__*/) | |
+#define MXS_STRNDUP_A(s, n) mxs_strndup_a(s, n/*, __func__*/) | |
+ | |
+ | |
+/** | |
+ * @brief Abort the process if the pointer is NULL. | |
+ * | |
+ * To be used in circumstances where a memory allocation failure | |
+ * cannot - currently - be dealt with properly. | |
+ */ | |
+#define MXS_ABORT_IF_NULL(p) do { if (!p) { abort(); } } while (false) | |
+ | |
+/** | |
+ * @brief Abort the process if the provided value is non-zero. | |
+ * | |
+ * To be used in circumstances where a memory allocation or other | |
+ * fatal error cannot - currently - be dealt with properly. | |
+ */ | |
+#define MXS_ABORT_IF_TRUE(b) do { if (b) { abort(); } } while (false) | |
+ | |
+/** | |
+ * @brief Abort the process if the provided value is zero. | |
+ * | |
+ * To be used in circumstances where a memory allocation or other | |
+ * fatal error cannot - currently - be dealt with properly. | |
+ */ | |
+#define MXS_ABORT_IF_FALSE(b) do { if (!b) { abort(); } } while (false) | |
+ | |
+MXS_END_DECLS | |
diff -urN MaxScale-maxscale-2.0.1.orig/server/include/maxscale/cdefs.h MaxScale-maxscale-2.0.1/server/include/maxscale/cdefs.h | |
--- MaxScale-maxscale-2.0.1.orig/server/include/maxscale/cdefs.h 1970-01-01 00:00:00.000000000 +0000 | |
+++ MaxScale-maxscale-2.0.1/server/include/maxscale/cdefs.h 2016-11-08 11:52:13.864810227 +0000 | |
@@ -0,0 +1,76 @@ | |
+#pragma once | |
+/* | |
+ * 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 cdefs.h | |
+ * | |
+ * This file has several purposes. | |
+ * | |
+ * - Its purpose is the same as that of x86_64-linux-gnu/sys/cdefs.h, that is, | |
+ * it defines things that are dependent upon the compilation environment. | |
+ * - Since this *must* be included as the very first header by all other MaxScale | |
+ * headers, it allows you to redfine things globally, should that be necessary, | |
+ * for instance, when debugging something. | |
+ * - Global constants applicable across the line can be defined here. | |
+ */ | |
+ | |
+#ifdef __cplusplus | |
+# define MXS_BEGIN_DECLS extern "C" { | |
+# define MXS_END_DECLS } | |
+#else | |
+# define MXS_BEGIN_DECLS | |
+# define MXS_END_DECLS | |
+#endif | |
+ | |
+#define _XOPEN_SOURCE 700 | |
+#define OPENSSL_THREAD_DEFINES | |
+ | |
+/** | |
+ * Define intended for use with strerror. | |
+ * | |
+ * char errbuf[MXS_STRERROR_BUFLEN]; | |
+ * strerror_r(errno, errbuf, sizeof(errbuf)) | |
+ */ | |
+#define MXS_STRERROR_BUFLEN 512 | |
+ | |
+/** | |
+ * Returns the smaller of two items. | |
+ * | |
+ * @param a A value. | |
+ * @param b Another value. | |
+ * | |
+ * @return a if a is smaller than b, b otherwise. | |
+ * | |
+ * @note This a macro, so the arguments will be evaluated more than once. | |
+ */ | |
+#define MXS_MIN(a,b) ((a)<(b) ? (a) : (b)) | |
+ | |
+/** | |
+ * Returns the larger of two items. | |
+ * | |
+ * @param a A value. | |
+ * @param b Another value. | |
+ * | |
+ * @return a if a is larger than b, b otherwise. | |
+ * | |
+ * @note This a macro, so the arguments will be evaluated more than once. | |
+ */ | |
+#define MXS_MAX(a,b) ((a)>(b) ? (a) : (b)) | |
+ | |
+/** | |
+ * COMMON INCLUDE FILES | |
+ */ | |
+#include <stdbool.h> | |
+#include <stddef.h> | |
+#include <stdint.h> | |
diff -urN MaxScale-maxscale-2.0.1.orig/server/modules/monitor/auroramon.c MaxScale-maxscale-2.0.1/server/modules/monitor/auroramon.c | |
--- MaxScale-maxscale-2.0.1.orig/server/modules/monitor/auroramon.c 1970-01-01 00:00:00.000000000 +0000 | |
+++ MaxScale-maxscale-2.0.1/server/modules/monitor/auroramon.c 2016-11-08 17:14:53.380763231 +0000 | |
@@ -0,0 +1,386 @@ | |
+/* | |
+ * 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 auroramon.c - Amazon RDS Aurora monitor | |
+ */ | |
+ | |
+#include <modinfo.h> | |
+#include <thread.h> | |
+#include <monitor.h> | |
+#include <mysqld_error.h> | |
+#include <alloc.h> | |
+#include <skygw_debug.h> | |
+ | |
+static char *version_str = (char*)"V1.0.0"; | |
+ | |
+/*lint -e14 */ | |
+MODULE_INFO info = | |
+{ | |
+ MODULE_API_MONITOR, | |
+ MODULE_BETA_RELEASE, | |
+ MONITOR_VERSION, | |
+ "Aurora monitor" | |
+}; | |
+/*lint +e14 */ | |
+ | |
+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 */ | |
+} AURORA_MONITOR; | |
+ | |
+/** | |
+ * Implementation of the mandatory version entry point | |
+ * | |
+ * @return version string of the module | |
+ */ | |
+/*lint -e14 */ | |
+char * | |
+version() | |
+{ | |
+ return version_str; | |
+} | |
+ | |
+/** | |
+ * The module initialisation routine, called when the module is first loaded. | |
+ */ | |
+/*lint -e14 */ | |
+void | |
+ModuleInit() | |
+{ | |
+} | |
+/*lint +e14 */ | |
+ | |
+/** | |
+ * @brief Update the status of a server | |
+ * | |
+ * This function connects to the database and queries it for its status. The | |
+ * status of the server is adjusted accordingly based on the results of the | |
+ * query. | |
+ * | |
+ * @param monitor Monitor object | |
+ * @param database Server whose status should be updated | |
+ */ | |
+void update_server_status(MONITOR *monitor, MONITOR_SERVERS *database) | |
+{ | |
+ if (!SERVER_IN_MAINT(database->server)) | |
+ { | |
+ SERVER temp_server = {.status = database->server->status}; | |
+ server_clear_status(&temp_server, SERVER_RUNNING | SERVER_MASTER | SERVER_SLAVE | SERVER_AUTH_ERROR); | |
+ database->mon_prev_status = database->server->status; | |
+ | |
+ /** Try to connect to or ping the database */ | |
+ connect_result_t rval = mon_connect_to_db(monitor, database); | |
+ | |
+ if (rval == MONITOR_CONN_OK) | |
+ { | |
+ server_set_status(&temp_server, SERVER_RUNNING); | |
+ MYSQL_RES *result; | |
+ | |
+ /** Connection is OK, query for replica status */ | |
+ if (mysql_query(database->con, "SELECT @@aurora_server_id, server_id FROM " | |
+ "information_schema.replica_host_status " | |
+ "WHERE session_id = 'MASTER_SESSION_ID'") == 0 && | |
+ (result = mysql_store_result(database->con))) | |
+ { | |
+ ss_dassert(mysql_field_count(database->con) == 2); | |
+ MYSQL_ROW row = mysql_fetch_row(result); | |
+ int status = SERVER_SLAVE; | |
+ | |
+ /** The master will return a row with two identical non-NULL fields */ | |
+ if (row[0] && row[1] && strcmp(row[0], row[1]) == 0) | |
+ { | |
+ status = SERVER_MASTER; | |
+ } | |
+ | |
+ server_set_status(&temp_server, status); | |
+ mysql_free_result(result); | |
+ } | |
+ else | |
+ { | |
+ MXS_ERROR("Failed to query server %s (%s:%d): %d, %s", | |
+ database->server->unique_name, database->server->name, | |
+ database->server->port, mysql_errno(database->con), | |
+ mysql_error(database->con)); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ /** Failed to connect to the database */ | |
+ if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR) | |
+ { | |
+ server_set_status(&temp_server, SERVER_AUTH_ERROR); | |
+ } | |
+ | |
+ if (mon_status_changed(database) && mon_print_fail_status(database)) | |
+ { | |
+ mon_log_connect_error(database, rval); | |
+ } | |
+ } | |
+ | |
+ server_transfer_status(database->server, &temp_server); | |
+ } | |
+} | |
+ | |
+/** | |
+ * @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 | |
+ * | |
+ * @param arg The MONITOR object for this monitor | |
+ */ | |
+static void | |
+monitorMain(void *arg) | |
+{ | |
+ MONITOR *monitor = (MONITOR*)arg; | |
+ AURORA_MONITOR *handle = monitor->handle; | |
+ | |
+ if (mysql_thread_init()) | |
+ { | |
+ MXS_ERROR("mysql_thread_init failed in Aurora monitor. Exiting."); | |
+ return; | |
+ } | |
+ | |
+ while (!handle->shutdown) | |
+ { | |
+ for (MONITOR_SERVERS *ptr = monitor->databases; ptr; ptr = ptr->next) | |
+ { | |
+ update_server_status(monitor, ptr); | |
+ | |
+ if (SERVER_IS_DOWN(ptr->server)) | |
+ { | |
+ /** Hang up all DCBs connected to the failed server */ | |
+ dcb_hangup_foreach(ptr->server); | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * 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); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ /** Sleep until the next monitoring interval */ | |
+ int ms = 0; | |
+ while (ms < monitor->interval && !handle->shutdown) | |
+ { | |
+ thread_millisleep(MON_BASE_INTERVAL_MS); | |
+ ms += MON_BASE_INTERVAL_MS; | |
+ } | |
+ } | |
+ | |
+ mysql_thread_end(); | |
+} | |
+ | |
+/** | |
+ * Helper function to free the monitor handle | |
+ */ | |
+static void auroramon_free(AURORA_MONITOR *handle) | |
+{ | |
+ if (handle) | |
+ { | |
+ MXS_FREE(handle->script); | |
+ MXS_FREE(handle); | |
+ } | |
+} | |
+ | |
+/** | |
+ * @brief Start the monitor | |
+ * | |
+ * This function initializes the monitor and starts the monitoring thread. | |
+ * | |
+ * @param arg The MONITOR structure for this monitor | |
+ * @param opt The configuration parameters for this monitor | |
+ * @return Monitor handle | |
+ */ | |
+static void * | |
+startMonitor(void *arg, void *opt) | |
+{ | |
+ MONITOR* mon = (MONITOR*) arg; | |
+ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*) opt; | |
+ bool have_events = false, script_error = false; | |
+ AURORA_MONITOR *handle = mon->handle; | |
+ | |
+ if (handle) | |
+ { | |
+ handle->shutdown = false; | |
+ } | |
+ else | |
+ { | |
+ if ((handle = (AURORA_MONITOR *) MXS_MALLOC(sizeof(AURORA_MONITOR))) == NULL) | |
+ { | |
+ return NULL; | |
+ } | |
+ | |
+ 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 " | |
+ "WHERE session_id = 'MASTER_SESSION_ID'")) | |
+ { | |
+ MXS_ERROR("Failed to start monitor. See earlier errors for more information."); | |
+ 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)); | |
+ } | |
+ } | |
+ | |
+ if (thread_start(&handle->thread, monitorMain, mon) == NULL) | |
+ { | |
+ MXS_ERROR("Failed to start monitor thread for monitor '%s'.", mon->name); | |
+ auroramon_free(handle); | |
+ return NULL; | |
+ } | |
+ | |
+ return handle; | |
+} | |
+ | |
+/** | |
+ * Stop a running monitor | |
+ * | |
+ * @param arg Handle on thr running monior | |
+ */ | |
+static void | |
+stopMonitor(void *arg) | |
+{ | |
+ MONITOR* mon = (MONITOR*) arg; | |
+ AURORA_MONITOR *handle = (AURORA_MONITOR *) mon->handle; | |
+ | |
+ handle->shutdown = true; | |
+ thread_wait(handle->thread); | |
+} | |
+ | |
+/** | |
+ * Diagnostic interface | |
+ * | |
+ * @param dcb DCB to send output | |
+ * @param mon The monitor | |
+ */ | |
+static void | |
+diagnostics(DCB *dcb, void *mon) | |
+{ | |
+} | |
+ | |
+static MONITOR_OBJECT MyObject = | |
+{ | |
+ startMonitor, | |
+ stopMonitor, | |
+ diagnostics | |
+}; | |
+ | |
+/** | |
+ * The module entry point routine. It is this routine that must populate the | |
+ * structure that is referred to as the "module object", this is a structure | |
+ * with the set of external entry points for this module. | |
+ * | |
+ * @return The module object | |
+ */ | |
+MONITOR_OBJECT * | |
+GetModuleObject() | |
+{ | |
+ return &MyObject; | |
+} | |
+/*lint +e14 */ | |
diff -urN MaxScale-maxscale-2.0.1.orig/server/modules/monitor/CMakeLists.txt MaxScale-maxscale-2.0.1/server/modules/monitor/CMakeLists.txt | |
--- MaxScale-maxscale-2.0.1.orig/server/modules/monitor/CMakeLists.txt 2016-09-29 20:48:21.000000000 +0000 | |
+++ MaxScale-maxscale-2.0.1/server/modules/monitor/CMakeLists.txt 2016-11-08 11:39:51.276315719 +0000 | |
@@ -16,6 +16,12 @@ | |
set_target_properties(ndbclustermon PROPERTIES VERSION "2.1.0") | |
install(TARGETS ndbclustermon DESTINATION ${MAXSCALE_LIBDIR}) | |
+add_library(auroramon SHARED auroramon.c) | |
+target_link_libraries(auroramon maxscale-common) | |
+add_dependencies(auroramon pcre2) | |
+set_target_properties(auroramon PROPERTIES VERSION "1.0.0") | |
+install(TARGETS auroramon DESTINATION ${MAXSCALE_LIBDIR}) | |
+ | |
if(BUILD_MMMON) | |
add_library(mmmon SHARED mmmon.c) | |
target_link_libraries(mmmon maxscale-common) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment