Merge branch 'release-1.0beta-refresh' into blr

Fix conflict and remove some redundant code

Conflicts:
	server/core/poll.c
This commit is contained in:
Mark Riddoch 2014-09-24 16:49:12 +01:00
commit 63252e94f2
56 changed files with 1644 additions and 352 deletions

138
CMakeLists.txt Normal file
View File

@ -0,0 +1,138 @@
cmake_minimum_required(VERSION 2.6)
include(macros.cmake)
enable_testing()
set_variables()
set_maxscale_version()
set(CMAKE_INSTALL_PREFIX "${INSTALL_DIR}" CACHE INTERNAL "Prefix prepended to install directories." FORCE)
project(MaxScale)
check_deps()
check_dirs()
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib:${CMAKE_INSTALL_PREFIX}/modules)
configure_file(${CMAKE_SOURCE_DIR}/server/include/version.h.in ${CMAKE_SOURCE_DIR}/server/include/version.h)
configure_file(${CMAKE_SOURCE_DIR}/maxscale.conf.in ${CMAKE_SOURCE_DIR}/maxscale.conf @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/init.d/maxscale.in ${CMAKE_SOURCE_DIR}/etc/init.d/maxscale @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/ubuntu/init.d/maxscale.in ${CMAKE_SOURCE_DIR}/etc/ubuntu/init.d/maxscale @ONLY)
set(CMAKE_C_FLAGS "-Wall -fPIC")
set(CMAKE_CXX_FLAGS "-Wall -fPIC")
if(BUILD_TYPE MATCHES Debug)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -pthread -pipe -DSS_DEBUG -Wformat -Werror=format-security -fstack-protector --param=ssp-buffer-size=4")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -pthread -pipe -DSS_DEBUG -Wformat -Werror=format-security -fstack-protector --param=ssp-buffer-size=4")
message(STATUS "Generating debugging symbols")
elseif(BUILD_TYPE MATCHES Optimized)
if(NOT (DEFINED OLEVEL))
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
message(STATUS "Optimization level at: 2")
endif()
else()
endif()
if(DEFINED OLEVEL )
if((OLEVEL GREATER -1) AND (OLEVEL LESS 4) )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O${OLEVEL}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O${OLEVEL}")
message(STATUS "Optimization level at: ${OLEVEL}")
else()
message(WARNING "Optimization level was set to a bad value, ignoring it. (Valid values are 0-3)")
endif()
endif()
if(GCOV)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov")
endif()
include_directories(${MYSQL_DIR})
include_directories(${MYSQL_DIR}/private)
include_directories(${MYSQL_DIR}/extra)
include_directories(${MYSQL_DIR}/..)
include_directories(utils)
include_directories(log_manager)
include_directories(query_classifier)
include_directories(server/include)
include_directories(server/inih)
include_directories(server/modules/include)
add_subdirectory(utils)
add_subdirectory(log_manager)
add_subdirectory(query_classifier)
add_subdirectory(server)
add_subdirectory(client)
# Install startup scripts and ldconfig files
if( NOT ( (DEFINED INSTALL_SYSTEM_FILES) AND ( NOT ( INSTALL_SYSTEM_FILES ) ) ) )
install(FILES maxscale.conf DESTINATION /etc/ld.so.conf.d/ PERMISSIONS WORLD_EXECUTE WORLD_READ)
if(DEB_BASED)
install(FILES etc/ubuntu/init.d/maxscale DESTINATION /etc/init.d/ PERMISSIONS WORLD_EXECUTE)
else()
install(FILES etc/init.d/maxscale DESTINATION /etc/init.d/ PERMISSIONS WORLD_EXECUTE)
endif()
message(STATUS "Installing maxscale.conf to: /etc/ld.so.conf.d")
message(STATUS "Installing startup scripts to: /etc/init.d")
endif()
file(GLOB DOCS Documentation/*.pdf)
message(STATUS "Installing MaxScale to: ${CMAKE_INSTALL_PREFIX}/")
install(FILES server/MaxScale_template.cnf DESTINATION etc)
install(FILES ${ERRMSG} DESTINATION mysql)
install(FILES ${DOCS} DESTINATION Documentation)
# See if we are on a RPM-capable or DEB-capable system
find_program(RPMBUILD rpmbuild)
find_program(DEBBUILD dpkg-buildpackage)
if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) )
message(STATUS "Generating RPM packages")
set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM")
endif()
if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) )
set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB")
execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE})
message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}")
endif()
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MaxScale")
set(CPACK_PACKAGE_VERSION_MAJOR "${MAXSCALE_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}")
set(CPACK_PACKAGE_CONTACT "SkySQL Ab")
set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}")
set(CPACK_PACKAGE_NAME "maxscale")
set(CPACK_PACKAGE_VENDOR "SkySQL Ab")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/README)
set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
set(CPACK_RPM_SPEC_INSTALL_POST "/sbin/ldconfig")
set(CPACK_RPM_PACKAGE_NAME "maxscale")
set(CPACK_RPM_PACKAGE_VENDOR "SkySQL Ab")
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
set(CPACK_RPM_PACKAGE_AUTOREQPROV " no")
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/etc /etc/ld.so.conf.d /etc/init.d /etc/rc.d/init.d")
set(CPACK_RPM_SPEC_MORE_DEFINE "%define ignore \#")
set(CPACK_RPM_USER_FILELIST "%ignore /etc/init.d")
set(CPACK_RPM_USER_FILELIST "%ignore /etc/ld.so.conf.d")
set(CPACK_RPM_USER_FILELIST "%ignore /etc")
include(CPack)
add_custom_target(testall
COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DBUILD_TYPE=Debug -DINSTALL_DIR=${CMAKE_BINARY_DIR} -DINSTALL_SYSTEM_FILES=N ${CMAKE_SOURCE_DIR}
COMMAND make install
COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null"
COMMAND make test
COMMAND /bin/sh -c "killall -KILL maxscale"
COMMENT "Running full test suite")

65
README
View File

@ -152,6 +152,71 @@ max_connections=4096
Please check errmsg.sys is found in the MaxScale install_dir DEST/MaxScale/mysql
\section Building Building MaxScale with CMake
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.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
values, you can run CMake in interactive mode by using the -i flag or use a CMake GUI (for example, ccmake for command line).
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 simply deleting the build directory.
To build MaxScale using CMake:
cd <path to MaxScale source>
mkdir build
cd build
cmake ..
make
make install
This generates the required makefiles in the current directory, compiles and links all the programs and installs
all the required files in their right places.
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.
If you run into any trouble while configuring CMake, you can always remove the 'CMakeCache.txt' file to clear CMake's
internal cache. This resets all values to their defaults and can be used to fix a 'stuck' configuration of CMake. This
is also a good reason why you should always build into a separate directory, because you can safely wipe the build directory clean without the
danger of deleting important files when something goes wrong.
The default values that CMake uses can be found in the 'macros.cmake' file. If you wish to change these, edit the 'macros.cmake' file
or define the variables manually at configuration time.
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 location (libmysqld.a for static and libmysqld.so for dynamic)
MYSQL_DIR=<path> Path to MySQL headers
ERRMSG=<path> Path to errmsg.sys file
STATIC_EMBEDDED=[Y|N] Whether to link the static or the dynamic verson of the library
GCOV=[Y|N] Generate gcov output
OLEVEL=<0-3> Level of optimization
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
MaxScale consists of a core executable and a number of modules that implement

7
client/CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
add_executable(maxadmin maxadmin.c)
find_library(HIST edit)
if(HIST)
add_definitions(-DHISTORY)
target_link_libraries(maxadmin ${HIST})
endif()
install(TARGETS maxadmin DESTINATION bin)

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;
@ -94,109 +108,36 @@ char *hostname = "localhost";
char *port = "6603";
char *user = "admin";
char *passwd = NULL;
int so, cmdlen;
char *cmd;
int argno = 0;
int so;
int option_index = 0;
char c;
cmd = malloc(1);
*cmd = 0;
cmdlen = 1;
for (i = 1; i < argc; i++)
{
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;
}
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;
}
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;
}
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);
}
break;
}
}
}
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, " ");
}
}
while ((c = getopt_long(argc, argv, "h:p:P:u:v?",
long_options, &option_index))
>= 0)
{
switch (c) {
case 'h':
hostname = strdup(optarg);
break;
case 'p':
passwd = strdup(optarg);
break;
case 'P':
port = strdup(optarg);
break;
case 'u':
user = strdup(optarg);
break;
case 'v':
PrintVersion(*argv);
exit(EXIT_SUCCESS);
case '?':
DoUsage(*argv);
exit(optopt ? EXIT_FAILURE : EXIT_SUCCESS);
}
}
if (fatal)
exit(1);
if (passwd == NULL)
{
struct termios tty_attr;
@ -234,14 +175,28 @@ int argno = 0;
exit(1);
}
if (cmdlen > 1)
{
cmd[cmdlen - 2] = '\0'; /* Remove trailing space */
if (access(cmd, R_OK) == 0)
DoSource(so, cmd);
else
sendCommand(so, cmd);
exit(0);
if (optind < argc) {
int i, len = 0;
char *cmd;
for (i = optind; i < argc; i++) {
len += strlen(argv[i]) + 1;
}
cmd = malloc(len);
strcpy(cmd, argv[optind]);
for (i = optind +1; i < argc; i++) {
strcat(cmd, " ");
strcat(cmd, argv[i]);
}
if (access(cmd, R_OK) == 0)
DoSource(so, cmd);
else
sendCommand(so, cmd);
free(cmd);
exit(0);
}
(void) setlocale(LC_CTYPE, "");
@ -318,7 +273,10 @@ int argno = 0;
}
else if (*buf)
{
sendCommand(so, buf);
if (!sendCommand(so, buf))
{
return 0;
}
}
}
@ -343,6 +301,7 @@ connectMaxScale(char *hostname, char *port)
{
struct sockaddr_in addr;
int so;
int keepalive = 1;
if ((so = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
@ -360,6 +319,9 @@ int so;
hostname, port, strerror(errno));
return -1;
}
if (setsockopt(so, SOL_SOCKET,
SO_KEEPALIVE, &keepalive , sizeof(keepalive )))
perror("setsockopt");
return so;
}
@ -432,11 +394,14 @@ authMaxScale(int so, char *user, char *password)
{
char buf[20];
read(so, buf, 4);
if (read(so, buf, 4) != 4)
return 0;
write(so, user, strlen(user));
read(so, buf, 8);
if (read(so, buf, 8) != 8)
return 0;
write(so, password, strlen(password));
read(so, buf, 6);
if (read(so, buf, 6) != 6)
return 0;
return strncmp(buf, "FAILED", 6);
}
@ -445,7 +410,7 @@ char buf[20];
* Send a comamnd using the MaxScaled protocol, display the return data
* on standard output.
*
* Input terminates with a lien containing jsut the text OK
* Input terminates with a lien containing just the text OK
*
* @param so The socket connect to MaxScale
* @param cmd The command to send
@ -455,12 +420,13 @@ static int
sendCommand(int so, char *cmd)
{
char buf[80];
int i, j, newline = 0;
int i, j, newline = 1;
write(so, cmd, strlen(cmd));
if (write(so, cmd, strlen(cmd)) == -1)
return 0;
while (1)
{
if ((i = read(so, buf, 80)) == -1)
if ((i = read(so, buf, 80)) <= 0)
return 0;
for (j = 0; j < i; j++)
{
@ -533,23 +499,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

@ -0,0 +1,210 @@
#!/bin/sh
failure=0
passed=0
maxadmin -pskysql help >& /dev/null
if [ $? -eq "1" ]; then
echo "Auth test (correct password): Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Auth test (correct password): Passed"
fi
maxadmin -pwrongpasswd help >& /dev/null
if [ $? -eq "0" ]; then
echo "Auth test (wrong password): Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Auth test (wrong password): Passed"
fi
maxadmin --password=skysql help >& /dev/null
if [ $? -eq "1" ]; then
echo "Auth test (long option): Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Auth test (long option): Passed"
fi
maxadmin -pskysql enable log debug >& /dev/null
if [ $? -eq "1" ]; then
echo "Enable debug log: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Enable debug log: Passed"
fi
maxadmin -pskysql enable log trace >& /dev/null
if [ $? -eq "1" ]; then
echo "Enable trace log: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Enable trace log: Passed"
fi
maxadmin -pskysql disable log debug >& /dev/null
if [ $? -eq "1" ]; then
echo "Disable debug log: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Disable debug log: Passed"
fi
maxadmin -pskysql disable log trace >& /dev/null
if [ $? -eq "1" ]; then
echo "Disable trace log: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Disable trace log: Passed"
fi
for cmd in clients dcbs filters listeners modules monitors services servers sessions threads
do
maxadmin -pskysql list $cmd | grep -s '-' >& /dev/null
if [ $? -eq "1" ]; then
echo "list command ($cmd): Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "list command ($cmd): Passed"
fi
done
for cmd in dcbs dbusers epoll filters modules monitors services servers sessions threads users
do
maxadmin -pskysql show $cmd | grep -s ' ' >& /dev/null
if [ $? -eq "1" ]; then
echo "show command ($cmd): Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "show command ($cmd): Passed"
fi
done
master=`maxadmin -pskysql list servers | awk '/Master/ { print $1; }'`
if [ $? -eq "1" ]; then
echo "Extract master server: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Extract master server: Passed"
fi
if [ "$master" = "" ]; then
echo "Get master server: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Get master server: Passed"
fi
maxadmin -pskysql show server $master | grep -s 'Master' >& /dev/null
if [ $? -eq "1" ]; then
echo "show server master: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "show server master: Passed"
fi
maxadmin -pskysql set server $master maint >& /dev/null
if [ $? -eq "1" ]; then
echo "set server: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "set server: Passed"
fi
maxadmin -pskysql list servers | grep $master | grep -s Maint >& /dev/null
if [ $? -eq "1" ]; then
echo "set maintenance mode: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "set maintenance mode: Passed"
fi
maxadmin -pskysql clear server $master maint >& /dev/null
if [ $? -eq "1" ]; then
echo "clear server: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "clear server: Passed"
fi
maxadmin -pskysql list servers | grep $master | grep -s Maint >& /dev/null
if [ $? -eq "0" ]; then
echo "clear maintenance mode: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "clear maintenance mode: Passed"
fi
dcbs=`maxadmin -pskysql list dcbs | awk -F\| '/listening/ { if ( NF > 1 ) print $1 }'`
if [ $? -eq "1" ]; then
echo "Get dcb listeners: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Get dcb listeners: Passed"
fi
for i in $dcbs
do
maxadmin -pskysql show dcb $i | grep -s 'listening' >& /dev/null
if [ $? -eq "1" ]; then
echo "show dcb listeners: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "show dcb listeners: Passed"
fi
done
sessions=`maxadmin -pskysql list sessions | awk -F\| '/Listener/ { if ( NF > 1 ) print $1 }'`
if [ $? -eq "1" ]; then
echo "Get listener sessions: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Get listener sessions: Passed"
fi
for i in $sessions
do
maxadmin -pskysql show session $i | grep -s 'Listener' >& /dev/null
if [ $? -eq "1" ]; then
echo "show session listeners: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "show session listeners: Passed"
fi
done
filters=`maxadmin -pskysql list filters | awk -F\| '{ if ( NF > 1 ) print $1 }'| grep -v Options`
if [ $? -eq "1" ]; then
echo "Get Filter list: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "Get filter list: Passed"
fi
for i in $filters
do
maxadmin -pskysql show filter $i | grep -s 'Filter' >& /dev/null
if [ $? -eq "1" ]; then
echo "show filter: Failed"
failure=`expr $failure + 1`
else
passed=`expr $passed + 1`
echo "show filter: Passed"
fi
done
echo "Test run complete. $passed passes, $failure failures"
exit $failure

157
etc/init.d/maxscale.in Executable file
View File

@ -0,0 +1,157 @@
#!/bin/sh
#
# maxscale: The SkySQL MaxScale database proxy
#
# description: MaxScale provides database specific proxy functionality
#
# processname: maxscale
#
### BEGIN INIT INFO
# Provides: maxscale
# Required-Start: $syslog $local_fs
# Required-Stop: $syslog $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: The maxscale database proxy
# Description: MaxScale is a database proxy server that can be used to front end
# database clusters offering different routing, filtering and protocol choices
### END INIT INFO
#############################################
# MaxScale HOME, PIDFILE, LIB
#############################################
export MAXSCALE_HOME=@INSTALL_DIR@
export MAXSCALE_PIDFILE=$MAXSCALE_HOME/log/maxscale.pid
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MAXSCALE_HOME/lib
###############################
# LSB Exit codes (non-Status)
###############################
_RETVAL_GENERIC=1
_RETVAL_NOT_INSTALLED=5
_RETVAL_NOT_RUNNING=7
###############################
# LSB Status action Exit codes
###############################
_RETVAL_STATUS_OK=0
_RETVAL_STATUS_NOT_RUNNING=3
# Sanity checks.
[ -x $MAXSCALE_HOME/bin/maxscale ] || exit $_RETVAL_NOT_INSTALLED
# Source function library.
. /etc/rc.d/init.d/functions
# we can rearrange this easily
processname=maxscale
servicename=maxscale
RETVAL=0
start() {
echo -n $"Starting MaxScale: "
my_check=`status -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale`
CHECK_RET=$?
[ $CHECK_RET -eq 0 ] && echo -n " found $my_check" && success && CHECK_RET=0
daemon --pidfile $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale >& /dev/null
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$servicename
if [ $CHECK_RET -ne 0 ]; then
sleep 2
my_check=`status -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale`
CHECK_RET=$?
[ $CHECK_RET -eq 0 ] && echo -n $my_check && success || failure
fi
# Return rigth code
if [ $RETVAL -ne 0 ]; then
failure
RETVAL=$_RETVAL_NOT_RUNNING
fi
echo
return $RETVAL
}
stop() {
echo -n $"Stopping MaxScale: "
killproc -p $MAXSCALE_PIDFILE -TERM
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$servicename
# Return rigth code
if [ $RETVAL -ne 0 ]; then
RETVAL=$_RETVAL_NOT_RUNNING
fi
return $RETVAL
}
reload() {
echo -n $"Reloading MaxScale: "
killproc -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale -HUP
RETVAL=$?
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
# return 0 on success
# return 3 on any error
echo -n $"Checking MaxScale status: "
status -p $MAXSCALE_PIDFILE 'MaxScale'
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
echo -ne "\033[1A"
[ $RETVAL -eq 1 ] && warning || failure
echo -ne "\033[1B"
RETVAL=$_RETVAL_STATUS_NOT_RUNNING
else
echo -ne "\033[1A"
success
echo -ne "\033[1B"
RETVAL=$_RETVAL_STATUS_OK
fi
exit $RETVAL
;;
restart)
stop
start
;;
condrestart)
if [ -f /var/lock/subsys/$servicename ]; then
stop
start
fi
;;
reload)
reload
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
;;
esac
exit $RETVAL

View File

@ -0,0 +1,145 @@
#!/bin/sh
#
# maxscale: The SkySQL MaxScale database proxy
#
# description: MaxScale provides database specific proxy functionality
#
# processname: maxscale
#
### BEGIN INIT INFO
# Provides: maxscale
# Required-Start: $syslog $local_fs
# Required-Stop: $syslog $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: The maxscale database proxy
# Description: MaxScale is a database proxy server that can be used to front end
# database clusters offering different routing, filtering and protocol choices
### END INIT INFO
#############################################
# MaxScale HOME, PIDFILE, LIB
#############################################
export MAXSCALE_HOME=@INSTALL_DIR@
export MAXSCALE_PIDFILE=$MAXSCALE_HOME/log/maxscale.pid
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MAXSCALE_HOME/lib
###############################
# LSB Exit codes (non-Status)
###############################
_RETVAL_GENERIC=1
_RETVAL_NOT_INSTALLED=5
_RETVAL_NOT_RUNNING=7
###############################
# LSB Status action Exit codes
###############################
_RETVAL_STATUS_OK=0
_RETVAL_STATUS_NOT_RUNNING=3
# Sanity checks.
[ -x $MAXSCALE_HOME/bin/maxscale ] || exit $_RETVAL_NOT_INSTALLED
#################################
# stop/start/status related vars
#################################
NAME=maxscale
DAEMON=$MAXSCALE_HOME/bin/maxscale
# Source function library.
. /lib/lsb/init-functions
# we can rearrange this easily
processname=maxscale
servicename=maxscale
RETVAL=0
start() {
log_daemon_msg "Starting MaxScale"
start_daemon -p $MAXSCALE_PIDFILE $DAEMON 2> /dev/null
sleep 2
status_of_proc -p $MAXSCALE_PIDFILE $DAEMON $NAME
log_end_msg $?
}
stop() {
log_daemon_msg "Stopping MaxScale"
killproc -p $PIDFILE $DAEMON 2>&1 /dev/null
maxscale_wait_stop
log_end_msg $?
}
reload() {
log_daemon_msg "Reloading MaxScale"
killproc -p $MAXSCALE_PIDFILE $DAEMON 1
log_end_msg $?
}
maxscale_wait_stop() {
PIDTMP=$(pidofproc -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale)
kill -TERM "${PIDTMP:-}" 2> /dev/null;
if [ -n "${PIDTMP:-}" ] && kill -0 "${PIDTMP:-}" 2> /dev/null; then
local i=0
while kill -0 "${PIDTMP:-}" 2> /dev/null; do
if [ $i = '60' ]; then
break
STATUS=2
fi
[ "$VERBOSE" != no ] && log_progress_msg "."
sleep 1
i=$(($i+1))
done
return $STATUS
else
return $STATUS
fi
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
# return 0 on success
# return 3 on any error
log_daemon_msg "Checking MaxScale"
status_of_proc -p $MAXSCALE_PIDFILE $DAEMON $NAME
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
[ $RETVAL -eq 1 ]
RETVAL=$_RETVAL_STATUS_NOT_RUNNING
else
RETVAL=$_RETVAL_STATUS_OK
fi
log_end_msg $RETVAL
;;
restart)
stop
start
;;
reload)
reload
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload}"
;;
esac
exit $RETVAL

