Merge branch 'cmake_build' into query_classifier_test

This commit is contained in:
Markus Makela
2014-09-22 14:39:02 +03:00
18 changed files with 368 additions and 231 deletions

View File

@ -1,8 +1,7 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 2.6)
include(macros.cmake)
enable_testing()
set_variables()
set_maxscale_version()

29
README
View File

@ -157,7 +157,7 @@ Please check errmsg.sys is found in the MaxScale install_dir DEST/MaxScale/mysql
You can also build MaxScale with CMake which makes the build process a bit more simple.
All the same dependencies are required as with the normal MaxScale build with the addition of CMake
version 2.6 for regular builds and 2.8 or newer if you wish to generate packages.
version 2.6 for regular builds and 2.8.12 or newer if you wish to generate packages.
CMake tries to find all the required directories and files on its own but if it can't find them or you wish to
explicitly state the locations you can pass additional options to CMake by using the -D flag. To confirm the variable
@ -166,12 +166,15 @@ values, you can run CMake in interactive mode by using the -i flag or use a CMak
It is highly recommended to make a separate build directory to build into. This keeps the source and build trees clean and
makes it easy to get rid of everything you built.
By default, MaxScale installs to /usr/local/skysql and places init.d scripts and ldconfig files into their folders. Change the INSTALL_DIR
variable to your desired installation directory and set INSTALL_SYSTEM_FILES=N to prevent the init.d script and ldconfig file installation.
To build MaxScale using CMake:
To build and install MaxScale using CMake with a custom install location and a separate build directory:
cd <path to MaxScale source>
cmake -D_INSTALL_DIR=<install destination> <path to MaxScale source>
mkdir build
cd build
cmake ..
make
@ -184,19 +187,33 @@ To build MaxScale using the ccmake GUI:
ccmake <path to MaxScale source>
If you have your headers and libraries in non-standard locations, you can define those locations at configuration time as such:
cmake -D<variable>=<value>
By default, MaxScale installs to '/usr/local/skysql/maxscale' and places init.d scripts and ldconfig files into their folders. Change the INSTALL_DIR
variable to your desired installation directory and set INSTALL_SYSTEM_FILES=N to prevent the init.d script and ldconfig file installation.
All the parameters affecting CMake can be found in 'macros.cmake'. This file also has the parameters CMake uses for testing.
Variables controlling the CMake build process:
All the variables that control the CMake build process:
INSTALL_DIR=<path> Installation directory
BUILD_TYPE=[None|Debug|Release] Type of the build, defaults to Release (optimized)
INSTALL_SYSTEM_FILES=[Y|N] Install startup scripts and ld configuration files
EMBEDDED_LIB=<path> Path to the embedded library, filename included
MYSQL_DIR=<path> Path to MySQL headers
ERRMSG=<path> Path to errmsg.sys file
STATIC_EMBEDDED=[Y|N] Link the static or the dynamic verson of the library
GCOV=[Y|N] Generate gcov output
BUILD_TESTS=[Y|N] Build tests
DEPS_OK=[Y|N] Check dependencies, use N when you want to force a recheck of values
DEBUG_OUTPUT=[Y|N] Produce debugging output when configuring CMake
RABBITMQ_LIB=<path> Path to RabbitMQ-C libraries
RABBITMQ_HEADERS=<path> Path to RabbitMQ-C headers
MYSQL_CLIENT_LIB=<path> Path to MySQL client libraries
MYSQL_CLIENT_HEADERS=<path> Path to MySQL client headers
\section Running Running MaxScale

View File

@ -33,7 +33,7 @@ endif
CC=cc
CFLAGS=-c -Wall -g $(HISTFLAG)
CFLAGS=-c -Wall -g $(HISTFLAG) -I ../server/include
SRCS= maxadmin.c

View File

