Merge branch 'develop' into MAX-59

This commit is contained in:
MassimilianoPinto 2014-06-27 11:07:55 +02:00
commit 237bacd131
15 changed files with 336 additions and 36 deletions

View File

@ -25,6 +25,8 @@
* Date Who Description
* 13/06/14 Mark Riddoch Initial implementation
* 15/06/14 Mark Riddoch Addition of source command
* 26/06/14 Mark Riddoch Fix issue with final OK split across
* multiple reads
*
* @endverbatim
*/
@ -440,7 +442,9 @@ char buf[20];
/**
* Send a comamnd using the MaxScaled protocol, display the return data
* on standard output
* on standard output.
*
* Input terminates with a lien containing jsut the text OK
*
* @param so The socket connect to MaxScale
* @param cmd The command to send
@ -450,19 +454,38 @@ static int
sendCommand(int so, char *cmd)
{
char buf[80];
int i;
int i, j, newline = 0;
write(so, cmd, strlen(cmd));
while (1)
{
if ((i = read(so, buf, 80)) == -1)
return 0;
if (i > 1 && buf[i-1] == 'K' && buf[i-2] == 'O')
for (j = 0; j < i; j++)
{
write(1, buf, i - 2);
return 1;
if (newline == 1 && buf[j] == 'O')
newline = 2;
else if (newline == 2 && buf[j] == 'K' && j == i - 1)
{
return 1;
}
else if (newline == 2)
{
putchar('O');
putchar(buf[j]);
newline = 0;
}
else if (buf[j] == '\n' || buf[j] == '\r')
{
putchar(buf[j]);
newline = 1;
}
else
{
putchar(buf[j]);
newline = 0;
}
}
write(1, buf, i);
}
return 1;
}

View File

@ -1270,6 +1270,41 @@ DCB *dcb;
spinlock_release(&dcbspin);
}
/**
* Diagnotic routine to print client DCB data in a tabular form.
*
* @param pdcb DCB to print results to
*/
void
dListClients(DCB *pdcb)
{
DCB *dcb;
spinlock_acquire(&dcbspin);
dcb = allDCBs;
dcb_printf(pdcb, "Client Connections\n");
dcb_printf(pdcb, "-----------------+------------+----------------------+------------\n");
dcb_printf(pdcb, " %-15s | %-10s | %-20s | %s\n",
"Client", "DCB", "Service", "Session");
dcb_printf(pdcb, "-----------------+------------+----------------------+------------\n");
while (dcb)
{
if (dcb_isclient(dcb)
&& dcb->dcb_role == DCB_ROLE_REQUEST_HANDLER)
{
dcb_printf(pdcb, " %-15s | %10p | %-20s | %10p\n",
(dcb->remote ? dcb->remote : ""),
dcb, (dcb->session->service ?
dcb->session->service->name : ""),
dcb->session);
}
dcb = dcb->next;
}
dcb_printf(pdcb, "-----------------+------------+----------------------+------------\n\n");
spinlock_release(&dcbspin);
}
/**
* Diagnostic to print a DCB to another DCB
*
@ -1281,8 +1316,14 @@ dprintDCB(DCB *pdcb, DCB *dcb)
{
dcb_printf(pdcb, "DCB: %p\n", (void *)dcb);
dcb_printf(pdcb, "\tDCB state: %s\n", gw_dcb_state2string(dcb->state));
if (dcb->session && dcb->session->service)
dcb_printf(pdcb, "\tService: %s\n",
dcb->session->service->name);
if (dcb->remote)
dcb_printf(pdcb, "\tConnected to: %s\n", dcb->remote);
if (dcb->user)
dcb_printf(pdcb, "\tUsername: %s\n",
dcb->user);
dcb_printf(pdcb, "\tOwning Session: %p\n", dcb->session);
if (dcb->writeq)
dcb_printf(pdcb, "\tQueued write data: %d\n", gwbuf_length(dcb->writeq));

View File

@ -379,7 +379,9 @@ MODULES *ptr = registered;
: (ptr->info->status == MODULE_BETA_RELEASE
? "Beta"
: (ptr->info->status == MODULE_GA
? "GA" : "Unknown"))));
? "GA"
: (ptr->info->status == MODULE_EXPERIMENTAL
? "Experimental" : "Unknown")))));
dcb_printf(dcb, "\n");
ptr = ptr->next;
}

View File

@ -73,6 +73,7 @@ MONITOR *mon;
return NULL;
}
mon->handle = (*mon->module->startMonitor)(NULL);
mon->state |= MONITOR_STATE_RUNNING;
spinlock_acquire(&monLock);
mon->next = allMonitors;
allMonitors = mon;
@ -93,6 +94,7 @@ monitor_free(MONITOR *mon)
MONITOR *ptr;
mon->module->stopMonitor(mon->handle);
mon->state &= ~MONITOR_STATE_RUNNING;
spinlock_acquire(&monLock);
if (allMonitors == mon)
allMonitors = mon->next;
@ -119,6 +121,7 @@ void
monitorStart(MONITOR *monitor)
{
monitor->handle = (*monitor->module->startMonitor)(monitor->handle);
monitor->state |= MONITOR_STATE_RUNNING;
}
/**
@ -130,6 +133,7 @@ void
monitorStop(MONITOR *monitor)
{
monitor->module->stopMonitor(monitor->handle);
monitor->state &= ~MONITOR_STATE_RUNNING;
}
/**
@ -200,6 +204,47 @@ MONITOR *ptr;
spinlock_release(&monLock);
}
/**
* Show a single monitor
*
* @param dcb DCB for printing output
*/
void
monitorShow(DCB *dcb, MONITOR *monitor)
{
dcb_printf(dcb, "Monitor: %p\n", monitor);
dcb_printf(dcb, "\tName: %s\n", monitor->name);
if (monitor->module->diagnostics)
monitor->module->diagnostics(dcb, monitor->handle);
}
/**
* List all the monitors
*
* @param dcb DCB for printing output
*/
void
monitorList(DCB *dcb)
{
MONITOR *ptr;
spinlock_acquire(&monLock);
ptr = allMonitors;
dcb_printf(dcb, "+----------------------+---------------------\n");
dcb_printf(dcb, "| %-20s | Status\n", "Monitor");
dcb_printf(dcb, "+----------------------+---------------------\n");
while (ptr)
{
dcb_printf(dcb, "| %-20s | %s\n", ptr->name,
ptr->state & MONITOR_STATE_RUNNING
? "Running" : "Stopped");
ptr = ptr->next;
}
dcb_printf(dcb, "+----------------------+---------------------\n");
spinlock_release(&monLock);
}
/**
* Find a monitor by name
*
@ -249,6 +294,7 @@ void
monitorSetInterval (MONITOR *mon, unsigned long interval)
{
if (mon->module->setInterval != NULL) {
mon->interval = interval;
mon->module->setInterval(mon->handle, interval);
}
}

View File

@ -324,7 +324,8 @@ char *stat;
}
}
if (server->node_ts > 0) {
dcb_printf(dcb, "\tLast Repl Heartbeat:\t%lu\n", server->node_ts);
dcb_printf(dcb, "\tLast Repl Heartbeat:\t%s",
asctime(localtime(&server->node_ts)));
}
dcb_printf(dcb, "\tNumber of connections: %d\n", server->stats.n_connections);
dcb_printf(dcb, "\tCurrent no. of conns: %d\n", server->stats.n_current);

View File

@ -716,8 +716,8 @@ SERVER *ptr = service->databases;
int i;
printf("Service %p\n", service);
printf("\tService: %s\n", service->name);
printf("\tRouter: %s (%p)\n", service->routerModule, service->router);
printf("\tService: %s\n", service->name);
printf("\tRouter: %s (%p)\n", service->routerModule, service->router);
printf("\tStarted: %s", asctime(localtime(&service->stats.started)));
printf("\tBackend databases\n");
while (ptr)
@ -794,13 +794,16 @@ SERVER *server = service->databases;
int i;
dcb_printf(dcb, "Service %p\n", service);
dcb_printf(dcb, "\tService: %s\n", service->name);
dcb_printf(dcb, "\tRouter: %s (%p)\n", service->routerModule,
service->router);
dcb_printf(dcb, "\tService: %s\n",
service->name);
dcb_printf(dcb, "\tRouter: %s (%p)\n",
service->routerModule, service->router);
if (service->router)
service->router->diagnostics(service->router_instance, dcb);
dcb_printf(dcb, "\tStarted: %s",
dcb_printf(dcb, "\tStarted: %s",
asctime(localtime(&service->stats.started)));
dcb_printf(dcb, "\tRoot user access: %s\n",
service->enable_root ? "Enabled" : "Disabled");
if (service->n_filters)
{
dcb_printf(dcb, "\tFilter chain: ");
@ -818,9 +821,12 @@ int i;
server->protocol);
server = server->nextdb;
}
dcb_printf(dcb, "\tUsers data: %p\n", service->users);
dcb_printf(dcb, "\tTotal connections: %d\n", service->stats.n_sessions);
dcb_printf(dcb, "\tCurrently connected: %d\n", service->stats.n_current);
dcb_printf(dcb, "\tUsers data: %p\n",
service->users);
dcb_printf(dcb, "\tTotal connections: %d\n",
service->stats.n_sessions);
dcb_printf(dcb, "\tCurrently connected: %d\n",
service->stats.n_current);
}
/**

View File

@ -281,6 +281,7 @@ void printDCB(DCB *); /* Debug print routine */
void dprintAllDCBs(DCB *); /* Debug to print all DCB in the system */
void dprintDCB(DCB *, DCB *); /* Debug to print a DCB in the system */
void dListDCBs(DCB *); /* List all DCBs in the system */
void dListClients(DCB *); /* List al the client DCBs */
const char *gw_dcb_state2string(int); /* DCB state to string */
void dcb_printf(DCB *, const char *, ...); /* DCB version of printf */
int dcb_isclient(DCB *); /* the DCB is the client of the session */