View File

@ -0,0 +1,6 @@
add_library(log_manager SHARED log_manager.cc)
target_link_libraries(log_manager pthread aio stdc++)
install(TARGETS log_manager DESTINATION lib)
if(BUILD_TESTS)
add_subdirectory(test)
endif()

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

@ -0,0 +1,5 @@
add_executable(testlog testlog.c)
add_executable(testorder testorder.c)
target_link_libraries(testlog pthread log_manager utils)
target_link_libraries(testorder pthread log_manager utils)
add_test(NAME TestLogOrder COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/logorder.sh ${CMAKE_CURRENT_BINARY_DIR}/test.log 500 0 500 ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -2,24 +2,33 @@
if [[ $# -lt 4 ]]
then
echo "Usage: logorder.sh <iterations> <frequency of flushes> <message size>"
echo "Usage: logorder.sh <iterations> <frequency of flushes> <message size> <log file>"
echo "To disable log flushing, use 0 for flush frequency"
exit
fi
rm *.log
if [ $# -eq 5 ]
then
TDIR=$5
else
TDIR=$PWD
fi
#Create large messages
$PWD/testorder $1 $2 $3
$TDIR/testorder $1 $2 $3
TESTLOG=$4
MCOUNT=$1
BLOCKS=`cat skygw_err1.log |tr -s ' '|grep -o 'block:[[:digit:]]\+'|cut -d ':' -f 2`
MESSAGES=`cat skygw_err1.log |tr -s ' '|grep -o 'message|[[:digit:]]\+'|cut -d '|' -f 2`
BLOCKS=`cat $TDIR/skygw_err1.log |tr -s ' '|grep -o 'block:[[:digit:]]\+'|cut -d ':' -f 2`
MESSAGES=`cat $TDIR/skygw_err1.log |tr -s ' '|grep -o 'message|[[:digit:]]\+'|cut -d '|' -f 2`
prev=0
error=0
all_errors=0
for i in $BLOCKS
do
@ -27,6 +36,7 @@ do
if [[ $i -le $prev ]]
then
error=1
all_errors=1
echo "block mismatch: $i was after $prev." >> $TESTLOG
fi
prev=$i
@ -48,6 +58,7 @@ do
if [[ $i -ne $(( prev + 1 )) ]]
then
error=1
all_errors=1
echo "message mismatch: $i was after $prev." >> $TESTLOG
fi
prev=$i
@ -59,3 +70,9 @@ then
else
echo "Error: block buffer messages were written in the wrong order" >> $TESTLOG
fi
if [ $# -eq 5 ]
then
cat $TESTLOG
exit $all_errors
fi

210
macros.cmake Normal file
View File

@ -0,0 +1,210 @@
macro(set_maxscale_version)
#MaxScale version number
set(MAXSCALE_VERSION_MAJOR "1")
set(MAXSCALE_VERSION_MINOR "0")
set(MAXSCALE_VERSION_PATCH "0")
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}-beta")
endmacro()
macro(set_variables)
# Installation directory
set(INSTALL_DIR "/usr/local/skysql/maxscale/" CACHE PATH "MaxScale installation directory.")
# Build type
set(BUILD_TYPE "None" CACHE STRING "Build type, possible values are:None, Debug, Optimized.")
# hostname or IP address of MaxScale's host
set(TEST_HOST "127.0.0.1" CACHE STRING "hostname or IP address of MaxScale's host")
# port of read connection router module
set(TEST_PORT_RW "4008" CACHE STRING "port of read connection router module")
# port of read/write split router module
set(TEST_PORT_RW "4006" CACHE STRING "port of read/write split router module")
# port of read/write split router module with hints
set(TEST_PORT_RW_HINT "4006" CACHE STRING "port of read/write split router module with hints")
# master test server server_id
set(TEST_MASTER_ID "3000" CACHE STRING "master test server server_id")
# username of MaxScale user
set(TEST_USER "maxuser" CACHE STRING "username of MaxScale user")
# password of MaxScale user
set(TEST_PASSWORD "maxpwd" CACHE STRING "password of MaxScale user")
# Use static version of libmysqld
set(STATIC_EMBEDDED TRUE CACHE BOOL "Use static version of libmysqld")
# Build RabbitMQ components
set(BUILD_RABBITMQ FALSE CACHE BOOL "Build RabbitMQ components")
# Use gcov build flags
set(GCOV FALSE CACHE BOOL "Use gcov build flags")
# Install init.d scripts and ldconf configuration files
set(INSTALL_SYSTEM_FILES TRUE CACHE BOOL "Install init.d scripts and ldconf configuration files")
# Build tests
set(BUILD_TESTS TRUE CACHE BOOL "Build tests")
endmacro()
macro(check_deps)
# Check for libraries MaxScale depends on
set(MAXSCALE_DEPS aio ssl crypt crypto z m dl rt pthread)
foreach(lib ${MAXSCALE_DEPS})
find_library(lib${lib} ${lib})
if((DEFINED lib${lib}) AND (${lib${lib}} STREQUAL "lib${lib}-NOTFOUND"))
set(DEPS_ERROR TRUE)
set(FAILED_DEPS "${FAILED_DEPS} lib${lib}")
elseif(DEBUG_OUTPUT)
message(STATUS "Library was found at: ${lib${lib}}")
endif()
endforeach()
if(DEPS_ERROR)
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Cannot find dependencies: ${FAILED_DEPS}")
endif()
endmacro()
macro(check_dirs)
# This variable is used to prevent redundant checking of dependencies
set(DEPS_OK TRUE CACHE BOOL "If all the dependencies were found.")
# Find the MySQL headers if they were not defined
if(DEFINED MYSQL_DIR)
if(DEBUG_OUTPUT)
message(STATUS "Searching for MySQL headers at: ${MYSQL_DIR}")
endif()
find_path(MYSQL_DIR_LOC mysql.h PATHS ${MYSQL_DIR} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH)
endif()
find_path(MYSQL_DIR_LOC mysql.h PATH_SUFFIXES mysql mariadb)
if(DEBUG_OUTPUT)
message(STATUS "Search returned: ${MYSQL_DIR_LOC}")
endif()
if(${MYSQL_DIR_LOC} STREQUAL "MYSQL_DIR_LOC-NOTFOUND")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Fatal Error: MySQL headers were not found.")
else()
message(STATUS "Using MySQL headers found at: ${MYSQL_DIR}")
set(MYSQL_DIR ${MYSQL_DIR_LOC} CACHE PATH "Path to MySQL headers" FORCE)
endif()
set(MYSQL_DIR_LOC "" INTERNAL)
# Find the errmsg.sys file if it was not defied
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")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Fatal Error: The errmsg.sys file was not found, please define the path to it by using -DERRMSG=<path>")
else()
message(STATUS "Using errmsg.sys found at: ${ERRMSG_FILE}")
endif()
set(ERRMSG ${ERRMSG_FILE} CACHE FILEPATH "Path to the errmsg.sys file." FORCE)
set(ERRMSG_FILE "" INTERNAL)
# Find the embedded mysql library
if(STATIC_EMBEDDED)
set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
if (DEFINED EMBEDDED_LIB)
if(DEBUG_OUTPUT)
message(STATUS "Searching for libmysqld.a at: ${EMBEDDED_LIB}")
endif()
find_library(EMBEDDED_LIB_STATIC libmysqld.a PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH)
else()
find_library(EMBEDDED_LIB_STATIC libmysqld.a PATH_SUFFIXES mysql mariadb)
endif()
if(DEBUG_OUTPUT)
message(STATUS "Search returned: ${EMBEDDED_LIB_STATIC}")
endif()
set(EMBEDDED_LIB ${EMBEDDED_LIB_STATIC} CACHE FILEPATH "Path to libmysqld" FORCE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES})
set(OLD_SUFFIXES "" INTERNAL)
else()
if (DEFINED EMBEDDED_LIB)
if(DEBUG_OUTPUT)
message(STATUS "Searching for libmysqld.so at: ${EMBEDDED_LIB}")
endif()
find_library(EMBEDDED_LIB_DYNAMIC mysqld PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH)
else()
find_library(EMBEDDED_LIB_DYNAMIC mysqld PATH_SUFFIXES mysql mariadb)
endif()
if(DEBUG_OUTPUT)
message(STATUS "Search returned: ${EMBEDDED_LIB_DYNAMIC}")
endif()
set(EMBEDDED_LIB ${EMBEDDED_LIB_DYNAMIC} CACHE FILEPATH "Path to libmysqld" FORCE)
endif()
set(EMBEDDED_LIB_DYNAMIC "" INTERNAL)
set(EMBEDDED_LIB_STATIC "" INTERNAL)
# Inform the user about the embedded library
if( (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_STATIC-NOTFOUND") OR (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_DYNAMIC-NOTFOUND"))
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
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>")
else()
get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} REALPATH)
message(STATUS "Using embedded library: ${EMBEDDED_LIB}")
endif()
# Check which init.d script to install
find_file(RPM_FNC functions PATHS /etc/rc.d/init.d)
if(${RPM_FNC} MATCHES "RPM_FNC-NOTFOUND")
find_file(DEB_FNC init-functions PATHS /lib/lsb)
if(${DEB_FNC} MATCHES "DEB_FNC-NOTFOUND")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
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.")
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()
else()
set(DEB_BASED FALSE CACHE BOOL "If init.d script uses /lib/lsb/init-functions instead of /etc/rc.d/init.d/functions.")
endif()
set(DEB_FNC "" INTERNAL)
set(RPM_FNC "" INTERNAL)
#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")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Cannot find RabbitMQ libraries, please define the path to the libraries with -DRABBITMQ_LIB=<path>")
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")
set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.")
message(FATAL_ERROR "Cannot find RabbitMQ headers, please define the path to the headers with -DRABBITMQ_HEADERS=<path>")
else()
set(RABBITMQ_HEADERS ${RMQ_HEADERS} CACHE PATH "Path to RabbitMQ headers" FORCE)
message(STATUS "Using RabbitMQ headers found at: ${RABBITMQ_HEADERS}")
endif()
endif()
endmacro()

