Added validation and parsing for CHANGE MASTER TO
Added validation and parsing for CHANGE MASTER TO
This commit is contained in:
@ -15,7 +15,7 @@
|
|||||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*
|
*
|
||||||
* Copyright MariaDB Corporation Ab 2014
|
* Copyright MariaDB Corporation Ab 2014-2015
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,6 +179,16 @@ typedef struct master_server_config {
|
|||||||
char *filestem;
|
char *filestem;
|
||||||
} MASTER_SERVER_CFG;
|
} MASTER_SERVER_CFG;
|
||||||
|
|
||||||
|
/* Config struct for CHANGE MASTER TO options */
|
||||||
|
typedef struct change_master_options {
|
||||||
|
char *host;
|
||||||
|
char *port;
|
||||||
|
char *binlog_file;
|
||||||
|
char *binlog_pos;
|
||||||
|
char *user;
|
||||||
|
char *password;
|
||||||
|
} CHANGE_MASTER_OPTIONS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packet header for replication messages
|
* Packet header for replication messages
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -47,6 +47,7 @@
|
|||||||
* Call create/use binlog in blr_start_slave() (START SLAVE)
|
* Call create/use binlog in blr_start_slave() (START SLAVE)
|
||||||
* 29/06/2015 Massimiliano Pinto Successfully CHANGE MASTER results in updating master.ini
|
* 29/06/2015 Massimiliano Pinto Successfully CHANGE MASTER results in updating master.ini
|
||||||
* in blr_handle_change_master()
|
* in blr_handle_change_master()
|
||||||
|
* 20/08/2015 Massimiliano Pinto Added parsing and validation for CHANGE MASTER TO
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -107,17 +108,23 @@ static int blr_slave_send_ok(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave);
|
|||||||
static int blr_stop_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave);
|
static int blr_stop_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave);
|
||||||
static int blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave);
|
static int blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave);
|
||||||
static void blr_slave_send_error_packet(ROUTER_SLAVE *slave, char *msg, unsigned int err_num, char *status);
|
static void blr_slave_send_error_packet(ROUTER_SLAVE *slave, char *msg, unsigned int err_num, char *status);
|
||||||
static char *get_change_master_option(char *input, char *option);
|
|
||||||
static int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error);
|
static int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error);
|
||||||
static int blr_set_master_hostname(ROUTER_INSTANCE *router, char *command);
|
static int blr_set_master_hostname(ROUTER_INSTANCE *router, char *hostname);
|
||||||
static int blr_set_master_port(ROUTER_INSTANCE *router, char *command);
|
static int blr_set_master_port(ROUTER_INSTANCE *router, char *command);
|
||||||
static char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *command, char *error);
|
static char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *filename, char *error);
|
||||||
static void blr_master_get_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *current_master);
|
static void blr_master_get_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *current_master);
|
||||||
static void blr_master_free_config(MASTER_SERVER_CFG *current_master);
|
static void blr_master_free_config(MASTER_SERVER_CFG *current_master);
|
||||||
static void blr_master_restore_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *current_master);
|
static void blr_master_restore_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *current_master);
|
||||||
static void blr_master_set_empty_config(ROUTER_INSTANCE *router);
|
static void blr_master_set_empty_config(ROUTER_INSTANCE *router);
|
||||||
static void blr_master_apply_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *prev_master);
|
static void blr_master_apply_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *prev_master);
|
||||||
static int blr_slave_send_ok_message(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave, char *message);
|
static int blr_slave_send_ok_message(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave, char *message);
|
||||||
|
static char *blr_get_parsed_command_value(char *input);
|
||||||
|
static char **blr_validate_change_master_option(char *option, CHANGE_MASTER_OPTIONS *config);
|
||||||
|
static int blr_set_master_user(ROUTER_INSTANCE *router, char *user);
|
||||||
|
static int blr_set_master_password(ROUTER_INSTANCE *router, char *password);
|
||||||
|
static int blr_parse_change_master_command(char *input, char *error_string, CHANGE_MASTER_OPTIONS *config);
|
||||||
|
static int blr_handle_change_master_token(char *input, char *error, CHANGE_MASTER_OPTIONS *config);
|
||||||
|
static void blr_master_free_parsed_options(CHANGE_MASTER_OPTIONS *options);
|
||||||
|
|
||||||
void poll_fake_write_event(DCB *dcb);
|
void poll_fake_write_event(DCB *dcb);
|
||||||
|
|
||||||
@ -724,8 +731,8 @@ extern char *strcasestr();
|
|||||||
if (router->trx_safe && router->pending_transaction) {
|
if (router->trx_safe && router->pending_transaction) {
|
||||||
if (strcmp(router->binlog_name, router->prevbinlog) != 0)
|
if (strcmp(router->binlog_name, router->prevbinlog) != 0)
|
||||||
{
|
{
|
||||||
char message[1024+1] = "";
|
char message[BINLOG_ERROR_MSG_LEN+1] = "";
|
||||||
snprintf(message, 1024, "A transaction is open in current binlog file %s, It will be truncated at pos %lu by next START SLAVE command", current_master->logfile, current_master->safe_pos);
|
snprintf(message, BINLOG_ERROR_MSG_LEN, "A transaction is open in current binlog file %s, It will be truncated at pos %lu by next START SLAVE command", current_master->logfile, current_master->safe_pos);
|
||||||
blr_master_free_config(current_master);
|
blr_master_free_config(current_master);
|
||||||
|
|
||||||
return blr_slave_send_ok_message(router, slave, message);
|
return blr_slave_send_ok_message(router, slave, message);
|
||||||
@ -2590,8 +2597,8 @@ blr_stop_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
|||||||
router->binlog_name, router->current_pos, router->binlog_position)));
|
router->binlog_name, router->current_pos, router->binlog_position)));
|
||||||
|
|
||||||
if (router->trx_safe && router->pending_transaction) {
|
if (router->trx_safe && router->pending_transaction) {
|
||||||
char message[1024+1] = "";
|
char message[BINLOG_ERROR_MSG_LEN+1] = "";
|
||||||
snprintf(message, 1024, "A transaction is open at pos %lu, file %s", router->binlog_position, router->binlog_name);
|
snprintf(message, BINLOG_ERROR_MSG_LEN, "A transaction is open at pos %lu, file %s", router->binlog_position, router->binlog_name);
|
||||||
return blr_slave_send_ok_message(router, slave, message);
|
return blr_slave_send_ok_message(router, slave, message);
|
||||||
} else {
|
} else {
|
||||||
return blr_slave_send_ok(router, slave);
|
return blr_slave_send_ok(router, slave);
|
||||||
@ -2601,8 +2608,8 @@ blr_stop_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
|||||||
/**
|
/**
|
||||||
* Start replication from current configured master
|
* Start replication from current configured master
|
||||||
*
|
*
|
||||||
* @param router The binlog router instance
|
* @param router The binlog router instance
|
||||||
* @param slave The slave server to which we are sending the response
|
* @param slave The slave server to which we are sending the response
|
||||||
* @return Always 1 for error, for send_ok the bytes sent
|
* @return Always 1 for error, for send_ok the bytes sent
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -2634,10 +2641,10 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
|||||||
/* create a new binlog or just use current one */
|
/* create a new binlog or just use current one */
|
||||||
if (strlen(router->prevbinlog) && strcmp(router->prevbinlog, router->binlog_name)) {
|
if (strlen(router->prevbinlog) && strcmp(router->prevbinlog, router->binlog_name)) {
|
||||||
if (router->trx_safe && router->pending_transaction) {
|
if (router->trx_safe && router->pending_transaction) {
|
||||||
char msg[1024+1] = "";
|
char msg[BINLOG_ERROR_MSG_LEN+1] = "";
|
||||||
char file[PATH_MAX+1] = "";
|
char file[PATH_MAX+1] = "";
|
||||||
|
|
||||||
snprintf(msg, 1024, "A transaction is still opened at pos %lu in file %s. Truncating it ... Try START SLAVE again.", router->last_safe_pos, router->prevbinlog);
|
snprintf(msg, BINLOG_ERROR_MSG_LEN, "A transaction is still opened at pos %lu in file %s. Truncating it ... Try START SLAVE again.", router->last_safe_pos, router->prevbinlog);
|
||||||
|
|
||||||
|
|
||||||
/* Truncate previous binlog file to last_safe pos */
|
/* Truncate previous binlog file to last_safe pos */
|
||||||
@ -2773,95 +2780,114 @@ uint8_t mysql_err[2];
|
|||||||
slave->dcb->func.write(slave->dcb, pkt);
|
slave->dcb->func.write(slave->dcb, pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a 'change master to' option
|
|
||||||
*
|
|
||||||
* @param input The current command
|
|
||||||
* @param option_field The option to fetch
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
char *get_change_master_option(char *input, char *option_field) {
|
|
||||||
extern char *strcasestr();
|
|
||||||
char *option = NULL;
|
|
||||||
char *ptr = NULL;
|
|
||||||
char *new_ptr = NULL;
|
|
||||||
ptr = strcasestr(input, option_field);
|
|
||||||
if (ptr) {
|
|
||||||
char *end;
|
|
||||||
option = strdup(ptr);
|
|
||||||
end = strchr(option, ',');
|
|
||||||
if (end)
|
|
||||||
*end = '\0';
|
|
||||||
new_ptr = strdup(option);
|
|
||||||
free(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* handle a 'change master' operation
|
* handle a 'change master' operation
|
||||||
*
|
*
|
||||||
* @param router The router instance
|
* @param router The router instance
|
||||||
* @param command The change master SQL command
|
* @param command The change master SQL command
|
||||||
* @param error The error message, preallocated
|
* @param error The error message, preallocated BINLOG_ERROR_MSG_LEN + 1 bytes
|
||||||
* @return 0 on success, 1 on success with new binlog, -1 on failure
|
* @return 0 on success, 1 on success with new binlog, -1 on failure
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error) {
|
int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error) {
|
||||||
char *master_logfile = NULL;
|
char *master_logfile = NULL;
|
||||||
char *master_log_pos = NULL;
|
char *master_log_pos = NULL;
|
||||||
char *master_user = NULL;
|
|
||||||
char *master_password = NULL;
|
|
||||||
int change_binlog = 0;
|
int change_binlog = 0;
|
||||||
long long pos = 0;
|
long long pos = 0;
|
||||||
char *passed_pos = NULL;
|
|
||||||
MASTER_SERVER_CFG *current_master = NULL;
|
MASTER_SERVER_CFG *current_master = NULL;
|
||||||
|
CHANGE_MASTER_OPTIONS change_master;
|
||||||
|
int parse_ret;
|
||||||
|
char *cmd_ptr;
|
||||||
|
char *cmd_string;
|
||||||
|
|
||||||
|
if ((cmd_ptr = strcasestr(command, "TO")) == NULL) {
|
||||||
|
strncpy(error, "statement doesn't have the CHANGE MASTER TO syntax", BINLOG_ERROR_MSG_LEN);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* save current replication parameters */
|
if ((cmd_string = strdup(cmd_ptr + 2)) == NULL) {
|
||||||
|
strncpy(error, "error allocating memory for statement parsing", BINLOG_ERROR_MSG_LEN);
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse SQL command and populate with found options the change_master struct */
|
||||||
|
memset(&change_master, 0, sizeof(change_master));
|
||||||
|
|
||||||
|
parse_ret = blr_parse_change_master_command(cmd_string, error, &change_master);
|
||||||
|
|
||||||
|
free(cmd_string);
|
||||||
|
|
||||||
|
if (parse_ret) {
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s CHANGE MASTER TO parse error: %s", router->service->name, error)));
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate struct for current replication parameters */
|
||||||
current_master = (MASTER_SERVER_CFG *)calloc(1, sizeof(MASTER_SERVER_CFG));
|
current_master = (MASTER_SERVER_CFG *)calloc(1, sizeof(MASTER_SERVER_CFG));
|
||||||
|
|
||||||
if (!current_master) {
|
if (!current_master) {
|
||||||
strncpy(error, "error allocating memory for blr_master_get_config", BINLOG_ERROR_MSG_LEN);
|
strncpy(error, "error allocating memory for blr_master_get_config", BINLOG_ERROR_MSG_LEN);
|
||||||
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save data */
|
/* save data */
|
||||||
blr_master_get_config(router, current_master);
|
blr_master_get_config(router, current_master);
|
||||||
|
|
||||||
/* fetch new options from SQL command */
|
spinlock_acquire(&router->lock);
|
||||||
master_log_pos = get_change_master_option(command, "MASTER_LOG_POS");
|
|
||||||
master_user = get_change_master_option(command, "MASTER_USER");
|
|
||||||
master_password = get_change_master_option(command, "MASTER_PASSWORD");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change values in the router->service->dbref->server structure
|
* Change values in the router->service->dbref->server structure
|
||||||
* Change filename and position in the router structure
|
* Change filename and position in the router structure
|
||||||
*/
|
*/
|
||||||
spinlock_acquire(&router->lock);
|
|
||||||
|
/* Set new binlog position from parsed SQL command */
|
||||||
|
master_log_pos = change_master.binlog_pos;
|
||||||
|
if (master_log_pos == NULL) {
|
||||||
|
pos = 0;
|
||||||
|
} else {
|
||||||
|
pos = atoll(master_log_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the replication user */
|
||||||
|
blr_set_master_user(router, change_master.user);
|
||||||
|
|
||||||
|
/* Change the replication password */
|
||||||
|
blr_set_master_password(router, change_master.password);
|
||||||
|
|
||||||
/* Change the master name/address */
|
/* Change the master name/address */
|
||||||
blr_set_master_hostname(router, command);
|
blr_set_master_hostname(router, change_master.host);
|
||||||
|
|
||||||
/* Change the master port */
|
/* Change the master port */
|
||||||
blr_set_master_port(router, command);
|
blr_set_master_port(router, change_master.port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the binlog filename to request from master
|
* Change the binlog filename to request from master
|
||||||
* New binlog file could be the next one or current one
|
* New binlog file could be the next one or current one
|
||||||
*/
|
*/
|
||||||
master_logfile = blr_set_master_logfile(router, command, error);
|
master_logfile = blr_set_master_logfile(router, change_master.binlog_file, error);
|
||||||
|
|
||||||
if (master_logfile == NULL && router->master_state == BLRM_UNCONFIGURED) {
|
if (master_logfile == NULL && router->master_state == BLRM_UNCONFIGURED) {
|
||||||
strcpy(error, "Router is not configured for master connection, MASTER_LOG_FILE is required");
|
/* if there is another error message keep it */
|
||||||
|
if (!strlen(error)) {
|
||||||
|
strcpy(error, "Router is not configured for master connection, MASTER_LOG_FILE is required");
|
||||||
|
}
|
||||||
|
|
||||||
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
||||||
|
|
||||||
/* restore previous master_host and master_port */
|
/* restore previous master_host and master_port */
|
||||||
blr_master_restore_config(router, current_master);
|
blr_master_restore_config(router, current_master);
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -2873,7 +2899,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
* set master_logfile to current binlog_name
|
* set master_logfile to current binlog_name
|
||||||
*/
|
*/
|
||||||
if (master_logfile == NULL) {
|
if (master_logfile == NULL) {
|
||||||
/* if errors return */
|
/* if errors returned */
|
||||||
if (strlen(error)) {
|
if (strlen(error)) {
|
||||||
|
|
||||||
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
||||||
@ -2881,6 +2907,8 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
/* restore previous master_host and master_port */
|
/* restore previous master_host and master_port */
|
||||||
blr_master_restore_config(router, current_master);
|
blr_master_restore_config(router, current_master);
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -2892,17 +2920,6 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the position in the current or new binlog filename
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (master_log_pos == NULL) {
|
|
||||||
pos = 0;
|
|
||||||
} else {
|
|
||||||
passed_pos = master_log_pos + 15;
|
|
||||||
pos = atoll(passed_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If master connection is configured check new binlog name:
|
* If master connection is configured check new binlog name:
|
||||||
* If binlog name has changed to next one only position 4 is allowed
|
* If binlog name has changed to next one only position 4 is allowed
|
||||||
@ -2923,7 +2940,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
if (pos != 4) {
|
if (pos != 4) {
|
||||||
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_POS to %s for MASTER_LOG_FILE %s: "
|
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_POS to %s for MASTER_LOG_FILE %s: "
|
||||||
"Permitted binlog pos is %d. Current master_log_file=%s, master_log_pos=%lu",
|
"Permitted binlog pos is %d. Current master_log_file=%s, master_log_pos=%lu",
|
||||||
passed_pos,
|
master_log_pos,
|
||||||
master_logfile,
|
master_logfile,
|
||||||
4,
|
4,
|
||||||
router->binlog_name,
|
router->binlog_name,
|
||||||
@ -2938,14 +2955,13 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
|
|
||||||
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
||||||
|
|
||||||
if (master_log_pos)
|
|
||||||
free(master_log_pos);
|
|
||||||
if (master_logfile)
|
|
||||||
free(master_logfile);
|
|
||||||
|
|
||||||
/* restore previous master_host and master_port */
|
/* restore previous master_host and master_port */
|
||||||
blr_master_restore_config(router, current_master);
|
blr_master_restore_config(router, current_master);
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
|
free(master_logfile);
|
||||||
|
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -2961,11 +2977,6 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_FILE is [%s]",
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_FILE is [%s]",
|
||||||
router->service->name,
|
router->service->name,
|
||||||
router->binlog_name)));
|
router->binlog_name)));
|
||||||
|
|
||||||
if (master_log_pos)
|
|
||||||
free(master_log_pos);
|
|
||||||
if (master_logfile)
|
|
||||||
free(master_logfile);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
@ -2975,20 +2986,20 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
int return_error = 0;
|
int return_error = 0;
|
||||||
|
|
||||||
if (router->master_state == BLRM_UNCONFIGURED) {
|
if (router->master_state == BLRM_UNCONFIGURED) {
|
||||||
if (pos && pos != 4) {
|
if (master_log_pos != NULL && pos != 4) {
|
||||||
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_POS to %s: "
|
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_POS to %s: "
|
||||||
"Permitted binlog pos is 4. Specified master_log_file=%s",
|
"Permitted binlog pos is 4. Specified master_log_file=%s",
|
||||||
passed_pos,
|
master_log_pos,
|
||||||
master_logfile);
|
master_logfile);
|
||||||
|
|
||||||
return_error = 1;
|
return_error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (pos > 0 && pos != router->current_pos) {
|
if (master_log_pos != NULL && pos != router->current_pos) {
|
||||||
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_POS to %s: "
|
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_POS to %s: "
|
||||||
"Permitted binlog pos is %lu. Current master_log_file=%s, master_log_pos=%lu",
|
"Permitted binlog pos is %lu. Current master_log_file=%s, master_log_pos=%lu",
|
||||||
passed_pos,
|
master_log_pos,
|
||||||
router->current_pos,
|
router->current_pos,
|
||||||
router->binlog_name,
|
router->binlog_name,
|
||||||
router->current_pos);
|
router->current_pos);
|
||||||
@ -3001,14 +3012,13 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
if (return_error) {
|
if (return_error) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error)));
|
||||||
|
|
||||||
if (master_log_pos)
|
|
||||||
free(master_log_pos);
|
|
||||||
if (master_logfile)
|
|
||||||
free(master_logfile);
|
|
||||||
|
|
||||||
/* restore previous master_host and master_port */
|
/* restore previous master_host and master_port */
|
||||||
blr_master_restore_config(router, current_master);
|
blr_master_restore_config(router, current_master);
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
|
free(master_logfile);
|
||||||
|
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -3031,61 +3041,10 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_POS is [%u]",
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_POS is [%u]",
|
||||||
router->service->name,
|
router->service->name,
|
||||||
router->current_pos)));
|
router->current_pos)));
|
||||||
|
|
||||||
if (master_log_pos)
|
|
||||||
free(master_log_pos);
|
|
||||||
if (master_logfile)
|
|
||||||
free(master_logfile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change the replication user */
|
/* Log config changes (without passwords) */
|
||||||
if (master_user) {
|
|
||||||
char *ptr;
|
|
||||||
char *end;
|
|
||||||
ptr = strchr(master_user, '\'');
|
|
||||||
if (ptr)
|
|
||||||
ptr++;
|
|
||||||
else
|
|
||||||
ptr = master_user + 12;
|
|
||||||
|
|
||||||
end = strchr(ptr, '\'');
|
|
||||||
if (end)
|
|
||||||
*end ='\0';
|
|
||||||
|
|
||||||
if (router->user) {
|
|
||||||
free(router->user);
|
|
||||||
}
|
|
||||||
router->user = strdup(ptr);
|
|
||||||
|
|
||||||
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_USER is [%s]",
|
|
||||||
router->service->name,
|
|
||||||
router->user)));
|
|
||||||
|
|
||||||
free(master_user);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change the replication password */
|
|
||||||
if (master_password) {
|
|
||||||
char *ptr;
|
|
||||||
char *end;
|
|
||||||
ptr = strchr(master_password, '\'');
|
|
||||||
if (ptr)
|
|
||||||
ptr++;
|
|
||||||
else
|
|
||||||
ptr = master_password + 16;
|
|
||||||
|
|
||||||
end = strchr(ptr, '\'');
|
|
||||||
if (end)
|
|
||||||
*end ='\0';
|
|
||||||
|
|
||||||
if (router->password) {
|
|
||||||
free(router->password);
|
|
||||||
}
|
|
||||||
router->password = strdup(ptr);
|
|
||||||
|
|
||||||
free(master_password);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s: 'CHANGE MASTER TO executed'. Previous state MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'. New state is MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'",
|
LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s: 'CHANGE MASTER TO executed'. Previous state MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'. New state is MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'",
|
||||||
router->service->name,
|
router->service->name,
|
||||||
@ -3098,6 +3057,10 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
|
|
||||||
blr_master_free_config(current_master);
|
blr_master_free_config(current_master);
|
||||||
|
|
||||||
|
blr_master_free_parsed_options(&change_master);
|
||||||
|
|
||||||
|
free(master_logfile);
|
||||||
|
|
||||||
if (router->master_state == BLRM_UNCONFIGURED)
|
if (router->master_state == BLRM_UNCONFIGURED)
|
||||||
change_binlog = 1;
|
change_binlog = 1;
|
||||||
|
|
||||||
@ -3110,22 +3073,18 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error
|
|||||||
* Set new master hostname
|
* Set new master hostname
|
||||||
*
|
*
|
||||||
* @param router Current router instance
|
* @param router Current router instance
|
||||||
* @param command CHANGE MASTER TO command
|
* @param hostname The hostname to set
|
||||||
* @return 1 for applied change, 0 otherwise
|
* @return 1 for applied change, 0 otherwise
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
blr_set_master_hostname(ROUTER_INSTANCE *router, char *command) {
|
blr_set_master_hostname(ROUTER_INSTANCE *router, char *hostname) {
|
||||||
|
|
||||||
char *master_host = get_change_master_option(command, "MASTER_HOST");
|
if (hostname) {
|
||||||
|
|
||||||
if (master_host) {
|
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *end;
|
char *end;
|
||||||
ptr = strchr(master_host, '\'');
|
ptr = strchr(hostname, '\'');
|
||||||
if (ptr)
|
if (ptr)
|
||||||
ptr++;
|
ptr++;
|
||||||
else
|
|
||||||
ptr = master_host + 12;
|
|
||||||
|
|
||||||
end = strchr(ptr, '\'');
|
end = strchr(ptr, '\'');
|
||||||
|
|
||||||
@ -3138,34 +3097,27 @@ blr_set_master_hostname(ROUTER_INSTANCE *router, char *command) {
|
|||||||
router->service->name,
|
router->service->name,
|
||||||
router->service->dbref->server->name)));
|
router->service->dbref->server->name)));
|
||||||
|
|
||||||
free(master_host);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Set new master port
|
* Set new master port
|
||||||
*
|
*
|
||||||
* @param router Current router instance
|
* @param router Current router instance
|
||||||
* @param command CHANGE MASTER TO command
|
* @param port The server TCP port
|
||||||
* @return 1 for applied change, 0 otherwise
|
* @return 1 for applied change, 0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
blr_set_master_port(ROUTER_INSTANCE *router, char *command) {
|
blr_set_master_port(ROUTER_INSTANCE *router, char *port) {
|
||||||
char *master_port = get_change_master_option(command, "MASTER_PORT");
|
|
||||||
char *ptr;
|
|
||||||
unsigned short new_port;
|
unsigned short new_port;
|
||||||
|
|
||||||
if (master_port) {
|
if (port != NULL) {
|
||||||
ptr = master_port + 12;
|
|
||||||
|
|
||||||
new_port = atoi(ptr);
|
new_port = atoi(port);
|
||||||
|
|
||||||
free(master_port);
|
|
||||||
|
|
||||||
if (new_port) {
|
if (new_port) {
|
||||||
server_update_port(router->service->dbref->server, new_port);
|
server_update_port(router->service->dbref->server, new_port);
|
||||||
@ -3187,43 +3139,38 @@ blr_set_master_port(ROUTER_INSTANCE *router, char *command) {
|
|||||||
* The routing must be called holding router->lock
|
* The routing must be called holding router->lock
|
||||||
*
|
*
|
||||||
* @param router Current router instance
|
* @param router Current router instance
|
||||||
* @param command CHANGE MASTER TO command
|
* @param filename Binlog file name
|
||||||
* @param error The error msg for command
|
* @param error The error msg for command, pre-allocated BINLOG_ERROR_MSG_LEN + 1 bytes
|
||||||
* @return New binlog file or NULL on error
|
* @return New binlog file or NULL on error
|
||||||
*/
|
*/
|
||||||
char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *command, char *error) {
|
char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *filename, char *error) {
|
||||||
int change_binlog = 0;
|
int change_binlog = 0;
|
||||||
char *new_binlog_file = NULL;
|
char *new_binlog_file = NULL;
|
||||||
char *logfile = get_change_master_option(command, "MASTER_LOG_FILE");
|
|
||||||
|
|
||||||
if (logfile) {
|
if (filename) {
|
||||||
char *ptr;
|
|
||||||
char *end;
|
|
||||||
long next_binlog_seqname;
|
long next_binlog_seqname;
|
||||||
|
char *file_ptr;
|
||||||
|
char *end;
|
||||||
|
|
||||||
ptr = strchr(logfile, '\'');
|
file_ptr = strchr(filename, '\'');
|
||||||
|
if (file_ptr)
|
||||||
|
file_ptr++;
|
||||||
|
|
||||||
if (ptr)
|
end = strchr(file_ptr, '\'');
|
||||||
ptr++;
|
if (end)
|
||||||
else
|
*end ='\0';
|
||||||
ptr = logfile + 16;
|
|
||||||
|
|
||||||
end = strchr(ptr+1, '\'');
|
|
||||||
|
|
||||||
if (end)
|
|
||||||
*end ='\0';
|
|
||||||
|
|
||||||
/* check binlog filename format */
|
/* check binlog filename format */
|
||||||
end = strchr(ptr, '.');
|
end = strchr(file_ptr, '.');
|
||||||
|
|
||||||
if (!end) {
|
if (!end) {
|
||||||
|
|
||||||
snprintf(error, BINLOG_ERROR_MSG_LEN, "%s: selected binlog [%s] has not the format '%s.yyyyyy'",
|
snprintf(error, BINLOG_ERROR_MSG_LEN, "%s: selected binlog [%s] is not in the format"
|
||||||
router->service->name, ptr,
|
" '%s.yyyyyy'",
|
||||||
|
router->service->name,
|
||||||
|
file_ptr,
|
||||||
router->fileroot);
|
router->fileroot);
|
||||||
|
|
||||||
free(logfile);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3231,17 +3178,16 @@ char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *command, char *error
|
|||||||
|
|
||||||
if (router->master_state == BLRM_UNCONFIGURED) {
|
if (router->master_state == BLRM_UNCONFIGURED) {
|
||||||
char *stem_end;
|
char *stem_end;
|
||||||
stem_end = strrchr(ptr, '.');
|
stem_end = strrchr(file_ptr, '.');
|
||||||
/* set filestem */
|
/* set filestem */
|
||||||
if (stem_end) {
|
if (stem_end) {
|
||||||
if (router->fileroot)
|
if (router->fileroot)
|
||||||
free(router->fileroot);
|
free(router->fileroot);
|
||||||
router->fileroot = strndup(ptr, stem_end-ptr);
|
router->fileroot = strndup(file_ptr, stem_end-file_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return new filename */
|
/* return new filename */
|
||||||
new_binlog_file = strdup(ptr);
|
new_binlog_file = strdup(file_ptr);
|
||||||
free(logfile);
|
|
||||||
|
|
||||||
return new_binlog_file;
|
return new_binlog_file;
|
||||||
}
|
}
|
||||||
@ -3255,13 +3201,11 @@ char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *command, char *error
|
|||||||
router->service->name,
|
router->service->name,
|
||||||
router->binlog_name);
|
router->binlog_name);
|
||||||
|
|
||||||
free(logfile);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare binlog file name with current one */
|
/* Compare binlog file name with current one */
|
||||||
if (strcmp(router->binlog_name, ptr) == 0) {
|
if (strcmp(router->binlog_name, file_ptr) == 0) {
|
||||||
/* No binlog name change, eventually new position will be checked later */
|
/* No binlog name change, eventually new position will be checked later */
|
||||||
change_binlog = 0;
|
change_binlog = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -3273,15 +3217,13 @@ char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *command, char *error
|
|||||||
|
|
||||||
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_FILE to %s: Permitted binlog file names are "
|
snprintf(error, BINLOG_ERROR_MSG_LEN, "Can not set MASTER_LOG_FILE to %s: Permitted binlog file names are "
|
||||||
"%s or %s.%06li. Current master_log_file=%s, master_log_pos=%lu",
|
"%s or %s.%06li. Current master_log_file=%s, master_log_pos=%lu",
|
||||||
ptr,
|
file_ptr,
|
||||||
router->binlog_name,
|
router->binlog_name,
|
||||||
router->fileroot,
|
router->fileroot,
|
||||||
next_binlog_seqname,
|
next_binlog_seqname,
|
||||||
router->binlog_name,
|
router->binlog_name,
|
||||||
router->current_pos);
|
router->current_pos);
|
||||||
|
|
||||||
free(logfile);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3290,9 +3232,8 @@ char *blr_set_master_logfile(ROUTER_INSTANCE *router, char *command, char *error
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate new filename */
|
/* allocate new filename */
|
||||||
new_binlog_file = strdup(ptr);
|
new_binlog_file = strdup(file_ptr);
|
||||||
|
|
||||||
free(logfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_binlog_file;
|
return new_binlog_file;
|
||||||
@ -3387,3 +3328,228 @@ blr_master_apply_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *prev_master)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the replication user
|
||||||
|
*
|
||||||
|
* @param router Current router instance
|
||||||
|
* @param user The userto set
|
||||||
|
* @return 1 for applied change, 0 otherwise
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
blr_set_master_user(ROUTER_INSTANCE *router, char *user) {
|
||||||
|
|
||||||
|
if (user != NULL) {
|
||||||
|
char *ptr;
|
||||||
|
char *end;
|
||||||
|
ptr = strchr(user, '\'');
|
||||||
|
if (ptr)
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
end = strchr(ptr, '\'');
|
||||||
|
if (end)
|
||||||
|
*end ='\0';
|
||||||
|
|
||||||
|
if (router->user) {
|
||||||
|
free(router->user);
|
||||||
|
}
|
||||||
|
router->user = strdup(ptr);
|
||||||
|
|
||||||
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_USER is [%s]",
|
||||||
|
router->service->name,
|
||||||
|
router->user)));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the replication password
|
||||||
|
*
|
||||||
|
* @param router Current router instance
|
||||||
|
* @param password The password to set
|
||||||
|
* @return 1 for applied change, 0 otherwise
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
blr_set_master_password(ROUTER_INSTANCE *router, char *password) {
|
||||||
|
if (password != NULL) {
|
||||||
|
char *ptr;
|
||||||
|
char *end;
|
||||||
|
ptr = strchr(password, '\'');
|
||||||
|
if (ptr)
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
end = strchr(ptr, '\'');
|
||||||
|
if (end)
|
||||||
|
*end ='\0';
|
||||||
|
|
||||||
|
if (router->password) {
|
||||||
|
free(router->password);
|
||||||
|
}
|
||||||
|
router->password = strdup(ptr);
|
||||||
|
|
||||||
|
/* don't log new password */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a CHANGE MASTER TO SQL command
|
||||||
|
*
|
||||||
|
* @param input The command to be parsed
|
||||||
|
* @param error_string Pre-allocated string for error message, BINLOG_ERROR_MSG_LEN + 1 bytes
|
||||||
|
* @param config master option struct to fill
|
||||||
|
* @return 0 on success, 1 on failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
blr_parse_change_master_command(char *input, char *error_string, CHANGE_MASTER_OPTIONS *config) {
|
||||||
|
char *sep = ",";
|
||||||
|
char *word, *brkb;
|
||||||
|
|
||||||
|
if ((word = strtok_r(input, sep, &brkb)) == NULL) {
|
||||||
|
sprintf(error_string, "Unable to parse query [%s]", input);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* parse options key=val */
|
||||||
|
if (blr_handle_change_master_token(word, error_string, config))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((word = strtok_r(NULL, sep, &brkb)) != NULL) {
|
||||||
|
/* parse options key=val */
|
||||||
|
if (blr_handle_change_master_token(word, error_string, config))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate option and set the value for a change master option
|
||||||
|
*
|
||||||
|
* @param input Current option with value
|
||||||
|
* @param error pre-allocted string for error message, BINLOG_ERROR_MSG_LEN + 1 bytes
|
||||||
|
* @param config master option struct to fill
|
||||||
|
* @return 0 on success, 1 on error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
blr_handle_change_master_token(char *input, char *error, CHANGE_MASTER_OPTIONS *config) {
|
||||||
|
/* space+TAB+= */
|
||||||
|
char *sep = " =";
|
||||||
|
char *word, *brkb;
|
||||||
|
char *value = NULL;
|
||||||
|
char **option_field = NULL;
|
||||||
|
|
||||||
|
if ((word = strtok_r(input, sep, &brkb)) == NULL) {
|
||||||
|
sprintf(error, "error parsing %s", brkb);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
if ((option_field = blr_validate_change_master_option(word, config)) == NULL) {
|
||||||
|
sprintf(error, "option '%s' is not supported", word);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value must be freed after usage */
|
||||||
|
if ((value = blr_get_parsed_command_value(brkb)) == NULL) {
|
||||||
|
sprintf(error, "missing value for '%s'", word);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
*option_field = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value of a change master option
|
||||||
|
*
|
||||||
|
* @param input Current option with value
|
||||||
|
* @return The new allocated option value or NULL
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
blr_get_parsed_command_value(char *input) {
|
||||||
|
/* space+TAB+= */
|
||||||
|
char *sep = " =";
|
||||||
|
char *ret = NULL;
|
||||||
|
char *word;
|
||||||
|
char *value = NULL;
|
||||||
|
|
||||||
|
if (strlen(input))
|
||||||
|
value = strdup(input);
|
||||||
|
else
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if ((word = strtok_r(NULL, sep, &input)) != NULL) {
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
/* remove trailing spaces */
|
||||||
|
ptr = value + strlen(value) - 1;
|
||||||
|
while (ptr > value && isspace(*ptr))
|
||||||
|
*ptr-- = 0;
|
||||||
|
|
||||||
|
ret = strdup(strstr(value, word));
|
||||||
|
|
||||||
|
free(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a change master option
|
||||||
|
*
|
||||||
|
* @param option The option to check
|
||||||
|
* @param config The option structure
|
||||||
|
* @return A pointer to the field in the option strucure or NULL
|
||||||
|
*/
|
||||||
|
static char
|
||||||
|
**blr_validate_change_master_option(char *option, CHANGE_MASTER_OPTIONS *config) {
|
||||||
|
if (strcasecmp(option, "master_host") == 0) {
|
||||||
|
return &config->host;
|
||||||
|
} else if (strcasecmp(option, "master_port") == 0) {
|
||||||
|
return &config->port;
|
||||||
|
} else if (strcasecmp(option, "master_log_file") == 0) {
|
||||||
|
return &config->binlog_file;
|
||||||
|
} else if (strcasecmp(option, "master_log_pos") == 0) {
|
||||||
|
return &config->binlog_pos;
|
||||||
|
} else if (strcasecmp(option, "master_user") == 0) {
|
||||||
|
return &config->user;
|
||||||
|
} else if (strcasecmp(option, "master_password") == 0) {
|
||||||
|
return &config->password;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free parsed master options struct pointers
|
||||||
|
*
|
||||||
|
* @param options Parsed option struct
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
blr_master_free_parsed_options(CHANGE_MASTER_OPTIONS *options) {
|
||||||
|
free(options->host);
|
||||||
|
options->host = NULL;
|
||||||
|
|
||||||
|
free(options->port);
|
||||||
|
options->port = NULL;
|
||||||
|
|
||||||
|
free(options->user);
|
||||||
|
options->user = NULL;
|
||||||
|
|
||||||
|
free(options->password);
|
||||||
|
options->password = NULL;
|
||||||
|
|
||||||
|
free(options->binlog_file);
|
||||||
|
options->binlog_file = NULL;
|
||||||
|
|
||||||
|
free(options->binlog_pos);
|
||||||
|
options->binlog_pos = NULL;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user