View File

@ -38,7 +38,8 @@ typedef enum {
MODULE_IN_DEVELOPMENT = 0,
MODULE_ALPHA_RELEASE,
MODULE_BETA_RELEASE,
MODULE_GA
MODULE_GA,
MODULE_EXPERIMENTAL
} MODULE_STATUS;
/**

View File

@ -78,13 +78,21 @@ typedef struct {
*/
#define MONITOR_VERSION {1, 0, 0}
/**
* Monitor state bit mask values
*/
#define MONITOR_STATE_RUNNING 0x0001
/**
* Representation of the running monitor.
*/
typedef struct monitor {
char *name; /**< The name of the monitor module */
unsigned int state; /**< The monitor status */
MONITOR_OBJECT *module; /**< The "monitor object" */
void *handle; /**< Handle returned from startMonitor */
int interval; /**< The monitor interval */
struct monitor *next; /**< Next monitor in the linked list */
} MONITOR;
@ -97,6 +105,8 @@ extern void monitorStop(MONITOR *);
extern void monitorStart(MONITOR *);
extern void monitorStopAll();
extern void monitorShowAll(DCB *);
extern void monitorShow(DCB *, MONITOR *);
extern void monitorList(DCB *);
extern void monitorSetId(MONITOR *, unsigned long);
extern void monitorSetInterval (MONITOR *, unsigned long);
extern void monitorSetReplicationHeartbeat(MONITOR *, int);