2
maxscale.conf.in Normal file
View File

@ -0,0 +1,2 @@
@INSTALL_DIR@/modules
@INSTALL_DIR@/lib

View File

@ -0,0 +1,6 @@
add_library(query_classifier SHARED query_classifier.cc)
target_link_libraries(query_classifier ${EMBEDDED_LIB})
install(TARGETS query_classifier DESTINATION lib)
if(BUILD_TESTS)
add_subdirectory(test)
endif()

View File

@ -359,17 +359,37 @@ static bool create_parse_tree(
Parser_state parser_state;
bool failp = FALSE;
const char* virtual_db = "skygw_virtual";
#if defined(SS_DEBUG_EXTRA)
LOGIF(LM, (skygw_log_write_flush(
LOGFILE_MESSAGE,
"[readwritesplit:create_parse_tree] 1.")));
#endif
if (parser_state.init(thd, thd->query(), thd->query_length())) {
failp = TRUE;
goto return_here;
}
mysql_reset_thd_for_next_command(thd);
/** Set some database to thd so that parsing won't fail because of
* missing database. Then parse. */
failp = thd->set_db(virtual_db, strlen(virtual_db));
#if defined(SS_DEBUG_EXTRA)
LOGIF(LM, (skygw_log_write_flush(
LOGFILE_MESSAGE,
"[readwritesplit:create_parse_tree] 2.")));
#endif
mysql_reset_thd_for_next_command(thd);
#if defined(SS_DEBUG_EXTRA)
LOGIF(LM, (skygw_log_write_flush(
LOGFILE_MESSAGE,
"[readwritesplit:create_parse_tree] 3.")));
#endif
/**
* Set some database to thd so that parsing won't fail because of
* missing database. Then parse.
*/
failp = thd->set_db(virtual_db, strlen(virtual_db));
#if defined(SS_DEBUG_EXTRA)
LOGIF(LM, (skygw_log_write_flush(
LOGFILE_MESSAGE,
"[readwritesplit:create_parse_tree] 4.")));
#endif
if (failp) {
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
@ -377,6 +397,11 @@ static bool create_parse_tree(
}
failp = parse_sql(thd, &parser_state, NULL);
#if defined(SS_DEBUG_EXTRA)
LOGIF(LM, (skygw_log_write_flush(
LOGFILE_MESSAGE,
"[readwritesplit:create_parse_tree] 5.")));
#endif
if (failp) {
LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG,

View File

@ -0,0 +1 @@
add_subdirectory(canonical_tests)

View File

@ -0,0 +1,12 @@
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
${CMAKE_CURRENT_BINARY_DIR}/test.log
${CMAKE_CURRENT_SOURCE_DIR}/input.sql
${CMAKE_CURRENT_BINARY_DIR}/output.sql
${CMAKE_CURRENT_SOURCE_DIR}/expected.sql
$<TARGET_FILE:canonizer>)

View File

@ -1,5 +1,5 @@
#! /bin/sh
if [[ $# -ne 4 ]]
if [[ $# -lt 4 ]]
then
echo "Usage: canontest.sh <logfile name> <input file> <output file> <expected output>"
exit 0
@ -9,13 +9,29 @@ INPUT=$2
OUTPUT=$3
EXPECTED=$4
DIFFLOG=diff.out
$PWD/canonizer $INPUT $OUTPUT
if [ $# -eq 5 ]
then
EXECUTABLE=$5
else
EXECUTABLE=$PWD/canonizer
fi
$EXECUTABLE $INPUT $OUTPUT
diff $OUTPUT $EXPECTED > $DIFFLOG
if [ $? -eq 0 ]
then
echo "PASSED" >> $TESTLOG
exval=0
else
echo "FAILED" >> $TESTLOG
echo "Diff output: " >> $TESTLOG
cat $DIFFLOG >> $TESTLOG
exval=1
fi
if [ $# -eq 5 ]
then
cat $TESTLOG
exit $exval
fi

View File

@ -1,7 +1,7 @@
select md5(?) =?, sleep(?), rand(?);
select * from my1 where md5(?) =?;
select md5(?) =?;
select * from my1 where md5(?) =?;
select md5("?") =?, sleep(?), rand(?)
select * from my1 where md5("?") =?
select md5("?") =?
select * from my1 where md5("?") =?
select sleep(?)
select * from tst where lname='?'
select ?,?,?,?,?,? from tst
@ -13,5 +13,5 @@ create table tst(fname varchar(30), lname varchar(30))
update tst set lname="?" where fname like '?' or lname like '?'
delete from tst where lname like '?' and fname like '?'
select ? from tst where fname='?' or lname like '?'
select ?,?,?,? from tst where name='?' or name='?' or name='?'
select ?,?,?,? from tst where name='?' or name='?' or name='?' or name='?'
select count(?),count(?),count(?),count(?),count (?),count(?) from tst

View File

@ -1,44 +1,21 @@
cmake_minimum_required (VERSION 2.6)
if (NOT ( DEFINED MYSQL_CLIENT_LIB ) )
find_library(MYSQL_CLIENT_LIB NAMES mysqlclient PATHS /usr/lib /usr/lib64 PATH_SUFFIXES mysql mariadb)
endif()
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /usr/lib/mariadb /usr/lib64/mariadb)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/include /usr/local/include /usr/include/mysql /usr/local/include/mysql /usr/include/mariadb /usr/local/include/mariadb)
if (NOT ( DEFINED MYSQL_CLIENT_HEADERS ) )
find_path(MYSQL_CLIENT_HEADERS NAMES mysql.h PATH_SUFFIXES mysql mariadb)
endif()
include(InstallRequiredSystemLibraries)
project (consumer)
find_path(MYSQL_INCLUDE_DIRS mysql.h)
find_library(MYSQL_LIBRARIES NAMES mysqlclient)
find_library(RABBITMQ_C_LIBRARIES NAMES rabbitmq)
include_directories(${MYSQL_INCLUDE_DIRS})
include_directories(${RABBITMQ_C_INCLUDE_DIRS})
include_directories(${CMAKE_SOURCE_DIR}/inih)
add_subdirectory (inih)
link_directories(${CMAKE_SOURCE_DIR}/inih)
if(RABBITMQ_C_LIBRARIES AND MYSQL_LIBRARIES AND MYSQL_INCLUDE_DIRS)
add_executable (consumer consumer.c ${MYSQL_LIBRARIES} ${RABBITMQ_C_LIBRARIES})
target_link_libraries(consumer mysqlclient)
target_link_libraries(consumer rabbitmq)
target_link_libraries(consumer inih)
install(TARGETS consumer DESTINATION bin)
install(FILES consumer.cnf DESTINATION share/consumer)
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)
install(FILES consumer.cnf DESTINATION etc)
else(RABBITMQ_C_LIBRARIES AND MYSQL_LIBRARIES AND MYSQL_INCLUDE_DIRS)
message(FATAL_ERROR "Error: Can not find requred libraries: libmysqld, librabbitmq.")
else()
endif(RABBITMQ_C_LIBRARIES AND MYSQL_LIBRARIES AND MYSQL_INCLUDE_DIRS)
message(FATAL_ERROR "Error: Can not find requred libraries and headers: librabbitmq libmysqlclient")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "RabbitMQ Consumer Client")
set(CPACK_PACKAGE_NAME "RabbitMQ Consumer")
set(CPACK_GENERATOR "RPM")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_RPM_PACKAGE_NAME "rabbitmq-consumer")
set(CPACK_RPM_PACKAGE_VENDOR "SkySQL Ab")
set(CPACK_RPM_PACKAGE_AUTOREQPROV " no")
include(CPack)
endif()

6
server/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
add_subdirectory(core)
add_subdirectory(modules)
add_subdirectory(inih)
if(BUILD_TESTS)
add_subdirectory(test)
endif()

View File

@ -0,0 +1,22 @@
file(GLOB FULLCORE_SRC *.c)
add_library(fullcore STATIC ${FULLCORE_SRC})
target_link_libraries(fullcore log_manager utils pthread ${EMBEDDED_LIB} ssl aio rt crypt dl crypto inih z m stdc++)
add_executable(maxscale atomic.c buffer.c spinlock.c gateway.c
gw_utils.c utils.c dcb.c load_utils.c session.c service.c server.c
poll.c config.c users.c hashtable.c dbusers.c thread.c gwbitmask.c
monitor.c adminusers.c secrets.c filter.c modutil.c hint.c housekeeper.c)
target_link_libraries(maxscale ${EMBEDDED_LIB} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++)
install(TARGETS maxscale DESTINATION bin)
add_executable(maxkeys maxkeys.c secrets.c utils.c)
target_link_libraries(maxkeys log_manager utils pthread crypt crypto)
install(TARGETS maxkeys DESTINATION bin)
add_executable(maxpasswd maxpasswd.c secrets.c utils.c)
target_link_libraries(maxpasswd log_manager utils pthread crypt crypto)
install(TARGETS maxpasswd DESTINATION bin)
if(BUILD_TESTS)
add_subdirectory(test)
endif()

View File

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

View File

@ -123,12 +123,6 @@ DCB *rval;
rval->dcb_errhandle_called = false;
#endif
rval->dcb_role = role;
#if 1
simple_mutex_init(&rval->dcb_write_lock, "DCB write mutex");
simple_mutex_init(&rval->dcb_read_lock, "DCB read mutex");
rval->dcb_write_active = false;
rval->dcb_read_active = false;
#endif
spinlock_init(&rval->dcb_initlock);
spinlock_init(&rval->writeqlock);
spinlock_init(&rval->delayqlock);
@ -225,43 +219,11 @@ dcb_add_to_zombieslist(DCB *dcb)
spinlock_release(&zombiespin);
return;
}
#if 1
/*<
* Add closing dcb to the top of the list.
*/
dcb->memdata.next = zombies;
zombies = dcb;
#else
if (zombies == NULL) {
zombies = dcb;
} else {
DCB *ptr = zombies;
while (ptr->memdata.next)
{
ss_info_dassert(
ptr->memdata.next->state == DCB_STATE_ZOMBIE,
"Next zombie is not in DCB_STATE_ZOMBIE state");
ss_info_dassert(
ptr != dcb,
"Attempt to add DCB to zombies list although it "
"is already there.");
if (ptr == dcb)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Attempt to add DCB to zombies "
"list when it is already in the list")));
break;
}
ptr = ptr->memdata.next;
}
if (ptr != dcb) {
ptr->memdata.next = dcb;
}
}
#endif
/*<
* Set state which indicates that it has been added to zombies
* list.
@ -396,8 +358,6 @@ DCB_CALLBACK *cb;
spinlock_release(&dcb->cb_lock);
bitmask_free(&dcb->memdata.bitmask);
simple_mutex_done(&dcb->dcb_read_lock);
simple_mutex_done(&dcb->dcb_write_lock);
free(dcb);
}
@ -411,15 +371,10 @@ DCB_CALLBACK *cb;
* the memdata.bitmask then the DCB is no longer able to be
* referenced and it can be finally removed.
*
* 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 excluded The DCB the thread currently uses, NULL or valid DCB.
*/
DCB *
dcb_process_zombies(int threadid, DCB *excluded)
dcb_process_zombies(int threadid)
{
DCB *ptr, *lptr;
DCB* dcb_list = NULL;
@ -453,10 +408,10 @@ bool succp = false;
CHK_DCB(ptr);
/*
* Skip processing of the excluded DCB or DCB's that are
* Skip processing of DCB's that are
* in the event queue waiting to be processed.
*/
if (ptr == excluded || ptr->evq.next || ptr->evq.prev)
if (ptr->evq.next || ptr->evq.prev)
{
lptr = ptr;
ptr = ptr->memdata.next;

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;
@ -1061,9 +1082,36 @@ int main(int argc, char **argv)
succp = false;
}
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();
usage();
succp = false;
break;
}
@ -1345,12 +1393,23 @@ int main(int argc, char **argv)
argv[0] = "MaxScale";
argv[1] = "-j";
argv[2] = buf;
argv[3] = "-s"; /*< store to shared memory */
argv[4] = "LOGFILE_DEBUG,LOGFILE_TRACE"; /*< ..these logs to shm */
argv[5] = "-l"; /*< write to syslog */
argv[6] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< ..these logs to syslog */
argv[7] = NULL;
skygw_logmanager_init(7, argv);
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 */
argv[6] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< ..these logs to syslog */
argv[7] = NULL;
skygw_logmanager_init(7, argv);
}
}
/*<
@ -1629,8 +1688,13 @@ static void log_flush_cb(
static void unlink_pidfile(void)
{
if (strlen(pidfile)) {
if (unlink(pidfile)) {
fprintf(stderr, "MaxScale failed to remove pidfile %s: error %d, %s\n", pidfile, errno, strerror(errno));
if (unlink(pidfile))
{
fprintf(stderr,
"MaxScale failed to remove pidfile %s: error %d, %s\n",
pidfile,
errno,
strerror(errno));
}
}
}

View File

@ -17,6 +17,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hint.h>
/**

View File

@ -76,7 +76,7 @@ unsigned char *ptr;
ptr = GWBUF_DATA(buf);
*length = *ptr++;
*length += (*ptr++ << 8);
*length += (*ptr++ << 8);
*length += (*ptr++ << 16);
ptr += 2; // Skip sequence id and COM_QUERY byte
*length = *length - 1;
*sql = (char *)ptr;
@ -111,7 +111,7 @@ unsigned char *ptr;
ptr = GWBUF_DATA(buf);
*residual = *ptr++;
*residual += (*ptr++ << 8);
*residual += (*ptr++ << 8);
*residual += (*ptr++ << 16);
ptr += 2; // Skip sequence id and COM_QUERY byte
*residual = *residual - 1;
*length = GWBUF_LENGTH(buf) - 5;
@ -143,7 +143,7 @@ GWBUF *addition;
ptr = GWBUF_DATA(orig);
length = *ptr++;
length += (*ptr++ << 8);
length += (*ptr++ << 8);
length += (*ptr++ << 16);
ptr += 2; // Skip sequence id and COM_QUERY byte
newlength = strlen(sql);
@ -178,11 +178,11 @@ GWBUF *addition;
*
* @param buf GWBUF buffer including the query
*
* @return Plaint text query if the packet type is COM_QUERY. Otherwise return
* @return Plain text query if the packet type is COM_QUERY. Otherwise return
* a string including the packet type.
*/
char* modutil_get_query(
GWBUF* buf)
char *
modutil_get_query(GWBUF *buf)
{
uint8_t* packet;
mysql_server_cmd_t packet_type;

View File

@ -60,8 +60,9 @@ MONITOR *mon;
{
return NULL;
}
mon->state = MONITOR_STATE_ALLOC;
mon->name = strdup(name);
if ((mon->module = load_module(module, MODULE_MONITOR)) == NULL)
{
LOGIF(LE, (skygw_log_write_flush(
@ -73,7 +74,8 @@ MONITOR *mon;
return NULL;
}
mon->handle = (*mon->module->startMonitor)(NULL);
mon->state |= MONITOR_STATE_RUNNING;
mon->state = MONITOR_STATE_RUNNING;
spinlock_acquire(&monLock);
mon->next = allMonitors;
allMonitors = mon;
@ -94,7 +96,7 @@ monitor_free(MONITOR *mon)
MONITOR *ptr;
mon->module->stopMonitor(mon->handle);
mon->state &= ~MONITOR_STATE_RUNNING;
mon->state = MONITOR_STATE_FREED;
spinlock_acquire(&monLock);
if (allMonitors == mon)
allMonitors = mon->next;
@ -121,7 +123,7 @@ void
monitorStart(MONITOR *monitor)
{
monitor->handle = (*monitor->module->startMonitor)(monitor->handle);
monitor->state |= MONITOR_STATE_RUNNING;
monitor->state = MONITOR_STATE_RUNNING;
}
/**
@ -132,8 +134,9 @@ monitorStart(MONITOR *monitor)
void
monitorStop(MONITOR *monitor)
{
monitor->state = MONITOR_STATE_STOPPING;
monitor->module->stopMonitor(monitor->handle);
monitor->state &= ~MONITOR_STATE_RUNNING;
monitor->state = MONITOR_STATE_STOPPED;
}
/**

View File

@ -51,6 +51,13 @@ extern int lm_enabled_logfiles_bitmask;
* zombie management
* 29/08/14 Mark Riddoch Addition of thread status data, load average
* etc.
* 23/09/14 Mark Riddoch Make use of RDHUP conditional to allow CentOS 5
* builds.
* 24/09/14 Mark Riddoch Introduction of the event queue for processing the
* incoming events rather than processing them immediately
* in the loop after the epoll_wait. This allows for better
* thread utilisaiton and fairer scheduling of the event
* processing.
*
* @endverbatim
*/
@ -204,8 +211,12 @@ poll_add_dcb(DCB *dcb)
struct epoll_event ev;
CHK_DCB(dcb);
#ifdef EPOLLRDHUP
ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLHUP | EPOLLET;
#else
ev.events = EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLET;
#endif
ev.data.ptr = dcb;
/*<
@ -380,7 +391,11 @@ DCB *zombies = NULL;
{
/* Process of the queue of waiting requests */
while (process_pollq(thread_id))
zombies = dcb_process_zombies(thread_id, NULL);
{
if (thread_data)
thread_data[thread_id].state = THREAD_ZPROCESSING;
zombies = dcb_process_zombies(thread_id);
}
atomic_add(&n_waiting, 1);
#if BLOCKINGPOLL
@ -494,15 +509,13 @@ DCB *zombies = NULL;
}
spinlock_release(&pollqlock);
}
/*< for */
}
if (thread_data)
{
thread_data[thread_id].state = THREAD_ZPROCESSING;
}
zombies = dcb_process_zombies(thread_id, NULL);
zombies = dcb_process_zombies(thread_id);
if (do_shutdown)
{
@ -515,6 +528,8 @@ DCB *zombies = NULL;
thread_data[thread_id].state = THREAD_STOPPED;
}
bitmask_clear(&poll_mask, thread_id);
/** Release mysql thread context */
mysql_thread_end();
return;
}
if (thread_data)
@ -522,8 +537,6 @@ DCB *zombies = NULL;
thread_data[thread_id].state = THREAD_IDLE;
}
} /*< while(1) */
/** Release mysql thread context */
mysql_thread_end();
}
/**
@ -762,6 +775,7 @@ uint32_t ev;
spinlock_release(&dcb->dcb_initlock);
}
#ifdef EPOLLRDHUP
if (ev & EPOLLRDHUP)
{
int eno = 0;
@ -788,6 +802,7 @@ uint32_t ev;
else
spinlock_release(&dcb->dcb_initlock);
}
#endif
spinlock_acquire(&pollqlock);
if (dcb->evq.pending_events == 0)
@ -932,12 +947,14 @@ char *str;
strcat(str, "|");
strcat(str, "HUP");
}
#ifdef EPOLLRDHUP
if (event & EPOLLRDHUP)
{
if (*str)
strcat(str, "|");
strcat(str, "RDHUP");
}
#endif
return str;
}

View File

@ -0,0 +1,13 @@
add_executable(test_hash testhash.c)
add_executable(test_spinlock testspinlock.c)
add_executable(test_filter testfilter.c)
add_executable(test_adminusers testadminusers.c)
target_link_libraries(test_hash fullcore)
target_link_libraries(test_spinlock fullcore)
target_link_libraries(test_filter fullcore)
target_link_libraries(test_adminusers fullcore)
add_test(TestHash test_hash)
add_test(TestSpinlock test_spinlock)
add_test(TestFilter test_filter)
add_test(TestAdminUsers test_adminusers)

View File

@ -210,12 +210,6 @@ typedef struct dcb {
dcb_role_t dcb_role;
SPINLOCK dcb_initlock;
DCBEVENTQ evq; /**< The event queue for this DCB */
#if 1
simple_mutex_t dcb_read_lock;
simple_mutex_t dcb_write_lock;
bool dcb_read_active;
bool dcb_write_active;
#endif
int fd; /**< The descriptor */
dcb_state_t state; /**< Current descriptor state */
int flags; /**< DCB flags */
@ -295,7 +289,7 @@ DCB *dcb_clone(DCB *);
int dcb_read(DCB *, GWBUF **);
int dcb_drain_writeq(DCB *);
void dcb_close(DCB *);
DCB *dcb_process_zombies(int, DCB*); /* Process Zombies except the one behind the pointer */
DCB *dcb_process_zombies(int); /* Process Zombies except the one behind the pointer */
void printAllDCBs(); /* Debug to print all DCB in the system */
void printDCB(DCB *); /* Debug print routine */
void dprintAllDCBs(DCB *); /* Debug to print all DCB in the system */