@ -47,6 +47,9 @@
#include <dirent.h>
#include <locale.h>
#include <errno.h>
#include <getopt.h>
#include <version.h>
#ifdef HISTORY
#include <histedit.h>
@ -59,6 +62,7 @@ static int sendCommand(int so, char *cmd);
static void DoSource(int so, char *cmd);
static void DoUsage();
static int isquit(char *buf);
static void PrintVersion(const char *progname);
#ifdef HISTORY
static char *
@ -70,6 +74,16 @@ prompt(EditLine *el __attribute__((__unused__)))
}
#endif
static struct option long_options[] = {
{"host", required_argument, 0, 'h'},
{"user", required_argument, 0, 'u'},
{"password", required_argument, 0, 'p'},
{"port", required_argument, 0, 'P'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
/**
* The main for the maxadmin client
*
@ -79,7 +93,7 @@ prompt(EditLine *el __attribute__((__unused__)))
int
main(int argc, char **argv)
{
int i, num, rv, fatal = 0;
int i, num, rv;
#ifdef HISTORY
char *buf;
EditLine *el = NULL;
@ -96,106 +110,38 @@ char *user = "admin";
char *passwd = NULL;
int so, cmdlen;
char *cmd;
int argno = 0;
int option_index = 0;
char c;
cmd = malloc(1);
*cmd = 0;
cmdlen = 1;
for (i = 1; i < argc; i++)
while ((c = getopt_long(argc, argv, "h:p:P:u:v?",
long_options, &option_index))
>= 0)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'u': /* User */
if (argv[i][2])
user = &(argv[i][2]);
else if (i + 1 < argc)
user = argv[++i];
else
{
fprintf(stderr, "Missing username"
"in -u option.\n");
fatal = 1;
}
switch (c) {
case 'h':
hostname = strdup(optarg);
break;
case 'p': /* Password */
if (argv[i][2])
passwd = &(argv[i][2]);
else if (i + 1 < argc)
passwd = argv[++i];
else
{
fprintf(stderr, "Missing password "
"in -p option.\n");
fatal = 1;
}
case 'p':
passwd = strdup(optarg);
break;
case 'h': /* hostname */
if (argv[i][2])
hostname = &(argv[i][2]);
else if (i + 1 < argc)
hostname = argv[++i];
else
{
fprintf(stderr, "Missing hostname value "
"in -h option.\n");
fatal = 1;
}
case 'P':
port = strdup(optarg);
break;
case 'P': /* Port */
if (argv[i][2])
port = &(argv[i][2]);
else if (i + 1 < argc)
port = argv[++i];
else
{
fprintf(stderr, "Missing Port value "
"in -P option.\n");
fatal = 1;
}
break;
case '-':
{
char *word;
word = &argv[i][2];
if (strcmp(word, "help") == 0)
{
DoUsage();
exit(0);
}
case 'u':
user = strdup(optarg);
break;
case 'v':
PrintVersion(*argv);
exit(EXIT_SUCCESS);
case '?':
DoUsage(*argv);
exit(optopt ? EXIT_FAILURE : EXIT_SUCCESS);
}
}
}
else
{
/* Arguments after the second argument are quoted
* to allow for quoted names on the command line
* to be passed on in quotes.
*/
if (argno++ > 1)
{
cmdlen += strlen(argv[i]) + 3;
cmd = realloc(cmd, cmdlen);
strcat(cmd, "\"");
strcat(cmd, argv[i]);
strcat(cmd, "\" ");
}
else
{
cmdlen += strlen(argv[i]) + 1;
cmd = realloc(cmd, cmdlen);
strcat(cmd, argv[i]);
strcat(cmd, " ");
}
}
}
if (fatal)
exit(1);
if (passwd == NULL)
{
@ -533,23 +479,34 @@ FILE *fp;
return;
}
/**
* Print version information
*/
static void
PrintVersion(const char *progname)
{
printf("%s Version %s\n", progname, MAXSCALE_VERSION);
}
/**
* Display the --help text.
*/
static void
DoUsage()
DoUsage(const char *progname)
{
printf("maxadmin: The MaxScale administrative and monitor client.\n\n");
printf("Usage: maxadmin [-u user] [-p password] [-h hostname] [-P port] [<command file> | <command>]\n\n");
printf(" -u user The user name to use for the connection, default\n");
PrintVersion(progname);
printf("The MaxScale administrative and monitor client.\n\n");
printf("Usage: %s [-u user] [-p password] [-h hostname] [-P port] [<command file> | <command>]\n\n", progname);
printf(" -u|--user=... The user name to use for the connection, default\n");
printf(" is admin.\n");
printf(" -p password The user password, if not given the password will\n");
printf(" -p|--password=... The user password, if not given the password will\n");
printf(" be prompted for interactively\n");
printf(" -h hostname The maxscale host to connecto to. The default is\n");
printf(" -h|--hostname=... The maxscale host to connecto to. The default is\n");
printf(" localhost\n");
printf(" -P port The port to use for the connection, the default\n");
printf(" -P|--port=... The port to use for the connection, the default\n");
printf(" port is 6603.\n");
printf(" --help Print this help text.\n");
printf(" -v|--version print version information and exit\n");
printf(" -?|--help Print this help text.\n");
printf("Any remaining arguments are treated as MaxScale commands or a file\n");
printf("containing commands to execute.\n");
}