View File

@ -390,11 +390,24 @@ struct timeval tv;
static void
diagnostic(FILTER *instance, void *fsession, DCB *dcb)
{
QLA_INSTANCE *my_instance = (QLA_INSTANCE *)instance;
QLA_SESSION *my_session = (QLA_SESSION *)fsession;
if (my_session)
{
dcb_printf(dcb, "\t\tLogging to file %s.\n",
dcb_printf(dcb, "\t\tLogging to file %s.\n",
my_session->filename);
}
if (my_instance->source)
dcb_printf(dcb, "\t\tLimit logging to connections from %s\n",
my_instance->source);
if (my_instance->userName)
dcb_printf(dcb, "\t\tLimit logging to user %s\n",
my_instance->userName);
if (my_instance->match)
dcb_printf(dcb, "\t\tInclude queries that match %s\n",
my_instance->match);
if (my_instance->nomatch)
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
my_instance->nomatch);
}

View File

@ -345,6 +345,14 @@ REGEX_SESSION *my_session = (REGEX_SESSION *)fsession;
dcb_printf(dcb, "\t\tNo. of queries altered by filter: %d\n",
my_session->replacements);
}
if (my_instance->source)
dcb_printf(dcb,
"\t\tReplacement limited to connections from %s\n",
my_instance->source);
if (my_instance->user)
dcb_printf(dcb,
"\t\tReplacement limit to user %s\n",
my_instance->user);
}
/**

View File

@ -118,7 +118,8 @@ typedef struct {
int active; /* filter is active? */
DCB *branch_dcb; /* Client DCB for "branch" service */
SESSION *branch_session;/* The branch service session */
int n_duped; /* Number of duplicated querise */
int n_duped; /* Number of duplicated queries */
int n_rejected; /* Number of rejected queries */
int residual; /* Any outstanding SQL text */
} TEE_SESSION;
@ -418,6 +419,10 @@ GWBUF *clone = NULL;
my_session->n_duped++;
SESSION_ROUTE_QUERY(my_session->branch_session, clone);
}
else
{
my_session->n_rejected++;
}
return rval;
}
@ -435,11 +440,28 @@ GWBUF *clone = NULL;
static void
diagnostic(FILTER *instance, void *fsession, DCB *dcb)
{
TEE_INSTANCE *my_instance = (TEE_INSTANCE *)instance;
TEE_SESSION *my_session = (TEE_SESSION *)fsession;
if (my_instance->source)
dcb_printf(dcb, "\t\tLimit to connections from %s\n",
my_instance->source);
dcb_printf(dcb, "\t\tDuplicate statements to service %s\n",
my_instance->service->name);
if (my_instance->userName)
dcb_printf(dcb, "\t\tLimit to user %s\n",
my_instance->userName);
if (my_instance->match)
dcb_printf(dcb, "\t\tInclude queries that match %s\n",
my_instance->match);
if (my_instance->nomatch)
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
my_instance->nomatch);
if (my_session)
{
dcb_printf(dcb, "\t\tNo. of statements duplicated: %d.\n",
my_session->n_duped);
dcb_printf(dcb, "\t\tNo. of statements rejected: %d.\n",
my_session->n_rejected);
}
}

