diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 3fe975f5c..7f3fc587d 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -408,3 +408,80 @@ MODULES *ptr = registered; } dcb_printf(dcb, "----------------+-------------+---------+-------+-------------------------\n\n"); } + +/** + * Provide a row to the result set that defines the set of modules + * + * @param set The result set + * @param data The index of the row to send + * @return The next row or NULL + */ +static RESULT_ROW * +moduleRowCallback(RESULTSET *set, void *data) +{ +int *rowno = (int *)data; +int i = 0;; +char *stat, buf[20]; +RESULT_ROW *row; +MODULES *ptr; + + ptr = registered; + while (i < *rowno && ptr) + { + i++; + ptr = ptr->next; + } + if (ptr == NULL) + { + free(data); + return NULL; + } + (*rowno)++; + row = resultset_make_row(set); + resultset_row_set(row, 0, ptr->module); + resultset_row_set(row, 1, ptr->type); + resultset_row_set(row, 2, ptr->version); + sprintf(buf, "%d.%d.%d", ptr->info->api_version.major, + ptr->info->api_version.minor, + ptr->info->api_version.patch); + resultset_row_set(row, 3, buf); + resultset_row_set(row, 4, ptr->info->status == MODULE_IN_DEVELOPMENT + ? "In Development" + : (ptr->info->status == MODULE_ALPHA_RELEASE + ? "Alpha" + : (ptr->info->status == MODULE_BETA_RELEASE + ? "Beta" + : (ptr->info->status == MODULE_GA + ? "GA" + : (ptr->info->status == MODULE_EXPERIMENTAL + ? "Experimental" : "Unknown"))))); + return row; +} + +/** + * Return a resultset that has the current set of modules in it + * + * @return A Result set + */ +RESULTSET * +moduleGetList() +{ +RESULTSET *set; +int *data; + + if ((data = (int *)malloc(sizeof(int))) == NULL) + return NULL; + *data = 0; + if ((set = resultset_create(moduleRowCallback, data)) == NULL) + { + free(data); + return NULL; + } + resultset_add_column(set, "Module Name", 18, COL_TYPE_VARCHAR); + resultset_add_column(set, "Module Type", 12, COL_TYPE_VARCHAR); + resultset_add_column(set, "Version", 10, COL_TYPE_VARCHAR); + resultset_add_column(set, "API Version", 8, COL_TYPE_VARCHAR); + resultset_add_column(set, "Status", 15, COL_TYPE_VARCHAR); + + return set; +} diff --git a/server/core/monitor.c b/server/core/monitor.c index 23b8ee4ef..66f138e85 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -362,3 +362,66 @@ monitorSetNetworkTimeout(MONITOR *mon, int type, int value) { mon->module->setNetworkTimeout(mon->handle, type, value); } } + +/** + * Provide a row to the result set that defines the set of monitors + * + * @param set The result set + * @param data The index of the row to send + * @return The next row or NULL + */ +static RESULT_ROW * +monitorRowCallback(RESULTSET *set, void *data) +{ +int *rowno = (int *)data; +int i = 0;; +char buf[20]; +RESULT_ROW *row; +MONITOR *ptr; + + spinlock_acquire(&monLock); + ptr = allMonitors; + while (i < *rowno && ptr) + { + i++; + ptr = ptr->next; + } + if (ptr == NULL) + { + spinlock_release(&monLock); + free(data); + return NULL; + } + (*rowno)++; + row = resultset_make_row(set); + resultset_row_set(row, 0, ptr->name); + resultset_row_set(row, 1, ptr->state & MONITOR_STATE_RUNNING + ? "Running" : "Stopped"); + spinlock_release(&monLock); + return row; +} + +/** + * Return a resultset that has the current set of monitors in it + * + * @return A Result set + */ +RESULTSET * +monitorGetList() +{ +RESULTSET *set; +int *data; + + if ((data = (int *)malloc(sizeof(int))) == NULL) + return NULL; + *data = 0; + if ((set = resultset_create(monitorRowCallback, data)) == NULL) + { + free(data); + return NULL; + } + resultset_add_column(set, "Monitor", 20, COL_TYPE_VARCHAR); + resultset_add_column(set, "Status", 10, COL_TYPE_VARCHAR); + + return set; +} diff --git a/server/include/modules.h b/server/include/modules.h index adda2b255..56215b5d2 100644 --- a/server/include/modules.h +++ b/server/include/modules.h @@ -19,6 +19,7 @@ */ #include #include +#include /** * @file modules.h Utilities for loading modules @@ -34,6 +35,7 @@ * 29/05/14 Mark Riddoch Addition of filter modules * 01/10/14 Mark Riddoch Addition of call to unload all modules on * shutdown + * 19/02/15 Mark Riddoch Addition of moduleGetList * @endverbatim */ @@ -63,6 +65,7 @@ extern void unload_module(const char *module); extern void unload_all_modules(); extern void printModules(); extern void dprintAllModules(DCB *); -char* get_maxscale_home(void); +extern char *get_maxscale_home(void); +extern RESULTSET *moduleGetList(); #endif diff --git a/server/include/monitor.h b/server/include/monitor.h index c08e8153e..27d3f8144 100644 --- a/server/include/monitor.h +++ b/server/include/monitor.h @@ -19,6 +19,7 @@ */ #include #include +#include /** * @file monitor.h The interface to the monitor module @@ -35,6 +36,7 @@ * 28/08/14 Massimiliano Pinto Addition of detectStaleMaster * 30/10/14 Massimiliano Pinto Addition of disableMasterFailback * 07/11/14 Massimiliano Pinto Addition of setNetworkTimeout + * 19/02/15 Mark Riddoch Addition of monitorGetList * * @endverbatim */ @@ -143,4 +145,5 @@ extern void monitorSetReplicationHeartbeat(MONITOR *, int); extern void monitorDetectStaleMaster(MONITOR *, int); extern void monitorDisableMasterFailback(MONITOR *, int); extern void monitorSetNetworkTimeout(MONITOR *, int, int); +extern RESULTSET *monitorGetList(); #endif diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index 027e77f8a..a65ced34e 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -169,7 +170,43 @@ exec_show_servers(DCB *dcb, MAXINFO_TREE *tree) { RESULTSET *set; - if ((set = serverGetList(SESSION_LIST_CONNECTION)) == NULL) + if ((set = serverGetList()) == NULL) + return; + + resultset_stream_mysql(set, dcb); + resultset_free(set); +} + +/** + * Fetch the list of modules and stream as a result set + * + * @param dcb DCB to which to stream result set + * @param tree Potential liek clause (currently unused) + */ +static void +exec_show_modules(DCB *dcb, MAXINFO_TREE *tree) +{ +RESULTSET *set; + + if ((set = moduleGetList()) == NULL) + return; + + resultset_stream_mysql(set, dcb); + resultset_free(set); +} + +/** + * Fetch the list of monitors and stream as a result set + * + * @param dcb DCB to which to stream result set + * @param tree Potential liek clause (currently unused) + */ +static void +exec_show_monitors(DCB *dcb, MAXINFO_TREE *tree) +{ +RESULTSET *set; + + if ((set = monitorGetList()) == NULL) return; resultset_stream_mysql(set, dcb); @@ -190,6 +227,8 @@ static struct { { "sessions", exec_show_sessions }, { "clients", exec_show_clients }, { "servers", exec_show_servers }, + { "modules", exec_show_modules }, + { "monitors", exec_show_monitors }, { NULL, NULL } }; @@ -318,8 +357,8 @@ char buf[80]; (char *)(*variables[context->index].func)()); break; case VT_INT: - snprintf(buf, 80, "%d", - (int)(*variables[context->index].func)()); + snprintf(buf, 80, "%ld", + (long)(*variables[context->index].func)()); resultset_row_set(row, 1, buf); break; } @@ -407,8 +446,8 @@ char buf[80]; (char *)(*status[context->index].func)()); break; case VT_INT: - snprintf(buf, 80, "%d", - (int)(*status[context->index].func)()); + snprintf(buf, 80, "%ld", + (long)(*status[context->index].func)()); resultset_row_set(row, 1, buf); break; } @@ -473,6 +512,7 @@ maxinfo_pattern_match(char *pattern, char *str) { int anchor, len, trailing; char *fixed; +extern char *strcasestr(); if (*pattern != '%') {