Merge branch 'develop' into binlog_server_wait_data

This commit is contained in:
MassimilianoPinto
2016-08-29 16:23:11 +02:00
22 changed files with 710 additions and 61 deletions

View File

@ -0,0 +1,113 @@
#Cache
## Overview
The cache filter is capable of caching the result of SELECTs, so that subsequent identical
SELECTs are served directly by MaxScale, without being routed to any server.
## Configuration
The cache filter is straightforward to configure and simple to add to any
existing service.
```
[Cache]
type=filter
module=cache
ttl=5
storage=...
storage_args=...
[Cached Routing Service]
type=service
...
filters=Cache
```
Each configured cache filter uses a storage of its own. That is, if there
are two services, each configured with a specific cache filter, then,
even if queries target the very same servers the cached data will not
be shared.
Two services can use the same cache filter, but then either the services
should use the very same servers _or_ a completely different set of servers,
where the used table names are different. Otherwise there can be unintended
sharing.
### Filter Parameters
The cache filter has one mandatory parameter - `storage` - and a few
optional ones.
#### `storage`
The name of the module that provides the storage for the cache. That
module will be loaded and provided with the value of `storage_args` as
argument. For instance:
```
storage=storage_rocksdb
```
#### `storage_args`
A comma separated list of arguments to be provided to the storage module,
specified in `storage`, when it is loaded. Note that the needed arguments
depend upon the specific module. For instance,
```
storage_args=path=/usr/maxscale/cache/rocksdb
```
#### `allowed_references`
Specifies whether any or only fully qualified references are allowed in
queries stored to the cache.
```
allowed_references=[fully-qualified|any]
```
The default is `fully-qualified`, which means that only queries where
the database name is included in the table name are subject to caching.
```
select col from db.tbl;
```
If `any` is specified, then also queries where the table name is not
fully qualified are subject to caching.
```
select col from tbl;
```
Care should be excersized before this setting is changed, because, for
instance, the following is likely to produce unexpected results.
```
use db1;
select col from tbl;
...
use db2;
select col from tbl;
```
The setting can be changed to `any`, provided fully qualified names
are always used or if the names of tables in different databases are
different.
#### `maximum_resultset_size`
Specifies the maximum size a resultset can have, measured in kibibytes,
in order to be stored in the cache. A resultset larger than this, will
not be stored.
```
maximum_resultset_size=64
```
The default value is TBD.
#### `ttl`
_Time to live_; the amount of time - in seconds - the cached result is used
before it is refreshed from the server.
If nothing is specified, the default _ttl_ value is 10.
```
ttl=60
```
#Storage
## Storage RocksDB

View File