View File

@ -539,11 +539,40 @@ int i, inserted;
static void
diagnostic(FILTER *instance, void *fsession, DCB *dcb)
{
TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance;
TOPN_SESSION *my_session = (TOPN_SESSION *)fsession;
int i;
dcb_printf(dcb, "\t\tReport size %d\n",
my_instance->topN);
if (my_instance->source)
dcb_printf(dcb, "\t\tLimit logging to connections from %s\n",
my_instance->source);
if (my_instance->user)
dcb_printf(dcb, "\t\tLimit logging to user %s\n",
my_instance->user);
if (my_instance->match)
dcb_printf(dcb, "\t\tInclude queries that match %s\n",
my_instance->match);
if (my_instance->exclude)
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
my_instance->exclude);
if (my_session)
{
dcb_printf(dcb, "\t\tLogging to file %s.\n",
my_session->filename);
dcb_printf(dcb, "\t\tCurrent Top %d:\n", my_instance->topN);
for (i = 0; i < my_instance->topN; i++)
{
if (my_session->top[i]->sql)
{
dcb_printf(dcb, "\t\t%d place:\n", i + 1);
dcb_printf(dcb, "\t\t\tExecution time: %.3f seconds\n",
(double)((my_session->top[i]->duration.tv_sec * 1000)
+ (my_session->top[i]->duration.tv_usec / 1000)) / 1000);
dcb_printf(dcb, "\t\t\tSQL: %s\n",
my_session->top[i]->sql);
}
}
}
}

View File