View File

@ -69,7 +69,7 @@ typedef struct {
void (*unregisterServer)(void *, SERVER *);
void (*defaultUser)(void *, char *, char *);
void (*diagnostics)(DCB *, void *);
void (*setInterval)(void *, unsigned long);
void (*setInterval)(void *, size_t);
void (*defaultId)(void *, unsigned long);
void (*replicationHeartbeat)(void *, int);
void (*detectStaleMaster)(void *, int);
@ -81,21 +81,30 @@ typedef struct {
*/
#define MONITOR_VERSION {1, 0, 0}
/** Monitor's poll frequency */
#define MON_BASE_INTERVAL_MS 100
/**
* Monitor state bit mask values
*/
#define MONITOR_STATE_RUNNING 0x0001
typedef enum
{
MONITOR_STATE_ALLOC = 0x00,
MONITOR_STATE_RUNNING = 0x01,
MONITOR_STATE_STOPPING = 0x02,
MONITOR_STATE_STOPPED = 0x04,
MONITOR_STATE_FREED = 0x08
} monitor_state_t;
/**
* Representation of the running monitor.
*/
typedef struct monitor {
char *name; /**< The name of the monitor module */
unsigned int state; /**< The monitor status */
monitor_state_t state; /**< The state of the monitor */
MONITOR_OBJECT *module; /**< The "monitor object" */
void *handle; /**< Handle returned from startMonitor */
int interval; /**< The monitor interval */
size_t interval; /**< The monitor interval */
struct monitor *next; /**< Next monitor in the linked list */
} MONITOR;

View File

@ -0,0 +1 @@
#define MAXSCALE_VERSION "@MAXSCALE_VERSION@"

View File

@ -0,0 +1 @@
add_library(inih ini.c)

View File

@ -0,0 +1,5 @@
include_directories(monitor)
add_subdirectory(routing)
add_subdirectory(protocol)
add_subdirectory(monitor)
add_subdirectory(filter)

View File

@ -0,0 +1,27 @@
if(BUILD_RABBITMQ)
add_library(mqfilter SHARED mqfilter.c)
target_link_libraries(mqfilter query_classifier log_manager utils rabbitmq)
install(TARGETS mqfilter DESTINATION modules)
endif()
add_library(regexfilter SHARED regexfilter.c)
target_link_libraries(regexfilter log_manager utils)
install(TARGETS regexfilter DESTINATION modules)
add_library(testfilter SHARED testfilter.c)
target_link_libraries(testfilter log_manager utils)
install(TARGETS testfilter DESTINATION modules)
add_library(qlafilter SHARED qlafilter.c)
target_link_libraries(qlafilter log_manager utils)
install(TARGETS qlafilter DESTINATION modules)
add_library(tee SHARED tee.c)
target_link_libraries(tee log_manager utils)
install(TARGETS tee DESTINATION modules)
add_library(topfilter SHARED topfilter.c)
target_link_libraries(topfilter log_manager utils)
install(TARGETS topfilter DESTINATION modules)
add_subdirectory(hint)

View File

@ -0,0 +1,4 @@
add_library(hintfilter SHARED hintfilter.c hintparser.c)
set_target_properties(hintfilter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib)
target_link_libraries(hintfilter ssl log_manager utils)
install(TARGETS hintfilter DESTINATION modules)

View File

@ -30,13 +30,15 @@
* @endverbatim
*/
#include <dcb.h>
#include <spinlock.h>
/**
* The telnetd specific protocol structure to put in the DCB.
*/
typedef struct maxscaled {
int state; /**< The connection state */
char *username; /**< The login name of the user */
SPINLOCK lock; /**< Protocol structure lock */
int state; /**< The connection state */
char *username; /**< The login name of the user */
} MAXSCALED;
#define MAXSCALED_STATE_LOGIN 1 /**< Issued login prompt */

View File

@ -0,0 +1,11 @@
add_library(mysqlmon SHARED mysql_mon.c)
target_link_libraries(mysqlmon log_manager utils ${EMBEDDED_LIB})
install(TARGETS mysqlmon DESTINATION modules)
add_library(galeramon SHARED galera_mon.c)
target_link_libraries(galeramon log_manager utils ${EMBEDDED_LIB})
install(TARGETS galeramon DESTINATION modules)
add_library(ndbclustermon SHARED ndbcluster_mon.c)
target_link_libraries(ndbclustermon log_manager utils ${EMBEDDED_LIB})
install(TARGETS ndbclustermon DESTINATION modules)

View File

@ -67,9 +67,20 @@ static void registerServer(void *, SERVER *);
static void unregisterServer(void *, SERVER *);
static void defaultUsers(void *, char *, char *);
static void diagnostics(DCB *, void *);
static void setInterval(void *, unsigned long);
static void setInterval(void *, size_t);
static MONITOR_OBJECT MyObject = { startMonitor, stopMonitor, registerServer, unregisterServer, defaultUsers, diagnostics, setInterval, NULL, NULL, NULL };
static MONITOR_OBJECT MyObject = {
startMonitor,
stopMonitor,
registerServer,
unregisterServer,
defaultUsers,
diagnostics,
setInterval,
NULL,
NULL,
NULL,
};
/**
* Implementation of the mandatory version entry point
@ -413,6 +424,7 @@ monitorMain(void *arg)
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
MONITOR_SERVERS *ptr;
long master_id;
size_t nrounds = 0;
if (mysql_thread_init())
{
@ -423,10 +435,9 @@ long master_id;
return;
}
handle->status = MONITOR_RUNNING;
while (1)
{
master_id = -1;
if (handle->shutdown)
{
handle->status = MONITOR_STOPPING;
@ -434,7 +445,23 @@ long master_id;
handle->status = MONITOR_STOPPED;
return;
}
/** Wait base interval */
thread_millisleep(MON_BASE_INTERVAL_MS);
/**
* Calculate how far away the monitor interval is from its full
* cycle and if monitor interval time further than the base
* interval, then skip monitoring checks. Excluding the first
* round.
*/
if (nrounds != 0 &&
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >
MON_BASE_INTERVAL_MS)
{
nrounds += 1;
continue;
}
nrounds += 1;
master_id = -1;
ptr = handle->databases;
while (ptr)
@ -491,7 +518,6 @@ long master_id;
ptr = ptr->next;
}
thread_millisleep(handle->interval);
}
}
@ -502,7 +528,7 @@ long master_id;
* @param interval The interval to set in monitor struct, in milliseconds
*/
static void
setInterval(void *arg, unsigned long interval)
setInterval(void *arg, size_t interval)
{
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
memcpy(&handle->interval, &interval, sizeof(unsigned long));

View File

@ -80,7 +80,7 @@ static void registerServer(void *, SERVER *);
static void unregisterServer(void *, SERVER *);
static void defaultUser(void *, char *, char *);
static void diagnostics(DCB *, void *);
static void setInterval(void *, unsigned long);
static void setInterval(void *, size_t);
static void defaultId(void *, unsigned long);
static void replicationHeartbeat(void *, int);
static void detectStaleMaster(void *, int);
@ -95,7 +95,18 @@ static int add_slave_to_master(long *, int, long);
static void monitor_set_pending_status(MONITOR_SERVERS *, int);
static void monitor_clear_pending_status(MONITOR_SERVERS *, int);
static MONITOR_OBJECT MyObject = { startMonitor, stopMonitor, registerServer, unregisterServer, defaultUser, diagnostics, setInterval, defaultId, replicationHeartbeat, detectStaleMaster };
static MONITOR_OBJECT MyObject = {
startMonitor,
stopMonitor,
registerServer,
unregisterServer,
defaultUser,
diagnostics,
setInterval,
defaultId,
replicationHeartbeat,
detectStaleMaster
};
/**
* Implementation of the mandatory version entry point
@ -577,6 +588,7 @@ int replication_heartbeat = handle->replicationHeartbeat;
int detect_stale_master = handle->detectStaleMaster;
int num_servers=0;
MONITOR_SERVERS *root_master;
size_t nrounds = 0;
if (mysql_thread_init())
{
@ -586,8 +598,8 @@ MONITOR_SERVERS *root_master;
"module. Exiting.\n")));
return;
}
handle->status = MONITOR_RUNNING;
while (1)
{
if (handle->shutdown)
@ -597,6 +609,22 @@ MONITOR_SERVERS *root_master;
handle->status = MONITOR_STOPPED;
return;
}
/** Wait base interval */
thread_millisleep(MON_BASE_INTERVAL_MS);
/**
* Calculate how far away the monitor interval is from its full
* cycle and if monitor interval time further than the base
* interval, then skip monitoring checks. Excluding the first
* round.
*/
if (nrounds != 0 &&
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >
MON_BASE_INTERVAL_MS)
{
nrounds += 1;
continue;
}
nrounds += 1;
/* reset num_servers */
num_servers = 0;
@ -686,10 +714,7 @@ MONITOR_SERVERS *root_master;
ptr = ptr->next;
}
}
/* wait for the configured interval */
thread_millisleep(handle->interval);
}
} /*< while (1) */
}
/**
@ -704,7 +729,7 @@ defaultId(void *arg, unsigned long id)
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
memcpy(&handle->id, &id, sizeof(unsigned long));
}
/**
* Set the monitor sampling interval.
*
@ -712,7 +737,7 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
* @param interval The interval to set in monitor struct, in milliseconds
*/
static void
setInterval(void *arg, unsigned long interval)
setInterval(void *arg, size_t interval)
{
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
memcpy(&handle->interval, &interval, sizeof(unsigned long));

View File

@ -61,9 +61,20 @@ static void registerServer(void *, SERVER *);
static void unregisterServer(void *, SERVER *);
static void defaultUsers(void *, char *, char *);
static void diagnostics(DCB *, void *);
static void setInterval(void *, unsigned long);
static void setInterval(void *, size_t);
static MONITOR_OBJECT MyObject = { startMonitor, stopMonitor, registerServer, unregisterServer, defaultUsers, diagnostics, setInterval, NULL, NULL, NULL };
static MONITOR_OBJECT MyObject = {
startMonitor,
stopMonitor,
registerServer,
unregisterServer,
defaultUsers,
diagnostics,
setInterval,
NULL,
NULL,
NULL
};
/**
* Implementation of the mandatory version entry point
@ -410,6 +421,7 @@ monitorMain(void *arg)
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
MONITOR_SERVERS *ptr;
long master_id;
size_t nrounds = 0;
if (mysql_thread_init())
{
@ -420,10 +432,9 @@ long master_id;
return;
}
handle->status = MONITOR_RUNNING;
while (1)
{
master_id = -1;
if (handle->shutdown)
{
handle->status = MONITOR_STOPPING;
@ -432,6 +443,23 @@ long master_id;
return;
}
/** Wait base interval */
thread_millisleep(MON_BASE_INTERVAL_MS);
/**
* Calculate how far away the monitor interval is from its full
* cycle and if monitor interval time further than the base
* interval, then skip monitoring checks. Excluding the first
* round.
*/
if (nrounds != 0 &&
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >
MON_BASE_INTERVAL_MS)
{
nrounds += 1;
continue;
}
nrounds += 1;
master_id = -1;
ptr = handle->databases;
while (ptr)
@ -452,8 +480,6 @@ long master_id;
ptr = ptr->next;
}
thread_millisleep(handle->interval);
}
}
@ -464,7 +490,7 @@ long master_id;
* @param interval The interval to set in monitor struct, in milliseconds
*/
static void
setInterval(void *arg, unsigned long interval)
setInterval(void *arg, size_t interval)
{
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
memcpy(&handle->interval, &interval, sizeof(unsigned long));

View File

@ -0,0 +1,24 @@
add_library(MySQLClient SHARED mysql_client.c mysql_common.c)
target_link_libraries(MySQLClient log_manager utils)
install(TARGETS MySQLClient DESTINATION modules)
add_library(MySQLBackend SHARED mysql_backend.c mysql_common.c)
target_link_libraries(MySQLBackend log_manager utils)
install(TARGETS MySQLBackend DESTINATION modules)
add_library(telnetd SHARED telnetd.c)
target_link_libraries(telnetd log_manager utils)
install(TARGETS telnetd DESTINATION modules)
add_library(HTTPD SHARED httpd.c)
target_link_libraries(HTTPD log_manager utils)
install(TARGETS HTTPD DESTINATION modules)
add_library(maxscaled SHARED maxscaled.c)
target_link_libraries(maxscaled log_manager utils)
install(TARGETS maxscaled DESTINATION modules)

View File

@ -166,7 +166,6 @@ char *password;
{
dcb_printf(dcb, "FAILED");
maxscaled->state = MAXSCALED_STATE_LOGIN;
free(maxscaled->username);
}
gwbuf_consume(head, GWBUF_LENGTH(head));
free(password);
@ -276,16 +275,18 @@ int n_connect = 0;
client_dcb->fd = so;
client_dcb->remote = strdup(inet_ntoa(addr.sin_addr));
memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL));
client_dcb->session =
session_alloc(dcb->session->service, client_dcb);
maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED));
client_dcb->protocol = (void *)maxscaled_pr;
if (maxscaled_pr == NULL)
{
if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL)
{
client_dcb->protocol = NULL;
dcb_add_to_zombieslist(client_dcb);
return n_connect;
}
maxscaled_pr->username = NULL;
spinlock_init(&maxscaled_pr->lock);
client_dcb->protocol = (void *)maxscaled_pr;
client_dcb->session =
session_alloc(dcb->session->service, client_dcb);
if (poll_add_dcb(client_dcb) == -1)
{
@ -294,7 +295,6 @@ int n_connect = 0;
}
n_connect++;
maxscaled_pr->state = MAXSCALED_STATE_LOGIN;
maxscaled_pr->username = NULL;
dcb_printf(client_dcb, "USER");
}
}
@ -313,11 +313,16 @@ maxscaled_close(DCB *dcb)
{
MAXSCALED *maxscaled = dcb->protocol;
if (maxscaled && maxscaled->username)
if (!maxscaled)
return 0;
spinlock_acquire(&maxscaled->lock);
if (maxscaled->username)
{
free(maxscaled->username);
maxscaled->username = NULL;
}
spinlock_release(&maxscaled->lock);
return 0;
}

