Merge branch 'develop' into shm_log_fix
Conflicts: log_manager/log_manager.cc
This commit is contained in:
commit
32575e3fc0
@ -98,7 +98,7 @@ 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)
|
||||
|
||||
install(DIRECTORY DESTINATION log)
|
||||
# See if we are on a RPM-capable or DEB-capable system
|
||||
find_program(RPMBUILD rpmbuild)
|
||||
find_program(DEBBUILD dpkg-buildpackage)
|
||||
@ -136,10 +136,16 @@ 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(buildtests
|
||||
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
|
||||
COMMENT "Building test suite..." VERBATIM
|
||||
)
|
||||
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 cp -vn ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf
|
||||
COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null"
|
||||
COMMAND /bin/sh -c "make test || echo \"Test results written to: ${CMAKE_BINARY_DIR}/Testing/Temporary/\""
|
||||
COMMAND killall maxscale
|
||||
COMMENT "Running full test suite" VERBATIM)
|
||||
COMMENT "Running full test suite..." VERBATIM)
|
2
README
2
README
@ -29,7 +29,7 @@ issues and communicate with the MaxScale community.
|
||||
or use the [forum](http://groups.google.com/forum/#!forum/maxscale) interface
|
||||
|
||||
Bugs can be reported in the MariaDB Corporation bugs database
|
||||
[bug.skysql.com](http://bugs.skysql.com)
|
||||
[bug.mariadb.com](http://bugs.mariadb.com)
|
||||
|
||||
\section Building Building MaxScale
|
||||
|
||||
|
@ -19,58 +19,58 @@ else
|
||||
fi
|
||||
maxadmin --password=skysql help >& /dev/null
|
||||
if [ $? -eq "1" ]; then
|
||||
echo "Auth test (long option): Failed"
|
||||
echo "Auth test (long option): Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Auth test (long option): Passed"
|
||||
echo "Auth test (long option): Passed"
|
||||
fi
|
||||
|
||||
maxadmin -pskysql enable log debug >& /dev/null
|
||||
if [ $? -eq "1" ]; then
|
||||
echo "Enable debug log: Failed"
|
||||
echo "Enable debug log: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Enable debug log: Passed"
|
||||
echo "Enable debug log: Passed"
|
||||
fi
|
||||
|
||||
maxadmin -pskysql enable log trace >& /dev/null
|
||||
if [ $? -eq "1" ]; then
|
||||
echo "Enable trace log: Failed"
|
||||
echo "Enable trace log: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Enable trace log: Passed"
|
||||
echo "Enable trace log: Passed"
|
||||
fi
|
||||
|
||||
maxadmin -pskysql disable log debug >& /dev/null
|
||||
if [ $? -eq "1" ]; then
|
||||
echo "Disable debug log: Failed"
|
||||
echo "Disable debug log: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Disable debug log: Passed"
|
||||
echo "Disable debug log: Passed"
|
||||
fi
|
||||
|
||||
maxadmin -pskysql disable log trace >& /dev/null
|
||||
if [ $? -eq "1" ]; then
|
||||
echo "Disable trace log: Failed"
|
||||
echo "Disable trace log: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Disable trace log: Passed"
|
||||
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"
|
||||
echo "list command ($cmd): Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "list command ($cmd): Passed"
|
||||
echo "list command ($cmd): Passed"
|
||||
fi
|
||||
done
|
||||
|
||||
@ -206,5 +206,110 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
maxadmin -pskysql list services | \
|
||||
awk -F\| '{ if (NF > 1) { sub(/ +$/, "", $1); printf("show service \"%s\"\n", $1); } }' > script1.$$
|
||||
grep -cs "show service" script1.$$ >/dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "list services: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "list services: Passed"
|
||||
fi
|
||||
maxadmin -pskysql script1.$$ | grep -cs 'Service' > /dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Show Service: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Show Service: Passed"
|
||||
fi
|
||||
rm -f script1.$$
|
||||
|
||||
|
||||
maxadmin -pskysql list monitors | \
|
||||
awk -F\| '{ if (NF > 1) { sub(/ +$/, "", $1); printf("show monitor \"%s\"\n", $1); } }' > script1.$$
|
||||
grep -cs "show monitor" script1.$$ >/dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "list monitors: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "list monitors: Passed"
|
||||
fi
|
||||
maxadmin -pskysql script1.$$ | grep -cs 'Monitor' > /dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Show Monitor: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Show Monitor: Passed"
|
||||
fi
|
||||
rm -f script1.$$
|
||||
|
||||
|
||||
maxadmin -pskysql list sessions | \
|
||||
awk -F\| ' /^0x/ { if (NF > 1) { sub(/ +$/, "", $1); printf("show session \"%s\"\n", $1); } }' > script1.$$
|
||||
grep -cs "show session" script1.$$ >/dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "list sessions: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "list sessions: Passed"
|
||||
fi
|
||||
maxadmin -pskysql script1.$$ | grep -cs 'Session' > /dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Show Session: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Show Session: Passed"
|
||||
fi
|
||||
rm -f script1.$$
|
||||
|
||||
|
||||
maxadmin -pskysql list dcbs | \
|
||||
awk -F\| ' /^ 0x/ { if (NF > 1) { sub(/ +$/, "", $1); sub(/ 0x/, "0x", $1); printf("show dcb \"%s\"\n", $1); } }' > script1.$$
|
||||
grep -cs "show dcb" script1.$$ >/dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "list dcbs: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "list dcbs: Passed"
|
||||
fi
|
||||
maxadmin -pskysql script1.$$ | grep -cs 'DCB' > /dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Show DCB: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Show DCB: Passed"
|
||||
fi
|
||||
rm -f script1.$$
|
||||
|
||||
|
||||
maxadmin -pskysql list services | \
|
||||
awk -F\| '{ if (NF > 1) { sub(/ +$/, "", $1); printf("show dbusers \"%s\"\n", $1); } }' > script1.$$
|
||||
grep -cs "show dbusers" script1.$$ >/dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "list services: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "list services: Passed"
|
||||
fi
|
||||
maxadmin -pskysql script1.$$ | grep -cs 'Users table data' > /dev/null
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Show dbusers: Failed"
|
||||
failure=`expr $failure + 1`
|
||||
else
|
||||
passed=`expr $passed + 1`
|
||||
echo "Show dbusers: Passed"
|
||||
fi
|
||||
rm -f script1.$$
|
||||
|
||||
|
||||
echo "Test run complete. $passed passes, $failure failures"
|
||||
exit $failure
|
||||
|
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -2,9 +2,9 @@ maxscale (1.0-beta) UNRELEASED; urgency=low
|
||||
|
||||
* Beta release
|
||||
|
||||
-- Timofey Turenko <timofey.turenko@skysql.com> Fri, 05 Jul 2014 14:00:00 +0200
|
||||
-- Timofey Turenko <timofey.turenko@mariadb.com> Fri, 05 Jul 2014 14:00:00 +0200
|
||||
maxscale (0.7-1) UNRELEASED; urgency=low
|
||||
|
||||
* Initial release. (Closes: #XXXXXX)
|
||||
|
||||
-- Timofey Turenko <timofey.turenko@skysql.com> Tue, 11 Mar 2014 22:59:35 +0200
|
||||
-- Timofey Turenko <timofey.turenko@mariadb.com> Tue, 11 Mar 2014 22:59:35 +0200
|
||||
|
@ -270,12 +270,14 @@ static void blockbuf_register(blockbuf_t* bb);
|
||||
static void blockbuf_unregister(blockbuf_t* bb);
|
||||
static bool logfile_set_enabled(logfile_id_t id, bool val);
|
||||
static char* add_slash(char* str);
|
||||
static bool file_exists_and_is_writable(char* filename, bool* writable);
|
||||
|
||||
static bool check_file_and_path(
|
||||
char* filename,
|
||||
bool* nameconflict,
|
||||
bool* writable);
|
||||
|
||||
static bool file_is_symlink(char* filename);
|
||||
|
||||
|
||||
|
||||
|
||||
const char* get_suffix_default(void)
|
||||
{
|
||||
return ".log";
|
||||
@ -356,11 +358,6 @@ static bool logmanager_init_nomutex(
|
||||
fw = &lm->lm_filewriter;
|
||||
fn->fn_state = UNINIT;
|
||||
fw->fwr_state = UNINIT;
|
||||
|
||||
/**
|
||||
* Set global variable
|
||||
*/
|
||||
lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles;
|
||||
|
||||
/** Initialize configuration including log file naming info */
|
||||
if (!fnames_conf_init(fn, argc, argv)) {
|
||||
@ -368,14 +365,23 @@ static bool logmanager_init_nomutex(
|
||||
}
|
||||
|
||||
/** Initialize logfiles */
|
||||
if(!logfiles_init(lm)) {
|
||||
goto return_succp;
|
||||
if(!logfiles_init(lm))
|
||||
{
|
||||
err = 1;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
/** Initialize filewriter data and open the (first) log file(s)
|
||||
/**
|
||||
* Set global variable
|
||||
*/
|
||||
lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles;
|
||||
|
||||
/** Initialize filewriter data and open the (first) log file(s)
|
||||
* for each log file type. */
|
||||
if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes)) {
|
||||
goto return_succp;
|
||||
if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes))
|
||||
{
|
||||
err = 1;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
/** Initialize and start filewriter thread */
|
||||
@ -383,8 +389,9 @@ static bool logmanager_init_nomutex(
|
||||
thr_filewriter_fun,
|
||||
(void *)fw);
|
||||
|
||||
if ((err = skygw_thread_start(fw->fwr_thread)) != 0) {
|
||||
goto return_succp;
|
||||
if ((err = skygw_thread_start(fw->fwr_thread)) != 0)
|
||||
{
|
||||
goto return_succp;
|
||||
}
|
||||
/** Wait message from filewriter_thr */
|
||||
skygw_message_wait(fw->fwr_clientmes);
|
||||
@ -393,10 +400,11 @@ static bool logmanager_init_nomutex(
|
||||
lm->lm_enabled = true;
|
||||
|
||||
return_succp:
|
||||
if (err != 0) {
|
||||
if (err != 0)
|
||||
{
|
||||
/** This releases memory of all created objects */
|
||||
logmanager_done_nomutex();
|
||||
fprintf(stderr, "* Initializing logmanager failed.\n");
|
||||
fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n");
|
||||
}
|
||||
return succp;
|
||||
}
|
||||
@ -1769,7 +1777,7 @@ static bool logfiles_init(
|
||||
write_syslog);
|
||||
|
||||
if (!succp) {
|
||||
fprintf(stderr, "Initializing logfiles failed\n");
|
||||
fprintf(stderr, "*\n* Error : Initializing log files failed.\n");
|
||||
break;
|
||||
}
|
||||
lid <<= 1;
|
||||
@ -1917,10 +1925,11 @@ static char* add_slash(
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @node Check if the file exists in the local file system and if it does,
|
||||
* whether it is writable.
|
||||
*
|
||||
|
||||
/**
|
||||
* @node Check if the path and file exist in the local file system and if they do,
|
||||
* check if they are accessible and writable.
|
||||
*
|
||||
* Parameters:
|
||||
* @param filename - <usage>
|
||||
* <description>
|
||||
@ -1928,55 +1937,91 @@ static char* add_slash(
|
||||
* @param writable - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @return
|
||||
* @return true & writable if file exists and it is writable,
|
||||
* true & not writable if file exists but it can't be written,
|
||||
* false & writable if file doesn't exist but directory could be written, and
|
||||
* false & not writable if directory can't be written.
|
||||
*
|
||||
*
|
||||
* @details Note, that an space character is written to the end of file.
|
||||
* @details Note, that a space character is written to the end of file.
|
||||
* TODO: recall what was the reason for not succeeding with simply
|
||||
* calling access, and fstat. vraa 26.11.13
|
||||
*
|
||||
*/
|
||||
static bool file_exists_and_is_writable(
|
||||
char* filename,
|
||||
bool* writable)
|
||||
static bool check_file_and_path(
|
||||
char* filename,
|
||||
bool* writable)
|
||||
{
|
||||
int fd;
|
||||
bool exists = true;
|
||||
|
||||
if (filename == NULL)
|
||||
{
|
||||
exists = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = open(filename, O_CREAT|O_EXCL, S_IRWXU);
|
||||
|
||||
/** file exist */
|
||||
if (fd == -1)
|
||||
{
|
||||
/** Open file and write a byte for test */
|
||||
fd = open(filename, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG);
|
||||
|
||||
if (fd != -1)
|
||||
{
|
||||
char c = ' ';
|
||||
if (write(fd, &c, 1) == 1)
|
||||
{
|
||||
*writable = true;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
exists = false;
|
||||
}
|
||||
}
|
||||
return exists;
|
||||
int fd;
|
||||
bool exists;
|
||||
|
||||
if (filename == NULL)
|
||||
{
|
||||
exists = false;
|
||||
*writable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = open(filename, O_CREAT|O_EXCL, S_IRWXU);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
/** File exists, check permission to read/write */
|
||||
if (errno == EEXIST)
|
||||
{
|
||||
/** Open file and write a byte for test */
|
||||
fd = open(filename, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"*\n* Error : Can't access %s due "
|
||||
"to %s.\n",
|
||||
filename,
|
||||
strerror(errno));
|
||||
*writable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
char c = ' ';
|
||||
if (write(fd, &c, 1) == 1)
|
||||
{
|
||||
*writable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"*\n* Error : Can't write to "
|
||||
"%s due to %s.\n",
|
||||
filename,
|
||||
strerror(errno));
|
||||
*writable = false;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
exists = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"*\n* Error : Can't access %s due to %s.\n",
|
||||
filename,
|
||||
strerror(errno));
|
||||
exists = false;
|
||||
*writable = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
exists = false;
|
||||
*writable = true;
|
||||
}
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool file_is_symlink(
|
||||
char* filename)
|
||||
{
|
||||
@ -2112,7 +2157,8 @@ static bool logfile_init(
|
||||
logfile->lf_full_file_name =
|
||||
form_full_file_name(strparts, logfile->lf_name_seqno, 2);
|
||||
|
||||
if (store_shmem) {
|
||||
if (store_shmem)
|
||||
{
|
||||
strparts[0].sp_string = logfile->lf_linkpath;
|
||||
/**
|
||||
* Create name for link file
|
||||
@ -2121,17 +2167,7 @@ static bool logfile_init(
|
||||
form_full_file_name(strparts,
|
||||
logfile->lf_name_seqno,
|
||||
2);
|
||||
fprintf(stderr, "%s\t: %s->%s\n",
|
||||
STRLOGNAME(logfile_id),
|
||||
logfile->lf_full_link_name,
|
||||
logfile->lf_full_file_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s\t: %s\n",
|
||||
STRLOGNAME(logfile_id),
|
||||
logfile->lf_full_file_name);
|
||||
}
|
||||
/**
|
||||
* At least one of the files couldn't be created. Increase
|
||||
* sequence number and retry until succeeds.
|
||||
@ -2147,31 +2183,57 @@ static bool logfile_init(
|
||||
* If file exists but is different type, create fails and
|
||||
* new, increased sequence number is added to file name.
|
||||
*/
|
||||
if (file_exists_and_is_writable(logfile->lf_full_file_name,
|
||||
&writable))
|
||||
{
|
||||
if (!writable ||
|
||||
file_is_symlink(logfile->lf_full_file_name))
|
||||
{
|
||||
nameconflicts = true;
|
||||
goto file_create_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (store_shmem)
|
||||
{
|
||||
writable = false;
|
||||
if (check_file_and_path(
|
||||
logfile->lf_full_file_name,
|
||||
&writable))
|
||||
{
|
||||
/** Found similarly named file which isn't writable */
|
||||
if (!writable ||
|
||||
file_is_symlink(logfile->lf_full_file_name))
|
||||
{
|
||||
nameconflicts = true;
|
||||
goto file_create_fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Opening the file failed for some other reason than
|
||||
* existing non-writable file. Shut down.
|
||||
*/
|
||||
if (!writable)
|
||||
{
|
||||
succp = false;
|
||||
goto return_with_succp;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists_and_is_writable(
|
||||
logfile->lf_full_link_name,
|
||||
&writable))
|
||||
{
|
||||
if (!writable ||
|
||||
!file_is_symlink(logfile->lf_full_link_name))
|
||||
{
|
||||
unlink(logfile->lf_full_link_name);
|
||||
}
|
||||
}
|
||||
if (store_shmem)
|
||||
{
|
||||
if (check_file_and_path(
|
||||
logfile->lf_full_file_name,
|
||||
&writable))
|
||||
{
|
||||
/** Found similarly named file which isn't writable */
|
||||
if (!writable ||
|
||||
file_is_symlink(logfile->lf_full_file_name))
|
||||
{
|
||||
unlink(logfile->lf_full_file_name);
|
||||
nameconflicts = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Opening the file failed for some other reason than
|
||||
* existing non-writable file. Shut down.
|
||||
*/
|
||||
if (!writable)
|
||||
{
|
||||
succp = false;
|
||||
goto return_with_succp;
|
||||
}
|
||||
}
|
||||
}
|
||||
file_create_fail:
|
||||
if (namecreatefail || nameconflicts)
|
||||
@ -2188,7 +2250,6 @@ file_create_fail:
|
||||
free(logfile->lf_full_link_name);
|
||||
logfile->lf_full_link_name = NULL;
|
||||
}
|
||||
goto return_with_succp;
|
||||
}
|
||||
} while (namecreatefail || nameconflicts);
|
||||
/**
|
||||
@ -2202,11 +2263,24 @@ file_create_fail:
|
||||
MAXNBLOCKBUFS) == NULL)
|
||||
{
|
||||
ss_dfprintf(stderr,
|
||||
"Initializing logfile blockbuf list "
|
||||
"failed\n");
|
||||
"*\n* Error : Initializing buffers for log files "
|
||||
"failed.");
|
||||
logfile_free_memory(logfile);
|
||||
goto return_with_succp;
|
||||
}
|
||||
if (store_shmem)
|
||||
{
|
||||
fprintf(stderr, "%s\t: %s->%s\n",
|
||||
STRLOGNAME(logfile_id),
|
||||
logfile->lf_full_link_name,
|
||||
logfile->lf_full_file_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s\t: %s\n",
|
||||
STRLOGNAME(logfile_id),
|
||||
logfile->lf_full_file_name);
|
||||
}
|
||||
succp = true;
|
||||
logfile->lf_state = RUN;
|
||||
CHK_LOGFILE(logfile);
|
||||
@ -2244,12 +2318,18 @@ static void logfile_done(
|
||||
{
|
||||
switch(lf->lf_state) {
|
||||
case RUN:
|
||||
CHK_LOGFILE(lf);
|
||||
ss_dassert(lf->lf_npending_writes == 0);
|
||||
CHK_LOGFILE(lf);
|
||||
ss_dassert(lf->lf_npending_writes == 0);
|
||||
/** fallthrough */
|
||||
case INIT:
|
||||
mlist_done(&lf->lf_blockbuf_list);
|
||||
logfile_free_memory(lf);
|
||||
lf->lf_state = DONE;
|
||||
/** Test if list is initialized before freeing it */
|
||||
if (lf->lf_blockbuf_list.mlist_versno != 0)
|
||||
{
|
||||
mlist_done(&lf->lf_blockbuf_list);
|
||||
}
|
||||
logfile_free_memory(lf);
|
||||
lf->lf_state = DONE;
|
||||
/** fallthrough */
|
||||
case DONE:
|
||||
case UNINIT:
|
||||
default:
|
||||
|
111
macros.cmake
111
macros.cmake
@ -1,9 +1,15 @@
|
||||
function(debugmsg MSG)
|
||||
if(DEBUG_OUTPUT)
|
||||
message(STATUS "DEBUG: ${MSG}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(set_maxscale_version)
|
||||
|
||||
#MaxScale version number
|
||||
set(MAXSCALE_VERSION_MAJOR "1")
|
||||
set(MAXSCALE_VERSION_MINOR "0")
|
||||
set(MAXSCALE_VERSION_PATCH "1")
|
||||
set(MAXSCALE_VERSION_PATCH "2")
|
||||
set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}")
|
||||
set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}-beta")
|
||||
|
||||
@ -57,11 +63,12 @@ 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"))
|
||||
if((DEFINED lib${lib}) AND (${lib${lib}} MATCHES "NOTFOUND"))
|
||||
set(DEPS_ERROR TRUE)
|
||||
set(FAILED_DEPS "${FAILED_DEPS} lib${lib}")
|
||||
elseif(DEBUG_OUTPUT)
|
||||
@ -82,27 +89,29 @@ macro(check_dirs)
|
||||
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()
|
||||
debugmsg("Searching for MySQL headers at: ${MYSQL_DIR}")
|
||||
find_path(MYSQL_DIR_LOC mysql.h PATHS ${MYSQL_DIR} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_path(MYSQL_DIR_LOC mysql.h PATH_SUFFIXES mysql mariadb)
|
||||
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")
|
||||
|
||||
debugmsg("Search returned: ${MYSQL_DIR_LOC}")
|
||||
|
||||
if(${MYSQL_DIR_LOC} MATCHES "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)
|
||||
message(STATUS "Using MySQL headers found at: ${MYSQL_DIR}")
|
||||
endif()
|
||||
set(MYSQL_DIR_LOC "" INTERNAL)
|
||||
|
||||
unset(MYSQL_DIR_LOC)
|
||||
|
||||
# Find the errmsg.sys file if it was not defied
|
||||
if( DEFINED ERRMSG )
|
||||
debugmsg("Looking for errmsg.sys at: ${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)
|
||||
@ -113,48 +122,62 @@ macro(check_dirs)
|
||||
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)
|
||||
unset(ERRMSG_FILE)
|
||||
|
||||
# Find the embedded mysql library
|
||||
if(STATIC_EMBEDDED)
|
||||
|
||||
if (DEFINED EMBEDDED_LIB)
|
||||
if( NOT (IS_DIRECTORY ${EMBEDDED_LIB}) )
|
||||
debugmsg("EMBEDDED_LIB is not a directory: ${EMBEDDED_LIB}")
|
||||
if(${CMAKE_VERSION} VERSION_LESS 2.12 )
|
||||
set(COMP_VAR PATH)
|
||||
else()
|
||||
set(COMP_VAR DIRECTORY)
|
||||
endif()
|
||||
get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} ${COMP_VAR})
|
||||
debugmsg("EMBEDDED_LIB directory component: ${EMBEDDED_LIB}")
|
||||
endif()
|
||||
debugmsg("Searching for the embedded library at: ${EMBEDDED_LIB}")
|
||||
endif()
|
||||
|
||||
if(STATIC_EMBEDDED)
|
||||
|
||||
debugmsg("Using the static embedded library...")
|
||||
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()
|
||||
debugmsg("Searching for libmysqld.a at: ${EMBEDDED_LIB}")
|
||||
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()
|
||||
debugmsg("Search returned: ${EMBEDDED_LIB_STATIC}")
|
||||
|
||||
set(EMBEDDED_LIB ${EMBEDDED_LIB_STATIC} CACHE FILEPATH "Path to libmysqld" FORCE)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES})
|
||||
set(OLD_SUFFIXES "" INTERNAL)
|
||||
|
||||
else()
|
||||
else()
|
||||
debugmsg("Using the dynamic embedded library...")
|
||||
set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so")
|
||||
if (DEFINED EMBEDDED_LIB)
|
||||
if(DEBUG_OUTPUT)
|
||||
message(STATUS "Searching for libmysqld.so at: ${EMBEDDED_LIB}")
|
||||
endif()
|
||||
debugmsg("Searching for libmysqld.so at: ${EMBEDDED_LIB}")
|
||||
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()
|
||||
debugmsg("Search returned: ${EMBEDDED_LIB_DYNAMIC}")
|
||||
set(EMBEDDED_LIB ${EMBEDDED_LIB_DYNAMIC} CACHE FILEPATH "Path to libmysqld" FORCE)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES})
|
||||
|
||||
endif()
|
||||
set(EMBEDDED_LIB_DYNAMIC "" INTERNAL)
|
||||
set(EMBEDDED_LIB_STATIC "" INTERNAL)
|
||||
|
||||
unset(EMBEDDED_LIB_DYNAMIC)
|
||||
unset(EMBEDDED_LIB_STATIC)
|
||||
unset(OLD_SUFFIXES)
|
||||
|
||||
# Inform the user about the embedded library
|
||||
if( (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_STATIC-NOTFOUND") OR (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_DYNAMIC-NOTFOUND"))
|
||||
if( (${EMBEDDED_LIB} MATCHES "NOTFOUND") OR (${EMBEDDED_LIB} MATCHES "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()
|
||||
@ -176,17 +199,19 @@ macro(check_dirs)
|
||||
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)
|
||||
unset(DEB_FNC)
|
||||
unset(RPM_FNC)
|
||||
|
||||
#Check RabbitMQ headers and libraries
|
||||
if(BUILD_RABBITMQ)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
if(DEFINED RABBITMQ_LIB)
|
||||
find_library(RMQ_LIB rabbitmq PATHS ${RABBITMQ_LIB} NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_library(RMQ_LIB rabbitmq)
|
||||
endif()
|
||||
find_library(RMQ_LIB rabbitmq)
|
||||
if(RMQ_LIB STREQUAL "RMQ_LIB-NOTFOUND")
|
||||
if(RMQ_LIB MATCHES "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()
|
||||
@ -196,16 +221,22 @@ macro(check_dirs)
|
||||
|
||||
if(DEFINED RABBITMQ_HEADERS)
|
||||
find_file(RMQ_HEADERS amqp.h PATHS ${RABBITMQ_HEADERS} NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_file(RMQ_HEADERS amqp.h)
|
||||
endif()
|
||||
find_file(RMQ_HEADERS amqp.h)
|
||||
if(RMQ_HEADERS STREQUAL "RMQ_HEADERS-NOTFOUND")
|
||||
if(RMQ_HEADERS MATCHES "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()
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${RABBITMQ_HEADERS})
|
||||
check_c_source_compiles("#include <amqp.h>\n int main(){if(AMQP_DELIVERY_PERSISTENT){return 0;}return 1;}" HAVE_RMQ50)
|
||||
if(NOT HAVE_RMQ50)
|
||||
message(FATAL_ERROR "Old version of RabbitMQ-C library found. Version 0.5 or newer is required.")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
@ -224,4 +255,4 @@ endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES ALLDIRS)
|
||||
set(${VAR} "${ALLDIRS}" CACHE PATH " " FORCE)
|
||||
endfunction()
|
||||
endfunction()
|
||||
|
@ -18,6 +18,7 @@ Copyright MariaDB Corporation Ab
|
||||
*/
|
||||
|
||||
/** getpid */
|
||||
#include <my_config.h>
|
||||
#include <unistd.h>
|
||||
#include <mysql.h>
|
||||
#include <skygw_utils.h>
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <my_config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <my_config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@ -8,7 +9,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
static char* server_options[] = {
|
||||
"SkySQL Gateway",
|
||||
"MariaDB Corporation MaxScale",
|
||||
"--no-defaults",
|
||||
"--datadir=.",
|
||||
"--language=.",
|
||||
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
MariaDB Corporation change details:
|
||||
- Removed unnecessary file driver
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
#include "access_method_factory.h"
|
||||
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
MariaDB Corporation change details:
|
||||
- Added GTID event handler
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
MariaDB Corporation change details:
|
||||
- Added GTID event handler
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@ MariaDB Corporation change details:
|
||||
- Added support for setting binlog position based on GTID
|
||||
- Added support for MySQL and MariDB server types
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@ MariaDB Corporation change details:
|
||||
- Added support for setting binlog position based on GTID
|
||||
- Added support for MySQL and MariDB server types
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
MariaDB Corporation change details:
|
||||
- Added support for GTID event handling for both MySQL and MariaDB
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@ MariaDB Corporation change details:
|
||||
- Added support for GTID event handling for both MySQL and MariaDB
|
||||
- Added support for setting binlog position based on GTID
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
MariaDB Corporation change details:
|
||||
- Added support for GTID event handling for both MySQL and MariaDB
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
MariaDB Corporation change details:
|
||||
- Added support for GTID event handling for both MySQL and MariaDB
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
#ifndef _BINLOG_EVENT_H
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
MariaDB Corporation change details:
|
||||
- Added support for GTID event handling for both MySQL and MariaDB
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
@ -28,7 +28,7 @@ MariaDB Corporation change details:
|
||||
- Added support for starting binlog dump from GTID position
|
||||
- Added error handling using exceptions
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
#include "binlog_api.h"
|
||||
|
@ -28,7 +28,7 @@ MariaDB Corporation change details:
|
||||
- Added support for starting binlog dump from GTID position
|
||||
- Added support for MariaDB server
|
||||
|
||||
Author: Jan Lindström (jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström (jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
*/
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(modules)
|
||||
add_subdirectory(inih)
|
||||
if(BUILD_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. It is free
|
||||
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
@ -13,11 +13,11 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2013
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file buffer.h - The Gateway buffer management functions
|
||||
* @file buffer.h - The MaxScale buffer management functions
|
||||
*
|
||||
* The buffer management is based on the principle of a linked list
|
||||
* of variable size buffer, the intention beign to allow longer
|
||||
|
@ -41,6 +41,7 @@
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <my_config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -816,7 +817,7 @@ int error_count = 0;
|
||||
int found = 0;
|
||||
while (obj1)
|
||||
{
|
||||
if (strcmp(s, obj1->object) == 0 &&
|
||||
if (strcmp(trim(s), obj1->object) == 0 &&
|
||||
obj->element && obj1->element)
|
||||
{
|
||||
found = 1;
|
||||
@ -1448,7 +1449,7 @@ SERVER *server;
|
||||
int found = 0;
|
||||
while (obj1)
|
||||
{
|
||||
if (strcmp(s, obj1->object) == 0 &&
|
||||
if (strcmp(trim(s), obj1->object) == 0 &&
|
||||
obj->element && obj1->element)
|
||||
{
|
||||
found = 1;
|
||||
|
@ -28,6 +28,9 @@
|
||||
* 06/02/2014 Massimiliano Pinto Mysql user root selected based on configuration flag
|
||||
* 26/02/2014 Massimiliano Pinto Addd: replace_mysql_users() routine may replace users' table based on a checksum
|
||||
* 28/02/2014 Massimiliano Pinto Added Mysql user@host authentication
|
||||
* 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts:
|
||||
* x.y.z.%, x.y.%.%, x.%.%.%
|
||||
* 03/10/14 Massimiliano Pinto Added netmask to user@host authentication for wildcard in IPv4 hosts
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -50,13 +53,14 @@
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
static int getUsers(SERVICE *service, struct users *users);
|
||||
static int getUsers(SERVICE *service, USERS *users);
|
||||
static int uh_cmpfun( void* v1, void* v2);
|
||||
static void *uh_keydup(void* key);
|
||||
static void uh_keyfree( void* key);
|
||||
static int uh_hfun( void* key);
|
||||
char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
|
||||
char *mysql_format_user_entry(void *data);
|
||||
int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd);
|
||||
|
||||
/**
|
||||
* Load the user/passwd form mysql.user table into the service users' hashtable
|
||||
@ -82,7 +86,7 @@ int
|
||||
reload_mysql_users(SERVICE *service)
|
||||
{
|
||||
int i;
|
||||
struct users *newusers, *oldusers;
|
||||
USERS *newusers, *oldusers;
|
||||
|
||||
if ((newusers = mysql_users_alloc()) == NULL)
|
||||
return 0;
|
||||
@ -108,15 +112,17 @@ int
|
||||
replace_mysql_users(SERVICE *service)
|
||||
{
|
||||
int i;
|
||||
struct users *newusers, *oldusers;
|
||||
USERS *newusers, *oldusers;
|
||||
|
||||
if ((newusers = mysql_users_alloc()) == NULL)
|
||||
return -1;
|
||||
|
||||
i = getUsers(service, newusers);
|
||||
|
||||
if (i <= 0)
|
||||
if (i <= 0) {
|
||||
users_free(newusers);
|
||||
return i;
|
||||
}
|
||||
|
||||
spinlock_acquire(&service->spin);
|
||||
oldusers = service->users;
|
||||
@ -148,6 +154,92 @@ struct users *newusers, *oldusers;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new MySQL user with host, password and netmask into the service users table
|
||||
*
|
||||
* The netmask values are:
|
||||
* 0 for any, 32 for single IPv4
|
||||
* 24 for a class C from a.b.c.%, 16 for a Class B from a.b.%.% and 8 for a Class A from a.%.%.%
|
||||
*
|
||||
* @param users The users table
|
||||
* @param user The user name
|
||||
* @param host The host to add, with possible wildcards
|
||||
* @param passwd The sha1(sha1(passoword)) to add
|
||||
* @return 1 on success, 0 on failure
|
||||
*/
|
||||
|
||||
int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd) {
|
||||
struct sockaddr_in serv_addr;
|
||||
MYSQL_USER_HOST key;
|
||||
char ret_ip[INET_ADDRSTRLEN + 1]="";
|
||||
int found_range=0;
|
||||
int found_any=0;
|
||||
int ret = 0;
|
||||
|
||||
/* prepare the user@host data struct */
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
/* set user */
|
||||
key.user = strdup(user);
|
||||
|
||||
if(key.user == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* handle ANY, Class C,B,A */
|
||||
|
||||
/* ANY */
|
||||
if (strcmp(host, "%") == 0) {
|
||||
strcpy(ret_ip, "0.0.0.0");
|
||||
found_any = 1;
|
||||
} else {
|
||||
char *tmp;
|
||||
strcpy(ret_ip, host);
|
||||
tmp = ret_ip+strlen(ret_ip)-1;
|
||||
|
||||
/* start from Class C */
|
||||
while(*tmp) {
|
||||
if (*tmp == '%') {
|
||||
/* set only the last IPv4 byte to 1
|
||||
* avoiding setipadress() failure
|
||||
* for Class C address
|
||||
*/
|
||||
found_range++;
|
||||
if (found_range == 1)
|
||||
*tmp = '1';
|
||||
else
|
||||
*tmp = '0';
|
||||
}
|
||||
tmp--;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill IPv4 data struct */
|
||||
if (setipaddress(&serv_addr.sin_addr, ret_ip)) {
|
||||
|
||||
/* copy IPv4 data into key.ipv4 */
|
||||
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
||||
|
||||
if (found_range) {
|
||||
/* let's zero the last IP byte: a.b.c.0 we set above to 1*/
|
||||
key.ipv4.sin_addr.s_addr &= 0x00FFFFFF;
|
||||
key.netmask = 32 - (found_range * 8);
|
||||
} else {
|
||||
key.netmask = 32 - (found_any * 32);
|
||||
}
|
||||
|
||||
/* add user@host as key and passwd as value in the MySQL users hash table */
|
||||
if (mysql_users_add(users, &key, passwd))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
free(key.user);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the user/passwd form mysql.user table into the service users' hashtable
|
||||
* environment.
|
||||
@ -157,7 +249,7 @@ struct users *newusers, *oldusers;
|
||||
* @return -1 on any error or the number of users inserted (0 means no users at all)
|
||||
*/
|
||||
static int
|
||||
getUsers(SERVICE *service, struct users *users)
|
||||
getUsers(SERVICE *service, USERS *users)
|
||||
{
|
||||
MYSQL *con = NULL;
|
||||
MYSQL_ROW row;
|
||||
@ -173,8 +265,6 @@ getUsers(SERVICE *service, struct users *users)
|
||||
char *users_data = NULL;
|
||||
int nusers = 0;
|
||||
int users_data_row_len = MYSQL_USER_MAXLEN + MYSQL_HOST_MAXLEN + MYSQL_PASSWORD_LEN;
|
||||
struct sockaddr_in serv_addr;
|
||||
MYSQL_USER_HOST key;
|
||||
|
||||
/* enable_root for MySQL protocol module means load the root user credentials from backend databases */
|
||||
if(service->enable_root) {
|
||||
@ -311,63 +401,26 @@ getUsers(SERVICE *service, struct users *users)
|
||||
* added to hashtable.
|
||||
*/
|
||||
|
||||
char ret_ip[INET_ADDRSTRLEN + 1]="";
|
||||
const char *rc;
|
||||
int rc = 0;
|
||||
|
||||
/* prepare the user@host data struct */
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
memset(&key, 0, sizeof(key));
|
||||
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], strlen(row[2]) ? row[2]+1 : row[2]);
|
||||
|
||||
/* if host == '%', 0 is passed */
|
||||
if (setipaddress(&serv_addr.sin_addr, strcmp(row[1], "%") ? row[1] : "0.0.0.0")) {
|
||||
if (rc == 1) {
|
||||
LOGIF(LD, (skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [mysql_users_add()] Added user %s@%s",
|
||||
pthread_self(),
|
||||
row[0],
|
||||
row[1])));
|
||||
|
||||
key.user = strdup(row[0]);
|
||||
|
||||
if(key.user == NULL) {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [getUsers()] strdup() failed for user %s",
|
||||
pthread_self(),
|
||||
row[0])));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
||||
|
||||
rc = inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN);
|
||||
|
||||
/* add user@host as key and passwd as value in the MySQL users hash table */
|
||||
if (mysql_users_add(users, &key, strlen(row[2]) ? row[2]+1 : row[2])) {
|
||||
LOGIF(LD, (skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [mysql_users_add()] Added user %s@%s(%s)",
|
||||
pthread_self(),
|
||||
row[0],
|
||||
row[1],
|
||||
rc == NULL ? "NULL" : ret_ip)));
|
||||
|
||||
/* Append data in the memory area for SHA1 digest */
|
||||
strncat(users_data, row[3], users_data_row_len);
|
||||
|
||||
total_users++;
|
||||
} else {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [mysql_users_add()] Failed adding user %s@%s(%s)",
|
||||
pthread_self(),
|
||||
row[0],
|
||||
row[1],
|
||||
rc == NULL ? "NULL" : ret_ip)));
|
||||
}
|
||||
|
||||
free(key.user);
|
||||
/* Append data in the memory area for SHA1 digest */
|
||||
strncat(users_data, row[3], users_data_row_len);
|
||||
|
||||
total_users++;
|
||||
} else {
|
||||
/* setipaddress() failed, skip user add and log this*/
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [getUsers()] setipaddress failed: user %s@%s not added",
|
||||
"%lu [mysql_users_add()] Failed adding user %s@%s",
|
||||
pthread_self(),
|
||||
row[0],
|
||||
row[1])));
|
||||
@ -475,7 +528,7 @@ static int uh_hfun( void* key) {
|
||||
* Currently only IPv4 addresses are supported
|
||||
*
|
||||
* @param key1 The key value, i.e. username@host (IPv4)
|
||||
* @param key1 The key value, i.e. username@host (IPv4)
|
||||
* @param key2 The key value, i.e. username@host (IPv4)
|
||||
* @return The compare value
|
||||
*/
|
||||
|
||||
@ -486,7 +539,7 @@ static int uh_cmpfun( void* v1, void* v2) {
|
||||
if (v1 == NULL || v2 == NULL || hu1 == NULL || hu2 == NULL || hu1->user == NULL || hu2->user == NULL)
|
||||
return 0;
|
||||
|
||||
if (strcmp(hu1->user, hu2->user) == 0 && (hu1->ipv4.sin_addr.s_addr == hu2->ipv4.sin_addr.s_addr)) {
|
||||
if (strcmp(hu1->user, hu2->user) == 0 && (hu1->ipv4.sin_addr.s_addr == hu2->ipv4.sin_addr.s_addr) && (hu1->netmask >= hu2->netmask)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
@ -513,6 +566,7 @@ static void *uh_keydup(void* key) {
|
||||
return NULL;
|
||||
|
||||
memcpy(&rval->ipv4, ¤t_key->ipv4, sizeof(struct sockaddr_in));
|
||||
memcpy(&rval->netmask, ¤t_key->netmask, sizeof(int));
|
||||
|
||||
return (void *) rval;
|
||||
}
|
||||
@ -561,13 +615,25 @@ char *mysql_format_user_entry(void *data)
|
||||
if (mysql_user == NULL)
|
||||
return NULL;
|
||||
|
||||
if (entry->ipv4.sin_addr.s_addr == INADDR_ANY) {
|
||||
snprintf(mysql_user, mysql_user_len, "%s@%%", entry->user);
|
||||
} else {
|
||||
if (entry->ipv4.sin_addr.s_addr == INADDR_ANY && entry->netmask == 0) {
|
||||
snprintf(mysql_user, mysql_user_len-1, "%s@%%", entry->user);
|
||||
} else if ( (entry->ipv4.sin_addr.s_addr & 0xFF000000) == 0 && entry->netmask == 24) {
|
||||
snprintf(mysql_user, mysql_user_len-1, "%s@%i.%i.%i.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256), (entry->ipv4.sin_addr.s_addr & 0x00FF0000) / (256 * 256));
|
||||
} else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFF0000) == 0 && entry->netmask == 16) {
|
||||
snprintf(mysql_user, mysql_user_len-1, "%s@%i.%i.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256));
|
||||
} else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFFFF00) == 0 && entry->netmask == 8) {
|
||||
snprintf(mysql_user, mysql_user_len-1, "%s@%i.%%.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF);
|
||||
} else if (entry->netmask == 32) {
|
||||
strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN);
|
||||
strcat(mysql_user, "@");
|
||||
inet_ntop(AF_INET, &(entry->ipv4).sin_addr, mysql_user+strlen(mysql_user), INET_ADDRSTRLEN);
|
||||
} else {
|
||||
snprintf(mysql_user, MYSQL_USER_MAXLEN-6, "warn: %s", entry->user);
|
||||
strcat(mysql_user, "@");
|
||||
inet_ntop(AF_INET, &(entry->ipv4).sin_addr, mysql_user+strlen(mysql_user), INET_ADDRSTRLEN);
|
||||
|
||||
}
|
||||
|
||||
return mysql_user;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
* @endverbatim
|
||||
*/
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <my_config.h>
|
||||
#include <ftw.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@ -72,7 +73,9 @@
|
||||
#include <execinfo.h>
|
||||
|
||||
/** for procname */
|
||||
#define _GNU_SOURCE
|
||||
#if !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
extern char *program_invocation_name;
|
||||
extern char *program_invocation_short_name;
|
||||
@ -173,6 +176,9 @@ static bool resolve_maxscale_conf_fname(
|
||||
char* cnf_file_arg);
|
||||
static bool resolve_maxscale_homedir(
|
||||
char** p_home_dir);
|
||||
|
||||
static char* check_dir_access(char* dirname);
|
||||
|
||||
/**
|
||||
* Handler for SIGHUP signal. Reload the configuration for the
|
||||
* gateway.
|
||||
@ -533,7 +539,7 @@ return_succp:
|
||||
static bool resolve_maxscale_homedir(
|
||||
char** p_home_dir)
|
||||
{
|
||||
bool succp = false;
|
||||
bool succp;
|
||||
char* tmp;
|
||||
char* log_context = NULL;
|
||||
|
||||
@ -592,65 +598,55 @@ static bool resolve_maxscale_homedir(
|
||||
if (*p_home_dir != NULL)
|
||||
{
|
||||
log_context = strdup("Current working directory");
|
||||
goto check_home_dir;
|
||||
}
|
||||
|
||||
check_home_dir:
|
||||
if (*p_home_dir != NULL)
|
||||
{
|
||||
if (!file_is_readable(*p_home_dir))
|
||||
{
|
||||
char* tailstr = "MaxScale doesn't have read permission "
|
||||
"to MAXSCALE_HOME.";
|
||||
char* logstr = (char*)malloc(strlen(log_context)+
|
||||
1+
|
||||
strlen(tailstr)+
|
||||
1);
|
||||
snprintf(logstr,
|
||||
strlen(log_context)+
|
||||
1+
|
||||
strlen(tailstr)+1,
|
||||
"%s:%s",
|
||||
log_context,
|
||||
tailstr);
|
||||
print_log_n_stderr(true, true, logstr, logstr, 0);
|
||||
free(logstr);
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
if (!file_is_writable(*p_home_dir))
|
||||
{
|
||||
char* tailstr = "MaxScale doesn't have write permission "
|
||||
"to MAXSCALE_HOME. Exiting.";
|
||||
char* logstr = (char*)malloc(strlen(log_context)+
|
||||
1+
|
||||
strlen(tailstr)+
|
||||
1);
|
||||
snprintf(logstr,
|
||||
strlen(log_context)+
|
||||
1+
|
||||
strlen(tailstr)+1,
|
||||
"%s:%s",
|
||||
log_context,
|
||||
tailstr);
|
||||
print_log_n_stderr(true, true, logstr, logstr, 0);
|
||||
free(logstr);
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
if (!daemon_mode)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Using %s as MAXSCALE_HOME = %s\n",
|
||||
log_context,
|
||||
tmp);
|
||||
}
|
||||
succp = true;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
return_succp:
|
||||
free (tmp);
|
||||
|
||||
if (*p_home_dir != NULL)
|
||||
{
|
||||
char* errstr;
|
||||
|
||||
errstr = check_dir_access(*p_home_dir);
|
||||
|
||||
if (errstr != NULL)
|
||||
{
|
||||
char* logstr = (char*)malloc(strlen(log_context)+
|
||||
1+
|
||||
strlen(errstr)+
|
||||
1);
|
||||
|
||||
snprintf(logstr,
|
||||
strlen(log_context)+
|
||||
1+
|
||||
strlen(errstr)+1,
|
||||
"%s: %s",
|
||||
log_context,
|
||||
errstr);
|
||||
|
||||
print_log_n_stderr(true, true, logstr, logstr, 0);
|
||||
|
||||
free(errstr);
|
||||
free(logstr);
|
||||
succp = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = true;
|
||||
|
||||
if (!daemon_mode)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Using %s as MAXSCALE_HOME = %s\n",
|
||||
log_context,
|
||||
tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
free (tmp);
|
||||
|
||||
if (log_context != NULL)
|
||||
{
|
||||
@ -667,6 +663,42 @@ return_succp:
|
||||
return succp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check read and write accessibility to a directory.
|
||||
* @param dirname directory to be checked
|
||||
*
|
||||
* @return NULL if directory can be read and written, an error message if either
|
||||
* read or write is not permitted.
|
||||
*/
|
||||
static char* check_dir_access(
|
||||
char* dirname)
|
||||
{
|
||||
char* errstr = NULL;
|
||||
|
||||
if (dirname == NULL)
|
||||
{
|
||||
errstr = strdup("Directory argument is NULL");
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
if (!file_is_readable(dirname))
|
||||
{
|
||||
errstr = strdup("MaxScale doesn't have read permission "
|
||||
"to MAXSCALE_HOME.");
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
if (!file_is_writable(dirname))
|
||||
{
|
||||
errstr = strdup("MaxScale doesn't have write permission "
|
||||
"to MAXSCALE_HOME. Exiting.");
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
retblock:
|
||||
return errstr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @node Provides error printing for non-formatted error strings.
|
||||
@ -1370,13 +1402,51 @@ int main(int argc, char **argv)
|
||||
{
|
||||
if (!resolve_maxscale_homedir(&home_dir))
|
||||
{
|
||||
ss_dassert(home_dir == NULL);
|
||||
ss_dassert(home_dir != NULL);
|
||||
rc = MAXSCALE_HOMELESS;
|
||||
goto return_main;
|
||||
}
|
||||
sprintf(mysql_home, "%s/mysql", home_dir);
|
||||
setenv("MYSQL_HOME", mysql_home, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* log_context = strdup("Home directory command-line argument");
|
||||
char* errstr;
|
||||
|
||||
errstr = check_dir_access(home_dir);
|
||||
|
||||
if (errstr != NULL)
|
||||
{
|
||||
char* logstr = (char*)malloc(strlen(log_context)+
|
||||
1+
|
||||
strlen(errstr)+
|
||||
1);
|
||||
|
||||
snprintf(logstr,
|
||||
strlen(log_context)+
|
||||
1+
|
||||
strlen(errstr)+1,
|
||||
"%s: %s",
|
||||
log_context,
|
||||
errstr);
|
||||
|
||||
print_log_n_stderr(true, true, logstr, logstr, 0);
|
||||
|
||||
free(errstr);
|
||||
free(logstr);
|
||||
rc = MAXSCALE_HOMELESS;
|
||||
goto return_main;
|
||||
}
|
||||
else if (!daemon_mode)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Using %s as MAXSCALE_HOME = %s\n",
|
||||
log_context,
|
||||
home_dir);
|
||||
}
|
||||
free(log_context);
|
||||
}
|
||||
|
||||
/*<
|
||||
* Init Log Manager for MaxScale.
|
||||
@ -1386,8 +1456,9 @@ int main(int argc, char **argv)
|
||||
* argv[0]
|
||||
*/
|
||||
{
|
||||
char buf[1024];
|
||||
char *argv[8];
|
||||
char buf[1024];
|
||||
char *argv[8];
|
||||
bool succp;
|
||||
|
||||
sprintf(buf, "%s/log", home_dir);
|
||||
mkdir(buf, 0777);
|
||||
@ -1400,7 +1471,7 @@ int main(int argc, char **argv)
|
||||
argv[4] = "LOGFILE_MESSAGE,LOGFILE_ERROR"
|
||||
"LOGFILE_DEBUG,LOGFILE_TRACE";
|
||||
argv[5] = NULL;
|
||||
skygw_logmanager_init(5, argv);
|
||||
succp = skygw_logmanager_init(5, argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1409,7 +1480,13 @@ int main(int argc, char **argv)
|
||||
argv[5] = "-l"; /*< write to syslog */
|
||||
argv[6] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< ..these logs to syslog */
|
||||
argv[7] = NULL;
|
||||
skygw_logmanager_init(7, argv);
|
||||
succp = skygw_logmanager_init(7, argv);
|
||||
}
|
||||
|
||||
if (!succp)
|
||||
{
|
||||
rc = MAXSCALE_BADCONFIG;
|
||||
goto return_main;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1670,9 +1747,11 @@ static void log_flush_cb(
|
||||
void* arg)
|
||||
{
|
||||
ssize_t timeout_ms = *(ssize_t *)arg;
|
||||
const struct timespec ts1 = {0, 1000000*timeout_ms};
|
||||
struct timespec ts2;
|
||||
struct timespec ts1;
|
||||
|
||||
ts1.tv_sec = timeout_ms/1000;
|
||||
ts1.tv_nsec = (timeout_ms%1000)*1000000;
|
||||
|
||||
LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE,
|
||||
"Started MaxScale log flusher.")));
|
||||
while (!do_exit) {
|
||||
@ -1680,7 +1759,7 @@ static void log_flush_cb(
|
||||
skygw_log_flush(LOGFILE_MESSAGE);
|
||||
skygw_log_flush(LOGFILE_TRACE);
|
||||
skygw_log_flush(LOGFILE_DEBUG);
|
||||
nanosleep(&ts1, &ts2);
|
||||
nanosleep(&ts1, NULL);
|
||||
}
|
||||
LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE,
|
||||
"Finished MaxScale log flusher.")));
|
||||
|
@ -116,7 +116,7 @@ HINT *hint;
|
||||
return head;
|
||||
hint->next = head;
|
||||
hint->type = HINT_PARAMETER;
|
||||
hint->data = pname;
|
||||
hint->data = strdup(pname);
|
||||
hint->value = strdup(value);
|
||||
return hint;
|
||||
}
|
||||
@ -151,4 +151,4 @@ bool hint_exists(
|
||||
p_hint = &(*p_hint)->next;
|
||||
}
|
||||
return succp;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*
|
||||
* Copyright MariaDB Corporation Ab 2013-2014
|
||||
*/
|
||||
#include <my_config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
@ -1,3 +1,4 @@
|
||||
add_executable(test_mysql_users test_mysql_users.c)
|
||||
add_executable(test_hash testhash.c)
|
||||
add_executable(test_hint testhint.c)
|
||||
add_executable(test_spinlock testspinlock.c)
|
||||
@ -10,6 +11,7 @@ add_executable(test_service testservice.c)
|
||||
add_executable(test_server testserver.c)
|
||||
add_executable(test_users testusers.c)
|
||||
add_executable(test_adminusers testadminusers.c)
|
||||
target_link_libraries(test_mysql_users fullcore MySQLClient)
|
||||
target_link_libraries(test_hash fullcore)
|
||||
target_link_libraries(test_hint fullcore)
|
||||
target_link_libraries(test_spinlock fullcore)
|
||||
@ -22,6 +24,7 @@ target_link_libraries(test_service fullcore)
|
||||
target_link_libraries(test_server fullcore)
|
||||
target_link_libraries(test_users fullcore)
|
||||
target_link_libraries(test_adminusers fullcore)
|
||||
add_test(testMySQLUsers test_mysql_users)
|
||||
add_test(TestHash test_hash)
|
||||
add_test(TestHint test_hint)
|
||||
add_test(TestSpinlock test_spinlock)
|
||||
|
@ -1,32 +0,0 @@
|
||||
# cleantests - clean local and subdirectories' tests
|
||||
# buildtests - build all local and subdirectories' tests
|
||||
# runtests - run all local tests
|
||||
# testall - clean, build and run local and subdirectories' tests
|
||||
|
||||
include ../../../build_gateway.inc
|
||||
include ../../../makefile.inc
|
||||
|
||||
CC=cc
|
||||
DEBUG=Y
|
||||
cleantests:
|
||||
- $(DEL) *.o
|
||||
- $(DEL) test_mysql_users
|
||||
- $(DEL) *~
|
||||
|
||||
testall: cleantests buildtests runtests
|
||||
|
||||
buildtests :
|
||||
$(CC) $(CFLAGS) \
|
||||
-I$(ROOT_PATH)/server/include \
|
||||
-I$(ROOT_PATH)/utils \
|
||||
-I$(ROOT_PATH)/log_manager \
|
||||
test_mysql_users.c ../secrets.o ../service.o ../gwbitmask.o ../load_utils.o ../session.o ../poll.o ../dcb.o ../utils.o ../buffer.o ../gw_utils.o ../hashtable.o ../atomic.o ../spinlock.o ../users.o ../dbusers.o ../../../utils/skygw_utils.o ../../../log_manager/log_manager.o -o test_mysql_users -L$(EMBEDDED_LIB) -lmysqlclient -lpthread -lssl -lz -lm -lcrypt -lcrypto -ldl -laio -lrt -lstdc++
|
||||
runtests:
|
||||
@echo ""
|
||||
@echo "-------------------------------"
|
||||
@echo $(shell date)
|
||||
@echo "Test MaxScale core"
|
||||
@echo "-------------------------------"
|
||||
@echo ""
|
||||
@echo "MaxSclale Load MySQL users"
|
||||
@./test_mysql_users
|
@ -24,6 +24,7 @@
|
||||
* Date Who Description
|
||||
* 14/02/2014 Massimiliano Pinto Initial implementation
|
||||
* 17/02/2014 Massimiliano Pinto Added check ipv4
|
||||
* 03/10/2014 Massimiliano Pinto Added check for wildcard hosts
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -77,6 +78,7 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
|
||||
/* add user@host as key and passwd as value in the MySQL users hash table */
|
||||
if (!mysql_users_add(mysql_users, &key, password)) {
|
||||
fprintf(stderr, "Failed adding %s@%s(%lu)\n", username, ret_ip, fix_ipv4);
|
||||
users_free(mysql_users);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -107,6 +109,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor
|
||||
char *fetch_data;
|
||||
|
||||
mysql_users = mysql_users_alloc();
|
||||
|
||||
/* prepare the user@host data struct */
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
memset(&key, 0, sizeof(key));
|
||||
@ -115,6 +118,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor
|
||||
if (hostname)
|
||||
if(!setipaddress(&serv_addr.sin_addr, hostname)) {
|
||||
fprintf(stderr, "setipaddress failed for host [%s]\n", hostname);
|
||||
users_free(mysql_users);
|
||||
return 1;
|
||||
}
|
||||
if (username)
|
||||
@ -129,6 +133,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor
|
||||
/* add user@host as key and passwd as value in the MySQL users hash table */
|
||||
if (!mysql_users_add(mysql_users, &key, password)) {
|
||||
fprintf(stderr, "mysql_users_add() failed for %s@%s\n", username, hostname);
|
||||
users_free(mysql_users);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -138,6 +143,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor
|
||||
if (hostname)
|
||||
if(!setipaddress(&serv_addr.sin_addr, hostname)) {
|
||||
fprintf(stderr, "setipaddress failed for host [%s]\n", hostname);
|
||||
users_free(mysql_users);
|
||||
return 1;
|
||||
}
|
||||
key.user = username;
|
||||
@ -153,6 +159,73 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *password, char *from) {
|
||||
USERS *mysql_users;
|
||||
int ret;
|
||||
struct sockaddr_in client_addr;
|
||||
DCB *dcb;
|
||||
SERVICE *service;
|
||||
|
||||
dcb = dcb_alloc(DCB_ROLE_INTERNAL);
|
||||
|
||||
if (dcb == NULL) {
|
||||
fprintf(stderr, "dcb_alloc() failed\n");
|
||||
return 1;
|
||||
}
|
||||
if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) {
|
||||
fprintf(stderr, "service_alloc() failed\n");
|
||||
dcb_free(dcb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&client_addr, 0, sizeof(client_addr));
|
||||
|
||||
if (hostname) {
|
||||
if(!setipaddress(&client_addr.sin_addr, from)) {
|
||||
fprintf(stderr, "setipaddress failed for host [%s]\n", from);
|
||||
free(service);
|
||||
dcb_free(dcb);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* client IPv4 in raw data*/
|
||||
memcpy(&dcb->ipv4, (struct sockaddr_in *)&client_addr, sizeof(struct sockaddr_in));
|
||||
|
||||
dcb->service = service;
|
||||
|
||||
mysql_users = mysql_users_alloc();
|
||||
|
||||
service->users = mysql_users;
|
||||
|
||||
|
||||
// the routine returns 1 on success
|
||||
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password);
|
||||
if (!ret) {
|
||||
fprintf(stderr, "add_mysql_users_with_host_ipv4 passed(%s@%s, %s) FAILED\n", username, hostname, password);
|
||||
users_free(mysql_users);
|
||||
free(service);
|
||||
dcb_free(dcb);
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
char db_passwd[100]="";
|
||||
|
||||
dcb->remote=strdup(from);
|
||||
//fprintf(stderr, "add_mysql_users_with_host_ipv4 passed(%s@%s, %s) OK\n", username, hostname, password);
|
||||
|
||||
fprintf(stderr, "Checking '%s' @ '%s' against (%s@%s)\n", username, from, username, hostname);
|
||||
|
||||
// returns 0 on success
|
||||
ret = gw_find_mysql_user_password_sha1(username, db_passwd, dcb);
|
||||
}
|
||||
|
||||
users_free(mysql_users);
|
||||
free(service);
|
||||
dcb_free(dcb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int ret;
|
||||
@ -180,6 +253,7 @@ int main() {
|
||||
assert(ret == 1);
|
||||
ret = set_and_get_single_mysql_users(NULL, NULL, NULL);
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_single_mysql_users_ipv4("negative", -467295, "_ncd");
|
||||
assert(ret == 1);
|
||||
ret = set_and_get_single_mysql_users_ipv4("extra", 0xFFFFFFFFFUL * 100, "JJcd");
|
||||
@ -189,19 +263,77 @@ int main() {
|
||||
ret = set_and_get_single_mysql_users_ipv4(NULL, '\0', "JJcd");
|
||||
assert(ret == 1);
|
||||
|
||||
|
||||
for (i = 256*256*256; i <= 256*256*256 + 5; i++) {
|
||||
char user[129] = "";
|
||||
snprintf(user, 128, "user_%i", k);
|
||||
ret = set_and_get_single_mysql_users_ipv4(user, i, "JJcd");
|
||||
assert(ret == 0);
|
||||
k++;
|
||||
}
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "%", "one", "127.0.0.1");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "%", "", "127.0.0.1");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "%", "two", "192.168.2.2");
|
||||
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
||||
assert(ret == 0);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.168.1.%", "foo", "192.168.2.2");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.168.%.%", "foo", "192.168.2.2");
|
||||
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
||||
assert(ret == 0);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.68.0.2");
|
||||
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
||||
assert(ret == 0);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.0.0.2");
|
||||
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
||||
assert(ret == 0);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "foo", "192.2.0.2");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.1", "foo", "192.0.0.2");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "foo", "192.1.0.2");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "y78764o", "192.3.2.1");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "1234567890123456789012345678901234567890", "192.3.2.1");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "1234567890123456789012345678901234567890f8__uuo5", "192.3.2.1");
|
||||
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
||||
assert(ret == 0);
|
||||
|
||||
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "fo887778o", "192.134.0.2");
|
||||
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||
assert(ret == 1);
|
||||
|
||||
fprintf(stderr, "----------------\n");
|
||||
fprintf(stderr, "<<< Test completed\n");
|
||||
|
||||
time(&t);
|
||||
fprintf(stderr, "%s\n", asctime(localtime(&t)));
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -266,6 +266,14 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int result = 0;
|
||||
char *home, buf[1024];
|
||||
|
||||
/* Unlink any existing password file before running this test */
|
||||
if ((home = getenv("MAXSCALE_HOME")) == NULL)
|
||||
home = "/usr/local/skysql";
|
||||
sprintf(buf, "%s/etc/passwd", home);
|
||||
if (strcmp(buf, "/etc/passwd") != 0)
|
||||
unlink(buf);
|
||||
|
||||
result += test1();
|
||||
result += test2();
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -32,6 +32,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <buffer.h>
|
||||
#include <hint.h>
|
||||
|
||||
/**
|
||||
* test1 Allocate a buffer and do lots of things
|
||||
@ -41,6 +42,7 @@ static int
|
||||
test1()
|
||||
{
|
||||
GWBUF *buffer, *extra, *clone, *partclone, *transform;
|
||||
HINT *hint;
|
||||
int size = 100;
|
||||
int bite1 = 35;
|
||||
int bite2 = 60;
|
||||
@ -58,6 +60,10 @@ int buflen;
|
||||
ss_info_dassert(size == buflen, "Incorrect buffer size");
|
||||
ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty");
|
||||
ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined");
|
||||
ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer");
|
||||
hint = hint_create_parameter(NULL, strdup("name"), "value");
|
||||
gwbuf_add_hint(buffer, hint);
|
||||
ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint");
|
||||
ss_dfprintf(stderr, "\t..done\nSet a property for the buffer");
|
||||
gwbuf_add_property(buffer, "name", "value");
|
||||
ss_info_dassert(0 == strcmp("value", gwbuf_get_property(buffer, "name")), "Should now have correct property");
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -51,6 +51,7 @@ int buflen;
|
||||
ss_dfprintf(stderr,
|
||||
"testdcb : creating buffer with type DCB_ROLE_SERVICE_LISTENER");
|
||||
dcb = dcb_alloc(DCB_ROLE_SERVICE_LISTENER);
|
||||
printDCB(dcb);
|
||||
ss_info_dassert(dcb_isvalid(dcb), "New DCB must be valid");
|
||||
ss_dfprintf(stderr, "\t..done\nAllocated dcb.");
|
||||
clone = dcb_clone(dcb);
|
||||
|
83
server/core/test/testgwbitmask.c
Normal file
83
server/core/test/testgwbitmask.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This file is distributed as part of MaxScale. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 13-10-2014 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gwbitmask.h>
|
||||
|
||||
#include <skygw_debug.h>
|
||||
|
||||
/**
|
||||
* test1 Allocate table of users and mess around with it
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
test1()
|
||||
{
|
||||
static GWBITMASK bitmask, another;
|
||||
int i;
|
||||
|
||||
/* Hint tests */
|
||||
ss_dfprintf(stderr,
|
||||
"testgwbitmask : Initialise a bitmask");
|
||||
bitmask_init(&bitmask);
|
||||
ss_info_dassert(BIT_LENGTH_INITIAL == bitmask.length, "Length should be initial length.");
|
||||
for (i = 0; i < BIT_LENGTH_INITIAL; i++) {
|
||||
ss_info_dassert(0 == bitmask_isset(&bitmask, i), "All bits should initially be zero");
|
||||
}
|
||||
ss_info_dassert(0 != bitmask_isallclear(&bitmask), "Should be all clear");
|
||||
ss_dfprintf(stderr, "\t..done\nSet an arbitrary bit.");
|
||||
bitmask_set(&bitmask, 17);
|
||||
bitmask_copy(&another, &bitmask);
|
||||
ss_info_dassert(0 != bitmask_isset(&another, 17), "Test bit should be set");
|
||||
ss_dfprintf(stderr, "\t..done\nClear the arbitrary bit.");
|
||||
bitmask_clear(&bitmask, 17);
|
||||
ss_info_dassert(0 == bitmask_isset(&bitmask, 17), "Test bit should be clear");
|
||||
ss_info_dassert(0 != bitmask_isallclear(&bitmask), "Should be all clear");
|
||||
ss_dfprintf(stderr, "\t..done\nFree the bitmask.");
|
||||
bitmask_free(&bitmask);
|
||||
ss_info_dassert(0 == bitmask.length, "Length should be zero after bit mask freed.");
|
||||
ss_dfprintf(stderr, "\t..done\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
result += test1();
|
||||
|
||||
exit(result);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -49,7 +49,7 @@ HINT *hint;
|
||||
hint = hint_create_parameter(NULL, strdup("name"), "value");
|
||||
ss_info_dassert(NULL != hint, "New hint list should not be null");
|
||||
ss_info_dassert(0 == strcmp("value", hint->value), "Hint value should be correct");
|
||||
ss_info_dassert(0 != hint_exists(hint, HINT_PARAMETER), "Hint of parameter type should exist");
|
||||
ss_info_dassert(0 != hint_exists(&hint, HINT_PARAMETER), "Hint of parameter type should exist");
|
||||
ss_dfprintf(stderr, "\t..done\nFree hints.");
|
||||
if (NULL != hint) hint_free(hint);
|
||||
ss_dfprintf(stderr, "\t..done\n");
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2014
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,7 @@
|
||||
* 25/06/13 Mark Riddoch Initial implementation
|
||||
* 25/02/13 Massimiliano Pinto Added users table refresh rate default values
|
||||
* 28/02/14 Massimiliano Pinto Added MySQL user and host data structure
|
||||
* 03/10/14 Massimiliano Pinto Added netmask to MySQL user and host data structure
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -52,11 +53,13 @@
|
||||
typedef struct mysql_user_host_key {
|
||||
char *user;
|
||||
struct sockaddr_in ipv4;
|
||||
int netmask;
|
||||
} MYSQL_USER_HOST;
|
||||
|
||||
extern int load_mysql_users(SERVICE *service);
|
||||
extern int reload_mysql_users(SERVICE *service);
|
||||
extern int mysql_users_add(USERS *users, MYSQL_USER_HOST *key, char *auth);
|
||||
extern int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd);
|
||||
extern USERS *mysql_users_alloc();
|
||||
extern char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
|
||||
extern int replace_mysql_users(SERVICE *service);
|
||||
|
@ -58,6 +58,7 @@
|
||||
*@endverbatim
|
||||
* See the individual struct documentations for logging trigger parameters
|
||||
*/
|
||||
#include <my_config.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <filter.h>
|
||||
|
4
server/modules/filter/test/Makefile
Executable file → Normal file
4
server/modules/filter/test/Makefile
Executable file → Normal file
@ -1,4 +1,4 @@
|
||||
# This file is distributed as part of MaxScale form SkySQL. It is free
|
||||
# This file is distributed as part of MaxScale form MariaDB Corporation. It is free
|
||||
# software: you can redistribute it and/or modify it under the terms of the
|
||||
# GNU General Public License as published by the Free Software Foundation,
|
||||
# version 2.
|
||||
@ -12,7 +12,7 @@
|
||||
# this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Copyright SkySQL Ab 2014
|
||||
# Copyright MariaDB Corporation Ab 2014
|
||||
|
||||
include ../../../../build_gateway.inc
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef _FILTER_HARNESS_H
|
||||
#define _FILTER_HARNESS_H
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. It is free
|
||||
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
@ -15,7 +15,7 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2013
|
||||
* Copyright MariaDB Corporation Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -558,6 +558,7 @@ static char* create_auth_fail_str(
|
||||
{
|
||||
sprintf(errstr, ferrstr, uname, hostaddr, (*sha1 == '\0' ? "NO" : "YES"));
|
||||
}
|
||||
free(uname);
|
||||
|
||||
retblock:
|
||||
return errstr;
|
||||
|
@ -31,6 +31,9 @@
|
||||
* localhost entry should be added for the selected user in the backends.
|
||||
* Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via
|
||||
* user@%
|
||||
* 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts:
|
||||
* x.y.z.%, x.y.%.%, x.%.%.%
|
||||
* 03/10/2014 Massimiliano Pinto Added netmask for wildcard in IPv4 hosts.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -1310,7 +1313,7 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
|
||||
/**
|
||||
* gw_find_mysql_user_password_sha1
|
||||
*
|
||||
* The routine fetches look for an user int he MaxScale users' table
|
||||
* The routine fetches look for an user int the MaxScale users' table
|
||||
* The users' table is dcb->service->users or a different one specified with void *repository
|
||||
*
|
||||
* If found the HEX password, representing sha1(sha1(password)), is converted in binary data and
|
||||
@ -1334,6 +1337,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
|
||||
|
||||
key.user = username;
|
||||
memcpy(&key.ipv4, client, sizeof(struct sockaddr_in));
|
||||
key.netmask = 32;
|
||||
|
||||
LOGIF(LD,
|
||||
(skygw_log_write_flush(
|
||||
@ -1343,73 +1347,119 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
|
||||
key.user,
|
||||
dcb->remote)));
|
||||
|
||||
/* look for user@current_host now */
|
||||
/* look for user@current_ipv4 now */
|
||||
user_password = mysql_users_fetch(service->users, &key);
|
||||
|
||||
if (!user_password) {
|
||||
/* The user is not authenticated @ current host */
|
||||
/* The user is not authenticated @ current IPv4 */
|
||||
|
||||
/* 1) Check for localhost first.
|
||||
* The check for localhost is 127.0.0.1 (IPv4 only)
|
||||
*/
|
||||
|
||||
if ((key.ipv4.sin_addr.s_addr == 0x0100007F) && !dcb->service->localhost_match_wildcard_host) {
|
||||
/* Skip the wildcard check and return 1 */
|
||||
LOGIF(LE,
|
||||
(skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : user %s@%s not found, try set "
|
||||
"'localhost_match_wildcard_host=1' in "
|
||||
"service definition of the configuration "
|
||||
"file.",
|
||||
key.user,
|
||||
dcb->remote)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 2) Continue and check for wildcard host, user@%
|
||||
* Return 1 if no match
|
||||
*/
|
||||
|
||||
memset(&key.ipv4, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
LOGIF(LD,
|
||||
(skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]",
|
||||
pthread_self(),
|
||||
key.user,
|
||||
dcb->remote)));
|
||||
|
||||
user_password = mysql_users_fetch(service->users, &key);
|
||||
|
||||
if (!user_password) {
|
||||
/* the user@% was not found.
|
||||
* Return 1
|
||||
while (1) {
|
||||
/*
|
||||
* (1) Check for localhost first: 127.0.0.1 (IPv4 only)
|
||||
*/
|
||||
|
||||
if ((key.ipv4.sin_addr.s_addr == 0x0100007F) && !dcb->service->localhost_match_wildcard_host) {
|
||||
/* Skip the wildcard check and return 1 */
|
||||
LOGIF(LE,
|
||||
(skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : user %s@%s not found, try set "
|
||||
"'localhost_match_wildcard_host=1' in "
|
||||
"service definition of the configuration "
|
||||
"file.",
|
||||
key.user,
|
||||
dcb->remote)));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* (2) check for possible IPv4 class C,B,A networks
|
||||
*/
|
||||
|
||||
/* Class C check */
|
||||
key.ipv4.sin_addr.s_addr &= 0x00FFFFFF;
|
||||
key.netmask -= 8;
|
||||
|
||||
user_password = mysql_users_fetch(service->users, &key);
|
||||
|
||||
if (user_password) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Class B check */
|
||||
key.ipv4.sin_addr.s_addr &= 0x0000FFFF;
|
||||
key.netmask -= 8;
|
||||
|
||||
user_password = mysql_users_fetch(service->users, &key);
|
||||
|
||||
if (user_password) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Class A check */
|
||||
key.ipv4.sin_addr.s_addr &= 0x000000FF;
|
||||
key.netmask -= 8;
|
||||
|
||||
user_password = mysql_users_fetch(service->users, &key);
|
||||
|
||||
if (user_password) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* (3) Continue check for wildcard host, user@%
|
||||
*/
|
||||
|
||||
memset(&key.ipv4, 0, sizeof(struct sockaddr_in));
|
||||
key.netmask = 0;
|
||||
|
||||
LOGIF(LD,
|
||||
(skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [MySQL Client Auth], user [%s@%s] not existent",
|
||||
"%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]",
|
||||
pthread_self(),
|
||||
key.user,
|
||||
dcb->remote)));
|
||||
return 1;
|
||||
|
||||
user_password = mysql_users_fetch(service->users, &key);
|
||||
|
||||
if (!user_password) {
|
||||
/*
|
||||
* the user@% has not been found.
|
||||
*/
|
||||
|
||||
LOGIF(LD,
|
||||
(skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [MySQL Client Auth], user [%s@%s] not existent",
|
||||
pthread_self(),
|
||||
key.user,
|
||||
dcb->remote)));
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* user@host found: now check the password
|
||||
*
|
||||
* Convert the hex data (40 bytes) to binary (20 bytes).
|
||||
* The gateway_password represents the SHA1(SHA1(real_password)).
|
||||
* Please note: the real_password is unknown and SHA1(real_password) is unknown as well
|
||||
*/
|
||||
/* If user@host has been found we get the the password in binary format*/
|
||||
if (user_password) {
|
||||
/*
|
||||
* Convert the hex data (40 bytes) to binary (20 bytes).
|
||||
* The gateway_password represents the SHA1(SHA1(real_password)).
|
||||
* Please note: the real_password is unknown and SHA1(real_password) is unknown as well
|
||||
*/
|
||||
int passwd_len=strlen(user_password);
|
||||
if (passwd_len) {
|
||||
passwd_len = (passwd_len <= (SHA_DIGEST_LENGTH * 2)) ? passwd_len : (SHA_DIGEST_LENGTH * 2);
|
||||
gw_hex2bin(gateway_password, user_password, passwd_len);
|
||||
}
|
||||
|
||||
if (strlen(user_password))
|
||||
gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1652,11 +1702,9 @@ void protocol_archive_srv_command(
|
||||
|
||||
s1 = &p->protocol_command;
|
||||
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [protocol_archive_srv_command] Move command %s from fd %d "
|
||||
"to command history.",
|
||||
pthread_self(),
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"Move command %s from fd %d to command history.",
|
||||
STRPACKETTYPE(s1->scom_cmd),
|
||||
p->owner_dcb->fd)));
|
||||
|
||||
@ -1728,8 +1776,8 @@ void protocol_add_srv_command(
|
||||
p->protocol_command.scom_next = server_command_init(NULL, cmd);
|
||||
}
|
||||
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
LOGFILE_DEBUG,
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"Added command %s to fd %d.",
|
||||
STRPACKETTYPE(cmd),
|
||||
p->owner_dcb->fd)));
|
||||
@ -1739,8 +1787,8 @@ void protocol_add_srv_command(
|
||||
|
||||
while (c != NULL && c->scom_cmd != MYSQL_COM_UNDEFINED)
|
||||
{
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
LOGFILE_DEBUG,
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"fd %d : %d %s",
|
||||
p->owner_dcb->fd,
|
||||
c->scom_cmd,
|
||||
|
@ -44,6 +44,7 @@
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <my_config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -15,6 +15,7 @@
|
||||
*
|
||||
* Copyright MariaDB Corporation Ab 2013-2014
|
||||
*/
|
||||
#include <my_config.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
@ -1707,6 +1708,12 @@ static int routeQuery(
|
||||
}
|
||||
goto retblock;
|
||||
}
|
||||
/** If buffer is not contiguous, make it such */
|
||||
if (querybuf->next != NULL)
|
||||
{
|
||||
querybuf = gwbuf_make_contiguous(querybuf);
|
||||
}
|
||||
|
||||
master_dcb = router_cli_ses->rses_master_ref->bref_dcb;
|
||||
CHK_DCB(master_dcb);
|
||||
|
||||
|
@ -18,7 +18,7 @@ echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$#" == "$NARGS" ]
|
||||
if [ "$#" = "$NARGS" ]
|
||||
then
|
||||
echo "CTest mode"
|
||||
TDIR=$7 #this is only used by CMake
|
||||
@ -267,7 +267,7 @@ do
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "$err" == "" ]]
|
||||
if [[ "$err" = "" ]]
|
||||
then
|
||||
echo "TEST PASSED" >> $TLOG
|
||||
else
|
||||
@ -293,7 +293,7 @@ do
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "$err" == "" ]]
|
||||
if [[ "$err" = "" ]]
|
||||
then
|
||||
echo "TEST PASSED" >> $TLOG
|
||||
else
|
||||
|
@ -1,3 +0,0 @@
|
||||
if(BUILD_TESTS)
|
||||
install(FILES MaxScale_test.cnf DESTINATION etc RENAME MaxScale.cnf)
|
||||
endif()
|
2
support/changelog.md
Normal file
2
support/changelog.md
Normal file
@ -0,0 +1,2 @@
|
||||
### 2013/06/15
|
||||
+ Some example changes
|
2
support/faq.md
Normal file
2
support/faq.md
Normal file
@ -0,0 +1,2 @@
|
||||
### is this a question?
|
||||
An answer
|
5
support/gitdoc.json
Normal file
5
support/gitdoc.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"googleGroup": "group_name",
|
||||
"irc": {"server": "irc.freenode.net", "channel": "#a_channel"},
|
||||
"domain": "yoursite.com"
|
||||
}
|
2
support/guide/overview.md
Normal file
2
support/guide/overview.md
Normal file
@ -0,0 +1,2 @@
|
||||
This directory is useful for many things, like how to install your software, if it has a CLI you
|
||||
can tell people how to use it, any many other uses.
|
14
support/reference/layout.md
Normal file
14
support/reference/layout.md
Normal file
@ -0,0 +1,14 @@
|
||||
### Navigation
|
||||
On the documentation/guide/reference pages, the sections created in your reference and guide
|
||||
directories will be listed on the right as the main navigation links, you can have subsections too.
|
||||
Any h3(###) lines you include in your reference/guide files will be added to the subsections under
|
||||
the main section link. They will be hidden until you hover over the main section link or have
|
||||
clicked the section link.
|
||||
|
||||
### Headers
|
||||
You can use any size headers you want, but it is adivised to use h3(###) and smaller, anything
|
||||
bigger than h3(e.g. h2) is usually too big for the default layout.
|
||||
|
||||
### Scrolling
|
||||
When you scroll down the page the navigation will follow you if the screen is big enough for the
|
||||
navigation to fit on the right side, otherwise it sits at the top.
|
27
support/reference/premium.md
Normal file
27
support/reference/premium.md
Normal file
@ -0,0 +1,27 @@
|
||||
### Premium repositories
|
||||
Once you get premium, the plan you selected delegates the number of premium repositories you're
|
||||
allowed to have. Premium repositories have many features not available without a premium plan.
|
||||
|
||||
### Personally hosted repositories
|
||||
The premium repositories you select are allowed to be hosted on their own domains, you can choose
|
||||
a domain in your `support/gitdoc.json` file. Just add a `domain` field with your domain, and
|
||||
point your domain at our site, and it will automatically load your repo.
|
||||
|
||||
### Private repositories
|
||||
Private repositories cannot be viewed without being set as a premium repository.
|
||||
|
||||
### Custom CSS
|
||||
You're premium repos can have custom layouts through CSS. Once you add a premium repo, simply create
|
||||
the file `support/styles.css` and refresh your repo, when the page refreshes you'll be able to
|
||||
see the custom CSS in action.
|
||||
|
||||
### Branches
|
||||
On premium repositories, you can select the branch you want to pull updates from, this is useful
|
||||
if you plan to display the documentation for a specific version of your software.
|
||||
|
||||
### Standard Git repos
|
||||
Standard Git repositories from non Github servers are supported after you have a premium plan.
|
||||
To add a standard repo to your account, add support for the repository(You can get the setup
|
||||
details from your profile page.), after that go to your profile page and at the bottom will be
|
||||
a form where you can fill out the information to add your repository. After that it can be updated
|
||||
just like any other repository.
|
71
support/tutorial.md
Normal file
71
support/tutorial.md
Normal file
@ -0,0 +1,71 @@
|
||||
### Introduction
|
||||
After you run the command on the profile page a basic setup is created for you, including this
|
||||
tutorial and a few other files. These files include content describing some of the details on
|
||||
how to format the content.
|
||||
|
||||
### Adding support
|
||||
If you used the script to generate the support files, you can skip this section.
|
||||
|
||||
In your repository to add support you'll need the `support` directory, inside this directory
|
||||
you will need to create a `gitdoc.json` file. This file contains details about the repository.
|
||||
```
|
||||
$ mkdir support/
|
||||
$ touch support/gitdoc.json
|
||||
```
|
||||
The other files in the `support` directory are optional, only `gitdoc.json` is required.
|
||||
|
||||
The following sections describe the information needed in the files.
|
||||
|
||||
### gitdoc.json
|
||||
There are a few fields in this file that make it easy to give your viewers extra details about
|
||||
the community, as well as the domain for premium repos.
|
||||
|
||||
#### googleGroup
|
||||
This is a field you can use to give your viewers a link to your google group. Just set the field
|
||||
to the name of your google group, and we'll create the link. It isn't required though, you can
|
||||
leave it out safely.
|
||||
|
||||
#### irc
|
||||
This is a field you can use to give your viewers the details to join your irc channel. To use it
|
||||
set an `object` with two fields. One of the fields is `server`, this is the server address for the
|
||||
irc network(e.g. `irc.freenode.net` for the freenode network). The next is the `channel` field,
|
||||
this tells the viewers the specific channel for your community. The channel requires you to
|
||||
include the prefix character though(e.g. #, &, +, !), since there are multiple.
|
||||
|
||||
#### domain
|
||||
This is a field you can use if your repository is premium. It tells us the name of the domain
|
||||
for your repo, so we can get your repo if we detect a custom domain. You can ignore it, or just
|
||||
set a placeholder if it's not premium yet.
|
||||
|
||||
#### analytics
|
||||
When you view the repo from a custom premium domain, if this field is given it'll include the
|
||||
Google Analytics snippet to track page views. This value should be your GA web property ID.
|
||||
|
||||
### changelog.md
|
||||
This file is just a markdown file displaying the changelog for your repository. For details on
|
||||
the markdown, view the default documentation created. This file can be safely ignored if you don't
|
||||
want to include a changelog page.
|
||||
|
||||
### faq.md
|
||||
This file is just a markdown file displaying the frequently asked questions for your repository.
|
||||
For details on the markdown, view the default documentation created. This file can be safely
|
||||
ignored if you don't want to include a faq page.
|
||||
|
||||
### tutorial.md
|
||||
This file is just a markdown file displaying the tutorial for your repository. For details on the
|
||||
markdown, view the default documentation created. This file can be safely ignored if you don't
|
||||
want to include a tutorial page.
|
||||
|
||||
### styles.css
|
||||
This file is used when your repository is premium to display custom layouts for your viewers. It
|
||||
can be safely ignored, or just as a place holder if the repo is not premium yet.
|
||||
|
||||
### reference/
|
||||
This directory is used to hold the markdown files for the documentation/reference page. Every file
|
||||
in this directory will be added as a section to the documentation with the section titled after
|
||||
the file name, so make sure it's readable.
|
||||
|
||||
### guide/
|
||||
This directory is used to hold the markdown files for the documentation/guide page. Every file in this
|
||||
directory will be added as a section to the guide with the section titled after the file name, so
|
||||
make sure it's readable.
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
Created: 20-06-2013
|
||||
Updated:
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
Created: 20-06-2013
|
||||
Updated:
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
Created: 20-06-2013
|
||||
Updated:
|
||||
*/
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
Created: 20-06-2013
|
||||
Updated:
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
Created: 15-07-2013
|
||||
Updated:
|
||||
*/
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
Created: 15-07-2013
|
||||
Updated:
|
||||
*/
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
Created: 20-06-2013
|
||||
Updated:
|
||||
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
Author: Jan Lindström jan.lindstrom@mariadb.com
|
||||
|
||||
Created: 20-06-2013
|
||||
Updated:
|
||||
|
@ -320,6 +320,7 @@ mlist_t* mlist_init(
|
||||
list->mlist_nodecount_max = maxnodes;
|
||||
/** Set data deletion callback fun */
|
||||
list->mlist_datadel = datadel;
|
||||
|
||||
if (name != NULL) {
|
||||
list->mlist_name = name;
|
||||
}
|
||||
@ -345,6 +346,7 @@ mlist_t* mlist_init(
|
||||
CHK_MLIST_CURSOR(c);
|
||||
*cursor = c;
|
||||
}
|
||||
list->mlist_versno = 2; /*< vresno != 0 means that list is initialized */
|
||||
CHK_MLIST(list);
|
||||
|
||||
return_list:
|
||||
|
@ -52,9 +52,7 @@ typedef struct mlist_st {
|
||||
bool mlist_deleted;
|
||||
size_t mlist_nodecount;
|
||||
size_t mlist_nodecount_max; /**< size limit. 0 == no limit */
|
||||
#if 1
|
||||
size_t mlist_versno;
|
||||
#endif
|
||||
bool mlist_flat;
|
||||
mlist_node_t* mlist_first;
|
||||
mlist_node_t* mlist_last;
|
||||
|
Loading…
x
Reference in New Issue
Block a user