@ -128,6 +128,10 @@ struct subcommand showoptions[] = {
"Show all currently loaded modules",
"Show all currently loaded modules",
{0, 0, 0} },
{ "monitor", 1, monitorShow,
"Show the monitor details",
"Show the monitor details",
{ARG_TYPE_MONITOR, 0, 0} },
{ "monitors", 0, monitorShowAll,
"Show the monitors that are configured",
"Show the monitors that are configured",
@ -168,6 +172,10 @@ struct subcommand showoptions[] = {
* The subcommands of the list command
*/
struct subcommand listoptions[] = {
{ "clients", 0, dListClients,
"List all the client connections to MaxScale",
"List all the client connections to MaxScale",
{0, 0, 0} },
{ "dcbs", 0, dListDCBs,
"List all the DCBs active within MaxScale",
"List all the DCBs active within MaxScale",
@ -181,8 +189,12 @@ struct subcommand listoptions[] = {
"List all the listeners defined within MaxScale",
{0, 0, 0} },
{ "modules", 0, dprintAllModules,
"Show all currently loaded modules",
"Show all currently loaded modules",
"List all currently loaded modules",
"List all currently loaded modules",
{0, 0, 0} },
{ "monitors", 0, monitorList,
"List all monitors",
"List all monitors",
{0, 0, 0} },
{ "services", 0, dListServices,
"List all the services defined within MaxScale",
@ -300,18 +312,30 @@ struct subcommand reloadoptions[] = {
{ "dbusers", 1, reload_dbusers,
"Reload the dbuser data for a service. E.g. reload dbusers \"splitter service\"",
"Reload the dbuser data for a service. E.g. reload dbusers 0x849420",
{ARG_TYPE_DBUSERS, 0, 0} },
{ARG_TYPE_SERVICE, 0, 0} },
{ NULL, 0, NULL, NULL, NULL,
{0, 0, 0} }
};
static void enable_log_action(DCB *, char *);
static void disable_log_action(DCB *, char *);
static void enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor);
static void disable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor);
static void enable_service_root(DCB *dcb, SERVICE *service);
static void disable_service_root(DCB *dcb, SERVICE *service);
/**
* * The subcommands of the enable command
* */
struct subcommand enableoptions[] = {
{
"heartbeat",
1,
enable_monitor_replication_heartbeat,
"Enable the monitor replication heartbeat, pass a monitor name as argument",
"Enable the monitor replication heartbeat, pass a monitor name as argument",
{ARG_TYPE_MONITOR, 0, 0}
},
{
"log",
1,
@ -322,6 +346,14 @@ struct subcommand enableoptions[] = {
"message E.g. enable log message.",
{ARG_TYPE_STRING, 0, 0}
},
{
"root",
1,
enable_service_root,
"Enable root access to a service, pass a service name to enable root access",
"Enable root access to a service, pass a service name to enable root access",
{ARG_TYPE_SERVICE, 0, 0}
},
{
NULL,
0,
@ -337,24 +369,40 @@ struct subcommand enableoptions[] = {
* * The subcommands of the disable command
* */
struct subcommand disableoptions[] = {
{
"log",
1,
disable_log_action,
"Disable Log for MaxScale, Options: debug | trace | error | message "
"E.g. disable log debug",
"Disable Log for MaxScale, Options: debug | trace | error | message "
"E.g. disable log debug",
{ARG_TYPE_STRING, 0, 0}
},
{
{
"heartbeat",
1,
disable_monitor_replication_heartbeat,
"Disable the monitor replication heartbeat",
"Disable the monitor replication heartbeat",
{ARG_TYPE_MONITOR, 0, 0}
},
{
"log",
1,
disable_log_action,
"Disable Log for MaxScale, Options: debug | trace | error | message "
"E.g. disable log debug",
"Disable Log for MaxScale, Options: debug | trace | error | message "
"E.g. disable log debug",
{ARG_TYPE_STRING, 0, 0}
},
{
"root",
1,
disable_service_root,
"Disable root access to a service",
"Disable root access to a service",
{ARG_TYPE_SERVICE, 0, 0}
},
{
NULL,
0,
NULL,
NULL,
NULL,
{0, 0, 0}
}
}
};
#if defined(SS_DEBUG)
@ -850,7 +898,7 @@ unsigned int bitvalue;
static void
reload_dbusers(DCB *dcb, SERVICE *service)
{
dcb_printf(dcb, "Loaded %d database users for server %s.\n",
dcb_printf(dcb, "Loaded %d database users for service %s.\n",
reload_mysql_users(service), service->name);
}
@ -958,6 +1006,55 @@ restart_monitor(DCB *dcb, MONITOR *monitor)
monitorStart(monitor);
}
/**
* Enable replication heartbeat for a monitor
*
* @param dcb Connection to user interface
* @param monitor The monitor
*/
static void
enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor)
{
monitorSetReplicationHeartbeat(monitor, 1);
}
/**
* Disable replication heartbeat for a monitor
*
* @param dcb Connection to user interface
* @param monitor The monitor
*/
static void
disable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor)
{
monitorSetReplicationHeartbeat(monitor, 0);
}
/**
* Enable root access to a service
*
* @param dcb Connection to user interface
* @param service The service
*/
static void
enable_service_root(DCB *dcb, SERVICE *service)
{
serviceEnableRootUser(service, 1);
}
/**
* Disable root access to a service
*
* @param dcb Connection to user interface
* @param service The service
*/
static void
disable_service_root(DCB *dcb, SERVICE *service)
{
serviceEnableRootUser(service, 0);
}
/**
* The log enable action
*/