View File

@ -255,7 +255,7 @@ static int logmanager_write_log(
bool use_valist,
bool spread_down,
size_t len,
char* str,
const char* str,
va_list valist);
static blockbuf_t* blockbuf_init(logfile_id_t id);
@ -609,7 +609,7 @@ static int logmanager_write_log(
bool use_valist,
bool spread_down,
size_t str_len,
char* str,
const char* str,
va_list valist)
{
logfile_t* lf;
@ -623,7 +623,7 @@ static int logmanager_write_log(
CHK_LOGMANAGER(lm);
if (id < LOGFILE_FIRST || id > LOGFILE_LAST) {
char* errstr = "Invalid logfile id argument.";
const char* errstr = "Invalid logfile id argument.";
/**
* invalid id, since we don't have logfile yet.
*/
@ -1181,7 +1181,7 @@ static bool logfile_set_enabled(
CHK_LOGMANAGER(lm);
if (id < LOGFILE_FIRST || id > LOGFILE_LAST) {
char* errstr = "Invalid logfile id argument.";
const char* errstr = "Invalid logfile id argument.";
/**
* invalid id, since we don't have logfile yet.
*/
@ -1235,7 +1235,7 @@ return_succp:
int skygw_log_write_flush(
logfile_id_t id,
char* str,
const char* str,
...)
{
int err = 0;
@ -1291,7 +1291,7 @@ return_err:
int skygw_log_write(
logfile_id_t id,
char* str,
const char* str,
...)
{
int err = 0;

View File

@ -72,9 +72,9 @@ void skygw_logmanager_exit(void);
* free private write buffer list
*/
void skygw_log_done(void);
int skygw_log_write(logfile_id_t id, char* format, ...);
int skygw_log_write(logfile_id_t id, const char* format, ...);
int skygw_log_flush(logfile_id_t id);
int skygw_log_write_flush(logfile_id_t id, char* format, ...);
int skygw_log_write_flush(logfile_id_t id, const char* format, ...);
int skygw_log_enable(logfile_id_t id);
int skygw_log_disable(logfile_id_t id);

View File

@ -70,6 +70,7 @@ macro(check_deps)
if(DEPS_ERROR)
message(FATAL_ERROR "Cannot find dependencies: ${FAILED_DEPS}")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
endif()
endmacro()
@ -86,19 +87,23 @@ macro(check_dirs)
set(MYSQL_DIR ${MYSQL_DIR_LOC} CACHE PATH "Path to MySQL headers" FORCE)
if(${MYSQL_DIR} STREQUAL "MYSQL_DIR-NOTFOUND")
message(FATAL_ERROR "Fatal Error: MySQL headers were not found.")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
else()
message(STATUS "Using MySQL headers found at: ${MYSQL_DIR}")
endif()
# Find the errmsg.sys file if it was not defied
if( NOT ( DEFINED ERRMSG ) )
find_file(ERRMSG errmsg.sys PATHS /usr/share/mysql /usr/local/share/mysql ${CUSTOM_ERRMSG} PATH_SUFFIXES english)
if(${ERRMSG} STREQUAL "ERRMSG-NOTFOUND")
message(FATAL_ERROR "Fatal Error: The errmsg.sys file was not found.")
elseif(DEBUG_OUTPUT)
message(STATUS "Using errmsg.sys found at: ${ERRMSG}")
if( DEFINED ERRMSG )
find_file(ERRMSG_FILE errmsg.sys PATHS ${ERRMSG} NO_DEFAULT_PATH)
endif()
find_file(ERRMSG_FILE errmsg.sys PATHS /usr/share/mysql /usr/local/share/mysql PATH_SUFFIXES english)
if(${ERRMSG_FILE} MATCHES "ERRMSG_FILE-NOTFOUND")
message(FATAL_ERROR "Fatal Error: The errmsg.sys file was not found, please define the path to it by using -DERRMSG=<path>")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
else()
message(STATUS "Using errmsg.sys found at: ${ERRMSG_FILE}")
endif()
set(ERRMSG ${ERRMSG_FILE} CACHE FILEPATH "Path to the errmsg.sys file." FORCE)
# Find the embedded mysql library
if(STATIC_EMBEDDED)
@ -132,6 +137,7 @@ macro(check_dirs)
# Inform the user about the embedded library
if( (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_STATIC-NOTFOUND") OR (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_DYNAMIC-NOTFOUND"))
message(FATAL_ERROR "Library not found: libmysqld. If your install of MySQL is in a non-default location, please provide the location with -DEMBEDDED_LIB=<path to library>")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
else()
get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} REALPATH)
message(STATUS "Using embedded library: ${EMBEDDED_LIB}")
@ -144,6 +150,7 @@ macro(check_dirs)
find_file(DEB_FNC init-functions PATHS /lib/lsb)
if(${DEB_FNC} MATCHES "DEB_FNC-NOTFOUND")
message(FATAL_ERROR "Cannot find required init-functions in /lib/lsb/ or /etc/rc.d/init.d/, please confirm that your system files are OK.")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
else()
set(DEB_BASED TRUE CACHE BOOL "If init.d script uses /lib/lsb/init-functions instead of /etc/rc.d/init.d/functions.")
endif()
@ -151,6 +158,34 @@ macro(check_dirs)
set(DEB_BASED FALSE CACHE BOOL "If init.d script uses /lib/lsb/init-functions instead of /etc/rc.d/init.d/functions.")
endif()
#Check RabbitMQ headers and libraries
if(BUILD_RABBITMQ)
if(DEFINED RABBITMQ_LIB)
find_library(RMQ_LIB rabbitmq PATHS ${RABBITMQ_LIB} NO_DEFAULT_PATH)
endif()
find_library(RMQ_LIB rabbitmq)
if(RMQ_LIB STREQUAL "RMQ_LIB-NOTFOUND")
message(FATAL_ERROR "Cannot find RabbitMQ libraries, please define the path to the libraries with -DRABBITMQ_LIB=<path>")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
else()
set(RABBITMQ_LIB ${RMQ_LIB} CACHE PATH "Path to RabbitMQ libraries" FORCE)
message(STATUS "Using RabbitMQ libraries found at: ${RABBITMQ_LIB}")
endif()
if(DEFINED RABBITMQ_HEADERS)
find_file(RMQ_HEADERS amqp.h PATHS ${RABBITMQ_HEADERS} NO_DEFAULT_PATH)
endif()
find_file(RMQ_HEADERS amqp.h)
if(RMQ_HEADERS STREQUAL "RMQ_HEADERS-NOTFOUND")
message(FATAL_ERROR "Cannot find RabbitMQ headers, please define the path to the headers with -DRABBITMQ_HEADERS=<path>")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
else()
set(RABBITMQ_HEADERS ${RMQ_HEADERS} CACHE PATH "Path to RabbitMQ headers" FORCE)
message(STATUS "Using RabbitMQ headers found at: ${RABBITMQ_HEADERS}")
endif()
endif()
set(DEPS_OK TRUE CACHE BOOL "If all the dependencies were found.")

View File

@ -1 +1,3 @@
add_subdirectory(canonical_tests)
add_executable(classify classify.c)
target_link_libraries(classify fullcore)

View File

@ -1,4 +1,7 @@
file(COPY ${ERRMSG} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
if(${ERRMSG} MATCHES "ERRMSG-NOTFOUND")
message(FATAL_ERROR "The errmsg.sys file was not found, please define the path with -DERRMSG=<path>")
endif()
add_executable(canonizer canonizer.c)
target_link_libraries(canonizer pthread query_classifier z dl ssl aio crypt crypto rt m ${EMBEDDED_LIB} fullcore stdc++)
add_test(NAME TestCanonicalQuery COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/canontest.sh

View File

@ -1,7 +1,13 @@
if (NOT ( DEFINED MYSQL_CLIENT_LIB ) )
find_library(MYSQL_CLIENT_LIB NAMES mysqlclient PATHS /usr/lib /usr/lib64 PATH_SUFFIXES mysql mariadb)
endif()
if( ( RABBITMQ_LIB AND RABBITMQ_HEADERS ) AND ( NOT ( ${MYSQL_CLIENT_LIB} STREQUAL "MYSQL_CLIENT_LIB-NOTFOUND" ) ) )
if (NOT ( DEFINED MYSQL_CLIENT_HEADERS ) )
find_path(MYSQL_CLIENT_HEADERS NAMES mysql.h PATH_SUFFIXES mysql mariadb)
endif()
if( ( RABBITMQ_LIB AND RABBITMQ_HEADERS ) AND ( NOT ( ${MYSQL_CLIENT_LIB} STREQUAL "MYSQL_CLIENT_LIB-NOTFOUND" ) ) AND ( NOT ( ${MYSQL_CLIENT_HEADERS} STREQUAL "MYSQL_CLIENT_HEADERS-NOTFOUND" ) ) )
include_directories(${MYSQL_CLIENT_HEADERS})
add_executable (consumer consumer.c)
target_link_libraries(consumer ${MYSQL_CLIENT_LIB} rabbitmq inih)
install(TARGETS consumer DESTINATION bin)

View File

@ -1575,6 +1575,7 @@ static char *service_params[] =
"use_sql_variables_in", /*< rwsplit only */
"version_string",
"filters",
"weightby",
NULL
};

View File

@ -403,13 +403,16 @@ DCB_CALLBACK *cb;
* operation of clearing this bit means that no bits are set in
* the memdata.bitmask then the DCB is no longer able to be
* referenced and it can be finally removed.
* Thread won't clear its bit from bitmask of the DCB it is still using.
*
* The excluded DCB allows a thread to exclude a DCB from zombie processing.
* It is used when a thread calls dcb_process_zombies when there is
* a DCB that the caller knows it will continue processing with.
*
* @param threadid The thread ID of the caller
* @param dcb_in_use The DCB the thread currently uses, NULL or valid DCB.
* @param excluded The DCB the thread currently uses, NULL or valid DCB.
*/
DCB *
dcb_process_zombies(int threadid, DCB *dcb_in_use)
dcb_process_zombies(int threadid, DCB *excluded)
{
DCB *ptr, *lptr;
DCB* dcb_list = NULL;
@ -426,19 +429,34 @@ bool succp = false;
if (!zombies)
return NULL;
/*
* Process the zombie queue and create a list of DCB's that can be
* finally freed. This processing is down under a spinlock that
* will prevent new entries being added to the zombie queue. Therefore
* we do not want to do any expensive operations under this spinlock
* as it will block other threads. The expensive operations will be
* performed on the victim queue within holding the zombie queue
* spinlock.
*/
spinlock_acquire(&zombiespin);
ptr = zombies;
lptr = NULL;
while (ptr)
{
CHK_DCB(ptr);
/** Don't clear the bit from DCB the user currently uses */
if (dcb_in_use == NULL || ptr != dcb_in_use)
/*
* Skip processing of the excluded DCB
*/
if (ptr == excluded)
{
bitmask_clear(&ptr->memdata.bitmask, threadid);
lptr = ptr;
ptr = ptr->memdata.next;
}
if (ptr == dcb_in_use)
ss_dassert(!bitmask_isallclear(&ptr->memdata.bitmask));
else
{
bitmask_clear(&ptr->memdata.bitmask, threadid);
if (bitmask_isallclear(&ptr->memdata.bitmask))
{
@ -449,9 +467,9 @@ bool succp = false;
*
* ptr is the DCB we are processing
* lptr is the previous DCB on the zombie queue
* or NULL if the DCB is at the head of the queue
* tptr is the DCB after the one we are processing
* on the zombie queue
* or NULL if the DCB is at the head of the
* queue tptr is the DCB after the one we are
* processing on the zombie queue
*/
DCB *tptr = ptr->memdata.next;
if (lptr == NULL)
@ -460,8 +478,9 @@ bool succp = false;
lptr->memdata.next = tptr;
LOGIF(LD, (skygw_log_write_flush(
LOGFILE_DEBUG,
"%lu [dcb_process_zombies] Remove dcb %p fd %d "
"in state %s from zombies list.",
"%lu [dcb_process_zombies] Remove dcb "
"%p fd %d " "in state %s from the "
"list of zombies.",
pthread_self(),
ptr,
ptr->fd,
@ -487,17 +506,23 @@ bool succp = false;
ptr = ptr->memdata.next;
}
}
}
spinlock_release(&zombiespin);
/*
* Process the victim queue. These are DCBs that are not in
* use by any thread.
* The corresponding file descriptor is closed, the DCB marked
* as disconnected and the DCB itself is fianlly freed.
*/
dcb = dcb_list;
/** Close, and set DISCONNECTED victims */
while (dcb != NULL) {
DCB* dcb_next = NULL;
int rc = 0;
/*<
* Close file descriptor and move to clean-up phase.
*/
ss_dassert(dcb_in_use != dcb);
ss_dassert(excluded != dcb);
rc = close(dcb->fd);
if (rc < 0) {
@ -1119,8 +1144,8 @@ int above_water;
/**
* Removes dcb from poll set, and adds it to zombies list. As a consequense,
* dcb first moves to DCB_STATE_NOPOLLING, and then to DCB_STATE_ZOMBIE state.
* At the end of the function state may not be DCB_STATE_ZOMBIE because once dcb_initlock
* is released parallel threads may change the state.
* At the end of the function state may not be DCB_STATE_ZOMBIE because once
* dcb_initlock is released parallel threads may change the state.
*
* Parameters:
* @param dcb The DCB to close
@ -1943,9 +1968,11 @@ int rval = 0;
* to return immediately and and process other events.
*
* @param dcb The DCB that has data available
* @param thread_id The ID of the calling thread
* @param nozombies If non-zero then do not do zombie processing
*/
void
dcb_pollin(DCB *dcb, int thread_id)
dcb_pollin(DCB *dcb, int thread_id, int nozombies)
{
spinlock_acquire(&dcb->pollinlock);
@ -1956,6 +1983,7 @@ dcb_pollin(DCB *dcb, int thread_id)
if (dcb->readcheck)
{
dcb->stats.n_readrechecks++;
if (!nozombies)
dcb_process_zombies(thread_id, dcb);
}
dcb->readcheck = 0;
@ -1987,9 +2015,11 @@ dcb_pollin(DCB *dcb, int thread_id)
* to return immediately and and process other events.
*
* @param dcb The DCB thats available for writes
* @param thread_id The ID of the calling thread
* @param nozombies If non-zero then do not do zombie processing
*/
void
dcb_pollout(DCB *dcb, int thread_id)
dcb_pollout(DCB *dcb, int thread_id, int nozombies)
{
spinlock_acquire(&dcb->polloutlock);
@ -1999,6 +2029,7 @@ dcb_pollout(DCB *dcb, int thread_id)
do {
if (dcb->writecheck)
{
if (!nozombies)
dcb_process_zombies(thread_id, dcb);
dcb->stats.n_writerechecks++;
}

View File

@ -44,6 +44,7 @@
#include <string.h>
#include <gw.h>
#include <unistd.h>
#include <getopt.h>
#include <service.h>
#include <server.h>
#include <dcb.h>
@ -131,6 +132,17 @@ static bool libmysqld_started = FALSE;
*/
static bool daemon_mode = true;
const char *progname = NULL;
static struct option long_options[] = {
{"homedir", required_argument, 0, 'c'},
{"config", required_argument, 0, 'f'},
{"nodeamon", required_argument, 0, 'd'},
{"log", required_argument, 0, 'l'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
static void log_flush_shutdown(void);
static void log_flush_cb(void* arg);
static int write_pid_file(char *); /* write MaxScale pidfile */
@ -878,15 +890,19 @@ return_cnf_file_buf:
return cnf_file_buf;
}
static void usage(void)
{
fprintf(stderr,
"*\n* Usage : maxscale [-h] | [-d] [-c <home "
"directory>] [-f <config file name>]\n* where:\n* "
"-h help\n* -d enable running in terminal process (default:disabled)\n* "
"-c relative|absolute MaxScale home directory\n* "
"-f relative|absolute pathname of MaxScale configuration file (default:MAXSCALE_HOME/etc/MaxScale.cnf)\n*\n");
"\nUsage : %s [-h] | [-d] [-c <home directory>] [-f <config file name>]\n\n"
" -d|--nodaemon enable running in terminal process (default:disabled)\n"
" -c|--homedir=... relative|absolute MaxScale home directory\n"
" -f|--config=... relative|absolute pathname of MaxScale configuration file\n"
" (default: $MAXSCALE_HOME/etc/MaxScale.cnf)\n"
" -l|--log=... log to file or shared memory\n"
" -lfile or -lshm - defaults to shared memory\n"
" -v|--version print version info and exit\n"
" -?|--help show this help\n"
, progname);
}
/**
@ -943,6 +959,8 @@ int main(int argc, char **argv)
char* cnf_file_path = NULL; /*< conf file, to be freed */
char* cnf_file_arg = NULL; /*< conf filename from cmd-line arg */
void* log_flush_thr = NULL;
int option_index;
int logtofile = 0; /* Use shared memory or file */
ssize_t log_flush_timeout_ms = 0;
sigset_t sigset;
sigset_t sigpipe_mask;
@ -954,6 +972,8 @@ int main(int argc, char **argv)
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
progname = *argv;
#if defined(SS_DEBUG)
memset(conn_open, 0, sizeof(bool)*10240);
memset(dcb_fake_write_errno, 0, sizeof(unsigned char)*10240);
@ -980,7 +1000,8 @@ int main(int argc, char **argv)
goto return_main;
}
}
while ((opt = getopt(argc, argv, "dc:f:h")) != -1)
while ((opt = getopt_long(argc, argv, "dc:f:l:v?",
long_options, &option_index)) != -1)
{
bool succp = true;
@ -1062,6 +1083,33 @@ int main(int argc, char **argv)
}
break;
case 'v':
rc = EXIT_SUCCESS;
goto return_main;
case 'l':
if (strncasecmp(optarg, "file") == 0)
logtofile = 1;
else if (strncasecmp(optarg, "shm") == 0)
logtofile = 0;
else
{
char* logerr = "Configuration file argument "
"identifier \'-l\' was specified but "
"the argument didn't specify\n a valid "
"configuration file or the argument "
"was missing.";
print_log_n_stderr(true, true, logerr, logerr, 0);
usage();
succp = false;
}
break;
case '?':
usage();
rc = EXIT_SUCCESS;
goto return_main;
default:
usage();
succp = false;
@ -1345,6 +1393,16 @@ int main(int argc, char **argv)
argv[0] = "MaxScale";
argv[1] = "-j";
argv[2] = buf;
if (logtofile)
{
argv[3] = "-l"; /*< write to syslog */
argv[4] = "LOGFILE_MESSAGE,LOGFILE_ERROR"
"LOGFILE_DEBUG,LOGFILE_TRACE";
argv[5] = NULL;
skygw_logmanager_init(5, argv);
}
else
{
argv[3] = "-s"; /*< store to shared memory */
argv[4] = "LOGFILE_DEBUG,LOGFILE_TRACE"; /*< ..these logs to shm */
argv[5] = "-l"; /*< write to syslog */
@ -1352,6 +1410,7 @@ int main(int argc, char **argv)
argv[7] = NULL;
skygw_logmanager_init(7, argv);
}
}
/*<
* Resolve the full pathname for configuration file and check for

View File

@ -16,6 +16,7 @@
* Copyright SkySQL Ab 2014
*/
#include <stdlib.h>
#include <string.h>
#include <housekeeper.h>
#include <thread.h>
#include <spinlock.h>

View File

@ -125,7 +125,7 @@ unsigned char *ptr;
/**
* Replace the contents of a GWBUF with the new SQL statement passed as a text string.
* The routine takes care of the modification needed to the MySQL packet,
* returning a GWBUF chian that cna be used to send the data to a MySQL server
* returning a GWBUF chain that can be used to send the data to a MySQL server
*
* @param orig The original request in a GWBUF
* @param sql The SQL text to replace in the packet

View File

@ -49,10 +49,19 @@ extern int lm_enabled_logfiles_bitmask;
* @endverbatim
*/
/**
* Control the use of mutexes for the epoll_wait call. Setting to 1 will
* cause the epoll_wait calls to be moved under a mutex. This may be useful
* for debuggign purposes but should be avoided in general use.
*/
#define MUTEX_EPOLL 0
static int epoll_fd = -1; /*< The epoll file descriptor */
static int do_shutdown = 0; /*< Flag the shutdown of the poll subsystem */
static GWBITMASK poll_mask;
#if MUTEX_EPOLL
static simple_mutex_t epoll_wait_mutex; /*< serializes calls to epoll_wait */
#endif
static int n_waiting = 0; /*< No. of threads in epoll_wait */
/**
@ -154,7 +163,9 @@ int i;
thread_data[i].state = THREAD_STOPPED;
}
}
#if MUTEX_EPOLL
simple_mutex_init(&epoll_wait_mutex, "epoll_wait_mutex");
#endif
hktask_add("Load Average", poll_loadav, NULL, POLL_LOAD_FREQ);
n_avg_samples = 15 * 60 / POLL_LOAD_FREQ;
@ -359,7 +370,7 @@ DCB *zombies = NULL;
thread_id)));
no_op = TRUE;
}
#if 0
#if MUTEX_EPOLL
simple_mutex_lock(&epoll_wait_mutex, TRUE);
#endif
if (thread_data)
@ -385,7 +396,7 @@ DCB *zombies = NULL;
{
atomic_add(&n_waiting, -1);
if (process_zombies_only) {
#if 0
#if MUTEX_EPOLL
simple_mutex_unlock(&epoll_wait_mutex);
#endif
goto process_zombies;
@ -413,7 +424,7 @@ DCB *zombies = NULL;
if (n_waiting == 0)
atomic_add(&pollStats.n_nothreads, 1);
#if 0
#if MUTEX_EPOLL
simple_mutex_unlock(&epoll_wait_mutex);
#endif
#endif /* BLOCKINGPOLL */
@ -504,7 +515,7 @@ DCB *zombies = NULL;
#else
atomic_add(&pollStats.n_write,
1);
dcb_pollout(dcb, thread_id);
dcb_pollout(dcb, thread_id, nfds);
#endif
} else {
LOGIF(LD, (skygw_log_write(
@ -554,7 +565,7 @@ DCB *zombies = NULL;
#if MUTEX_BLOCK
dcb->func.read(dcb);
#else
dcb_pollin(dcb, thread_id);
dcb_pollin(dcb, thread_id, nfds);
#endif
}
#if MUTEX_BLOCK
@ -609,8 +620,16 @@ DCB *zombies = NULL;
eno,
strerror(eno))));
atomic_add(&pollStats.n_hup, 1);
spinlock_acquire(&dcb->dcb_initlock);
if ((dcb->flags & DCBF_HUNG) == 0)
{
dcb->flags |= DCBF_HUNG;
spinlock_release(&dcb->dcb_initlock);
dcb->func.hangup(dcb);
}
else
spinlock_release(&dcb->dcb_initlock);
}
if (ev & EPOLLRDHUP)
{
@ -628,8 +647,16 @@ DCB *zombies = NULL;
eno,
strerror(eno))));
atomic_add(&pollStats.n_hup, 1);
spinlock_acquire(&dcb->dcb_initlock);
if ((dcb->flags & DCBF_HUNG) == 0)
{
dcb->flags |= DCBF_HUNG;
spinlock_release(&dcb->dcb_initlock);
dcb->func.hangup(dcb);
}
else
spinlock_release(&dcb->dcb_initlock);
}
} /*< for */
no_op = FALSE;
}

View File

@ -271,8 +271,8 @@ int fail_accept_errno;
#define DCB_BELOW_LOW_WATER(x) ((x)->low_water && (x)->writeqlen < (x)->low_water)
#define DCB_ABOVE_HIGH_WATER(x) ((x)->high_water && (x)->writeqlen > (x)->high_water)
void dcb_pollin(DCB *, int);
void dcb_pollout(DCB *, int);
void dcb_pollin(DCB *, int, int);
void dcb_pollout(DCB *, int, int);
DCB *dcb_get_zombies(void);
int gw_write(
#if defined(SS_DEBUG)
@ -317,6 +317,9 @@ void dcb_call_foreach (DCB_REASON reason);
void dcb_call_foreach (
DCB_REASON reason);
/* DCB flags values */
#define DCBF_CLONE 0x0001 /* DCB is a clone */
/**
* DCB flags values
*/
#define DCBF_CLONE 0x0001 /*< DCB is a clone */
#define DCBF_HUNG 0x0002 /*< Hangup has been dispatched */
#endif /* _DCB_H */

View File

@ -1,11 +1,7 @@
if(BUILD_RABBITMQ)
if(RABBITMQ_LIB AND RABBITMQ_HEADERS)
add_library(mqfilter SHARED mqfilter.c)
target_link_libraries(mqfilter query_classifier log_manager utils rabbitmq)
install(TARGETS mqfilter DESTINATION modules)
else()
message(ERROR "Error: Cannot find the required librabbitmq-c locations, please check that you have them configured correctly.")
endif()
endif()
add_library(regexfilter SHARED regexfilter.c)