Added parameters for commands and changed the execv call to execvp.
This commit is contained in:
@ -5,12 +5,123 @@ extern int lm_enabled_logfiles_bitmask;
|
|||||||
extern size_t log_ses_count[];
|
extern size_t log_ses_count[];
|
||||||
extern __thread log_info_t tls_log_info;
|
extern __thread log_info_t tls_log_info;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tokenize a string into arguments suitable for a execvp call.
|
||||||
|
* @param args Argument string
|
||||||
|
* @param argv Array of char pointers to be filled with tokenized arguments
|
||||||
|
* @return 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
int tokenize_arguments(char* args, char** argv)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
bool quoted = false;
|
||||||
|
bool read = false;
|
||||||
|
bool escaped = false;
|
||||||
|
char *ptr,*start;
|
||||||
|
char qc;
|
||||||
|
|
||||||
|
start = args;
|
||||||
|
ptr = start;
|
||||||
|
|
||||||
|
while(*ptr != '\0' && i < MAXSCALE_EXTCMD_ARG_MAX)
|
||||||
|
{
|
||||||
|
if(escaped)
|
||||||
|
{
|
||||||
|
escaped = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(*ptr == '\\')
|
||||||
|
{
|
||||||
|
escaped = true;
|
||||||
|
}
|
||||||
|
else if(quoted && !escaped && *ptr == qc) /** End of quoted string */
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
argv[i++] = strdup(start);
|
||||||
|
read = false;
|
||||||
|
quoted = false;
|
||||||
|
}
|
||||||
|
else if (!quoted)
|
||||||
|
{
|
||||||
|
if(isspace(*ptr))
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
if(read) /** New token */
|
||||||
|
{
|
||||||
|
argv[i++] = strdup(start);
|
||||||
|
read = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( *ptr == '\"' || *ptr == '\'')
|
||||||
|
{
|
||||||
|
/** New quoted token, strip quotes */
|
||||||
|
quoted = true;
|
||||||
|
qc = *ptr;
|
||||||
|
start = ptr + 1;
|
||||||
|
}
|
||||||
|
else if(!read)
|
||||||
|
{
|
||||||
|
start = ptr;
|
||||||
|
read = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
if(read)
|
||||||
|
argv[i++] = strdup(start);
|
||||||
|
argv[i] = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a new external command.
|
||||||
|
* The name and parameters are copied into the external command structure so
|
||||||
|
* the original memory can be freed if needed.
|
||||||
|
* @param command Command to execute with the parameters
|
||||||
|
* @return Pointer to new external command struct or NULL if an error occurred
|
||||||
|
*/
|
||||||
|
EXTERNCMD* externcmd_allocate(char* argstr)
|
||||||
|
{
|
||||||
|
EXTERNCMD* cmd;
|
||||||
|
|
||||||
|
if(argstr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if((cmd = (EXTERNCMD*)malloc(sizeof(EXTERNCMD))) != NULL)
|
||||||
|
{
|
||||||
|
if(tokenize_arguments(argstr,cmd->parameters) == -1)
|
||||||
|
{
|
||||||
|
free(cmd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a previously allocated external command.
|
||||||
|
* @param cmd Command to free
|
||||||
|
*/
|
||||||
|
void externcmd_free(EXTERNCMD* cmd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0;cmd->parameters[i] != NULL;i++)
|
||||||
|
{
|
||||||
|
free(cmd->parameters[i]);
|
||||||
|
}
|
||||||
|
free(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Execute a command in a separate process.
|
*Execute a command in a separate process.
|
||||||
*@param cmd Command to execute
|
*@param cmd Command to execute
|
||||||
*@return 0 on success, -1 on error.
|
*@return 0 on success, -1 on error.
|
||||||
*/
|
*/
|
||||||
int monitor_exec_cmd(char* cmd)
|
int externcmd_execute(EXTERNCMD* cmd)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -20,19 +131,20 @@ int monitor_exec_cmd(char* cmd)
|
|||||||
if(pid < 0)
|
if(pid < 0)
|
||||||
{
|
{
|
||||||
skygw_log_write(LOGFILE_ERROR,"Error: Failed to execute command '%s', fork failed: [%d] %s",
|
skygw_log_write(LOGFILE_ERROR,"Error: Failed to execute command '%s', fork failed: [%d] %s",
|
||||||
cmd,errno,strerror(errno));
|
cmd->parameters[0],errno,strerror(errno));
|
||||||
rval = -1;
|
rval = -1;
|
||||||
}
|
}
|
||||||
else if(pid == 0)
|
else if(pid == 0)
|
||||||
{
|
{
|
||||||
/** Child process, execute command */
|
/** Child process, execute command */
|
||||||
execl(cmd,cmd,NULL);
|
execvp(cmd->parameters[0],cmd->parameters);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
cmd->n_exec++;
|
||||||
LOGIF(LD,skygw_log_write(LD,"[monitor_exec_cmd] Forked child process %d : %s.",pid,cmd));
|
LOGIF(LD,skygw_log_write(LD,"[monitor_exec_cmd] Forked child process %d : %s.",pid,cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
#ifndef MON_EXEC_HG
|
#ifndef MON_EXEC_HG
|
||||||
#define MON_EXEC_HG
|
#define MON_EXEC_HG
|
||||||
|
|
||||||
#include <mon_exec.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <skygw_utils.h>
|
#include <skygw_utils.h>
|
||||||
#include <log_manager.h>
|
#include <log_manager.h>
|
||||||
|
#define MAXSCALE_EXTCMD_ARG_MAX 256
|
||||||
|
|
||||||
int monitor_exec_cmd(char* cmd);
|
typedef struct extern_cmd_t{
|
||||||
|
char* parameters[MAXSCALE_EXTCMD_ARG_MAX]; /*< Command arguments */
|
||||||
|
int n_exec; /*< Number of times executed */
|
||||||
|
}EXTERNCMD;
|
||||||
|
|
||||||
|
EXTERNCMD* externcmd_allocate(char* argstr);
|
||||||
|
void externcmd_free(EXTERNCMD* cmd);
|
||||||
|
int externcmd_execute(EXTERNCMD* cmd);
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,15 +197,9 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
handle->replicationHeartbeat = config_truth_value(params->value);
|
handle->replicationHeartbeat = config_truth_value(params->value);
|
||||||
else if(!strcmp(params->name,"master_down_script"))
|
else if(!strcmp(params->name,"master_down_script"))
|
||||||
{
|
{
|
||||||
if(access(params->value,F_OK) == 0)
|
if(handle->master_down_script)
|
||||||
{
|
externcmd_free(handle->master_down_script);
|
||||||
handle->master_down_script = strdup(params->value);
|
handle->master_down_script = externcmd_allocate(params->value);
|
||||||
handle->master_down_script_called = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skygw_log_write(LOGFILE_ERROR,"Error: could not find master_down_script file: %s",params->value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
params = params->next;
|
params = params->next;
|
||||||
}
|
}
|
||||||
@ -700,8 +694,11 @@ int log_no_master = 1;
|
|||||||
ptr->server->port)));
|
ptr->server->port)));
|
||||||
if(handle->master_down_script)
|
if(handle->master_down_script)
|
||||||
{
|
{
|
||||||
if(monitor_exec_cmd(handle->master_down_script))
|
if(externcmd_execute(handle->master_down_script))
|
||||||
skygw_log_write(LOGFILE_ERROR,"Error: Failed to execute command '%s' on server state change.",handle->master_down_script);
|
skygw_log_write(LOGFILE_ERROR,
|
||||||
|
"Error: Failed to execute command "
|
||||||
|
"'%s' on server state change.",
|
||||||
|
handle->master_down_script->parameters[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include <server.h>
|
#include <server.h>
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
|
#include <mon_exec.h>
|
||||||
/**
|
/**
|
||||||
* @file mysqlmon.h - The MySQL monitor functionality within the gateway
|
* @file mysqlmon.h - The MySQL monitor functionality within the gateway
|
||||||
*
|
*
|
||||||
@ -81,8 +81,7 @@ typedef struct {
|
|||||||
int write_timeout; /**< Timeout in seconds for each attempt to write to the server.
|
int write_timeout; /**< Timeout in seconds for each attempt to write to the server.
|
||||||
* There are retries and the total effective timeout value is two times the option value.
|
* There are retries and the total effective timeout value is two times the option value.
|
||||||
*/
|
*/
|
||||||
char *master_down_script;
|
EXTERNCMD* master_down_script;
|
||||||
int master_down_script_called;
|
|
||||||
} MYSQL_MONITOR;
|
} MYSQL_MONITOR;
|
||||||
|
|
||||||
#define MONITOR_RUNNING 1
|
#define MONITOR_RUNNING 1
|
||||||
|
Reference in New Issue
Block a user