Add new parameter type MXS_MODULE_PARAM_SERVERLIST
This is a list of servers, separated by commas. When queried as a config setting, returns a null-terminated array of SERVER*:s. The commit includes a serverlist parsing function, which should probably be used anywhere a similarly formed string is parsed.
This commit is contained in:
parent
dd82c46596
commit
3129efb3f7
@ -205,6 +205,17 @@ struct service* config_get_service(const MXS_CONFIG_PARAMETER *params, const cha
|
||||
*/
|
||||
struct server* config_get_server(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
|
||||
/**
|
||||
* @brief Get an array of servers. The caller should free the returned array, but not
|
||||
* the array elements.
|
||||
*
|
||||
* @param params List of configuration parameters
|
||||
* @param key Parameter name
|
||||
*
|
||||
* @return Pointer to a null-terminated array of servers, or null if none found.
|
||||
*/
|
||||
struct server** config_get_serverlist(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
|
||||
/**
|
||||
* @brief Get copy of parameter value if it is defined
|
||||
*
|
||||
|
@ -79,6 +79,7 @@ enum mxs_module_param_type
|
||||
MXS_MODULE_PARAM_PATH, /**< Path to a file or a directory */
|
||||
MXS_MODULE_PARAM_SERVICE, /**< Service name */
|
||||
MXS_MODULE_PARAM_SERVER, /**< Server name */
|
||||
MXS_MODULE_PARAM_SERVERLIST /**< List of server names, separated by ',' */
|
||||
};
|
||||
|
||||
/** Maximum and minimum values for integer types */
|
||||
|
@ -256,6 +256,7 @@ bool server_remove_parameter(SERVER *server, const char *name);
|
||||
|
||||
extern int server_free(SERVER *server);
|
||||
extern SERVER *server_find_by_unique_name(const char *name);
|
||||
extern SERVER** server_find_by_unique_names(char **server_names, int size);
|
||||
extern SERVER *server_find(const char *servname, unsigned short port);
|
||||
extern char *server_status(const SERVER *);
|
||||
extern void server_clear_set_status(SERVER *server, int specified_bits, int bits_to_set);
|
||||
|
@ -1057,6 +1057,24 @@ SERVER* config_get_server(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||
return server_find_by_unique_name(value);
|
||||
}
|
||||
|
||||
SERVER** config_get_serverlist(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||
{
|
||||
const char *value = config_get_value_string(params, key);
|
||||
char **server_names = NULL;
|
||||
SERVER **servers = NULL;
|
||||
int n_names = config_parse_server_list(value, &server_names);
|
||||
if (n_names > 0)
|
||||
{
|
||||
servers = server_find_by_unique_names(server_names, n_names);
|
||||
for (int i = 0; i < n_names; i++)
|
||||
{
|
||||
MXS_FREE(server_names[i]);
|
||||
}
|
||||
MXS_FREE(server_names);
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
char* config_copy_string(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||
{
|
||||
const char *value = config_get_value_string(params, key);
|
||||
@ -3413,6 +3431,30 @@ bool config_param_is_valid(const MXS_MODULE_PARAM *params, const char *key,
|
||||
}
|
||||
break;
|
||||
|
||||
case MXS_MODULE_PARAM_SERVERLIST:
|
||||
if (context)
|
||||
{
|
||||
valid = true;
|
||||
char **server_names = NULL;
|
||||
int n_serv = config_parse_server_list(value, &server_names);
|
||||
if (n_serv > 0)
|
||||
{
|
||||
/* Check that every server name in the list is found in the config. */
|
||||
for (int i = 0; i < n_serv; i++)
|
||||
{
|
||||
if (valid &&
|
||||
!config_contains_type(context, server_names[i], "server"))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
MXS_FREE(server_names[i]);
|
||||
}
|
||||
MXS_FREE(server_names);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MXS_MODULE_PARAM_PATH:
|
||||
valid = check_path_parameter(¶ms[i], value);
|
||||
break;
|
||||
@ -3427,3 +3469,70 @@ bool config_param_is_valid(const MXS_MODULE_PARAM *params, const char *key,
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
static int config_parse_server_list(const char *servers, char ***output_array)
|
||||
{
|
||||
ss_dassert(servers);
|
||||
|
||||
/* First, check the string for the maximum amount of servers it
|
||||
* might contain by counting the commas. */
|
||||
int out_arr_size = 1;
|
||||
const char *pos = servers;
|
||||
while ((pos = strchr(pos, ',')) != NULL)
|
||||
{
|
||||
pos++;
|
||||
out_arr_size++;
|
||||
}
|
||||
char **results = MXS_CALLOC(out_arr_size, sizeof(char*));
|
||||
if (!results)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse the server names from the list. They are separated by ',' and will
|
||||
* be trimmed of whitespace. */
|
||||
char srv_list_tmp[strlen(servers) + 1];
|
||||
strcpy(srv_list_tmp, servers);
|
||||
trim(srv_list_tmp);
|
||||
|
||||
bool error = false;
|
||||
int output_ind = 0;
|
||||
char *lasts;
|
||||
char *s = strtok_r(srv_list_tmp, ",", &lasts);
|
||||
while (s)
|
||||
{
|
||||
char srv_name_tmp[strlen(s) + 1];
|
||||
strcpy(srv_name_tmp, s);
|
||||
trim(srv_name_tmp);
|
||||
if (strlen(srv_name_tmp) > 0)
|
||||
{
|
||||
results[output_ind] = MXS_STRDUP(srv_name_tmp);
|
||||
if (!results[output_ind])
|
||||
{
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
output_ind++;
|
||||
}
|
||||
s = strtok_r(NULL, ",", &lasts);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
int i = 0;
|
||||
while (results[i])
|
||||
{
|
||||
MXS_FREE(results[i]);
|
||||
i++;
|
||||
}
|
||||
output_ind = 0;
|
||||
}
|
||||
|
||||
if (output_ind == 0)
|
||||
{
|
||||
MXS_FREE(results);
|
||||
results = NULL;
|
||||
}
|
||||
*output_array = results;
|
||||
return output_ind;
|
||||
}
|
||||
|
@ -111,4 +111,15 @@ SSL_LISTENER *make_ssl_structure(CONFIG_CONTEXT *obj, bool require_cert, int *er
|
||||
*/
|
||||
bool config_have_required_ssl_params(CONFIG_CONTEXT *obj);
|
||||
|
||||
/**
|
||||
* Parses a list of server names and writes the results in an array of strings
|
||||
* with one server in each. The output array and its elements should be deallocated
|
||||
* by the caller. The server names are not checked to be valid servers.
|
||||
*
|
||||
* @param servers A list of server names.
|
||||
* @param output_array Save location for the array of server names. Set to null if none found.
|
||||
* @return How many servers were found and set into the array.
|
||||
*/
|
||||
static int config_parse_server_list(const char *servers, char ***output_array);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -296,6 +296,41 @@ SERVER * server_find_by_unique_name(const char *name)
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find several servers with the names specified in an array with a given size.
|
||||
* The returned array (but not the elements) should be freed by the caller, and
|
||||
* is null-terminated.
|
||||
*
|
||||
* @param servers An array of server names
|
||||
* @param size number of elements in the server names array
|
||||
* @return A null-terminated array of SERVERs. May contain less elements than
|
||||
* requested if some server names are not found.
|
||||
*/
|
||||
SERVER** server_find_by_unique_names(char **server_names, int size)
|
||||
{
|
||||
ss_dassert(server_names);
|
||||
|
||||
SERVER **results = MXS_CALLOC(size + 1, sizeof(SERVER*)); // +1 for null
|
||||
if (!results)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int res_ind = 0;
|
||||
for (int i = 0; server_names[i] != NULL; i++)
|
||||
{
|
||||
SERVER *serv = server_find_by_unique_name(server_names[i]);
|
||||
if (serv)
|
||||
{
|
||||
results[res_ind] = serv;
|
||||
res_ind++;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an existing server
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user