Persist changes to the list of monitored servers

When a server is added to a monitor, an supplementary configuration file
is generated to persist this information. This will allow dynamic
modifications to server lists which will survive restarts and unexpected
downtime.

The monitor will only add new servers to its list of monitored
servers. This prevents duplicate entries in the list and makes it safe to
persist all used servers to the supplementary configuration file instead of only the ones that are not listed in the main configuration.
This commit is contained in:
Markus Makela
2016-11-12 21:55:42 +02:00
parent a651eff633
commit a17aa28eed
4 changed files with 214 additions and 32 deletions

View File

@ -561,6 +561,47 @@ static bool is_directory(const char *dir)
return rval;
}
/**
* @brief Check if a directory contains .cnf files
*
* @param path Path to a directory
* @return True if the directory contained one or more .cnf files
*/
static bool contains_cnf_files(const char *path)
{
bool rval = false;
glob_t matches;
const char suffix[] = "/*.cnf";
char pattern[strlen(path) + sizeof(suffix)];
strcpy(pattern, path);
strcat(pattern, suffix);
int rc = glob(pattern, GLOB_NOSORT, NULL, &matches);
switch (rc)
{
case 0:
rval = true;
break;
case GLOB_NOSPACE:
MXS_OOM();
break;
case GLOB_ABORTED:
MXS_ERROR("Failed to read directory '%s'", path);
break;
default:
ss_dassert(rc == GLOB_NOMATCH);
break;
}
globfree(&matches);
return rval;
}
/**
* @brief Load the specified configuration file for MaxScale
*
@ -605,7 +646,23 @@ config_load_and_process(const char* filename, bool (*process_config)(CONFIG_CONT
if (is_directory(persist_cnf))
{
rval = config_load_dir(persist_cnf, &dcontext, &ccontext);
DUPLICATE_CONTEXT p_dcontext;
/**
* We need to initialize a second duplicate context for the
* generated configuration files as the monitors and services will
* have duplicate sections. The duplicate sections are used to
* store changes to the list of servers the services and monitors
* use, and thus should not be treated as errors.
*/
if (duplicate_context_init(&p_dcontext))
{
rval = config_load_dir(persist_cnf, &p_dcontext, &ccontext);
duplicate_context_finish(&p_dcontext);
}
else
{
rval = false;
}
}
if (rval)
@ -613,6 +670,13 @@ config_load_and_process(const char* filename, bool (*process_config)(CONFIG_CONT
if (!check_config_objects(ccontext.next) || !process_config(ccontext.next))
{
rval = false;
if (contains_cnf_files(persist_cnf))
{
MXS_WARNING("One or more generated configurations were found at '%s'. "
"If the error relates to any of the files located there, "
"remove the offending configurations from this directory.",
persist_cnf);
}
}
}
}