Commit eeca1f86 authored by Sergei Golubchik's avatar Sergei Golubchik

merge with 5.1

parents 9c320883 4a4aa358
......@@ -699,7 +699,6 @@ ma_test_recovery.output
man/*.1
maria-win.patch
maria_log.00000*
maria_log_control
merge/*.ds?
merge/*.vcproj
missing
......@@ -1961,3 +1960,8 @@ client/strings_def.h
libmysql/strings_def.h
libmysql_r/strings_def.h
storage/maria/aria_log_control
CPackConfig.cmake
CPackSourceConfig.cmake
win/nmake_cache.txt
*.manifest
*.resource.txt
......@@ -114,6 +114,9 @@ ENDIF(ENABLED_DEBUG_SYNC)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
# in some places we use DBUG_OFF
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
......@@ -247,16 +250,15 @@ IF(WITHOUT_DYNAMIC_PLUGINS)
MESSAGE("Dynamic plugins are disabled.")
ENDIF(WITHOUT_DYNAMIC_PLUGINS)
FILE(GLOB STORAGE_SUBDIRS storage/*)
FILE(GLOB STORAGE_SUBDIRS storage/* plugin/*)
FOREACH(SUBDIR ${STORAGE_SUBDIRS})
FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/storage ${SUBDIR})
IF (EXISTS ${SUBDIR}/CMakeLists.txt)
# Check MYSQL_STORAGE_ENGINE macro is present
FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX MYSQL_STORAGE_ENGINE)
FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX "MYSQL_(STORAGE_ENGINE|PLUGIN)")
IF(HAVE_STORAGE_ENGINE)
# Extract name of engine from HAVE_STORAGE_ENGINE
STRING(REGEX REPLACE ".*MYSQL_STORAGE_ENGINE\\((.*\)\\).*"
"\\1" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
STRING(REGEX REPLACE ".*MYSQL_(STORAGE_ENGINE|PLUGIN)\\((.*\)\\).*"
"\\2" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
STRING(TOUPPER ${ENGINE_NAME} ENGINE)
STRING(TOLOWER ${ENGINE_NAME} ENGINE_LOWER)
......@@ -265,21 +267,23 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
# build as shared library (dynamic).
IF(EXISTS ${SUBDIR}/plug.in)
FILE(READ ${SUBDIR}/plug.in PLUGIN_FILE_CONTENT)
STRING (REGEX MATCH "MYSQL_PLUGIN_DYNAMIC" MYSQL_PLUGIN_DYNAMIC ${PLUGIN_FILE_CONTENT})
IF (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER}")
STRING (REGEX REPLACE
".*MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER},[ \\t]*\\[?([a-zA-Z0-9_]+/)*([a-zA-Z0-9_]+).*"
"\\2" MYSQL_PLUGIN_DYNAMIC ${PLUGIN_FILE_CONTENT})
ELSE (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER}")
SET (MYSQL_PLUGIN_DYNAMIC "")
ENDIF(PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER}")
IF (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER}")
STRING (REGEX REPLACE
".*MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER},[ \\t]*\\[?([a-zA-Z0-9_]+/)*([a-zA-Z0-9_]+).*"
"\\2"
MYSQL_PLUGIN_STATIC ${PLUGIN_FILE_CONTENT})
ELSE (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER}")
SET (MYSQL_PLUGIN_STATIC "")
ENDIF(PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER}")
STRING (REGEX MATCH "MYSQL_PLUGIN_MANDATORY" MYSQL_PLUGIN_MANDATORY ${PLUGIN_FILE_CONTENT})
STRING (REGEX MATCH "MYSQL_PLUGIN_STATIC" MYSQL_PLUGIN_STATIC ${PLUGIN_FILE_CONTENT})
#
# XTRADB is located in storage/xtradb, but it says everywhere it is 'innobase' (e.g.
# it declares 'builtin_innobase_plugin', not builtin_xtradb_plugin).
# Extract the intended plugin name from MYSQL_STORAGE_ENGINE definition and use it
# where appropriate.
STRING (REGEX MATCH "MYSQL_STORAGE_ENGINE.[a-z]*" PLUGIN_NAME ${PLUGIN_FILE_CONTENT})
STRING (REGEX REPLACE "MYSQL_STORAGE_ENGINE.(.*)" "\\1" PLUGIN_NAME ${PLUGIN_NAME})
# Also remember this "xtradb"/"innobase" name discrepancy for libmysqld/CMakeLists.txt:
SET (plugin_dir_${PLUGIN_NAME} ${DIRNAME})
IF(MYSQL_PLUGIN_MANDATORY)
SET(WITH_${ENGINE}_STORAGE_ENGINE TRUE)
ENDIF(MYSQL_PLUGIN_MANDATORY)
......@@ -293,15 +297,17 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${ENGINE_LOWER}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${MYSQL_PLUGIN_STATIC})
SET (MYSQLD_STATIC_ENGINES ${MYSQLD_STATIC_ENGINES} ${ENGINE})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
SET (${ENGINE}_DIR ${DIRNAME})
SET (${ENGINE}_DIR ${SUBDIR})
ENDIF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
ENDIF(EXISTS ${SUBDIR}/plug.in)
IF(NOT ENGINE_BUILD_TYPE STREQUAL "NONE")
SET (${ENGINE}_LIB ${MYSQL_PLUGIN_${ENGINE_BUILD_TYPE}})
LIST(APPEND ${ENGINE_BUILD_TYPE}_ENGINE_DIRECTORIES ${SUBDIR})
ENDIF(NOT ENGINE_BUILD_TYPE STREQUAL "NONE")
......
......@@ -865,7 +865,7 @@ AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h fpu_control.h \
ieeefp.h limits.h memory.h pwd.h select.h fnmatch.h \
stdlib.h stddef.h sys/stat.h \
stdlib.h stddef.h sys/stat.h sys/sockio.h \
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
......
......@@ -16,13 +16,27 @@
#ifndef _my_plugin_h
#define _my_plugin_h
/*
On Windows, exports from DLL need to be declared
*/
#if (defined(_WIN32) && defined(MYSQL_DYNAMIC_PLUGIN))
#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
#else
Also, plugin needs to be declared as extern "C" because MSVC
unlike other compilers, uses C++ mangling for variables not only
for functions.
*/
#if defined(_MSC_VER)
#if defined(MYSQL_DYNAMIC_PLUGIN)
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
#else
#define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
#endif
#else /* MYSQL_DYNAMIC_PLUGIN */
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C"
#else
#define MYSQL_PLUGIN_EXPORT
#endif
#endif /*MYSQL_DYNAMIC_PLUGIN */
#else /*_MSC_VER */
#define MYSQL_PLUGIN_EXPORT
#endif
......
......@@ -86,15 +86,13 @@ FOREACH(rpath ${VIO_SOURCES})
SET(LIB_SOURCES ${LIB_SOURCES} ../vio/${rpath})
ENDFOREACH(rpath)
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${plugin_dir_${ENGINE_LIB}}/CMakeLists.txt)
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
SET(ENGINE_DIR ${${ENGINE_LIB_UPPER}_DIR})
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/CMakeLists.txt)
FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES})
SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/${rpath})
SET (ENGINE_BUILD_TYPE "STATIC")
FOREACH (ENGINE ${MYSQLD_STATIC_ENGINES})
INCLUDE(${${ENGINE}_DIR}/CMakeLists.txt)
FOREACH(rpath ${${ENGINE}_SOURCES})
SET(LIB_SOURCES ${LIB_SOURCES} ${${ENGINE}_DIR}/${rpath})
ENDFOREACH(rpath)
ENDFOREACH(ENGINE_LIB)
ENDFOREACH(ENGINE)
SET(SOURCE_SUBLIBS FALSE)
......@@ -162,15 +160,14 @@ IF(MSVC AND CMAKE_SIZEOF_VOID_P MATCHES 8)
ENDIF()
# Add any additional libraries requested by engine(s)
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
IF(${ENGINE_LIB_UPPER}_LIBS)
TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE_LIB_UPPER}_LIBS})
ENDIF(${ENGINE_LIB_UPPER}_LIBS)
ENDFOREACH(ENGINE_LIB)
FOREACH (ENGINE ${MYSQLD_STATIC_ENGINES})
IF(${ENGINE}_LIBS)
TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE}_LIBS})
ENDIF(${ENGINE}_LIBS)
ENDFOREACH(ENGINE)
ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def)
ADD_DEPENDENCIES(libmysqld mysqlserver)
TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32)
TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32 iphlpapi)
MYSQL_INSTALL_TARGETS(mysqlserver libmysqld DESTINATION lib COMPONENT Embedded)
......@@ -15,6 +15,8 @@ max_heap_table_size= 1M
loose-skip-innodb
loose-skip-pbxt
loose-skip-feedback
loose-feedback-user-info= mysql-test
loose-innodb_data_file_path= ibdata1:10M:autoextend
......
install plugin feedback soname 'feedback.so';
select plugin_status from information_schema.plugins where plugin_name='feedback';
plugin_status
ACTIVE
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid';
VARIABLE_NAME VARIABLE_VALUE
FEEDBACK 1.0
FEEDBACK_SEND_RETRY_WAIT 60
FEEDBACK_SEND_TIMEOUT 60
FEEDBACK_URL http://mariadb.org/feedback_plugin/post
FEEDBACK_USER_INFO mysql-test
uninstall plugin feedback;
select plugin_status from information_schema.plugins where plugin_name='feedback';
plugin_status
ACTIVE
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid';
VARIABLE_NAME VARIABLE_VALUE
FEEDBACK 1.0
FEEDBACK_SEND_RETRY_WAIT 60
FEEDBACK_SEND_TIMEOUT 60
FEEDBACK_URL http://mariadb.org/feedback_plugin/post
FEEDBACK_USER_INFO mysql-test
select plugin_status from information_schema.plugins where plugin_name='feedback';
plugin_status
ACTIVE
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid';
VARIABLE_NAME VARIABLE_VALUE
FEEDBACK 1.0
FEEDBACK_SEND_RETRY_WAIT 60
FEEDBACK_SEND_TIMEOUT 60
FEEDBACK_URL http://mariadb.org/feedback_plugin/post
FEEDBACK_USER_INFO mysql-test
feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent
feedback plugin: server replied 'ok'
feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent
feedback plugin: server replied 'ok'
--source include/not_embedded.inc
if (`select length('$FEEDBACK_SO') = 0`) {
skip No feedback plugin;
}
--replace_regex /\.dll/.so/
eval install plugin feedback soname '$FEEDBACK_SO';
select plugin_status from information_schema.plugins where plugin_name='feedback';
--replace_result https http
--sorted_result
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid';
uninstall plugin feedback;
--loose-feedback
--plugin-load=$FEEDBACK_SO
if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active'`)
{
--skip Feedback plugin is not active
}
select plugin_status from information_schema.plugins where plugin_name='feedback';
--replace_result https http
--sorted_result
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid';
source t/feedback_plugin_load.test;
source include/big_test.inc;
if (!$MTR_FEEDBACK_PLUGIN) {
skip MTR_FEEDBACK_PLUGIN is not set;
}
#
# Yep. The plugin waits 5 minutes before sending anything,
# and there's no way to force it to send anything sooner.
# Let's wait, and hope that mtr is started with --parallel and
# is doing some work in other workers.
#
sleep 310;
source include/restart_mysqld.inc;
replace_result https http;
perl;
$log_error= $ENV{'MYSQLTEST_VARDIR'} . '/log/mysqld.1.err';
open(LOG, '<', $log_error) or die "open(< $log_error): $!";
/feedback plugin:.*/ && print "$&\n" while $_=<LOG>;
close LOG;
EOF
......@@ -3,7 +3,8 @@
#
# BUG#39746 - Debug flag breaks struct definition (server crash)
#
INSTALL PLUGIN simple_parser SONAME 'mypluglib.so';
--replace_result .dll .so
eval INSTALL PLUGIN simple_parser SONAME '$MYPLUGLIB_SO';
CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a) WITH PARSER simple_parser);
ALTER TABLE t1 ADD FULLTEXT(b) WITH PARSER simple_parser;
DROP TABLE t1;
......
......@@ -48,4 +48,5 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(mysys ${MYSYS_SOURCES})
TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
ENDIF(NOT SOURCE_SUBLIBS)
......@@ -16,11 +16,22 @@
/* get hardware address for an interface */
/* if there are many available, any non-zero one can be used */
#define DONT_DEFINE_VOID /* windows includes break if we do */
#include "mysys_priv.h"
#include <m_string.h>
#ifndef MAIN
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
{
uint i, res= 1;
for (i= 0; i < len; i++)
if ((*to++= *from++))
res= 0;
return res;
}
#ifdef __FreeBSD__
#include <net/ethernet.h>
......@@ -32,11 +43,10 @@
my_bool my_gethwaddr(uchar *to)
{
size_t len;
char *buf, *next, *end;
uchar *buf, *next, *end, *addr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
char zero_array[ETHER_ADDR_LEN] = {0};
int res= 1, mib[6]= {CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
goto err;
......@@ -52,9 +62,9 @@ my_bool my_gethwaddr(uchar *to)
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO)
{
sdl= (struct sockaddr_dl *)(ifm + 1);
memcpy(to, LLADDR(sdl), ETHER_ADDR_LEN);
res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
sdl = (struct sockaddr_dl *)(ifm + 1);
addr= LLADDR(sdl);
res= memcpy_and_test(to, addr, ETHER_ADDR_LEN);
}
}
......@@ -62,40 +72,94 @@ err:
return res;
}
#elif __linux__
#elif defined(__linux__) || defined(__sun__)
#include <net/if.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#define ETHER_ADDR_LEN 6
my_bool my_gethwaddr(uchar *to)
{
int fd, res= 1;
struct ifreq ifr;
char zero_array[ETHER_ADDR_LEN] = {0};
struct ifreq ifr[32];
struct ifconf ifc;
ifc.ifc_req= ifr;
ifc.ifc_len= sizeof(ifr);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
goto err;
bzero(&ifr, sizeof(ifr));
strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
do
if (ioctl(fd, SIOCGIFCONF, (char*)&ifc) >= 0)
{
if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0)
uint i;
for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++)
{
memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
#ifdef SIOCGIFHWADDR
if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0)
res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data,
ETHER_ADDR_LEN);
#else
/*
A bug in OpenSolaris prevents non-root from getting a mac address:
http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4720634
Thus, we'll use an alternative method and extract the address from the
arp table.
*/
struct arpreq arpr;
arpr.arp_pa= ifr[i].ifr_addr;
if (ioctl(fd, SIOCGARP, (char*)&arpr) >= 0)
res= memcpy_and_test(to, (uchar *)&arpr.arp_ha.sa_data,
ETHER_ADDR_LEN);
#endif
}
} while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6');
}
close(fd);
err:
return res;
}
#else /* FreeBSD elif linux */
#elif defined(_WIN32)
#include <winsock2.h>
#include <iphlpapi.h>
#define ETHER_ADDR_LEN 6
my_bool my_gethwaddr(uchar *to)
{
my_bool res= 1;
IP_ADAPTER_INFO *info= NULL;
ULONG info_len= 0;
if (GetAdaptersInfo(info, &info_len) != ERROR_BUFFER_OVERFLOW)
goto err;
info= alloca(info_len);
if (GetAdaptersInfo(info, &info_len) != NO_ERROR)
goto err;
while (info && res)
{
if (info->Type == MIB_IF_TYPE_ETHERNET &&
info->AddressLength == ETHER_ADDR_LEN)
res= memcpy_and_test(to, info->Address, ETHER_ADDR_LEN);
}
err:
return res;
}
#else /* neither FreeBSD nor linux not Windows */
/* just fail */
my_bool my_gethwaddr(uchar *to __attribute__((unused)))
{
......@@ -114,7 +178,7 @@ int main(int argc __attribute__((unused)),char **argv)
printf("my_gethwaddr failed with errno %d\n", errno);
exit(1);
}
for (i=0; i < sizeof(mac); i++)
for (i= 0; i < sizeof(mac); i++)
{
if (i) printf(":");
printf("%02x", mac[i]);
......
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include)
SET(FEEDBACK_SOURCES feedback.cc sender_thread.cc
url_base.cc url_http.cc utils.cc)
SET(FEEDBACK_LIBS Ws2_32)
MYSQL_PLUGIN(FEEDBACK)
pkgplugindir = $(pkglibdir)/plugin
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex -I$(top_srcdir)/sql
EXTRA_LTLIBRARIES = feedback.la libfeedback.la
pkgplugin_LTLIBRARIES = @plugin_feedback_shared_target@
feedback_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
feedback_la_CXXFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN
feedback_la_SOURCES = feedback.cc utils.cc url_base.cc url_http.cc \
sender_thread.cc
noinst_LTLIBRARIES = @plugin_feedback_static_target@
libfeedback_la_SOURCES= feedback.cc utils.cc url_base.cc url_http.cc \
sender_thread.cc
noinst_HEADERS = feedback.h
EXTRA_DIST = CMakeLists.txt plug.in
This diff is collapsed.
/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program 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 of the License.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_SERVER
#include <mysql_priv.h>
namespace feedback {
int fill_feedback(THD *thd, TABLE_LIST *tables, COND *cond);
int fill_plugin_version(THD *thd, TABLE_LIST *tables);
int fill_misc_data(THD *thd, TABLE_LIST *tables);
int fill_linux_info(THD *thd, TABLE_LIST *tables);
static const int SERVER_UID_SIZE= 29;
extern char server_uid_buf[SERVER_UID_SIZE+1], *user_info;
int calculate_server_uid(char *);
int prepare_linux_info();
extern ST_SCHEMA_TABLE *i_s_feedback;
extern ulong send_timeout, send_retry_wait;
pthread_handler_t background_thread(void *arg);
/**
The class for storing urls to send report data to.
Constructors are private, the object should be created with create() method.
send() method does the actual sending.
*/
class Url {
protected:
Url(LEX_STRING &url_arg) : full_url(url_arg) {}
const LEX_STRING full_url;
public:
virtual ~Url() { my_free(full_url.str, MYF(0)); }
const char *url() { return full_url.str; }
size_t url_length() { return full_url.length; }
virtual int send(const char* data, size_t data_length) = 0;
static Url* create(const char *url, size_t url_length);
};
extern Url **urls;
extern uint url_count;
/* these are used to communicate with the background thread */
extern pthread_mutex_t sleep_mutex;
extern pthread_cond_t sleep_condition;
extern volatile bool shutdown_plugin;
} // namespace feedback
MYSQL_PLUGIN(feedback,[MariaDB User Feedback Plugin],
[MariaDB User Feedback Plugin])
dnl Although it's not exactly obvious, top-level CMakeLists.txt parses plug.in
dnl files, in particular looking for what the library name should be. It uses
dnl regexp that matches MYSQL_PLUGIN_DYNAMIC or MYSQL_PLUGIN_STATIC, followed
dnl by an open parenthesys, and the plugin name. Having engine name enclosed in
dnl square brackets below causes this regexp to fail and as a result feedback
dnl plugin will not be considered for dynamic builds on Windows.
dnl Unfortunately, feedback cannot be built dynamically on Windows, because it
dnl needs to access server internals that aren't designed for plugin use and
dnl aren't marked with MYSQL_PLUGIN_IMPORT.
MYSQL_PLUGIN_DYNAMIC([feedback], [feedback.la])
ifelse(index(AC_PACKAGE_NAME, [MariaDB]), -1, [], [
dnl MariaDB and MySQL define static plugins differently.
dnl I only support MariaDB here, for now.
MYSQL_PLUGIN_STATIC(feedback, [libfeedback.la])
])
dnl MariaDB before 5.5 needs this define:
MYSQL_PLUGIN_DEFINE(feedback, [WITH_FEEDBACK_PLUGIN])
MYSQL_PLUGIN_ACTIONS(feedback, [
AC_CHECK_HEADERS([netdb.h sys/utsname.h])
])
/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program 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 of the License.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "feedback.h"
#include <time.h>
namespace feedback {
static THD *thd= 0; ///< background thread thd
static my_thread_id thd_thread_id; ///< its thread_id
static size_t needed_size= 20480;
static const time_t startup_interval= 60*5; ///< in seconds (5 minutes)
static const time_t first_interval= 60*60*24; ///< in seconds (one day)
static const time_t interval= 60*60*24*7; ///< in seconds (one week)
/**
reads the rows from a table and puts them, concatenated, in a String
@note
1. only supports two column tables - no less, no more.
2. it emulates mysql -e "select * from..." and thus it separates
columns with \t and starts the output with column names.
*/
static int table_to_string(TABLE *table, String *result)
{
bool res;
char buff1[MAX_FIELD_WIDTH], buff2[MAX_FIELD_WIDTH];
String str1(buff1, sizeof(buff1), system_charset_info);
String str2(buff2, sizeof(buff2), system_charset_info);
res= table->file->ha_rnd_init(1);
dbug_tmp_use_all_columns(table, table->read_set);
while(!res && !table->file->ha_rnd_next(table->record[0]))
{
table->field[0]->val_str(&str1);
table->field[1]->val_str(&str2);
if (result->reserve(str1.length() + str2.length() + 3))
res= 1;
else
{
result->qs_append(str1.ptr(), str1.length());
result->qs_append('\t');
result->qs_append(str2.ptr(), str2.length());
result->qs_append('\n');
}
}
res = res || result->append('\n');
/*
Note, "|=" and not "||" - because we want to call ha_rnd_end()
even if res is already 1.
*/
res |= table->file->ha_rnd_end();
return res;
}
/**
Initialize the THD and TABLE_LIST
The structures must be sufficiently initialized for create_tmp_table()
and fill_feedback() to work.
*/
static int prepare_for_fill(TABLE_LIST *tables)
{
/*
Add our thd to the list, for it to be visible in SHOW PROCESSLIST.
But don't generate thread_id every time - use the saved value
(every increment of global thread_id counts as a new connection
in SHOW STATUS and we want to avoid skewing the statistics)
*/
thd->thread_id= thd->variables.pseudo_thread_id= thd_thread_id;
pthread_mutex_lock(&LOCK_thread_count);
thread_count++;
threads.append(thd);
pthread_mutex_unlock(&LOCK_thread_count);
thd->thread_stack= (char*) &tables;
if (thd->store_globals())
return 1;
thd->mysys_var->current_cond= &sleep_condition;
thd->mysys_var->current_mutex= &sleep_mutex;
thd->proc_info="feedback";
thd->command=COM_SLEEP;
thd->version=refresh_version;
thd->system_thread= SYSTEM_THREAD_EVENT_WORKER; // whatever
thd->set_time();
thd->init_for_queries();
thd->real_id= pthread_self();
thd->db= NULL;
thd->db_length= 0;
thd->security_ctx->host_or_ip= "";
thd->security_ctx->db_access= DB_ACLS;
thd->security_ctx->master_access= ~NO_ACCESS;
bzero((char*) &thd->net, sizeof(thd->net));
lex_start(thd);
mysql_init_select(thd->lex);
tables->init_one_table(INFORMATION_SCHEMA_NAME.str,
i_s_feedback->table_name, TL_READ);
tables->schema_table= i_s_feedback;
tables->table= i_s_feedback->create_table(thd, tables);
if (!tables->table)
return 1;
tables->table->pos_in_table_list= tables;
return 0;
}
/**
Try to detect if this thread is going down
which can happen for different reasons:
* plugin is being unloaded
* mysqld server is being shut down
* the thread is being killed
*/
static bool going_down()
{
return shutdown_plugin || shutdown_in_progress || (thd && thd->killed);
}
/**
just like sleep, but waits on a condition and checks "plugin shutdown" status
*/
static int slept_ok(time_t sec)
{
struct timespec abstime;
int ret= 0;
set_timespec(abstime, sec);
pthread_mutex_lock(&sleep_mutex);
while (!going_down() && ret != ETIMEDOUT)
ret= pthread_cond_timedwait(&sleep_condition, &sleep_mutex, &abstime);
pthread_mutex_unlock(&sleep_mutex);
return !going_down();
}
/**
create a feedback report and send it to all specified urls
If "when" argument is not null, only it and the server uid are sent.
Otherwise a full report is generated.
*/
static void send_report(const char *when)
{
TABLE_LIST tables;
String str;
int i, last_todo;
Url **todo= (Url**)alloca(url_count*sizeof(Url*));
str.alloc(needed_size); // preallocate it to avoid many small mallocs
/*
on startup and shutdown the server may not be completely
initialized, and full report won't work.
We send a short status notice only.
*/
if (when)
{
str.length(0);
str.append(STRING_WITH_LEN("FEEDBACK_SERVER_UID"));
str.append('\t');
str.append(server_uid_buf);
str.append('\n');
str.append(STRING_WITH_LEN("FEEDBACK_WHEN"));
str.append('\t');
str.append(when);
str.append('\n');
str.append(STRING_WITH_LEN("FEEDBACK_USER_INFO"));
str.append('\t');
str.append(user_info);
str.append('\n');
str.append('\n');
}
else
{
/*
otherwise, prepare the THD and TABLE_LIST,
create and fill the temporary table with data just like
SELECT * FROM IFROEMATION_SCHEMA.feedback is doing,
read and concatenate table data into a String.
*/
if (!(thd= new THD()))
return;
if (prepare_for_fill(&tables))
goto ret;
if (fill_feedback(thd, &tables, NULL))
goto ret;
if (table_to_string(tables.table, &str))
goto ret;
needed_size= (size_t)(str.length() * 1.1);
free_tmp_table(thd, tables.table);
tables.table= 0;
}
/*
Try to send the report on every url from the list, remove url on success,
keep failed in the list. Repeat until the list is empty.
*/
memcpy(todo, urls, url_count*sizeof(Url*));
last_todo= url_count - 1;
do
{
for (i= 0; i <= last_todo;)
{
Url *url= todo[i];
if (thd) // for nicer SHOW PROCESSLIST
thd->set_query(const_cast<char*>(url->url()), url->url_length());
if (url->send(str.ptr(), str.length()))
i++;
else
todo[i]= todo[last_todo--];
}
if (last_todo < 0)
break;
} while (slept_ok(send_retry_wait)); // wait a little bit before retrying
ret:
if (thd)
{
if (tables.table)
free_tmp_table(thd, tables.table);
/*
clean up, free the thd.
reset all thread local status variables to minimize
the effect of the background thread on SHOW STATUS.
*/
pthread_mutex_lock(&LOCK_thread_count);
bzero(&thd->status_var, sizeof(thd->status_var));
thread_count--;
thd->killed= THD::KILL_CONNECTION;
pthread_cond_broadcast(&COND_thread_count);
pthread_mutex_unlock(&LOCK_thread_count);
delete thd;
thd= 0;
}
}
/**
background sending thread
*/
pthread_handler_t background_thread(void *arg __attribute__((unused)))
{
if (my_thread_init())
return 0;
pthread_mutex_lock(&LOCK_thread_count);
thd_thread_id= thread_id++;
pthread_mutex_unlock(&LOCK_thread_count);
if (slept_ok(startup_interval))
{
send_report("startup");
if (slept_ok(first_interval))
{
send_report(NULL);
while(slept_ok(interval))
send_report(NULL);
}
send_report("shutdown");
}
my_thread_end();
pthread_exit(0);
return 0;
}
} // namespace feedback
/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program 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 of the License.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "feedback.h"
namespace feedback {
Url* http_create(const char *url, size_t url_length);
/**
creates an Url object out of an url, if possible.
This is done by invoking corresponding creator functions
of the derived classes, until the first not NULL result.
*/
Url* Url::create(const char *url, size_t url_length)
{
url= my_strndup(url, url_length, MYF(MY_WME));
if (!url)
return NULL;
Url *self= http_create(url, url_length);
/*
here we can add
if (!self) self= smtp_create(url, url_length);
if (!self) self= tftp_create(url, url_length);
etc
*/
if (!self)
my_free(const_cast<char*>(url), MYF(0));
return self;
}
} // namespace feedback
/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program 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 of the License.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "feedback.h"
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef _WIN32
#undef VOID
#define VOID void
#include <ws2tcpip.h>
#define addrinfo ADDRINFOA
#endif
namespace feedback {
static const uint FOR_READING= 0;
static const uint FOR_WRITING= 1;
#ifdef MARIADB_BASE_VERSION
#define ssl_connect(A,B,C,D) sslconnect(A,B,C,D)
#else
#define ssl_connect(A,B,C,D) sslconnect(A,B,C)
#endif
/**
implementation of the Url class that sends the data via HTTP POST request.
Both http:// and https:// protocols are supported.
*/
class Url_http: public Url {
protected:
const LEX_STRING host, port, path;
bool ssl;
Url_http(LEX_STRING &url_arg, LEX_STRING &host_arg,
LEX_STRING &port_arg, LEX_STRING &path_arg, bool ssl_arg) :
Url(url_arg), host(host_arg), port(port_arg), path(path_arg), ssl(ssl_arg)
{}
~Url_http()
{
my_free(host.str, MYF(0));
my_free(port.str, MYF(0));
my_free(path.str, MYF(0));
}
public:
int send(const char* data, size_t data_length);
friend Url* http_create(const char *url, size_t url_length);
};
/**
create a Url_http object out of the url, if possible.
@note
Arbitrary limitations here.
The url must be http[s]://hostname[:port]/path
No username:password@ or ?script=parameters are supported.
But it's ok. This is not a generic purpose www browser - it only needs to be
good enough to POST the data to mariadb.org.
*/
Url* http_create(const char *url, size_t url_length)
{
const char *s;
LEX_STRING full_url= {const_cast<char*>(url), url_length};
LEX_STRING host, port, path;
bool ssl= false;
if (is_prefix(url, "http://"))
s= url + 7;
#ifdef HAVE_OPENSSL
else if (is_prefix(url, "https://"))
{
ssl= true;
s= url + 8;
}
#endif
else
return NULL;
for (url= s; *s && *s != ':' && *s != '/'; s++) /* no-op */;
host.str= const_cast<char*>(url);
host.length= s-url;
if (*s == ':')
{
for (url= ++s; *s && *s >= '0' && *s <= '9'; s++) /* no-op */;
port.str= const_cast<char*>(url);
port.length= s-url;
}
else
{
if (ssl)
{
port.str= const_cast<char*>("443");
port.length=3;
}
else
{
port.str= const_cast<char*>("80");
port.length=2;
}
}
if (*s == 0)
{
path.str= const_cast<char*>("/");
path.length= 1;
}
else
{
path.str= const_cast<char*>(s);
path.length= strlen(s);
}
if (!host.length || !port.length || path.str[0] != '/')
return NULL;
host.str= my_strndup(host.str, host.length, MYF(MY_WME));
port.str= my_strndup(port.str, port.length, MYF(MY_WME));
path.str= my_strndup(path.str, path.length, MYF(MY_WME));
if (!host.str || !port.str || !path.str)
{
my_free(host.str, MYF(MY_ALLOW_ZERO_PTR));
my_free(port.str, MYF(MY_ALLOW_ZERO_PTR));
my_free(path.str, MYF(MY_ALLOW_ZERO_PTR));
return NULL;
}
return new Url_http(full_url, host, port, path, ssl);
}
/* do the vio_write and check that all data were sent ok */
#define write_check(VIO, DATA, LEN) \
(vio_write((VIO), (uchar*)(DATA), (LEN)) != (LEN))
int Url_http::send(const char* data, size_t data_length)
{
my_socket fd= INVALID_SOCKET;
char buf[1024];
uint len;
addrinfo *addrs, *addr, filter= {0, AF_UNSPEC, SOCK_STREAM, 6, 0, 0, 0, 0};
int res= getaddrinfo(host.str, port.str, &filter, &addrs);
if (res)
{
sql_print_error("feedback plugin: getaddrinfo() failed for url '%s': %s",
full_url.str, gai_strerror(res));
return 1;
}
for (addr= addrs; addr != NULL; addr= addr->ai_next)
{
fd= socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (fd == INVALID_SOCKET)
continue;
if (connect(fd, addr->ai_addr, addr->ai_addrlen) == 0)
break;
closesocket(fd);
}
freeaddrinfo(addrs);
if (fd == INVALID_SOCKET)
{
sql_print_error("feedback plugin: could not connect for url '%s'",
full_url.str);
return 1;
}
Vio *vio= vio_new(fd, VIO_TYPE_TCPIP, 0);
if (!vio)
{
sql_print_error("feedback plugin: vio_new failed for url '%s'",
full_url.str);
closesocket(fd);
return 1;
}
#ifdef HAVE_OPENSSL
struct st_VioSSLFd *ssl_fd;
if (ssl)
{
buf[0]= 0;
if (!(ssl_fd= new_VioSSLConnectorFd(0, 0, 0, 0, 0)) ||
ssl_connect(ssl_fd, vio, send_timeout, buf))
{
sql_print_error("feedback plugin: ssl failed for url '%s' %s",
full_url.str, buf);
if (ssl_fd)
free_vio_ssl_acceptor_fd(ssl_fd);
closesocket(fd);
vio_delete(vio);
return 1;
}
}
#endif
static const LEX_STRING boundary=
{ C_STRING_WITH_LEN("----------------------------ba4f3696b39f") };
static const LEX_STRING header=
{ C_STRING_WITH_LEN("\r\n"
"Content-Disposition: form-data; name=\"data\"; filename=\"-\"\r\n"
"Content-Type: application/octet-stream\r\n\r\n")
};
len= my_snprintf(buf, sizeof(buf),
"POST %s HTTP/1.0\r\n"
"User-Agent: MariaDB User Feedback Plugin\r\n"
"Host: %s:%s\r\n"
"Accept: */*\r\n"
"Content-Length: %u\r\n"
"Content-Type: multipart/form-data; boundary=%s\r\n"
"\r\n",
path.str, host.str, port.str,
(uint)(2*boundary.length + header.length + data_length + 4),
boundary.str + 2);
vio_timeout(vio, FOR_READING, send_timeout);
vio_timeout(vio, FOR_WRITING, send_timeout);
res = write_check(vio, buf, len)
|| write_check(vio, boundary.str, boundary.length)
|| write_check(vio, header.str, header.length)
|| write_check(vio, data, data_length)
|| write_check(vio, boundary.str, boundary.length)
|| write_check(vio, "--\r\n", 4);
if (res)
sql_print_error("feedback plugin: failed to send report to '%s'",
full_url.str);
else
{
sql_print_information("feedback plugin: report to '%s' was sent",
full_url.str);
/*
if the data were send successfully, read the reply.
Extract the first string between <h1>...</h1> tags
and put it as a server reply into the error log.
*/
len= vio_read(vio, (uchar*)buf, sizeof(buf)-1);
if (len && len < sizeof(buf))
{
char *from;
buf[len+1]= 0; // safety
if ((from= strstr(buf, "<h1>")))
{
from+= 4;
char *to= strstr(from, "</h1>");
if (to)
*to= 0;
else
from= NULL;
}
if (from)
sql_print_information("feedback plugin: server replied '%s'", from);
else
sql_print_warning("feedback plugin: failed to parse server reply");
}
else
{
res= 1;
sql_print_error("feedback plugin: failed to read server reply");
}
}
vio_delete(vio);
#ifdef HAVE_OPENSSL
if (ssl)
{
SSL_CTX_free(ssl_fd->ssl_context);
my_free(ssl_fd, MYF(0));
}
#endif
return res;
}
} // namespace feedback
This diff is collapsed.
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
SET(FTEXAMPLE_SOURCES plugin_example.c)
MYSQL_PLUGIN(FTEXAMPLE)
......@@ -37,7 +37,9 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/sql/sql_yacc.h
PROPERTIES GENERATED 1)
ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER)
IF(WITH_FEEDBACK_STORAGE_ENGINE)
ADD_DEFINITIONS(-DWITH_FEEDBACK_PLUGIN)
ENDIF()
SET (SQL_SOURCE
../sql-common/client.c derror.cc des_key_file.cc
......
......@@ -3381,6 +3381,19 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
opt->name, plugin_name);
}
}
/*
PLUGIN_VAR_STR command-line options without PLUGIN_VAR_MEMALLOC, point
directly to values in the argv[] array. For plugins started at the
server startup, argv[] array is allocated with load_defaults(), and
freed when the server is shut down. But for plugins loaded with
INSTALL PLUGIN, the memory allocated with load_defaults() is freed with
freed() at the end of mysql_install_plugin(). Which means we cannot
allow any pointers into that area.
Thus, for all plugins loaded after the server was started,
we force all command-line options to be PLUGIN_VAR_MEMALLOC
*/
if (mysqld_server_started && !(opt->flags & PLUGIN_VAR_NOCMDOPT))
opt->flags|= PLUGIN_VAR_MEMALLOC;
break;
case PLUGIN_VAR_ENUM:
if (!opt->check)
......@@ -3537,6 +3550,10 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster"))
plugin_load_policy= PLUGIN_OFF;
#endif
#ifdef WITH_FEEDBACK_PLUGIN
if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "feedback"))
plugin_load_policy= PLUGIN_OFF;
#endif
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
......
MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine],
[Basic Write-only Read-never tables], [max,max-no-ndb])
MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole])
MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.la])
MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la])
MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine],
[Stores tables in text CSV format])
MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv])
MYSQL_PLUGIN_STATIC(csv, [libcsv.la])
MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging
MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine],
[Volatile memory based tables])
MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap])
MYSQL_PLUGIN_STATIC(heap, [libheap_s.la], [libheap_embedded.la])
MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables
MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine],
[Transactional Tables using InnoDB], [max,max-no-ndb])
MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase])
MYSQL_PLUGIN_STATIC(innobase, [libinnobase.la])
MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la])
MYSQL_PLUGIN_ACTIONS(innobase, [
......
......@@ -16,7 +16,6 @@
MYSQL_STORAGE_ENGINE(innodb_plugin,, [InnoDB Storage Engine],
[Transactional Tables using InnoDB], [])
MYSQL_PLUGIN_DIRECTORY(innodb_plugin, [storage/innodb_plugin])
# Enable if you know what you are doing (trying to link both InnoDB and
# InnoDB Plugin statically into MySQL does not work).
#MYSQL_PLUGIN_STATIC(innodb_plugin, [libinnobase.a])
......
......@@ -49,36 +49,36 @@ MYSQL_STORAGE_ENGINE(ARIA)
IF(NOT SOURCE_SUBLIBS)
ADD_DEPENDENCIES(aria GenError)
ADD_DEPENDENCIES(libaria_s GenError)
MYSQL_ADD_EXECUTABLE(aria_ftdump maria_ftdump.c)
TARGET_LINK_LIBRARIES(aria_ftdump aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(aria_ftdump libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_chk maria_chk.c)
TARGET_LINK_LIBRARIES(aria_chk aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(aria_chk libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_read_log maria_read_log.c)
TARGET_LINK_LIBRARIES(aria_read_log aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(aria_read_log libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_pack maria_pack.c)
TARGET_LINK_LIBRARIES(aria_pack aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(aria_pack libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_dump_log maria_dump_log.c unittest/ma_loghandler_examples.c)
TARGET_LINK_LIBRARIES(aria_dump_log aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(aria_dump_log libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_test1 ma_test1.c)
TARGET_LINK_LIBRARIES(ma_test1 aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(ma_test1 libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_test2 ma_test2.c)
TARGET_LINK_LIBRARIES(ma_test2 aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(ma_test2 libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_test3 ma_test3.c)
TARGET_LINK_LIBRARIES(ma_test3 aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(ma_test3 libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_rt_test ma_rt_test.c)
TARGET_LINK_LIBRARIES(ma_rt_test aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(ma_rt_test libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_sp_test ma_sp_test.c)
TARGET_LINK_LIBRARIES(ma_sp_test aria myisam mysys dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(ma_sp_test libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ENDIF(NOT SOURCE_SUBLIBS)
MYSQL_STORAGE_ENGINE(aria,, [Aria Storage Engine],
[Crash-safe tables with MyISAM heritage], [default,max,max-no-ndb])
MYSQL_PLUGIN_DIRECTORY(aria, [storage/maria])
MYSQL_PLUGIN_STATIC(aria, [libaria_s.la], [libaria_embedded.la])
MYSQL_PLUGIN_ACTIONS(aria, [
......
......@@ -13,10 +13,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/unittest/mytap)
LINK_LIBRARIES(maria myisam mytap mysys dbug strings wsock32 zlib)
LINK_LIBRARIES(libmaria_s libmyisam_s mytap mysys dbug strings wsock32 zlib)
ADD_EXECUTABLE(ma_control_file-t ma_control_file-t.c)
ADD_EXECUTABLE(trnman-t trnman-t.c)
......
......@@ -32,31 +32,31 @@ MYSQL_STORAGE_ENGINE(MYISAM)
IF(NOT SOURCE_SUBLIBS)
MYSQL_ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c DESTINATION bin)
TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(myisam_ftdump libmyisam_s mysys debug dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(myisamchk myisamchk.c DESTINATION bin)
TARGET_LINK_LIBRARIES(myisamchk myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(myisamchk libmyisam_s mysys debug dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(myisamlog myisamlog.c DESTINATION bin)
TARGET_LINK_LIBRARIES(myisamlog myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(myisamlog libmyisam_s mysys debug dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(myisampack myisampack.c DESTINATION bin)
TARGET_LINK_LIBRARIES(myisampack myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(myisampack libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(mi_test1 mi_test1.c)
TARGET_LINK_LIBRARIES(mi_test1 myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(mi_test1 libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(mi_test2 mi_test2.c)
TARGET_LINK_LIBRARIES(mi_test2 myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(mi_test2 libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(mi_test3 mi_test3.c)
TARGET_LINK_LIBRARIES(mi_test3 myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(mi_test3 libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(sp_test sp_test.c)
TARGET_LINK_LIBRARIES(sp_test myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(sp_test libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(rt_test rt_test.c)
TARGET_LINK_LIBRARIES(rt_test myisam mysys debug dbug strings zlib wsock32)
TARGET_LINK_LIBRARIES(rt_test libmyisam_s mysys debug dbug strings zlib wsock32)
SET_TARGET_PROPERTIES(myisamchk myisampack PROPERTIES LINK_FLAGS "setargv.obj")
......
dnl MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine],
dnl [Traditional non-transactional MySQL tables])
dnl MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam])
dnl MYSQL_PLUGIN_STATIC(myisam, [libmyisam_s.la], [libmyisam_embedded.la])
dnl MYSQL_PLUGIN_MANDATORY(myisam) dnl Default
MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine],
[Merge multiple MySQL tables into one])
MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg])
MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg_s.la], [libmyisammrg_embedded.la])
MYSQL_PLUGIN_MANDATORY(myisammrg)
......@@ -10,41 +10,41 @@
# ${engine}_LIBS variable containing extra libraries to link with may be set
MACRO(MYSQL_STORAGE_ENGINE engine)
MACRO(MYSQL_PLUGIN engine)
IF(NOT SOURCE_SUBLIBS)
# Add common include directories
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_BINARY_DIR}/include
${CMAKE_BINARY_DIR}/sql
)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include)
STRING(TOUPPER ${engine} engine)
STRING(TOLOWER ${engine} libname)
IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER)
#Create static library. The name of the library is <storage_engine>.lib
ADD_LIBRARY(${libname} ${${engine}_SOURCES})
ADD_DEPENDENCIES(${libname} GenError)
ADD_LIBRARY(${${engine}_LIB} ${${engine}_SOURCES})
ADD_DEPENDENCIES(${${engine}_LIB} GenError)
IF(${engine}_LIBS)
TARGET_LINK_LIBRARIES(${libname} ${${engine}_LIBS})
TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
MESSAGE("build ${engine} as static library")
MESSAGE("build ${engine} as static library (${${engine}_LIB}.lib)")
ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC")
ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN)
#Create a DLL.The name of the dll is ha_<storage_engine>.dll
#The dll is linked to the mysqld executable
SET(dyn_libname ha_${libname})
ADD_VERSION_INFO(${dyn_libname} SHARED ${engine}_SOURCES)
ADD_LIBRARY(${dyn_libname} MODULE ${${engine}_SOURCES})
TARGET_LINK_LIBRARIES (${dyn_libname} mysqlservices mysqld)
ADD_VERSION_INFO(${${engine}_LIB} SHARED ${engine}_SOURCES)
ADD_LIBRARY(${${engine}_LIB} MODULE ${${engine}_SOURCES})
TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices mysqld)
IF(${engine}_LIBS)
TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
# Install the plugin
MYSQL_INSTALL_TARGETS(${dyn_libname} DESTINATION lib/plugin COMPONENT Server)
MESSAGE("build ${engine} as DLL")
MYSQL_INSTALL_TARGETS(${${engine}_LIB} DESTINATION lib/plugin COMPONENT Server)
MESSAGE("build ${engine} as DLL (${${engine}_LIB}.dll)")
ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ENDIF(NOT SOURCE_SUBLIBS)
ENDMACRO(MYSQL_PLUGIN)
MACRO(MYSQL_STORAGE_ENGINE engine)
IF(NOT SOURCE_SUBLIBS)
MYSQL_PLUGIN(${engine})
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/regex ${CMAKE_BINARY_DIR}/sql
${CMAKE_SOURCE_DIR}/extra/yassl/include)
IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER)
ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ENDIF(NOT SOURCE_SUBLIBS)
ENDMACRO(MYSQL_STORAGE_ENGINE)
MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine],
[High Availability Clustered tables],)
MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb])
MYSQL_PLUGIN_STATIC(ndbcluster, [[\$(ndbcluster_libs) \$(ndbcluster_system_libs) \$(NDB_SCI_LIBS)]])
MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER])
MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition])
MYSQL_STORAGE_ENGINE(pbxt,no, [PBXT Storage Engine],
[MVCC-based transactional engine], [max,max-no-ndb])
MYSQL_PLUGIN_DIRECTORY(pbxt, [storage/pbxt])
MYSQL_PLUGIN_STATIC(pbxt, [src/libpbxt_s.la], [src/libpbxt_s_embedded.la])
MYSQL_PLUGIN_ACTIONS(pbxt, [
# AC_CONFIG_FILES(storage/pbxt/src/Makefile)
......
......@@ -13,15 +13,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# This is the CMakeLists for InnoDB Plugin
# This is the CMakeLists for XtraDB
# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
# CMakeLists.txt still needs to work with previous versions of MySQL.
IF (MYSQL_VERSION_ID GREATER "50137")
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
ENDIF (MYSQL_VERSION_ID GREATER "50137")
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
......
......@@ -16,7 +16,6 @@
MYSQL_STORAGE_ENGINE(xtradb, xtradb, [XtraDB Storage Engine],
[XtraDB - a drop-in replacement for InnoDB], [max,max-no-ndb])
MYSQL_PLUGIN_DIRECTORY(xtradb, [storage/xtradb])
MYSQL_PLUGIN_STATIC(xtradb, [libxtradb.la])
MYSQL_PLUGIN_DYNAMIC(xtradb, [ha_xtradb.la])
MYSQL_PLUGIN_ACTIONS(xtradb, [
......
......@@ -51,12 +51,10 @@ win\configure <options>
The options right now are:
WITH_INNOBASE_STORAGE_ENGINE Enable particular storage engines
WITH_PARTITION_STORAGE_ENGINE
WITH_ARCHIVE_STORAGE_ENGINE
WITH_BLACKHOLE_STORAGE_ENGINE
WITH_EXAMPLE_STORAGE_ENGINE
WITH_FEDERATED_STORAGE_ENGINE
--with-plugin-XXX Enable particular plugin or plugins
--with-plugins=XXX,YYY,...
--with-plugins=GROUP GROUP can be, for example, "max" or "max-no-ndb"
--without-plugin-XXX Disable particular plugin
__NT__ Enable named pipe support
MYSQL_SERVER_SUFFIX=<suffix> Server suffix, default none
COMPILATION_COMMENT=<comment> Server comment, default "Source distribution"
......@@ -70,7 +68,7 @@ The options right now are:
So the command line could look like:
win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
win\configure --with-plugin-innobase --with-plugin-partition MYSQL_SERVER_SUFFIX=-pro
Step 6
------
......
......@@ -5,4 +5,5 @@ cscript win\configure.js ^
WITH_PARTITION_STORAGE_ENGINE ^
WITH_ARIA_STORAGE_ENGINE ^
WITH_PBXT_STORAGE_ENGINE ^
WITH_XTRADB_STORAGE_ENGINE
WITH_XTRADB_STORAGE_ENGINE ^
WITH_FEEDBACK_STORAGE_ENGINE
......@@ -18,4 +18,5 @@ cscript win/configure.js \
WITH_ARIA_STORAGE_ENGINE \
WITH_PBXT_STORAGE_ENGINE \
WITH_XTRADB_STORAGE_ENGINE \
WITH_FEEDBACK_STORAGE_ENGINE \
WITH_EMBEDDED_SERVER
......@@ -126,7 +126,7 @@ try
var engineOptions = ParsePlugins();
for (option in engineOptions)
{
configfile.WriteLine("SET(" + engineOptions[option] + " TRUE)");
configfile.WriteLine("SET (" + engineOptions[option] + " TRUE)");
}
configfile.Close();
......@@ -302,7 +302,7 @@ function ParsePlugins()
{
var content = fso.OpenTextFile(filename, ForReading).ReadAll();
var match =
/MYSQL_STORAGE_ENGINE([ ]*)[\(]([^\)]+)[\)]/.exec(content);
/MYSQL_(PLUGIN|STORAGE_ENGINE)([ ]*)[\(]([^\)]+)[\)]/.exec(content);
if (match== null)
continue;
match = /\[[\w,\-_]+\][\s]?\)/.exec(match[0]);
......@@ -329,9 +329,9 @@ function ParsePlugins()
for(key in config)
{
var eng = config[key];
if(eng.isGroup != undefined && !eng.isGroup && eng.include != undefined)
if(eng.isGroup != undefined && !eng.isGroup && eng.include != undefined)
{
if (fso.FolderExists("storage\\"+key) || key=="PARTITION")
if (fso.FolderExists("storage\\"+key) || fso.FolderExists("plugin\\"+key) || key=="PARTITION")
{
arr[arr.length] = eng.include?
"WITH_"+key+"_STORAGE_ENGINE":"WITHOUT_"+key+"_STORAGE_ENGINE";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment