Merge branch 'develop' into 1.2.1-binlog_router_trx

This commit is contained in:
MassimilianoPinto
2015-08-25 16:10:43 +02:00
6 changed files with 225 additions and 37 deletions

View File

@ -86,6 +86,10 @@
#include <ini.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/file.h>
#define STRING_BUFFER_SIZE 1024
#define PIDFD_CLOSED -1
/** for procname */
#if !defined(_GNU_SOURCE)
@ -139,7 +143,7 @@ static char datadir[PATH_MAX+1] = "";
static bool datadir_defined = false; /*< If the datadir was already set */
/* The data directory we created for this gateway instance */
static char pidfile[PATH_MAX+1] = "";
static int pidfd = PIDFD_CLOSED;
/**
* exit flag for log flusher.
@ -181,6 +185,7 @@ static void log_flush_shutdown(void);
static void log_flush_cb(void* arg);
static int write_pid_file(); /* write MaxScale pidfile */
static void unlink_pidfile(void); /* remove pidfile */
static void unlock_pidfile();
static void libmysqld_done(void);
static bool file_write_header(FILE* outfile);
static bool file_write_footer(FILE* outfile);
@ -207,7 +212,7 @@ static bool resolve_maxscale_conf_fname(
static char* check_dir_access(char* dirname,bool,bool);
static int set_user();
bool pid_file_exists();
/** SSL multi-threading functions and structures */
static SPINLOCK* ssl_locks;
@ -1816,8 +1821,22 @@ int main(int argc, char **argv)
"MaxScale is running in process %i",
getpid())));
/** Check if a MaxScale process is already running */
if(pid_file_exists())
{
/** There is a process with the PID of the maxscale.pid file running.
* Assuming that this is an already running MaxScale process, we
* should exit with an error code. */
rc = MAXSCALE_ALREADYRUNNING;
goto return_main;
}
/* Write process pid into MaxScale pidfile */
write_pid_file();
if(write_pid_file() != 0)
{
rc = MAXSCALE_ALREADYRUNNING;
goto return_main;
}
/* Init MaxScale poll system */
poll_init();
@ -1922,6 +1941,7 @@ int main(int argc, char **argv)
unload_all_modules();
/* Remove Pidfile */
unlock_pidfile();
unlink_pidfile();
return_main:
@ -1983,6 +2003,21 @@ static void log_flush_cb(
"Finished MaxScale log flusher.")));
}
static void unlock_pidfile()
{
if(pidfd != PIDFD_CLOSED)
{
if(flock(pidfd,LOCK_UN|LOCK_NB) != 0)
{
char logbuf[STRING_BUFFER_SIZE + PATH_MAX];
char* logerr = "Failed to unlock PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pidfile);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
}
close(pidfd);
}
}
/**
* Unlink pid file, called at program exit
*/
@ -2000,6 +2035,131 @@ static void unlink_pidfile(void)
}
}
/**
* Check if the maxscale.pid file exists and has a valid PID in it. If one has already been
* written and a MaxScale process is running, this instance of MaxScale should shut down.
* @return True if the conditions for starting MaxScale are not met and false if
* no PID file was found or there is no process running with the PID of the maxscale.pid
* file. If false is returned, this process should continue normally.
*/
bool pid_file_exists()
{
char pathbuf[PATH_MAX+1];
char logbuf[STRING_BUFFER_SIZE + PATH_MAX];
char pidbuf[STRING_BUFFER_SIZE];
pid_t pid;
bool lock_failed = false;
snprintf(pathbuf, PATH_MAX, "%s/maxscale.pid",get_piddir());
pathbuf[PATH_MAX] = '\0';
if(access(pathbuf,F_OK) != 0)
return false;
if(access(pathbuf,R_OK) == 0)
{
int fd, b;
if((fd = open(pathbuf, O_RDWR)) == -1)
{
char* logerr = "Failed to open PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
return true;
}
if(flock(fd,LOCK_EX|LOCK_NB))
{
if(errno != EWOULDBLOCK)
{
char* logerr = "Failed to lock PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
close(fd);
return true;
}
lock_failed = true;
}
pidfd = fd;
b = read(fd,pidbuf,sizeof(pidbuf));
if(b == -1)
{
char* logerr = "Failed to read from PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
unlock_pidfile();
return true;
}
else if(b == 0)
{
/** Empty file */
char* logerr = "PID file read from '%s'. File was empty.\n"
"If the file is the correct PID file and no other MaxScale processes "
"are running, please remove it manually and start MaxScale again.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
unlock_pidfile();
return true;
}
pidbuf[b < sizeof(pidbuf) ? b : sizeof(pidbuf) - 1] = '\0';
pid = strtol(pidbuf,NULL,0);
if(pid < 1)
{
/** Bad PID */
char* logerr = "PID file read from '%s'. File contents not valid.\n"
"If the file is the correct PID file and no other MaxScale processes "
"are running, please remove it manually and start MaxScale again.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
unlock_pidfile();
return true;
}
if(kill(pid,0) == -1)
{
if(errno == ESRCH)
{
/** no such process, old PID file */
if(lock_failed)
{
char* logerr = "Locking the PID file '%s' failed. Read PID from file and no process found with PID %d. "
"Confirm that no other process holds the lock on the PID file.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf,pid);
print_log_n_stderr(true, true, logbuf, logbuf, 0);
close(fd);
}
return lock_failed;
}
else
{
char* logerr = "Failed to check the existence of process %d read from file '%s'";
snprintf(logbuf,sizeof(logbuf),logerr,pid,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
unlock_pidfile();
}
}
else
{
char* logerr = "MaxScale is already running. Process id: %d. "
"Use another location for the PID file to run multiple instances of MaxScale on the same machine.";
snprintf(logbuf,sizeof(logbuf),logerr,pid);
print_log_n_stderr(true, true, logbuf, logbuf, 0);
unlock_pidfile();
}
}
else
{
char* logerr = "Cannot open PID file '%s', no read permissions. "
"Please confirm that the user running MaxScale has read permissions on the file.";
snprintf(logbuf,sizeof(logbuf),logerr,pathbuf);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
}
return true;
}
/**
* Write process pid into pidfile anc close it
* Parameters:
@ -2009,33 +2169,58 @@ static void unlink_pidfile(void)
*/
static int write_pid_file() {
int fd = -1;
char logbuf[STRING_BUFFER_SIZE + PATH_MAX];
char pidstr[STRING_BUFFER_SIZE];
snprintf(pidfile, PATH_MAX, "%s/maxscale.pid",get_piddir());
fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd == -1) {
fprintf(stderr, "MaxScale failed to open pidFile %s: error %d, %s\n", pidfile, errno, strerror(errno));
return 1;
} else {
char pidstr[50]="";
/* truncate pidfile content */
if (ftruncate(fd, 0) == -1) {
fprintf(stderr, "MaxScale failed to truncate pidfile %s: error %d, %s\n", pidfile, errno, strerror(errno));
if(pidfd == PIDFD_CLOSED)
{
int fd = -1;
fd = open(pidfile, O_WRONLY | O_CREAT, 0777);
if (fd == -1) {
char* logerr = "Failed to open PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pidfile);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
return -1;
}
if(flock(fd,LOCK_EX|LOCK_NB))
{
if(errno == EWOULDBLOCK)
{
snprintf(logbuf,sizeof(logbuf),"Failed to lock PID file '%s', another process is holding a lock on it. "
"Please confirm that no other MaxScale process is using the same PID file location.",pidfile);
}
snprintf(pidstr, sizeof(pidstr)-1, "%d", getpid());
if (pwrite(fd, pidstr, strlen(pidstr), 0) != (ssize_t)strlen(pidstr)) {
fprintf(stderr, "MaxScale failed to write into pidfile %s: error %d, %s\n", pidfile, errno, strerror(errno));
/* close file and return */
close(fd);
return 1;
else
{
snprintf(logbuf,sizeof(logbuf),"Failed to lock PID file '%s'.",pidfile);
}
/* close file */
print_log_n_stderr(true, true, logbuf, logbuf, errno);
close(fd);
return -1;
}
pidfd = fd;
}
/* truncate pidfile content */
if (ftruncate(pidfd, 0)) {
char* logerr = "MaxScale failed to truncate PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pidfile);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
unlock_pidfile();
return -1;
}
snprintf(pidstr, sizeof(pidstr)-1, "%d", getpid());
if (pwrite(pidfd, pidstr, strlen(pidstr), 0) != (ssize_t)strlen(pidstr)) {
char* logerr = "MaxScale failed to write into PID file '%s'.";
snprintf(logbuf,sizeof(logbuf),logerr,pidfile);
print_log_n_stderr(true, true, logbuf, logbuf, errno);
unlock_pidfile();
return -1;
}
/* success */

View File

@ -67,7 +67,7 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
}
if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) {
fprintf(stderr, "service_alloc() failed\n");
dcb_free(dcb);
dcb_close(dcb);
return 1;
}
@ -97,7 +97,7 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
fprintf(stderr, "Failed adding %s@%s(%lu)\n", username, ret_ip, fix_ipv4);
users_free(mysql_users);
free(service);
dcb_free(dcb);
dcb_close(dcb);
return 1;
}
@ -114,7 +114,7 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
users_free(mysql_users);
free(service);
dcb_free(dcb);
dcb_close(dcb);
if (!fetch_data)
return 1;
@ -198,7 +198,7 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
}
if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) {
fprintf(stderr, "service_alloc() failed\n");
dcb_free(dcb);
dcb_close(dcb);
return ret;
}
@ -208,7 +208,7 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
if(!setipaddress(&client_addr.sin_addr, from)) {
fprintf(stderr, "setipaddress failed for host [%s]\n", from);
free(service);
dcb_free(dcb);
dcb_close(dcb);
return ret;
}
}
@ -216,7 +216,7 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
if ((data = (MYSQL_session *) calloc(1, sizeof(MYSQL_session))) == NULL) {
fprintf(stderr, "MYSQL_session alloc failed\n");
free(service);
dcb_free(dcb);
dcb_close(dcb);
return ret;
}
@ -235,7 +235,7 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
else
strncpy(data->db, "",MYSQL_DATABASE_MAXLEN);
/* freed by dcb_free(dcb) */
/* freed by dcb_close(dcb) */
dcb->data = data;
// the routine returns 1 on success
@ -264,7 +264,7 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
users_free(mysql_users);
free(service);
dcb_free(dcb);
dcb_close(dcb);
return ret;
}

View File

@ -63,6 +63,9 @@ static char* server_groups[] = {
NULL
};
int config_load(char *);
int module_create_feedback_report(GWBUF **buffer, MODULES *modules, FEEDBACK_CONF *cfg);
int do_http_post(GWBUF *buffer, void *cfg);
int main(int argc, char** argv)
{

View File

@ -37,7 +37,7 @@
#define MAXSCALE_BADCONFIG 1 /* Configuration fiel error */
#define MAXSCALE_NOLIBRARY 2 /* No embedded library found */
#define MAXSCALE_NOSERVICES 3 /* No servics are running */
#define MAXSCALE_HOMELESS 4 /* No MaxScale Home */
#define MAXSCALE_ALREADYRUNNING 4 /* MaxScale is already runing */
#define MAXSCALE_BADARG 5 /* Bad command line argument */
#define MAXSCALE_INTERNALERROR 6 /* Internal error, see error log */
#endif