@ -384,6 +384,13 @@ bool filter_load(FILTER_DEF* filter)
{
bool rval = false;
if (filter)
{
if (filter->filter)
{
// Already loaded and created.
rval = true;
}
else
{
if (filter->obj == NULL)
{
@ -391,11 +398,15 @@ bool filter_load(FILTER_DEF* filter)
if ((filter->obj = load_module(filter->module, MODULE_FILTER)) == NULL)
{
MXS_ERROR("Failed to load filter module '%s'.", filter->module);
return false;
}
}
if ((filter->filter = (filter->obj->createInstance)(filter->options,
if (filter->obj)
{
ss_dassert(!filter->filter);
if ((filter->filter = (filter->obj->createInstance)(filter->name,
filter->options,
filter->parameters)))
{
rval = true;
@ -404,7 +415,8 @@ bool filter_load(FILTER_DEF* filter)
{
MXS_ERROR("Failed to create filter '%s' instance.", filter->name);
}
}
}
}
return rval;
}

View File

@ -32,7 +32,7 @@
static int mysql_send_fieldcount(DCB *, int);
static int mysql_send_columndef(DCB *, char *, int, int, uint8_t);
static int mysql_send_columndef(DCB *, const char *, int, int, uint8_t);
static int mysql_send_eof(DCB *, int);
static int mysql_send_row(DCB *, RESULT_ROW *, int);
@ -95,9 +95,9 @@ resultset_free(RESULTSET *resultset)
* @return The numebr of columns added to the result set
*/
int
resultset_add_column(RESULTSET *set, char *name, int len, RESULT_COL_TYPE type)
resultset_add_column(RESULTSET *set, const char *cname, int len, RESULT_COL_TYPE type)
{
name = MXS_STRDUP(name);
char *name = MXS_STRDUP(cname);
RESULT_COLUMN *newcol = (RESULT_COLUMN *)MXS_MALLOC(sizeof(RESULT_COLUMN));
if (!name || !newcol)
@ -207,7 +207,7 @@ resultset_free_row(RESULT_ROW *row)
* @return The number of columns inserted
*/
int
resultset_row_set(RESULT_ROW *row, int col, char *value)
resultset_row_set(RESULT_ROW *row, int col, const char *value)
{
if (col < 0 || col >= row->n_cols)
{
@ -299,7 +299,7 @@ mysql_send_fieldcount(DCB *dcb, int count)
* @return Non-zero on success
*/
static int
mysql_send_columndef(DCB *dcb, char *name, int type, int len, uint8_t seqno)
mysql_send_columndef(DCB *dcb, const char *name, int type, int len, uint8_t seqno)
{
GWBUF *pkt;
uint8_t *ptr;
@ -443,7 +443,7 @@ mysql_send_row(DCB *dcb, RESULT_ROW *row, int seqno)
* @return Non-zero if the string is made of of numeric values
*/
static int
value_is_numeric(char *value)
value_is_numeric(const char *value)
{
int rval = 0;

View File

@ -67,7 +67,9 @@ typedef struct
*/
typedef struct filter_object
{
FILTER *(*createInstance)(char **options, FILTER_PARAMETER **);
FILTER *(*createInstance)(const char *name,
char **options,
FILTER_PARAMETER **params);
void *(*newSession)(FILTER *instance, SESSION *session);
void (*closeSession)(FILTER *instance, void *fsession);
void (*freeSession)(FILTER *instance, void *fsession);
@ -83,7 +85,7 @@ typedef struct filter_object
* is changed these values must be updated in line with the rules in the
* file modinfo.h.
*/
#define FILTER_VERSION {1, 1, 0}
#define FILTER_VERSION {2, 1, 0}
/**
* The definition of a filter from the configuration file.
* This is basically the link between a plugin to load and the

View File

@ -77,11 +77,11 @@ typedef struct resultset
extern RESULTSET *resultset_create(RESULT_ROW_CB, void *);
extern void resultset_free(RESULTSET *);
extern int resultset_add_column(RESULTSET *, char *, int, RESULT_COL_TYPE);
extern int resultset_add_column(RESULTSET *, const char *, int, RESULT_COL_TYPE);
extern void resultset_column_free(RESULT_COLUMN *);
extern RESULT_ROW *resultset_make_row(RESULTSET *);
extern void resultset_free_row(RESULT_ROW *);
extern int resultset_row_set(RESULT_ROW *, int, char *);
extern int resultset_row_set(RESULT_ROW *, int, const char *);
extern void resultset_stream_mysql(RESULTSET *, DCB *);
extern void resultset_stream_json(RESULTSET *, DCB *);

View File

@ -1,4 +1,4 @@
add_library(cache SHARED cache.c)
add_library(cache SHARED cache.c storage.c)
target_link_libraries(cache maxscale-common)
set_target_properties(cache PROPERTIES VERSION "1.0.0")
install_module(cache experimental)

View File

@ -11,13 +11,20 @@
* Public License.
*/
#include <filter.h>
#include <modinfo.h>
#define MXS_MODULE_NAME "cache"
#include <maxscale/alloc.h>
#include <filter.h>
#include <log_manager.h>
#include <modinfo.h>
#include <modutil.h>
#include <query_classifier.h>
#include "storage.h"
static char VERSION_STRING[] = "V1.0.0";
static FILTER *createInstance(char **options, FILTER_PARAMETER **);
static const int DEFAULT_TTL = 10;
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *sdata);
static void freeSession(FILTER *instance, void *sdata);
@ -27,6 +34,8 @@ static int routeQuery(FILTER *instance, void *sdata, GWBUF *queue);
static int clientReply(FILTER *instance, void *sdata, GWBUF *queue);
static void diagnostics(FILTER *instance, void *sdata, DCB *dcb);
#define C_DEBUG(format, ...) MXS_LOG_MESSAGE(LOG_NOTICE, format, ##__VA_ARGS__)
//
// Global symbols of the Module
//
@ -81,29 +90,129 @@ FILTER_OBJECT *GetModuleObject()
typedef struct cache_instance
{
const char *name;
const char *storage_name;
const char *storage_args;
uint32_t ttl; // Time to live in seconds.
CACHE_STORAGE_MODULE *module;
CACHE_STORAGE *storage;
} CACHE_INSTANCE;
typedef struct cache_session_data
{
DOWNSTREAM down;
UPSTREAM up;
CACHE_STORAGE_API *api; /**< The storage API to be used. */
CACHE_STORAGE *storage; /**< The storage to be used with this session data. */
DOWNSTREAM down; /**< The previous filter or equivalent. */
UPSTREAM up; /**< The next filter or equivalent. */
GWBUF *packets; /**< A possible incomplete packet. */
SESSION *session; /**< The session this data is associated with. */
char key[CACHE_KEY_MAXLEN]; /**< Key storage. */
char *used_key; /**< A key if one is ued. */
} CACHE_SESSION_DATA;
static bool route_using_cache(CACHE_INSTANCE *instance,
CACHE_SESSION_DATA *sdata,
const GWBUF *key,
GWBUF **value);
//
// API BEGIN
//
/**
* Create an instance of the cache filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *createInstance(char **options, FILTER_PARAMETER **params)
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
CACHE_INSTANCE *cinstance;
const char *storage_name = NULL;
const char *storage_args = NULL;
uint32_t ttl = DEFAULT_TTL;
bool error = false;
for (int i = 0; params[i]; ++i)
{
const FILTER_PARAMETER *param = params[i];
if (strcmp(param->name, "storage_name") == 0)
{
storage_name = param->value;
}
else if (strcmp(param->name, "storage_args") == 0)
{
storage_args = param->value;
}
else if (strcmp(param->name, "ttl") == 0)
{
int v = atoi(param->value);
if (v > 0)
{
ttl = v;
}
else
{
MXS_ERROR("The value of the configuration entry 'ttl' must "
"be an integer larger than 0.");
error = true;
}
}
else if (!filter_standard_parameter(params[i]->name))
{
MXS_ERROR("Unknown configuration entry '%s'.", param->name);
error = true;
}
}
CACHE_INSTANCE *cinstance = NULL;
if (!error)
{
if ((cinstance = MXS_CALLOC(1, sizeof(CACHE_INSTANCE))) != NULL)
{
CACHE_STORAGE_MODULE *module = cache_storage_open(storage_name);
if (module)
{
CACHE_STORAGE *storage = module->api->createInstance(name, ttl, 0, NULL);
if (storage)
{
cinstance->name = name;
cinstance->storage_name = storage_name;
cinstance->storage_args = storage_args;
cinstance->ttl = ttl;
cinstance->module = module;
cinstance->storage = storage;
MXS_NOTICE("Cache storage %s opened and initialized.", storage_name);
}
else
{
MXS_ERROR("Could not create storage instance for %s.", name);
cache_storage_close(module);
MXS_FREE(cinstance);
cinstance = NULL;
}
}
else
{
MXS_ERROR("Could not load cache storage module %s.", name);
MXS_FREE(cinstance);
cinstance = NULL;
}
}
}
else
{
cinstance = NULL;
}
return (FILTER*)cinstance;
@ -124,6 +233,9 @@ static void *newSession(FILTER *instance, SESSION *session)
if (csdata)
{
csdata->api = cinstance->module->api;
csdata->storage = cinstance->storage;
csdata->session = session;
}
return csdata;
@ -190,14 +302,97 @@ static void setUpstream(FILTER *instance, void *sdata, UPSTREAM *up)
*
* @param instance The filter instance data
* @param sdata The filter session data
* @param queue The query data
* @param packets The query data
*/
static int routeQuery(FILTER *instance, void *sdata, GWBUF *queue)
static int routeQuery(FILTER *instance, void *sdata, GWBUF *packets)
{
CACHE_INSTANCE *cinstance = (CACHE_INSTANCE*)instance;
CACHE_SESSION_DATA *csdata = (CACHE_SESSION_DATA*)sdata;
return csdata->down.routeQuery(csdata->down.instance, csdata->down.session, queue);
if (csdata->packets)
{
C_DEBUG("Old packets exist.");
gwbuf_append(csdata->packets, packets);
}
else
{
C_DEBUG("NO old packets exist.");
csdata->packets = packets;
}
packets = modutil_get_complete_packets(&csdata->packets);
int rv;
if (packets)
{
C_DEBUG("At least one complete packet exist.");
GWBUF *packet;
// TODO: Is it really possible to get more that one packet
// TODO: is this loop? If so, can those packets be sent
// TODO: after one and other, or do we need to wait for
// TODO: a replies? If there are more complete packets
// TODO: than one, then either CACHE_SESSION_DATA::key
// TODO: needs to be a queue
// TODO: modutil_get_next_MySQL_packet *copies* the data.
while ((packet = modutil_get_next_MySQL_packet(&packets)))
{
C_DEBUG("Processing packet.");
bool use_default = true;
if (modutil_is_SQL(packet))
{
C_DEBUG("Is SQL.");
// We do not care whether the query was fully parsed or not.
// If a query cannot be fully parsed, the worst thing that can
// happen is that caching is not used, even though it would be
// possible.
if (qc_get_operation(packet) == QUERY_OP_SELECT)
{
C_DEBUG("Is a SELECT");
GWBUF *result;
use_default = !route_using_cache(cinstance, csdata, packet, &result);
if (!use_default)
{
C_DEBUG("Using data from cache.");
gwbuf_free(packet);
DCB *dcb = csdata->session->client_dcb;
// TODO: This is not ok. Any filters before this filter, will not
// TODO: see this data.
rv = dcb->func.write(dcb, result);
}
}
else
{
C_DEBUG("Is NOT a SELECT");
}
}
else
{
C_DEBUG("Is NOT SQL.");
}
if (use_default)
{
C_DEBUG("Using default processing.");
rv = csdata->down.routeQuery(csdata->down.instance, csdata->down.session, packet);
}
}
}
else
{
C_DEBUG("Not even one complete packet exist; more data needed.");
// Ok, we need more data before we can do something.
rv = 1;
}
return rv;
}
/**
@ -212,6 +407,27 @@ static int clientReply(FILTER *instance, void *sdata, GWBUF *queue)
CACHE_INSTANCE *cinstance = (CACHE_INSTANCE*)instance;
CACHE_SESSION_DATA *csdata = (CACHE_SESSION_DATA*)sdata;
// TODO: queue can be put to the cache only if it is a complete
// TODO: response. If it isn't, then we need to stash it and wait
// TODO: we get a complete response.
// TODO: Since we will know from the first queue how big the
// TODO: entire response will be, this is also where we can decide
// TODO: that something is too large to cache. If it is, an existing
// TODO: item must be deleted.
if (csdata->used_key)
{
C_DEBUG("Key available, storing result.");
cache_result_t result = csdata->api->putValue(csdata->storage, csdata->used_key, queue);
csdata->used_key = NULL;
if (result != CACHE_RESULT_OK)
{
MXS_ERROR("Could not store cache item.");
}
}
return csdata->up.clientReply(csdata->up.instance, csdata->up.session, queue);
}
@ -232,3 +448,52 @@ static void diagnostics(FILTER *instance, void *sdata, DCB *dcb)
dcb_printf(dcb, "Hello World from Cache!\n");
}
//
// API END
//
/**
* Route a query via the cache.
*
* @param instance The filter instance.
* @param sdata Session data
* @param key A SELECT packet.
* @param value The result.
* @return True if the query was satisfied from the query.
*/
static bool route_using_cache(CACHE_INSTANCE *instance,
CACHE_SESSION_DATA *csdata,
const GWBUF *query,
GWBUF **value)
{
// TODO: This works *only* if only one request/response is handled at a time.
// TODO: Is that the case, or is it not?
cache_result_t result = csdata->api->getKey(csdata->storage, query, csdata->key);
if (result == CACHE_RESULT_OK)
{
result = csdata->api->getValue(csdata->storage, csdata->key, value);
switch (result)
{
case CACHE_RESULT_OK:
csdata->used_key = NULL;
break;
default:
MXS_ERROR("Could not get value from cache storage.");
case CACHE_RESULT_NOT_FOUND:
csdata->used_key = csdata->key;
break;
}
}
else
{
MXS_ERROR("Could not create cache key.");
csdata->used_key = NULL;
}
return result == CACHE_RESULT_OK;
}

View File

@ -0,0 +1,120 @@
#ifndef _MAXSCALE_FILTER_CACHE_CACHE_H
#define _MAXSCALE_FILTER_CACHE_CACHE_H
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <stdbool.h>
#include <stdint.h>
#include <buffer.h>
#include <mysql_client_server_protocol.h>
#include <skygw_debug.h>
EXTERN_C_BLOCK_BEGIN
typedef enum cache_result
{
CACHE_RESULT_OK,
CACHE_RESULT_NOT_FOUND,
CACHE_RESULT_OUT_OF_RESOURCES,
CACHE_RESULT_ERROR
} cache_result_t;
typedef void* CACHE_STORAGE;
enum
{
CACHE_KEY_MAXLEN = 128
};
typedef struct cache_storage_api
{
/**
* Called immediately after the storage module has been loaded.
*
* @return True if the initialization succeeded, false otherwise.
*/
bool (*initialize)();
/**
* Creates an instance of cache storage. This function should, if necessary,
* create the actual storage, initialize it and prepare to put and get
* cache items.
*
* @param name The name of the cache instance.
* @param ttl Time to live; number of seconds the value is valid.
* @param argc The number of elements in the argv array.
* @param argv Array of arguments, as passed in the `storage_args` parameter
* in the cache section in the MaxScale configuration file.
* @return A new cache instance, or NULL if the instance could not be
* created.
*/
CACHE_STORAGE* (*createInstance)(const char *name,
uint32_t ttl,
int argc, char* argv[]);
/**
* Frees an CACHE_STORAGE instance earlier created with createInstance.
*
* @param instance The CACHE_STORAGE instance to be freed.
*/
void (*freeInstance)(CACHE_STORAGE* instance);
/**
* Create a key for a GWBUF.
*
* @param storage Pointer to a CACHE_STORAGE.
* @param query An SQL query. Must be one contiguous buffer.
* @param key Pointer to array of CACHE_KEY_MAXLEN size where
* the key will be written.
* @return CACHE_RESULT_OK if a key was created, otherwise some error code.
*/
cache_result_t (*getKey)(CACHE_STORAGE* storage,
const GWBUF* query,
char* key);
/**
* Get a value from the cache.
*
* @param storage Pointer to a CACHE_STORAGE.
* @param key A key generated with getKey.
* @param result Pointer to variable that after a successful return will
* point to a GWBUF.
* @return CACHE_RESULT_OK if item was found,
* CACHE_RESULT_NOT_FOUND if item was not found (which may be because
* the ttl was reached), or some other error code.
*/
cache_result_t (*getValue)(CACHE_STORAGE* storage,
const char* key,
GWBUF** result);
/**
* Put a value to the cache.
*
* @param storage Pointer to a CACHE_STORAGE.
* @param key A key generated with getKey.
* @param value Pointer to GWBUF containing the value to be stored.
* Must be one contiguous buffer.
* @return CACHE_RESULT_OK if item was successfully put,
* CACHE_RESULT_OUT_OF_RESOURCES if item could not be put, due to
* some resource having become exhausted, or some other error code.
*/
cache_result_t (*putValue)(CACHE_STORAGE* storage,
const char* key,
const GWBUF* value);
} CACHE_STORAGE_API;
#define CACHE_STORAGE_ENTRY_POINT "CacheGetStorageAPI"
typedef CACHE_STORAGE_API* (*CacheGetStorageAPIFN)();
EXTERN_C_BLOCK_END
#endif

96
server/modules/filter/cache/storage.c vendored Normal file
View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include "storage.h"
#include <dlfcn.h>
#include <sys/param.h>
#include <maxscale/alloc.h>
#include <gwdirs.h>
#include <log_manager.h>
CACHE_STORAGE_MODULE* cache_storage_open(const char *name)
{
CACHE_STORAGE_MODULE* module = (CACHE_STORAGE_MODULE*)MXS_CALLOC(1, sizeof(CACHE_STORAGE_MODULE));
if (module)
{
char path[MAXPATHLEN + 1];
sprintf(path, "%s/lib%s.so", get_libdir(), name);
void *handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (handle)
{
module->handle = handle;
void *f = dlsym(module->handle, CACHE_STORAGE_ENTRY_POINT);
if (f)
{
module->api = ((CacheGetStorageAPIFN)f)();
if (module->api)
{
if (!(module->api->initialize)())
{
MXS_ERROR("Initialization of %s failed.", path);
(void)dlclose(module->handle);
MXS_FREE(module);
module = NULL;
}
}
else
{
MXS_ERROR("Could not obtain API object from %s.", name);
(void)dlclose(module->handle);
MXS_FREE(module);
module = NULL;
}
}
else
{
const char* s = dlerror();
MXS_ERROR("Could not look up symbol %s from %s: %s",
name, CACHE_STORAGE_ENTRY_POINT, s ? s : "");
MXS_FREE(module);
module = NULL;
}
}
else
{
const char* s = dlerror();
MXS_ERROR("Could not load %s: %s", name, s ? s : "");
MXS_FREE(module);
module = NULL;
}
}
return module;
}
void cache_storage_close(CACHE_STORAGE_MODULE *module)
{
if (module)
{
if (dlclose(module->handle) != 0)
{
const char *s = dlerror();
MXS_ERROR("Could not close module %s: ", s ? s : "");
}
MXS_FREE(module);
}
}

27
server/modules/filter/cache/storage.h vendored Normal file
View File

@ -0,0 +1,27 @@
#ifndef _MAXSCALE_FILTER_CACHE_STORAGE_H
#define _MAXSCALE_FILTER_CACHE_STORAGE_H
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include "cache_storage_api.h"
typedef struct cache_storage_module_t
{
void* handle;
CACHE_STORAGE_API* api;
} CACHE_STORAGE_MODULE;
CACHE_STORAGE_MODULE* cache_storage_open(const char *name);
void cache_storage_close(CACHE_STORAGE_MODULE *module);
#endif

View File

@ -57,7 +57,7 @@ MODULE_INFO info =
static char *version_str = "V1.1.0";
static FILTER *createInstance(char **options, FILTER_PARAMETER **params);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **params);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -156,13 +156,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
CCR_INSTANCE *my_instance;
int i;

View File

@ -99,7 +99,7 @@ static char *version_str = "V1.2.0";
/*
* The filter entry points
*/
static FILTER *createInstance(char **options, FILTER_PARAMETER **);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -1357,12 +1357,14 @@ static bool process_rule_file(const char* filename, FW_INSTANCE* instance)
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
FW_INSTANCE *my_instance;
int i;

View File

@ -82,7 +82,7 @@ static const char* datafile_name = "gatekeeper.data";
* return a non-NULL value when a hash hit is made */
static bool trueval = true;
static FILTER *createInstance(char **options, FILTER_PARAMETER **params);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **params);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -140,12 +140,13 @@ FILTER_OBJECT* GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER* createInstance(char **options, FILTER_PARAMETER **params)
static FILTER* createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
GK_INSTANCE *inst = MXS_CALLOC(1, sizeof(GK_INSTANCE));

View File

@ -33,7 +33,7 @@ MODULE_INFO info =
static char *version_str = "V1.0.0";
static FILTER *createInstance(char **options, FILTER_PARAMETER **params);
static FILTER *createInstance(const char* name, char **options, FILTER_PARAMETER **params);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -97,12 +97,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
HINT_INSTANCE *my_instance;

View File

@ -92,7 +92,7 @@ static int hktask_id = 0;
/*
* The filter entry points
*/
static FILTER *createInstance(char **options, FILTER_PARAMETER **);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -497,12 +497,14 @@ char** parse_optstr(char* str, char* tok, int* szstore)
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
MQ_INSTANCE *my_instance;
int paramcount = 0, parammax = 64, i = 0, x = 0, arrsize = 0;

View File

@ -51,7 +51,7 @@ MODULE_INFO info =
static char *version_str = "V1.1.0";
static FILTER *createInstance(char **options, FILTER_PARAMETER **params);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **params);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -137,13 +137,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param params The array of name/value pair parameters for the filter
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE*)MXS_MALLOC(sizeof(REGEXHINT_INSTANCE));

View File

@ -65,7 +65,7 @@ static char *version_str = "V1.1.1";
/*
* The filter entry points
*/
static FILTER *createInstance(char **options, FILTER_PARAMETER **);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -166,13 +166,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
QLA_INSTANCE *my_instance = (QLA_INSTANCE*) MXS_MALLOC(sizeof(QLA_INSTANCE));

View File

@ -51,7 +51,7 @@ MODULE_INFO info =
static char *version_str = "V1.1.0";
static FILTER *createInstance(char **options, FILTER_PARAMETER **params);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **params);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -172,13 +172,14 @@ void free_instance(REGEX_INSTANCE *instance)
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
REGEX_INSTANCE *my_instance;
int i, errnumber, cflags = PCRE2_CASELESS;

View File

@ -108,7 +108,7 @@ static char *version_str = "V1.0.0";
/*
* The filter entry points
*/
static FILTER *createInstance(char **options, FILTER_PARAMETER **);
static FILTER *createInstance(const char* name, char **options, FILTER_PARAMETER **);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -351,13 +351,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
TEE_INSTANCE *my_instance;
int i;

View File

@ -39,7 +39,7 @@ MODULE_INFO info =
static char *version_str = "V1.0.0";
static FILTER *createInstance(char **options, FILTER_PARAMETER **params);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **params);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -119,13 +119,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
TEST_INSTANCE *my_instance;

View File

@ -59,7 +59,7 @@ static char *version_str = "V1.0.1";
/*
* The filter entry points
*/
static FILTER *createInstance(char **options, FILTER_PARAMETER **);
static FILTER *createInstance(const char *name, char **options, FILTER_PARAMETER **);
static void *newSession(FILTER *instance, SESSION *session);
static void closeSession(FILTER *instance, void *session);
static void freeSession(FILTER *instance, void *session);
@ -179,13 +179,14 @@ GetModuleObject()
* Create an instance of the filter for a particular service
* within MaxScale.
*
* @param name The name of the instance (as defined in the config file).
* @param options The options for this filter
* @param params The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
createInstance(const char *name, char **options, FILTER_PARAMETER **params)
{
TOPN_INSTANCE *my_instance = (TOPN_INSTANCE*)MXS_MALLOC(sizeof(TOPN_INSTANCE));

View File

@ -63,7 +63,7 @@
#include <housekeeper.h>
#include <mysql.h>
#define GW_MYSQL_VERSION "5.5.5-10.0.0 "MAXSCALE_VERSION"-maxscale"
#define GW_MYSQL_VERSION "5.5.5-10.0.0 " MAXSCALE_VERSION "-maxscale"
#define GW_MYSQL_LOOP_TIMEOUT 300000000
#define GW_MYSQL_READ 0
#define GW_MYSQL_WRITE 1