View File

@ -0,0 +1,18 @@
add_library(testroute SHARED testroute.c)
target_link_libraries(testroute log_manager utils)
install(TARGETS testroute DESTINATION modules)
add_library(readconnroute SHARED readconnroute.c)
target_link_libraries(readconnroute log_manager utils)
install(TARGETS readconnroute DESTINATION modules)
add_library(debugcli SHARED debugcli.c debugcmd.c)
target_link_libraries(debugcli log_manager utils)
install(TARGETS debugcli DESTINATION modules)
add_library(cli SHARED cli.c debugcmd.c)
target_link_libraries(cli log_manager utils)
install(TARGETS cli DESTINATION modules)
add_subdirectory(readwritesplit)
add_subdirectory(binlog)

View File

@ -0,0 +1,4 @@
add_library(binlogrouter SHARED blr.c blr_master.c blr_cache.c blr_slave.c blr_file.c)
set_target_properties(binlogrouter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib)
target_link_libraries(binlogrouter ssl pthread log_manager ${EMBEDDED_LIB})
install(TARGETS binlogrouter DESTINATION modules)

View File

@ -0,0 +1,6 @@
add_library(readwritesplit SHARED readwritesplit.c)
target_link_libraries(readwritesplit ssl pthread log_manager utils query_classifier ${EMBEDDED_LIB})
install(TARGETS readwritesplit DESTINATION modules)
if(BUILD_TESTS)
add_subdirectory(test)
endif()

