config.c: Added configuration parameter processing for read_ses_variables_from_slaves and for write_ses_variables_to_all . The values are read from config file, qualified and stored to service. Values are loaded when instance is created. This is limitation in current implementation and will change so that configuration is dynamically changeable.
This commit is contained in:
parent
d799331c50
commit
92889ad216
@ -247,18 +247,28 @@ int error_count = 0;
|
||||
{
|
||||
char* max_slave_conn_str;
|
||||
char* max_slave_rlag_str;
|
||||
char *user;
|
||||
char *auth;
|
||||
char *enable_root_user;
|
||||
char *weightby;
|
||||
char *version_string;
|
||||
bool is_rwsplit = false;
|
||||
|
||||
obj->element = service_alloc(obj->object, router);
|
||||
char *user =
|
||||
config_get_value(obj->parameters, "user");
|
||||
char *auth =
|
||||
config_get_value(obj->parameters, "passwd");
|
||||
char *enable_root_user =
|
||||
config_get_value(obj->parameters, "enable_root_user");
|
||||
char *weightby =
|
||||
config_get_value(obj->parameters, "weightby");
|
||||
user = config_get_value(obj->parameters, "user");
|
||||
auth = config_get_value(obj->parameters, "passwd");
|
||||
enable_root_user = config_get_value(
|
||||
obj->parameters,
|
||||
"enable_root_user");
|
||||
weightby = config_get_value(obj->parameters, "weightby");
|
||||
|
||||
char *version_string = config_get_value(obj->parameters, "version_string");
|
||||
version_string = config_get_value(obj->parameters,
|
||||
"version_string");
|
||||
/** flag for rwsplit-specific parameters */
|
||||
if (strncmp(router, "readwritesplit", strlen("readwritesplit")+1) == 0)
|
||||
{
|
||||
is_rwsplit = true;
|
||||
}
|
||||
|
||||
if (obj->element == NULL) /*< if module load failed */
|
||||
{
|
||||
@ -374,7 +384,71 @@ int error_count = 0;
|
||||
param->value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Parameters for rwsplit router only */
|
||||
if (is_rwsplit)
|
||||
{
|
||||
CONFIG_PARAMETER* param;
|
||||
char* write_sesvars_to_all;
|
||||
char* read_sesvars_from_slaves;
|
||||
bool succp;
|
||||
|
||||
write_sesvars_to_all =
|
||||
config_get_value(obj->parameters,
|
||||
"write_ses_variables_to_all");
|
||||
|
||||
if (write_sesvars_to_all != NULL)
|
||||
{
|
||||
param = config_get_param(
|
||||
obj->parameters,
|
||||
"write_ses_variables_to_all");
|
||||
succp = service_set_param_value(obj->element,
|
||||
param,
|
||||
write_sesvars_to_all,
|
||||
COUNT_NONE,
|
||||
BOOL_TYPE);
|
||||
if (!succp)
|
||||
{
|
||||
LOGIF(LM, (skygw_log_write(
|
||||
LOGFILE_MESSAGE,
|
||||
"* Warning : invalid value type "
|
||||
"for parameter \'%s.%s = %s\'\n\tExpected "
|
||||
"type is <true/false> for write session "
|
||||
"variables to all backends.",
|
||||
((SERVICE*)obj->element)->name,
|
||||
param->name,
|
||||
param->value)));
|
||||
}
|
||||
}
|
||||
read_sesvars_from_slaves =
|
||||
config_get_value(
|
||||
obj->parameters,
|
||||
"read_ses_variables_from_slaves");
|
||||
|
||||
if (read_sesvars_from_slaves != NULL)
|
||||
{
|
||||
param = config_get_param(
|
||||
obj->parameters,
|
||||
"read_ses_variables_from_slaves");
|
||||
succp = service_set_param_value(obj->element,
|
||||
param,
|
||||
read_sesvars_from_slaves,
|
||||
COUNT_NONE,
|
||||
BOOL_TYPE);
|
||||
if (!succp)
|
||||
{
|
||||
LOGIF(LM, (skygw_log_write(
|
||||
LOGFILE_MESSAGE,
|
||||
"* Warning : invalid value type "
|
||||
"for parameter \'%s.%s = %s\'\n\tExpected "
|
||||
"type is <true/false> for write session "
|
||||
"variables to all backends.",
|
||||
((SERVICE*)obj->element)->name,
|
||||
param->name,
|
||||
param->value)));
|
||||
}
|
||||
}
|
||||
} /*< if (rw_split) */
|
||||
} /*< if (router) */
|
||||
else
|
||||
{
|
||||
obj->element = NULL;
|
||||
@ -1320,6 +1394,8 @@ static char *service_params[] =
|
||||
"enable_root_user",
|
||||
"max_slave_connections",
|
||||
"max_slave_replication_lag",
|
||||
"write_ses_variables_to_all", /*< rwsplit only */
|
||||
"read_ses_variables_from_slaves", /*< rwsplit only */
|
||||
"version_string",
|
||||
"filters",
|
||||
NULL
|
||||
|
@ -52,12 +52,26 @@
|
||||
#include <poll.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#include <../../../mariadb-5.5.30/include/ft_global.h>
|
||||
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
/** To be used with configuration type checks */
|
||||
typedef struct typelib_st {
|
||||
int tl_nelems;
|
||||
const char* tl_name;
|
||||
const char** tl_p_elems;
|
||||
} typelib_t;
|
||||
|
||||
static const char* bool_strings[9]= {"FALSE", "TRUE", "OFF", "ON", "N", "Y", "0", "1", "NO", "YES", 0};
|
||||
typelib_t bool_typelib = {array_nelems(bool_strings)-1, "bool_typelib", bool_strings};
|
||||
|
||||
static SPINLOCK service_spin = SPINLOCK_INIT;
|
||||
static SERVICE *allServices = NULL;
|
||||
|
||||
static int find_type(typelib_t* tl, const char* needle, int maxlen);
|
||||
|
||||
static void service_add_qualified_param(
|
||||
SERVICE* svc,
|
||||
CONFIG_PARAMETER* param);
|
||||
@ -1009,76 +1023,141 @@ bool service_set_param_value (
|
||||
{
|
||||
char* p;
|
||||
int valint;
|
||||
bool succp = true;
|
||||
|
||||
/**
|
||||
* Find out whether the value is numeric and ends with '%' or '\0'
|
||||
*/
|
||||
p = valstr;
|
||||
|
||||
while(isdigit(*p)) p++;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (p == valstr || (*p != '%' && *p != '\0'))
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
else if (*p == '%')
|
||||
{
|
||||
if (*(p+1) == '\0')
|
||||
{
|
||||
*p = '\0';
|
||||
valint = (int) strtol(valstr, (char **)NULL, 10);
|
||||
|
||||
if (valint == 0 && errno != 0)
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
else if (PARAM_IS_TYPE(type,PERCENT_TYPE))
|
||||
{
|
||||
succp = true;
|
||||
config_set_qualified_param(param, (void *)&valint, PERCENT_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Log error */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
}
|
||||
else if (*p == '\0')
|
||||
{
|
||||
valint = (int) strtol(valstr, (char **)NULL, 10);
|
||||
bool valbool;
|
||||
bool succp = true;
|
||||
|
||||
if (valint == 0 && errno != 0)
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
else if (PARAM_IS_TYPE(type,COUNT_TYPE))
|
||||
{
|
||||
succp = true;
|
||||
config_set_qualified_param(param, (void *)&valint, COUNT_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Log error */
|
||||
}
|
||||
}
|
||||
|
||||
if (type == PERCENT_TYPE || type == COUNT_TYPE)
|
||||
{
|
||||
/**
|
||||
* Find out whether the value is numeric and ends with '%' or '\0'
|
||||
*/
|
||||
p = valstr;
|
||||
|
||||
while(isdigit(*p)) p++;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (p == valstr || (*p != '%' && *p != '\0'))
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
else if (*p == '%')
|
||||
{
|
||||
if (*(p+1) == '\0')
|
||||
{
|
||||
*p = '\0';
|
||||
valint = (int) strtol(valstr, (char **)NULL, 10);
|
||||
|
||||
if (valint == 0 && errno != 0)
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
else if (PARAM_IS_TYPE(type,PERCENT_TYPE))
|
||||
{
|
||||
succp = true;
|
||||
config_set_qualified_param(param, (void *)&valint, PERCENT_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Log error */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
}
|
||||
else if (*p == '\0')
|
||||
{
|
||||
valint = (int) strtol(valstr, (char **)NULL, 10);
|
||||
|
||||
if (valint == 0 && errno != 0)
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
else if (PARAM_IS_TYPE(type,COUNT_TYPE))
|
||||
{
|
||||
succp = true;
|
||||
config_set_qualified_param(param, (void *)&valint, COUNT_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Log error */
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == BOOL_TYPE)
|
||||
{
|
||||
unsigned int rc;
|
||||
|
||||
rc = find_type(&bool_typelib, valstr, strlen(valstr)+1);
|
||||
|
||||
if (rc > 0)
|
||||
{
|
||||
succp = true;
|
||||
if (rc%2 == 1)
|
||||
{
|
||||
valbool = false;
|
||||
}
|
||||
else if (rc%2 == 0)
|
||||
{
|
||||
valbool = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
}
|
||||
if (succp)
|
||||
{
|
||||
service_add_qualified_param(service, param); /*< add param to svc */
|
||||
config_set_qualified_param(param, (void *)&valbool, BOOL_TYPE); /*< add param to config */
|
||||
}
|
||||
return succp;
|
||||
}
|
||||
/*
|
||||
* Function to find a string in typelib_t
|
||||
* (similar to find_type() of mysys/typelib.c)
|
||||
*
|
||||
* SYNOPSIS
|
||||
* find_type()
|
||||
* lib typelib_t
|
||||
* find String to find
|
||||
* length Length of string to find
|
||||
* part_match Allow part matching of value
|
||||
*
|
||||
* RETURN
|
||||
* 0 error
|
||||
* > 0 position in TYPELIB->type_names +1
|
||||
*/
|
||||
|
||||
static int find_type(
|
||||
typelib_t* tl,
|
||||
const char* needle,
|
||||
int maxlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tl == NULL || needle == NULL || maxlen <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i<tl->tl_nelems; i++)
|
||||
{
|
||||
if (strncasecmp(tl->tl_p_elems[i], needle, maxlen) == 0)
|
||||
{
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add qualified config parameter to SERVICE struct.
|
||||
*/
|
||||
*/
|
||||
static void service_add_qualified_param(
|
||||
SERVICE* svc,
|
||||
CONFIG_PARAMETER* param)
|
||||
|
@ -135,7 +135,7 @@ typedef struct service {
|
||||
struct service *next; /**< The next service in the linked list */
|
||||
} SERVICE;
|
||||
|
||||
typedef enum count_spec_t {COUNT_ATLEAST=0, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
|
||||
typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
|
||||
|
||||
#define SERVICE_STATE_ALLOC 1 /**< The service has been allocated */
|
||||
#define SERVICE_STATE_STARTED 2 /**< The service has been started */
|
||||
|
@ -118,6 +118,8 @@ typedef enum select_criteria {
|
||||
/** default values for rwsplit configuration parameters */
|
||||
#define CONFIG_MAX_SLAVE_CONN 1
|
||||
#define CONFIG_MAX_SLAVE_RLAG -1 /*< not used */
|
||||
#define CONFIG_READ_SESVARS_FROM_SLAVES false
|
||||
#define CONFIG_WRITE_SESVARS_TO_ALL false
|
||||
|
||||
#define GET_SELECT_CRITERIA(s) \
|
||||
(strncmp(s,"LEAST_GLOBAL_CONNECTIONS", strlen("LEAST_GLOBAL_CONNECTIONS")) == 0 ? \
|
||||
@ -232,6 +234,11 @@ typedef struct rwsplit_config_st {
|
||||
int rw_max_slave_conn_count;
|
||||
select_criteria_t rw_slave_select_criteria;
|
||||
int rw_max_slave_replication_lag;
|
||||
/** Route user- & system variable writes to all backends */
|
||||
bool rw_write_sesvars_to_all;
|
||||
/** Route queries including user- & system variables to slaves */
|
||||
bool rw_read_sesvars_from_slaves;
|
||||
|
||||
} rwsplit_config_t;
|
||||
|
||||
|
||||
|
@ -637,6 +637,21 @@ createInstance(SERVICE *service, char **options)
|
||||
refreshInstance(router, param);
|
||||
}
|
||||
router->rwsplit_version = service->svc_config_version;
|
||||
/** Set default values */
|
||||
router->rwsplit_config.rw_read_sesvars_from_slaves = CONFIG_READ_SESVARS_FROM_SLAVES;
|
||||
router->rwsplit_config.rw_write_sesvars_to_all = CONFIG_WRITE_SESVARS_TO_ALL;
|
||||
param = config_get_param(service->svc_config_param, "read_ses_variables_from_slaves");
|
||||
|
||||
if (param != NULL)
|
||||
{
|
||||
refreshInstance(router, param);
|
||||
}
|
||||
param = config_get_param(service->svc_config_param, "write_ses_variables_to_all");
|
||||
|
||||
if (param != NULL)
|
||||
{
|
||||
refreshInstance(router, param);
|
||||
}
|
||||
/**
|
||||
* We have completed the creation of the router data, so now
|
||||
* insert this router into the linked list of routers
|
||||
|
Loading…
x
Reference in New Issue
Block a user