Merge branch 'develop' into binlog_server_waitdata_encryption
This commit is contained in:
@ -130,7 +130,7 @@ avro_client_do_registration(AVRO_INSTANCE *router, AVRO_CLIENT *client, GWBUF *d
|
||||
const char reg_uuid[] = "REGISTER UUID=";
|
||||
const int reg_uuid_len = strlen(reg_uuid);
|
||||
int data_len = GWBUF_LENGTH(data) - reg_uuid_len;
|
||||
char *request = GWBUF_DATA(data);
|
||||
char *request = (char*)GWBUF_DATA(data);
|
||||
int ret = 0;
|
||||
|
||||
if (strstr(request, reg_uuid) != NULL)
|
||||
|
||||
@ -1896,7 +1896,7 @@ int
|
||||
blr_statistics(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
{
|
||||
char result[BLRM_COM_STATISTICS_SIZE + 1] = "";
|
||||
char *ptr;
|
||||
uint8_t *ptr;
|
||||
GWBUF *ret;
|
||||
unsigned long len;
|
||||
|
||||
@ -1932,7 +1932,7 @@ blr_statistics(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
int
|
||||
blr_ping(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
{
|
||||
char *ptr;
|
||||
uint8_t *ptr;
|
||||
GWBUF *ret;
|
||||
|
||||
if ((ret = gwbuf_alloc(5)) == NULL)
|
||||
|
||||
@ -349,7 +349,7 @@ blr_slave_query(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
char *ptr;
|
||||
extern char *strcasestr();
|
||||
|
||||
qtext = GWBUF_DATA(queue);
|
||||
qtext = (char*)GWBUF_DATA(queue);
|
||||
query_len = extract_field((uint8_t *)qtext, 24) - 1;
|
||||
qtext += 5; // Skip header and first byte of the payload
|
||||
query_text = strndup(qtext, query_len);
|
||||
@ -4712,35 +4712,28 @@ blr_handle_change_master_token(char *input, char *error, CHANGE_MASTER_OPTIONS *
|
||||
static char *
|
||||
blr_get_parsed_command_value(char *input)
|
||||
{
|
||||
/* space+TAB+= */
|
||||
char *sep = " \t=";
|
||||
char *ret = NULL;
|
||||
char *word;
|
||||
char *value = NULL;
|
||||
|
||||
if (strlen(input))
|
||||
if (input && *input)
|
||||
{
|
||||
value = MXS_STRDUP_A(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
char value[strlen(input) + 1];
|
||||
strcpy(value, input);
|
||||
|
||||
if ((word = get_next_token(NULL, sep, &input)) != NULL)
|
||||
{
|
||||
char *ptr;
|
||||
/* space+TAB+= */
|
||||
char *sep = " \t=";
|
||||
char *word;
|
||||
|
||||
/* remove trailing spaces */
|
||||
ptr = value + strlen(value) - 1;
|
||||
while (ptr > value && isspace(*ptr))
|
||||
if ((word = get_next_token(NULL, sep, &input)) != NULL)
|
||||
{
|
||||
*ptr-- = 0;
|
||||
/* remove trailing spaces */
|
||||
char *ptr = value + strlen(value) - 1;
|
||||
while (ptr > value && isspace(*ptr))
|
||||
{
|
||||
*ptr-- = 0;
|
||||
}
|
||||
|
||||
ret = MXS_STRDUP_A(strstr(value, word));
|
||||
}
|
||||
|
||||
ret = MXS_STRDUP_A(strstr(value, word));
|
||||
|
||||
MXS_FREE(value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <maxscale/service.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/router.h>
|
||||
#include <maxscale/atomic.h>
|
||||
@ -47,6 +46,9 @@
|
||||
|
||||
#include <maxscale/version.h>
|
||||
|
||||
// This isn't really a clean way of testing
|
||||
#include "../../../../core/maxscale/service.h"
|
||||
|
||||
static void printVersion(const char *progname);
|
||||
static void printUsage(const char *progname);
|
||||
extern int blr_test_parse_change_master_command(char *input, char *error_string, CHANGE_MASTER_OPTIONS *config);
|
||||
|
||||
@ -270,7 +270,7 @@ execute(ROUTER *instance, void *router_session, GWBUF *queue)
|
||||
/* Extract the characters */
|
||||
while (queue && (cmdlen < CMDBUFLEN - 1))
|
||||
{
|
||||
const char* data = GWBUF_DATA(queue);
|
||||
const char* data = (char*)GWBUF_DATA(queue);
|
||||
int len = GWBUF_LENGTH(queue);
|
||||
int n = MXS_MIN(len, CMDBUFLEN - cmdlen - 1);
|
||||
|
||||
|
||||
@ -291,7 +291,7 @@ execute(ROUTER *instance, void *router_session, GWBUF *queue)
|
||||
/* Extract the characters */
|
||||
while (queue && (cmdlen < CMDBUFLEN - 1))
|
||||
{
|
||||
const char* data = GWBUF_DATA(queue);
|
||||
const char* data = (char*)GWBUF_DATA(queue);
|
||||
int len = GWBUF_LENGTH(queue);
|
||||
int n = MXS_MIN(len, CMDBUFLEN - cmdlen - 1);
|
||||
|
||||
|
||||
@ -51,11 +51,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/service.h>
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/router.h>
|
||||
#include <maxscale/filter.h>
|
||||
#include <maxscale/modules.h>
|
||||
#include <maxscale/modulecmd.h>
|
||||
#include <maxscale/atomic.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
@ -71,6 +73,7 @@
|
||||
#include <maxscale/housekeeper.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/maxscale.h>
|
||||
#include <maxscale/config_runtime.h>
|
||||
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <sys/syslog.h>
|
||||
@ -285,6 +288,59 @@ struct subcommand showoptions[] =
|
||||
{ EMPTY_OPTION}
|
||||
};
|
||||
|
||||
bool listfuncs_cb(const MODULECMD *cmd, void *data)
|
||||
{
|
||||
DCB *dcb = (DCB*)data;
|
||||
|
||||
dcb_printf(dcb, "%s::%s(", cmd->domain, cmd->identifier);
|
||||
|
||||
|
||||
for (int i = 0; i < cmd->arg_count_max; i++)
|
||||
{
|
||||
modulecmd_arg_type_t *type = &cmd->arg_types[i];
|
||||
|
||||
if (MODULECMD_GET_TYPE(type) != MODULECMD_ARG_OUTPUT)
|
||||
{
|
||||
char *t = modulecmd_argtype_to_str(&cmd->arg_types[i]);
|
||||
|
||||
if (t)
|
||||
{
|
||||
dcb_printf(dcb, "%s%s", t, i < cmd->arg_count_max - 1 ? " " : "");
|
||||
MXS_FREE(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dcb_printf(dcb, ")\n");
|
||||
|
||||
|
||||
for (int i = 0; i < cmd->arg_count_max; i++)
|
||||
{
|
||||
modulecmd_arg_type_t *type = &cmd->arg_types[i];
|
||||
|
||||
if (MODULECMD_GET_TYPE(type) != MODULECMD_ARG_OUTPUT)
|
||||
{
|
||||
|
||||
char *t = modulecmd_argtype_to_str(&cmd->arg_types[i]);
|
||||
|
||||
if (t)
|
||||
{
|
||||
dcb_printf(dcb, " %s - %s\n", t, cmd->arg_types[i].description);
|
||||
MXS_FREE(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dcb_printf(dcb, "\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dListFunctions(DCB *dcb)
|
||||
{
|
||||
modulecmd_foreach(NULL, NULL, listfuncs_cb, dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
* The subcommands of the list command
|
||||
*/
|
||||
@ -350,6 +406,12 @@ struct subcommand listoptions[] =
|
||||
"List the status of the polling threads in MaxScale",
|
||||
{0, 0, 0}
|
||||
},
|
||||
{
|
||||
"functions", 0, 0, dListFunctions,
|
||||
"List registered functions",
|
||||
"List all registered functions",
|
||||
{0}
|
||||
},
|
||||
{ EMPTY_OPTION}
|
||||
};
|
||||
|
||||
@ -743,28 +805,9 @@ static void cmd_AddServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3
|
||||
|
||||
for (int i = 0; i < items && values[i]; i++)
|
||||
{
|
||||
SERVICE *service = service_find(values[i]);
|
||||
MONITOR *monitor = monitor_find(values[i]);
|
||||
|
||||
if (service || monitor)
|
||||
if (runtime_link_server(server, values[i]))
|
||||
{
|
||||
ss_dassert(service == NULL || monitor == NULL);
|
||||
|
||||
if (service)
|
||||
{
|
||||
serviceAddBackend(service, server);
|
||||
service_serialize_servers(service);
|
||||
}
|
||||
else if (monitor)
|
||||
{
|
||||
monitorAddServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
}
|
||||
|
||||
const char *target = service ? "service" : "monitor";
|
||||
|
||||
MXS_NOTICE("Added server '%s' to %s '%s'", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Added server '%s' to %s '%s'\n", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Added server '%s' to '%s'\n", server->unique_name, values[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -811,27 +854,9 @@ static void cmd_RemoveServer(DCB *dcb, SERVER *server, char *v1, char *v2, char
|
||||
|
||||
for (int i = 0; i < items && values[i]; i++)
|
||||
{
|
||||
SERVICE *service = service_find(values[i]);
|
||||
MONITOR *monitor = monitor_find(values[i]);
|
||||
|
||||
if (service || monitor)
|
||||
if (runtime_unlink_server(server, values[i]))
|
||||
{
|
||||
ss_dassert(service == NULL || monitor == NULL);
|
||||
|
||||
if (service)
|
||||
{
|
||||
serviceRemoveBackend(service, server);
|
||||
service_serialize_servers(service);
|
||||
}
|
||||
else if (monitor)
|
||||
{
|
||||
monitorRemoveServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
}
|
||||
|
||||
const char *target = service ? "service" : "monitor";
|
||||
MXS_NOTICE("Removed server '%s' from %s '%s'", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Removed server '%s' from %s '%s'\n", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Removed server '%s' from '%s'\n", server->unique_name, values[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -983,7 +1008,7 @@ static void createServer(DCB *dcb, char *name, char *address, char *port,
|
||||
|
||||
if (server_find_by_unique_name(name) == NULL)
|
||||
{
|
||||
if (server_create(name, address, port, protocol, authenticator, authenticator_options))
|
||||
if (runtime_create_server(name, address, port, protocol, authenticator, authenticator_options))
|
||||
{
|
||||
dcb_printf(dcb, "Created server '%s'\n", name);
|
||||
}
|
||||
@ -1000,6 +1025,23 @@ static void createServer(DCB *dcb, char *name, char *address, char *port,
|
||||
spinlock_release(&server_mod_lock);
|
||||
}
|
||||
|
||||
static void createListener(DCB *dcb, SERVICE *service, char *name, char *address,
|
||||
char *port, char *protocol, char *authenticator,
|
||||
char *authenticator_options, char *key, char *cert,
|
||||
char *ca, char *version, char *depth)
|
||||
{
|
||||
if (runtime_create_listener(service, name, address, port, protocol,
|
||||
authenticator, authenticator_options,
|
||||
key, cert, ca, version, depth))
|
||||
{
|
||||
dcb_printf(dcb, "Listener '%s' created\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Failed to create listener '%s', see log for more details\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
struct subcommand createoptions[] =
|
||||
{
|
||||
{
|
||||
@ -1019,6 +1061,33 @@ struct subcommand createoptions[] =
|
||||
ARG_TYPE_STRING, ARG_TYPE_STRING
|
||||
}
|
||||
},
|
||||
{
|
||||
"listener", 2, 12, createListener,
|
||||
"Create a new listener for a service",
|
||||
"Usage: create listener SERVICE NAME [HOST] [PORT] [PROTOCOL] [AUTHENTICATOR] [OPTIONS]\n"
|
||||
" [SSL_KEY] [SSL_CERT] [SSL_CA] [SSL_VERSION] [SSL_VERIFY_DEPTH]\n\n"
|
||||
"Create a new server from the following parameters.\n"
|
||||
"SERVICE Service where this listener is added\n"
|
||||
"NAME Listener name\n"
|
||||
"HOST Listener host address (default 0.0.0.0)\n"
|
||||
"PORT Listener port (default 3306)\n"
|
||||
"PROTOCOL Listener protocol (default MySQLClient)\n"
|
||||
"AUTHENTICATOR Authenticator module name (default MySQLAuth)\n"
|
||||
"OPTIONS Options for the authenticator module\n"
|
||||
"SSL_KEY Path to SSL private key\n"
|
||||
"SSL_CERT Path to SSL certificate\n"
|
||||
"SSL_CA Path to CA certificate\n"
|
||||
"SSL_VERSION SSL version (default MAX)\n"
|
||||
"SSL_VERIFY_DEPTH Certificate verification depth\n\n"
|
||||
"The first two parameters are required, the others are optional.\n"
|
||||
"Any of the optional parameters can also have the value 'default'\n"
|
||||
"which will be replaced with the default value.\n",
|
||||
{
|
||||
ARG_TYPE_SERVICE, ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING,
|
||||
ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING,
|
||||
ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING,
|
||||
}
|
||||
},
|
||||
{
|
||||
EMPTY_OPTION
|
||||
}
|
||||
@ -1032,7 +1101,7 @@ static void destroyServer(DCB *dcb, SERVER *server)
|
||||
char name[strlen(server->unique_name) + 1];
|
||||
strcpy(name, server->unique_name);
|
||||
|
||||
if (server_destroy(server))
|
||||
if (runtime_destroy_server(server))
|
||||
{
|
||||
dcb_printf(dcb, "Destroyed server '%s'\n", name);
|
||||
}
|
||||
@ -1042,6 +1111,18 @@ static void destroyServer(DCB *dcb, SERVER *server)
|
||||
}
|
||||
}
|
||||
|
||||
static void destroyListener(DCB *dcb, SERVICE *service, const char *name)
|
||||
{
|
||||
if (runtime_destroy_listener(service, name))
|
||||
{
|
||||
dcb_printf(dcb, "Destroyed listener '%s'\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Failed to destroy listener '%s', see log file for more details\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
struct subcommand destroyoptions[] =
|
||||
{
|
||||
{
|
||||
@ -1050,76 +1131,17 @@ struct subcommand destroyoptions[] =
|
||||
"Usage: destroy server NAME",
|
||||
{ARG_TYPE_SERVER}
|
||||
},
|
||||
{
|
||||
"listener", 2, 2, destroyListener,
|
||||
"Destroy a listener",
|
||||
"Usage: destroy listener SERVICE NAME",
|
||||
{ARG_TYPE_SERVICE, ARG_TYPE_STRING}
|
||||
},
|
||||
{
|
||||
EMPTY_OPTION
|
||||
}
|
||||
};
|
||||
|
||||
static bool handle_alter_server(SERVER *server, char *key, char *value)
|
||||
{
|
||||
bool valid = true;
|
||||
|
||||
if (strcmp(key, "address") == 0)
|
||||
{
|
||||
server_update_address(server, value);
|
||||
}
|
||||
else if (strcmp(key, "port") == 0)
|
||||
{
|
||||
server_update_port(server, atoi(value));
|
||||
}
|
||||
else if (strcmp(key, "monuser") == 0)
|
||||
{
|
||||
server_update_credentials(server, value, server->monpw);
|
||||
}
|
||||
else if (strcmp(key, "monpw") == 0)
|
||||
{
|
||||
server_update_credentials(server, server->monuser, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
void handle_server_ssl(DCB *dcb, SERVER *server, CONFIG_CONTEXT *obj)
|
||||
{
|
||||
if (config_have_required_ssl_params(obj))
|
||||
{
|
||||
int err = 0;
|
||||
SSL_LISTENER *ssl = make_ssl_structure(obj, true, &err);
|
||||
|
||||
if (err == 0 && ssl && listener_init_SSL(ssl) == 0)
|
||||
{
|
||||
/** Sync to prevent reads on partially initialized server_ssl */
|
||||
atomic_synchronize();
|
||||
|
||||
server->server_ssl = ssl;
|
||||
if (server_serialize(server))
|
||||
{
|
||||
dcb_printf(dcb, "SSL enabled for server '%s'\n", server->unique_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "SSL enabled for server '%s' but persisting "
|
||||
"it to disk failed, see log for more details.\n",
|
||||
server->unique_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Enabling SSL for server '%s' failed, see log "
|
||||
"for more details.\n", server->unique_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Error: SSL configuration requires the following parameters:\n"
|
||||
"ssl=required ssl_key=PATH ssl_cert=PATH ssl_ca_cert=PATH\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process multiple alter operations at once
|
||||
*
|
||||
@ -1134,6 +1156,12 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
|
||||
char *values[11] = {v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11};
|
||||
const int items = sizeof(values) / sizeof(values[0]);
|
||||
CONFIG_CONTEXT *obj = NULL;
|
||||
char *ssl_key = NULL;
|
||||
char *ssl_cert = NULL;
|
||||
char *ssl_ca = NULL;
|
||||
char *ssl_version = NULL;
|
||||
char *ssl_depth = NULL;
|
||||
bool enable = false;
|
||||
|
||||
for (int i = 0; i < items && values[i]; i++)
|
||||
{
|
||||
@ -1146,19 +1174,33 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
|
||||
|
||||
if (config_is_ssl_parameter(key))
|
||||
{
|
||||
/**
|
||||
* All the required SSL parameters must be defined at once to
|
||||
* enable SSL for created servers. This removes the problem
|
||||
* of partial configuration and allows a somewhat atomic
|
||||
* operation.
|
||||
*/
|
||||
if ((obj == NULL && (obj = config_context_create(server->unique_name)) == NULL) ||
|
||||
(!config_add_param(obj, key, value)))
|
||||
if (strcmp("ssl_cert", key) == 0)
|
||||
{
|
||||
dcb_printf(dcb, "Internal error, see log for more details\n");
|
||||
ssl_cert = value;
|
||||
}
|
||||
else if (strcmp("ssl_ca_cert", key) == 0)
|
||||
{
|
||||
ssl_ca = value;
|
||||
}
|
||||
else if (strcmp("ssl_key", key) == 0)
|
||||
{
|
||||
ssl_key = value;
|
||||
}
|
||||
else if (strcmp("ssl_version", key) == 0)
|
||||
{
|
||||
ssl_version = value;
|
||||
}
|
||||
else if (strcmp("ssl_cert_verify_depth", key) == 0)
|
||||
{
|
||||
ssl_depth = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
enable = strcmp("ssl", key) == 0 && strcmp(value, "required") == 0;
|
||||
/** Must be 'ssl' */
|
||||
}
|
||||
}
|
||||
else if (!handle_alter_server(server, key, value))
|
||||
else if (!runtime_alter_server(server, key, value))
|
||||
{
|
||||
dcb_printf(dcb, "Error: Bad key-value parameter: %s=%s\n", key, value);
|
||||
}
|
||||
@ -1169,87 +1211,24 @@ static void alterServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3,
|
||||
}
|
||||
}
|
||||
|
||||
if (obj)
|
||||
if (enable || ssl_key || ssl_cert || ssl_ca)
|
||||
{
|
||||
/** We have SSL parameters, try to process them */
|
||||
handle_server_ssl(dcb, server, obj);
|
||||
config_context_free(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a string value to a positive integer
|
||||
*
|
||||
* If the value is not a positive integer, an error is printed to @c dcb.
|
||||
*
|
||||
* @param value String value
|
||||
* @return 0 on error, otherwise a positive integer
|
||||
*/
|
||||
static long get_positive_int(const char *value)
|
||||
{
|
||||
char *endptr;
|
||||
long ival = strtol(value, &endptr, 10);
|
||||
|
||||
if (*endptr == '\0' && ival > 0)
|
||||
{
|
||||
return ival;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool handle_alter_monitor(MONITOR *monitor, char *key, char *value)
|
||||
{
|
||||
bool valid = false;
|
||||
|
||||
if (strcmp(key, "user") == 0)
|
||||
{
|
||||
valid = true;
|
||||
monitorAddUser(monitor, value, monitor->password);
|
||||
}
|
||||
else if (strcmp(key, "password") == 0)
|
||||
{
|
||||
valid = true;
|
||||
monitorAddUser(monitor, monitor->user, value);
|
||||
}
|
||||
else if (strcmp(key, "monitor_interval") == 0)
|
||||
{
|
||||
long ival = get_positive_int(value);
|
||||
if (ival)
|
||||
if (enable && ssl_key && ssl_cert && ssl_ca)
|
||||
{
|
||||
valid = true;
|
||||
monitorSetInterval(monitor, ival);
|
||||
/** We have SSL parameters, try to process them */
|
||||
if (!runtime_enable_server_ssl(server, ssl_key, ssl_cert, ssl_ca,
|
||||
ssl_version, ssl_depth))
|
||||
{
|
||||
dcb_printf(dcb, "Enabling SSL for server '%s' failed, see log "
|
||||
"for more details.\n", server->unique_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Error: SSL configuration requires the following parameters:\n"
|
||||
"ssl=required ssl_key=PATH ssl_cert=PATH ssl_ca_cert=PATH\n");
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "backend_connect_timeout") == 0)
|
||||
{
|
||||
long ival = get_positive_int(value);
|
||||
if (ival)
|
||||
{
|
||||
valid = true;
|
||||
monitorSetNetworkTimeout(monitor, MONITOR_CONNECT_TIMEOUT, ival);
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "backend_write_timeout") == 0)
|
||||
{
|
||||
long ival = get_positive_int(value);
|
||||
if (ival)
|
||||
{
|
||||
valid = true;
|
||||
monitorSetNetworkTimeout(monitor, MONITOR_WRITE_TIMEOUT, ival);
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "backend_read_timeout") == 0)
|
||||
{
|
||||
long ival = get_positive_int(value);
|
||||
if (ival)
|
||||
{
|
||||
valid = true;
|
||||
monitorSetNetworkTimeout(monitor, MONITOR_READ_TIMEOUT, ival);
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
static void alterMonitor(DCB *dcb, MONITOR *monitor, char *v1, char *v2, char *v3,
|
||||
@ -1268,7 +1247,7 @@ static void alterMonitor(DCB *dcb, MONITOR *monitor, char *v1, char *v2, char *v
|
||||
{
|
||||
*value++ = '\0';
|
||||
|
||||
if (!handle_alter_monitor(monitor, key, value))
|
||||
if (!runtime_alter_monitor(monitor, key, value))
|
||||
{
|
||||
dcb_printf(dcb, "Error: Bad key-value parameter: %s=%s\n", key, value);
|
||||
}
|
||||
@ -1311,6 +1290,78 @@ struct subcommand alteroptions[] =
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool requires_output_dcb(const MODULECMD *cmd)
|
||||
{
|
||||
modulecmd_arg_type_t *type = &cmd->arg_types[0];
|
||||
return cmd->arg_count_max > 0 && MODULECMD_GET_TYPE(type) == MODULECMD_ARG_OUTPUT;
|
||||
}
|
||||
|
||||
static void callFunction(DCB *dcb, char *domain, char *id, char *v3,
|
||||
char *v4, char *v5, char *v6, char *v7, char *v8, char *v9,
|
||||
char *v10, char *v11, char *v12)
|
||||
{
|
||||
const void *values[11] = {v3, v4, v5, v6, v7, v8, v9, v10, v11, v12};
|
||||
const int valuelen = sizeof(values) / sizeof(values[0]);
|
||||
int numargs = 0;
|
||||
|
||||
while (numargs < valuelen && values[numargs])
|
||||
{
|
||||
numargs++;
|
||||
}
|
||||
|
||||
const MODULECMD *cmd = modulecmd_find_command(domain, id);
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
if (requires_output_dcb(cmd))
|
||||
{
|
||||
/** The function requires a DCB for output, add the client DCB
|
||||
* as the first argument */
|
||||
for (int i = valuelen - 1; i > 0; i--)
|
||||
{
|
||||
values[i] = values[i - 1];
|
||||
}
|
||||
values[0] = dcb;
|
||||
numargs += numargs + 1 < valuelen - 1 ? 1 : 0;
|
||||
}
|
||||
|
||||
MODULECMD_ARG *arg = modulecmd_arg_parse(cmd, numargs, values);
|
||||
|
||||
if (arg)
|
||||
{
|
||||
if (!modulecmd_call_command(cmd, arg))
|
||||
{
|
||||
dcb_printf(dcb, "Failed to call function: %s\n", modulecmd_get_error());
|
||||
}
|
||||
modulecmd_arg_free(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Failed to parse arguments: %s\n", modulecmd_get_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "Function not found: %s\n", modulecmd_get_error());
|
||||
}
|
||||
}
|
||||
|
||||
struct subcommand calloptions[] =
|
||||
{
|
||||
{
|
||||
"function", 2, 12, callFunction,
|
||||
"Call module function",
|
||||
"Usage: call function NAMESPACE FUNCTION ARGS...\n"
|
||||
"To list all registered functions, run 'list functions'.\n",
|
||||
{ ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING,
|
||||
ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING,
|
||||
ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING, ARG_TYPE_STRING}
|
||||
},
|
||||
{
|
||||
EMPTY_OPTION
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The debug command table
|
||||
*/
|
||||
@ -1335,7 +1386,8 @@ static struct
|
||||
{ "restart", restartoptions },
|
||||
{ "shutdown", shutdownoptions },
|
||||
{ "show", showoptions },
|
||||
{ "sync", syncoptions },
|
||||
{ "sync", syncoptions },
|
||||
{ "call", calloptions },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@ -1457,7 +1509,7 @@ execute_cmd(CLI_SESSION *cli)
|
||||
args[0] = cli->cmdbuf;
|
||||
ptr = args[0];
|
||||
lptr = ptr;
|
||||
i = 0;
|
||||
i = 1;
|
||||
/*
|
||||
* Break the command line into a number of words. Whitespace is used
|
||||
* to delimit words and may be escaped by use of the \ character or
|
||||
@ -1465,7 +1517,7 @@ execute_cmd(CLI_SESSION *cli)
|
||||
* The array args contains the broken down words, one per index.
|
||||
*/
|
||||
|
||||
while (*ptr)
|
||||
while (*ptr && i <= MAXARGS + 2)
|
||||
{
|
||||
if (escape_next)
|
||||
{
|
||||
@ -1489,19 +1541,7 @@ execute_cmd(CLI_SESSION *cli)
|
||||
break;
|
||||
}
|
||||
|
||||
if (args[i] == ptr)
|
||||
{
|
||||
args[i] = ptr + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
if (i >= MAXARGS - 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
args[i] = ptr + 1;
|
||||
}
|
||||
args[i++] = ptr + 1;
|
||||
ptr++;
|
||||
lptr++;
|
||||
}
|
||||
@ -1523,14 +1563,13 @@ execute_cmd(CLI_SESSION *cli)
|
||||
}
|
||||
}
|
||||
*lptr = 0;
|
||||
args[MXS_MIN(MAXARGS - 1, i + 1)] = NULL;
|
||||
args[i] = NULL;
|
||||
|
||||
if (args[0] == NULL || *args[0] == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; args[i] && *args[i]; i++)
|
||||
;
|
||||
|
||||
argc = i - 2; /* The number of extra arguments to commands */
|
||||
|
||||
if (!strcasecmp(args[0], "help"))
|
||||
@ -1571,7 +1610,7 @@ execute_cmd(CLI_SESSION *cli)
|
||||
dcb_printf(dcb, "Available options to the %s command:\n", args[1]);
|
||||
for (j = 0; cmds[i].options[j].arg1; j++)
|
||||
{
|
||||
dcb_printf(dcb, "'%s' - %s\n\n\t%s\n\n", cmds[i].options[j].arg1,
|
||||
dcb_printf(dcb, "'%s' - %s\n\n%s\n\n", cmds[i].options[j].arg1,
|
||||
cmds[i].options[j].help, cmds[i].options[j].devhelp);
|
||||
|
||||
}
|
||||
@ -1755,7 +1794,7 @@ shutdown_service(DCB *dcb, SERVICE *service)
|
||||
static void
|
||||
restart_service(DCB *dcb, SERVICE *service)
|
||||
{
|
||||
serviceRestart(service);
|
||||
serviceStart(service);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -422,7 +422,8 @@ getCapabilities(void)
|
||||
static int
|
||||
maxinfo_statistics(INFO_INSTANCE *router, INFO_SESSION *session, GWBUF *queue)
|
||||
{
|
||||
char result[1000], *ptr;
|
||||
char result[1000];
|
||||
uint8_t *ptr;
|
||||
GWBUF *ret;
|
||||
int len;
|
||||
|
||||
@ -456,7 +457,7 @@ maxinfo_statistics(INFO_INSTANCE *router, INFO_SESSION *session, GWBUF *queue)
|
||||
static int
|
||||
maxinfo_ping(INFO_INSTANCE *router, INFO_SESSION *session, GWBUF *queue)
|
||||
{
|
||||
char *ptr;
|
||||
uint8_t *ptr;
|
||||
GWBUF *ret;
|
||||
int len;
|
||||
|
||||
|
||||
@ -694,7 +694,7 @@ void exec_restart_service(DCB *dcb, MAXINFO_TREE *tree)
|
||||
SERVICE* service = service_find(tree->value);
|
||||
if (service)
|
||||
{
|
||||
serviceRestart(service);
|
||||
serviceStart(service);
|
||||
maxinfo_send_ok(dcb);
|
||||
}
|
||||
else
|
||||
|
||||
@ -780,6 +780,8 @@ route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
|
||||
else if (!trx_active && !load_active &&
|
||||
!qc_query_is_type(qtype, QUERY_TYPE_MASTER_READ) &&
|
||||
!qc_query_is_type(qtype, QUERY_TYPE_WRITE) &&
|
||||
!qc_query_is_type(qtype, QUERY_TYPE_PREPARE_STMT) &&
|
||||
!qc_query_is_type(qtype, QUERY_TYPE_PREPARE_NAMED_STMT) &&
|
||||
(qc_query_is_type(qtype, QUERY_TYPE_READ) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_USERVAR_READ) ||
|
||||
|
||||
@ -327,7 +327,7 @@ bool check_for_multi_stmt(GWBUF *buf, void *protocol, mysql_server_cmd_t packet_
|
||||
if (proto->client_capabilities & GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS &&
|
||||
packet_type == MYSQL_COM_QUERY)
|
||||
{
|
||||
char *ptr, *data = GWBUF_DATA(buf) + 5;
|
||||
char *ptr, *data = (char*)GWBUF_DATA(buf) + 5;
|
||||
/** Payload size without command byte */
|
||||
int buflen = gw_mysql_get_byte3((uint8_t *)GWBUF_DATA(buf)) - 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user