View File

@ -0,0 +1,3 @@
add_test(NAME ReadWriteSplitTest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/rwsplit.sh testrwsplit.log ${TEST_HOST} ${TEST_PORT_RW} ${TEST_MASTER_ID} ${TEST_USER} ${TEST_PASSWORD} ${CMAKE_CURRENT_SOURCE_DIR})
set_tests_properties(ReadWriteSplitTest PROPERTIES DEPENDS RunExecutable)
add_subdirectory(test_hints)

View File

@ -1,5 +1,5 @@
#!/bin/sh
NARGS=6
NARGS=7
TLOG=$1
THOST=$2
TPORT=$3
@ -7,10 +7,10 @@ TMASTER_ID=$4
TUSER=$5
TPWD=$6
if [ $# != $NARGS ] ;
if [ $# -lt $(( NARGS - 1 )) ] ;
then
echo""
echo "Wrong number of arguments, gave "$#" but "$NARGS" is required"
echo "Wrong number of arguments, gave "$#" but "$(( NARGS - 1 ))" is required"
echo ""
echo "Usage :"
echo " rwsplit.sh <log filename> <host> <port> <master id> <user> <password>"
@ -18,12 +18,20 @@ echo ""
exit 1
fi
if [ "$#" == "$NARGS" ]
then
echo "CTest mode"
TDIR=$7 #this is only used by CMake
echo "Test directory is: $TDIR"
else
TDIR=.
fi
RUNCMD=mysql\ --host=$THOST\ -P$TPORT\ -u$TUSER\ -p$TPWD\ --unbuffered=true\ --disable-reconnect\ --silent
TINPUT=test_transaction_routing2.sql
TRETVAL=0
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -32,7 +40,7 @@ fi
TINPUT=test_transaction_routing2b.sql
TRETVAL=0
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -41,7 +49,7 @@ fi
TINPUT=test_transaction_routing3.sql
TRETVAL=2
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TMASTER_ID" ]; then
echo "$TINPUT FAILED, return value $a when one of the slave IDs was expected">>$TLOG;
else
@ -50,7 +58,7 @@ fi
TINPUT=test_transaction_routing3b.sql
TRETVAL=2
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TMASTER_ID" ]; then
echo "$TINPUT FAILED, return value $a when one of the slave IDs was expected">>$TLOG;
else
@ -60,7 +68,7 @@ fi
# test implicit transaction, that is, not started explicitly, autocommit=0
TINPUT=test_transaction_routing4.sql
TRETVAL=0
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -69,7 +77,7 @@ fi
TINPUT=test_transaction_routing4b.sql
TRETVAL=0
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -80,7 +88,7 @@ fi
TINPUT=select_for_var_set.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -90,7 +98,7 @@ fi
TINPUT=test_implicit_commit1.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -99,7 +107,7 @@ fi
TINPUT=test_implicit_commit2.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -108,7 +116,7 @@ fi
TINPUT=test_implicit_commit3.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -117,7 +125,7 @@ fi
TINPUT=test_implicit_commit4.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -126,7 +134,7 @@ fi
TINPUT=test_implicit_commit5.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -135,7 +143,7 @@ fi
TINPUT=test_implicit_commit6.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -144,7 +152,7 @@ fi
TINPUT=test_implicit_commit7.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -153,7 +161,7 @@ fi
TINPUT=test_autocommit_disabled1.sql
TRETVAL=1
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -162,7 +170,7 @@ fi
TINPUT=test_autocommit_disabled1b.sql
TRETVAL=1
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -173,7 +181,7 @@ fi
# it is again enabled.
TINPUT=test_autocommit_disabled2.sql
TRETVAL=1
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -181,10 +189,10 @@ else
fi
TINPUT=set_autocommit_disabled.sql
`$RUNCMD < ./$TINPUT`
`$RUNCMD < $TDIR/$TINPUT`
TINPUT=test_after_autocommit_disabled.sql
TRETVAL=$TMASTER_ID
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" = "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when it was not accetable">>$TLOG;
else
@ -194,37 +202,37 @@ fi
TINPUT=test_sescmd.sql
TRETVAL=2
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
echo "$TINPUT PASSED">>$TLOG ;
fi
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
echo "$TINPUT PASSED">>$TLOG ;
fi
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
echo "$TINPUT PASSED">>$TLOG ;
fi
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
echo "$TINPUT PASSED">>$TLOG ;
fi
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
echo "$TINPUT PASSED">>$TLOG ;
fi
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
else
@ -232,7 +240,7 @@ else
fi
TINPUT=test_temporary_table.sql
a=`$RUNCMD < ./$TINPUT`
a=`$RUNCMD < $TDIR/$TINPUT`
TRETVAL=1
if [ "$a" != "$TRETVAL" ]; then
echo "$TINPUT FAILED, return value $a when $TRETVAL was expected">>$TLOG;
@ -252,7 +260,7 @@ do
then
printf "."
fi
a=`$RUNCMD < $TINPUT 2>&1`
a=`$RUNCMD < $TDIR/$TINPUT 2>&1`
if [[ "`echo "$a"|grep -i 'error'`" != "" ]]
then
err=`echo "$a" | grep -i error`
@ -278,7 +286,7 @@ do
then
printf "."
fi
b=`$RUNCMD < $TINPUT 2>&1`
b=`$RUNCMD < $TDIR/$TINPUT 2>&1`
if [[ "`echo "$b"|grep -i 'null\|error'`" != "" ]]
then
err=`echo "$b" | grep -i null\|error`
@ -292,3 +300,8 @@ else
echo "Test FAILED at iteration $((j+1))" >> $TLOG
fi
echo "" >> $TLOG
if [ $# -eq $NARGS ]
then
cat $TLOG
fi

View File

@ -0,0 +1,3 @@
add_test(NAME SimpleHintTest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/rwsplit_hints.sh hints.log ${TEST_HOST} ${TEST_PORT_RW_HINT} ${TEST_MASTER_ID} ${TEST_USER} ${TEST_PASSWORD} simple_tests ${CMAKE_CURRENT_SOURCE_DIR})
add_test(NAME ComplexHintTest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/rwsplit_hints.sh hints.log ${TEST_HOST} ${TEST_PORT_RW_HINT} ${TEST_MASTER_ID} ${TEST_USER} ${TEST_PASSWORD} complex_tests ${CMAKE_CURRENT_SOURCE_DIR})
add_test(NAME StackHintTest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/rwsplit_hints.sh hints.log ${TEST_HOST} ${TEST_PORT_RW_HINT} ${TEST_MASTER_ID} ${TEST_USER} ${TEST_PASSWORD} stack_tests ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -1,5 +1,5 @@
#!/bin/bash
NARGS=7
NARGS=8
TLOG=$1
THOST=$2
TPORT=$3
@ -8,10 +8,10 @@ TUSER=$5
TPWD=$6
TESTINPUT=$7
if [ $# != $NARGS ] ;
if [ $# -lt $(( NARGS - 1 )) ] ;
then
echo""
echo "Wrong number of arguments, gave "$#" but "$NARGS" is required"
echo "Wrong number of arguments, gave "$#" but "$(( NARGS - 1 ))" is required"
echo ""
echo "Usage :"
echo " rwsplit_hints.sh <log filename> <host> <port> <master id> <user> <password> <test file>"
@ -19,6 +19,14 @@ echo ""
exit 1
fi
if [ $# -eq $NARGS ]
then
TDIR=$8
else
TDIR=.
fi
TESTINPUT=$TDIR/$TESTINPUT
RUNCMD=mysql\ --host=$THOST\ -P$TPORT\ -u$TUSER\ -p$TPWD\ --unbuffered=true\ --disable-reconnect\ --silent\ --comment
i=0
@ -63,3 +71,8 @@ then
else
echo "Test set: FAILED">>$TLOG;
fi
if [ $# -eq $NARGS ]
then
cat $TLOG
fi

View File

@ -0,0 +1,7 @@
file(COPY MaxScale_test.cnf DESTINATION ${CMAKE_BINARY_DIR}/etc)
file(RENAME ${CMAKE_BINARY_DIR}/etc/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf)
#add_test(NAME RunExecutable COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/startmaxscale.sh "${CMAKE_BINARY_DIR}/bin/" "-c ${CMAKE_BINARY_DIR}")
#set_tests_properties(RunExecutable PROPERTIES TIMEOUT 2)
#add_test(NAME KillExecutable COMMAND killall -KILL maxscale)
#set_tests_properties(KillExecutable PROPERTIES DEPENDS StackHintTest ) #this needs to be the last test that requires a running maxscale

5
server/test/startmaxscale.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
killall -KILL maxscale
sleep 1
setsid $1/maxscale $2
exit 0

2
utils/CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
add_library(utils skygw_utils.cc)
target_link_libraries(utils stdc++)