Uncrustify maxscale
See script directory for method. The script to run in the top level MaxScale directory is called maxscale-uncrustify.sh, which uses another script, list-src, from the same directory (so you need to set your PATH). The uncrustify version was 0.66.
This commit is contained in:
@ -24,7 +24,7 @@
|
||||
|
||||
#define avro_decode(n) ((n >> 1) ^ -(n & 1))
|
||||
#define encode_long(n) ((n << 1) ^ (n >> 63))
|
||||
#define more_bytes(b) (b & 0x80)
|
||||
#define more_bytes(b) (b & 0x80)
|
||||
|
||||
/**
|
||||
* @brief Read an Avro integer
|
||||
@ -37,7 +37,7 @@
|
||||
* @param dest Destination where the read value is written
|
||||
* @return True if value was read successfully
|
||||
*/
|
||||
bool maxavro_read_integer(MAXAVRO_FILE* file, uint64_t *dest)
|
||||
bool maxavro_read_integer(MAXAVRO_FILE* file, uint64_t* dest)
|
||||
{
|
||||
uint64_t rval = 0;
|
||||
uint8_t nread = 0;
|
||||
@ -70,7 +70,7 @@ bool maxavro_read_integer(MAXAVRO_FILE* file, uint64_t *dest)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool maxavro_read_integer_from_file(MAXAVRO_FILE* file, uint64_t *dest)
|
||||
bool maxavro_read_integer_from_file(MAXAVRO_FILE* file, uint64_t* dest)
|
||||
{
|
||||
uint64_t rval = 0;
|
||||
uint8_t nread = 0;
|
||||
@ -139,7 +139,7 @@ uint64_t avro_length_integer(uint64_t val)
|
||||
*/
|
||||
char* maxavro_read_string(MAXAVRO_FILE* file, size_t* size)
|
||||
{
|
||||
char *key = NULL;
|
||||
char* key = NULL;
|
||||
uint64_t len;
|
||||
|
||||
if (maxavro_read_integer(file, &len))
|
||||
@ -173,7 +173,7 @@ char* maxavro_read_string(MAXAVRO_FILE* file, size_t* size)
|
||||
*/
|
||||
char* maxavro_read_string_from_file(MAXAVRO_FILE* file, size_t* size)
|
||||
{
|
||||
char *key = NULL;
|
||||
char* key = NULL;
|
||||
uint64_t len;
|
||||
|
||||
if (maxavro_read_integer_from_file(file, &len))
|
||||
@ -243,7 +243,7 @@ uint64_t avro_length_string(const char* str)
|
||||
*
|
||||
* @see maxavro_get_error
|
||||
*/
|
||||
bool maxavro_read_float(MAXAVRO_FILE* file, float *dest)
|
||||
bool maxavro_read_float(MAXAVRO_FILE* file, float* dest)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
@ -282,7 +282,7 @@ uint64_t avro_length_float(float val)
|
||||
*
|
||||
* @see maxavro_get_error
|
||||
*/
|
||||
bool maxavro_read_double(MAXAVRO_FILE* file, double *dest)
|
||||
bool maxavro_read_double(MAXAVRO_FILE* file, double* dest)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
@ -321,7 +321,7 @@ uint64_t avro_length_double(double val)
|
||||
* @return A read map or NULL if an error occurred. The return value needs to be
|
||||
* freed with maxavro_map_free().
|
||||
*/
|
||||
MAXAVRO_MAP* maxavro_read_map_from_file(MAXAVRO_FILE *file)
|
||||
MAXAVRO_MAP* maxavro_read_map_from_file(MAXAVRO_FILE* file)
|
||||
{
|
||||
MAXAVRO_MAP* rval = NULL;
|
||||
uint64_t blocks;
|
||||
@ -337,7 +337,11 @@ MAXAVRO_MAP* maxavro_read_map_from_file(MAXAVRO_FILE *file)
|
||||
{
|
||||
size_t size;
|
||||
MAXAVRO_MAP* val = calloc(1, sizeof(MAXAVRO_MAP));
|
||||
if (val && (val->key = maxavro_read_string_from_file(file, &size)) && (val->value = maxavro_read_string_from_file(file, &size)))
|
||||
if (val
|
||||
&& (val->key
|
||||
= maxavro_read_string_from_file(file,
|
||||
&size))
|
||||
&& (val->value = maxavro_read_string_from_file(file, &size)))
|
||||
{
|
||||
val->next = rval;
|
||||
rval = val;
|
||||
@ -364,7 +368,7 @@ MAXAVRO_MAP* maxavro_read_map_from_file(MAXAVRO_FILE *file)
|
||||
*
|
||||
* @param value Map to free
|
||||
*/
|
||||
void maxavro_map_free(MAXAVRO_MAP *value)
|
||||
void maxavro_map_free(MAXAVRO_MAP* value)
|
||||
{
|
||||
while (value)
|
||||
{
|
||||
|
104
avro/maxavro.h
104
avro/maxavro.h
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -22,7 +22,7 @@
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
/** File magic and sync marker sizes block sizes */
|
||||
#define AVRO_MAGIC_SIZE 4
|
||||
#define AVRO_MAGIC_SIZE 4
|
||||
#define SYNC_MARKER_SIZE 16
|
||||
|
||||
/** The file magic */
|
||||
@ -45,22 +45,22 @@ enum maxavro_value_type
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
void *extra;
|
||||
char* name;
|
||||
void* extra;
|
||||
enum maxavro_value_type type;
|
||||
} MAXAVRO_SCHEMA_FIELD;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MAXAVRO_SCHEMA_FIELD *fields;
|
||||
size_t num_fields;
|
||||
MAXAVRO_SCHEMA_FIELD* fields;
|
||||
size_t num_fields;
|
||||
} MAXAVRO_SCHEMA;
|
||||
|
||||
enum maxavro_codec
|
||||
{
|
||||
MAXAVRO_CODEC_NULL,
|
||||
MAXAVRO_CODEC_DEFLATE,
|
||||
MAXAVRO_CODEC_SNAPPY, /**< Not yet implemented */
|
||||
MAXAVRO_CODEC_SNAPPY, /**< Not yet implemented */
|
||||
};
|
||||
|
||||
enum maxavro_error
|
||||
@ -73,86 +73,86 @@ enum maxavro_error
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE* file;
|
||||
char* filename; /*< The filename */
|
||||
MAXAVRO_SCHEMA* schema;
|
||||
FILE* file;
|
||||
char* filename;/*< The filename */
|
||||
MAXAVRO_SCHEMA* schema;
|
||||
enum maxavro_codec codec;
|
||||
uint64_t blocks_read; /*< Total number of data blocks read */
|
||||
uint64_t records_read; /*< Total number of records read */
|
||||
uint64_t bytes_read; /*< Total number of bytes read */
|
||||
uint64_t records_in_block;
|
||||
uint64_t records_read_from_block;
|
||||
uint64_t bytes_read_from_block;
|
||||
uint64_t buffer_size; /*< Size of the block in bytes */
|
||||
uint8_t *buffer; /**< The uncompressed data */
|
||||
uint8_t *buffer_end; /**< The byte after the end of the buffer*/
|
||||
uint8_t *buffer_ptr; /**< Pointer to @c buffer which is moved as records are read */
|
||||
uint64_t blocks_read; /*< Total number of data blocks read */
|
||||
uint64_t records_read;/*< Total number of records read */
|
||||
uint64_t bytes_read; /*< Total number of bytes read */
|
||||
uint64_t records_in_block;
|
||||
uint64_t records_read_from_block;
|
||||
uint64_t bytes_read_from_block;
|
||||
uint64_t buffer_size; /*< Size of the block in bytes */
|
||||
uint8_t* buffer; /**< The uncompressed data */
|
||||
uint8_t* buffer_end; /**< The byte after the end of the buffer*/
|
||||
uint8_t* buffer_ptr; /**< Pointer to @c buffer which is moved as records are read */
|
||||
/** The position @c ftell returns before the first record is read */
|
||||
long header_end_pos;
|
||||
long data_start_pos;
|
||||
long block_start_pos;
|
||||
bool metadata_read; /*< If datablock metadata has been read. This is kept
|
||||
* in memory if EOF is reached but an attempt to read
|
||||
* is made later when new data is available. We need
|
||||
* to know when to read it and when not to. */
|
||||
enum maxavro_error last_error; /*< Last error */
|
||||
uint8_t sync[SYNC_MARKER_SIZE];
|
||||
bool metadata_read; /*< If datablock metadata has been read. This is kept
|
||||
* in memory if EOF is reached but an attempt to read
|
||||
* is made later when new data is available. We need
|
||||
* to know when to read it and when not to. */
|
||||
enum maxavro_error last_error; /*< Last error */
|
||||
uint8_t sync[SYNC_MARKER_SIZE];
|
||||
} MAXAVRO_FILE;
|
||||
|
||||
/** A record field value */
|
||||
typedef union
|
||||
{
|
||||
uint64_t integer;
|
||||
double floating;
|
||||
char *string;
|
||||
bool boolean;
|
||||
void *bytes;
|
||||
double floating;
|
||||
char* string;
|
||||
bool boolean;
|
||||
void* bytes;
|
||||
} MAXAVRO_RECORD_VALUE;
|
||||
|
||||
/** A record value */
|
||||
typedef struct
|
||||
{
|
||||
MAXAVRO_SCHEMA_FIELD *field;
|
||||
MAXAVRO_RECORD_VALUE *value;
|
||||
size_t size;
|
||||
MAXAVRO_SCHEMA_FIELD* field;
|
||||
MAXAVRO_RECORD_VALUE* value;
|
||||
size_t size;
|
||||
} MAXAVRO_RECORD;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buffer; /*< Buffer memory */
|
||||
size_t buffersize; /*< Size of the buffer */
|
||||
size_t datasize; /*< size of written data */
|
||||
uint64_t records; /*< Number of successfully written records */
|
||||
MAXAVRO_FILE *avrofile; /*< The current open file */
|
||||
uint8_t* buffer; /*< Buffer memory */
|
||||
size_t buffersize; /*< Size of the buffer */
|
||||
size_t datasize; /*< size of written data */
|
||||
uint64_t records; /*< Number of successfully written records */
|
||||
MAXAVRO_FILE* avrofile; /*< The current open file */
|
||||
} MAXAVRO_DATABLOCK;
|
||||
|
||||
typedef struct avro_map_value
|
||||
{
|
||||
char* key;
|
||||
char* value;
|
||||
struct avro_map_value *next;
|
||||
struct avro_map_value *tail;
|
||||
int blocks; /*< Number of added key-value blocks */
|
||||
char* key;
|
||||
char* value;
|
||||
struct avro_map_value* next;
|
||||
struct avro_map_value* tail;
|
||||
int blocks; /*< Number of added key-value blocks */
|
||||
} MAXAVRO_MAP;
|
||||
|
||||
/** Opening and closing files */
|
||||
MAXAVRO_FILE* maxavro_file_open(const char* filename);
|
||||
void maxavro_file_close(MAXAVRO_FILE *file);
|
||||
void maxavro_file_close(MAXAVRO_FILE* file);
|
||||
|
||||
/** Reading records */
|
||||
json_t* maxavro_record_read_json(MAXAVRO_FILE *file);
|
||||
GWBUF* maxavro_record_read_binary(MAXAVRO_FILE *file);
|
||||
json_t* maxavro_record_read_json(MAXAVRO_FILE* file);
|
||||
GWBUF* maxavro_record_read_binary(MAXAVRO_FILE* file);
|
||||
|
||||
/** Navigation of the file */
|
||||
bool maxavro_record_seek(MAXAVRO_FILE *file, uint64_t offset);
|
||||
bool maxavro_record_set_pos(MAXAVRO_FILE *file, long pos);
|
||||
bool maxavro_next_block(MAXAVRO_FILE *file);
|
||||
bool maxavro_record_seek(MAXAVRO_FILE* file, uint64_t offset);
|
||||
bool maxavro_record_set_pos(MAXAVRO_FILE* file, long pos);
|
||||
bool maxavro_next_block(MAXAVRO_FILE* file);
|
||||
|
||||
/** Get binary format header */
|
||||
GWBUF* maxavro_file_binary_header(MAXAVRO_FILE *file);
|
||||
GWBUF* maxavro_file_binary_header(MAXAVRO_FILE* file);
|
||||
|
||||
/** File error functions */
|
||||
enum maxavro_error maxavro_get_error(MAXAVRO_FILE *file);
|
||||
const char* maxavro_get_error_string(MAXAVRO_FILE *file);
|
||||
enum maxavro_error maxavro_get_error(MAXAVRO_FILE* file);
|
||||
const char* maxavro_get_error_string(MAXAVRO_FILE* file);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -29,14 +29,14 @@ uint64_t maxavro_encode_float(uint8_t* dest, float val);
|
||||
uint64_t maxavro_encode_double(uint8_t* dest, double val);
|
||||
|
||||
/** Writing values straight to disk*/
|
||||
bool maxavro_write_integer(FILE *file, uint64_t val);
|
||||
bool maxavro_write_string(FILE *file, const char* str);
|
||||
bool maxavro_write_float(FILE *file, float val);
|
||||
bool maxavro_write_double(FILE *file, double val);
|
||||
bool maxavro_write_integer(FILE* file, uint64_t val);
|
||||
bool maxavro_write_string(FILE* file, const char* str);
|
||||
bool maxavro_write_float(FILE* file, float val);
|
||||
bool maxavro_write_double(FILE* file, double val);
|
||||
|
||||
MAXAVRO_DATABLOCK* maxavro_datablock_allocate(MAXAVRO_FILE *file, size_t buffersize)
|
||||
MAXAVRO_DATABLOCK* maxavro_datablock_allocate(MAXAVRO_FILE* file, size_t buffersize)
|
||||
{
|
||||
MAXAVRO_DATABLOCK *datablock = malloc(sizeof(MAXAVRO_DATABLOCK));
|
||||
MAXAVRO_DATABLOCK* datablock = malloc(sizeof(MAXAVRO_DATABLOCK));
|
||||
|
||||
if (datablock && (datablock->buffer = malloc(buffersize)))
|
||||
{
|
||||
@ -61,15 +61,15 @@ void maxavro_datablock_free(MAXAVRO_DATABLOCK* block)
|
||||
bool maxavro_datablock_finalize(MAXAVRO_DATABLOCK* block)
|
||||
{
|
||||
bool rval = true;
|
||||
FILE *file = block->avrofile->file;
|
||||
FILE* file = block->avrofile->file;
|
||||
|
||||
/** Store the current position so we can truncate the file if a write fails */
|
||||
long pos = ftell(file);
|
||||
|
||||
if (!maxavro_write_integer(file, block->records) ||
|
||||
!maxavro_write_integer(file, block->datasize) ||
|
||||
fwrite(block->buffer, 1, block->datasize, file) != block->datasize ||
|
||||
fwrite(block->avrofile->sync, 1, SYNC_MARKER_SIZE, file) != SYNC_MARKER_SIZE)
|
||||
if (!maxavro_write_integer(file, block->records)
|
||||
|| !maxavro_write_integer(file, block->datasize)
|
||||
|| fwrite(block->buffer, 1, block->datasize, file) != block->datasize
|
||||
|| fwrite(block->avrofile->sync, 1, SYNC_MARKER_SIZE, file) != SYNC_MARKER_SIZE)
|
||||
{
|
||||
int fd = fileno(file);
|
||||
ftruncate(fd, pos);
|
||||
@ -86,9 +86,9 @@ bool maxavro_datablock_finalize(MAXAVRO_DATABLOCK* block)
|
||||
return rval;
|
||||
}
|
||||
|
||||
static bool reallocate_datablock(MAXAVRO_DATABLOCK *block)
|
||||
static bool reallocate_datablock(MAXAVRO_DATABLOCK* block)
|
||||
{
|
||||
void *tmp = realloc(block->buffer, block->buffersize * 2);
|
||||
void* tmp = realloc(block->buffer, block->buffersize * 2);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
return false;
|
||||
@ -99,7 +99,7 @@ static bool reallocate_datablock(MAXAVRO_DATABLOCK *block)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool maxavro_datablock_add_integer(MAXAVRO_DATABLOCK *block, uint64_t val)
|
||||
bool maxavro_datablock_add_integer(MAXAVRO_DATABLOCK* block, uint64_t val)
|
||||
{
|
||||
if (block->datasize + 9 >= block->buffersize && !reallocate_datablock(block))
|
||||
{
|
||||
@ -111,7 +111,7 @@ bool maxavro_datablock_add_integer(MAXAVRO_DATABLOCK *block, uint64_t val)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool maxavro_datablock_add_string(MAXAVRO_DATABLOCK *block, const char* str)
|
||||
bool maxavro_datablock_add_string(MAXAVRO_DATABLOCK* block, const char* str)
|
||||
{
|
||||
if (block->datasize + 9 + strlen(str) >= block->buffersize && !reallocate_datablock(block))
|
||||
{
|
||||
@ -123,7 +123,7 @@ bool maxavro_datablock_add_string(MAXAVRO_DATABLOCK *block, const char* str)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool maxavro_datablock_add_float(MAXAVRO_DATABLOCK *block, float val)
|
||||
bool maxavro_datablock_add_float(MAXAVRO_DATABLOCK* block, float val)
|
||||
{
|
||||
if (block->datasize + sizeof(val) >= block->buffersize && !reallocate_datablock(block))
|
||||
{
|
||||
@ -135,7 +135,7 @@ bool maxavro_datablock_add_float(MAXAVRO_DATABLOCK *block, float val)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool maxavro_datablock_add_double(MAXAVRO_DATABLOCK *block, double val)
|
||||
bool maxavro_datablock_add_double(MAXAVRO_DATABLOCK* block, double val)
|
||||
{
|
||||
if (block->datasize + sizeof(val) >= block->buffersize && !reallocate_datablock(block))
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <maxscale/log.h>
|
||||
#include <zlib.h>
|
||||
|
||||
static bool maxavro_read_sync(FILE *file, uint8_t* sync)
|
||||
static bool maxavro_read_sync(FILE* file, uint8_t* sync)
|
||||
{
|
||||
bool rval = true;
|
||||
|
||||
@ -28,7 +28,8 @@ static bool maxavro_read_sync(FILE *file, uint8_t* sync)
|
||||
|
||||
if (ferror(file))
|
||||
{
|
||||
MXS_ERROR("Failed to read file sync marker: %d, %s", errno,
|
||||
MXS_ERROR("Failed to read file sync marker: %d, %s",
|
||||
errno,
|
||||
mxs_strerror(errno));
|
||||
}
|
||||
else if (feof(file))
|
||||
@ -44,7 +45,7 @@ static bool maxavro_read_sync(FILE *file, uint8_t* sync)
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool maxavro_verify_block(MAXAVRO_FILE *file)
|
||||
bool maxavro_verify_block(MAXAVRO_FILE* file)
|
||||
{
|
||||
char sync[SYNC_MARKER_SIZE];
|
||||
int rc = fread(sync, 1, SYNC_MARKER_SIZE, file->file);
|
||||
@ -57,7 +58,8 @@ bool maxavro_verify_block(MAXAVRO_FILE *file)
|
||||
else if (rc > 0 || !feof(file->file))
|
||||
{
|
||||
MXS_ERROR("Short read when reading sync marker. Read %d bytes instead of %d",
|
||||
rc, SYNC_MARKER_SIZE);
|
||||
rc,
|
||||
SYNC_MARKER_SIZE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -69,7 +71,9 @@ bool maxavro_verify_block(MAXAVRO_FILE *file)
|
||||
if (pos != expected)
|
||||
{
|
||||
MXS_ERROR("Sync marker mismatch due to wrong file offset. file is at %ld "
|
||||
"when it should be at %ld.", pos, expected);
|
||||
"when it should be at %ld.",
|
||||
pos,
|
||||
expected);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -86,8 +90,8 @@ bool maxavro_verify_block(MAXAVRO_FILE *file)
|
||||
|
||||
static uint8_t* read_block_data(MAXAVRO_FILE* file, long deflate_size)
|
||||
{
|
||||
uint8_t *temp_buffer = MXS_MALLOC(deflate_size);
|
||||
uint8_t *buffer = NULL;
|
||||
uint8_t* temp_buffer = MXS_MALLOC(deflate_size);
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
if (temp_buffer && fread(temp_buffer, 1, deflate_size, file->file) == deflate_size)
|
||||
{
|
||||
@ -117,10 +121,10 @@ static uint8_t* read_block_data(MAXAVRO_FILE* file, long deflate_size)
|
||||
|
||||
int rc;
|
||||
|
||||
while((rc = inflate(&stream, Z_FINISH)) == Z_BUF_ERROR)
|
||||
while ((rc = inflate(&stream, Z_FINISH)) == Z_BUF_ERROR)
|
||||
{
|
||||
int increment = inflate_size;
|
||||
uint8_t *temp = MXS_REALLOC(buffer, inflate_size + increment);
|
||||
uint8_t* temp = MXS_REALLOC(buffer, inflate_size + increment);
|
||||
|
||||
if (temp)
|
||||
{
|
||||
@ -170,8 +174,8 @@ bool maxavro_read_datablock_start(MAXAVRO_FILE* file)
|
||||
file->block_start_pos = ftell(file->file);
|
||||
file->metadata_read = false;
|
||||
uint64_t records, bytes;
|
||||
bool rval = maxavro_read_integer_from_file(file, &records) &&
|
||||
maxavro_read_integer_from_file(file, &bytes);
|
||||
bool rval = maxavro_read_integer_from_file(file, &records)
|
||||
&& maxavro_read_integer_from_file(file, &bytes);
|
||||
|
||||
if (rval)
|
||||
{
|
||||
@ -180,7 +184,8 @@ bool maxavro_read_datablock_start(MAXAVRO_FILE* file)
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
MXS_ERROR("Failed to read datablock start: %d, %s", errno,
|
||||
MXS_ERROR("Failed to read datablock start: %d, %s",
|
||||
errno,
|
||||
mxs_strerror(errno));
|
||||
}
|
||||
else
|
||||
@ -218,7 +223,7 @@ bool maxavro_read_datablock_start(MAXAVRO_FILE* file)
|
||||
* actual data. */
|
||||
static char* read_schema(MAXAVRO_FILE* file)
|
||||
{
|
||||
char *rval = NULL;
|
||||
char* rval = NULL;
|
||||
MAXAVRO_MAP* head = maxavro_read_map_from_file(file);
|
||||
MAXAVRO_MAP* map = head;
|
||||
|
||||
@ -270,7 +275,7 @@ static char* read_schema(MAXAVRO_FILE* file)
|
||||
*/
|
||||
MAXAVRO_FILE* maxavro_file_open(const char* filename)
|
||||
{
|
||||
FILE *file = fopen(filename, "rb");
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if (!file)
|
||||
{
|
||||
MXS_ERROR("Failed to open file '%s': %d, %s", filename, errno, strerror(errno));
|
||||
@ -296,7 +301,7 @@ MAXAVRO_FILE* maxavro_file_open(const char* filename)
|
||||
bool error = false;
|
||||
|
||||
MAXAVRO_FILE* avrofile = calloc(1, sizeof(MAXAVRO_FILE));
|
||||
char *my_filename = strdup(filename);
|
||||
char* my_filename = strdup(filename);
|
||||
|
||||
if (avrofile && my_filename)
|
||||
{
|
||||
@ -304,15 +309,15 @@ MAXAVRO_FILE* maxavro_file_open(const char* filename)
|
||||
avrofile->filename = my_filename;
|
||||
avrofile->last_error = MAXAVRO_ERR_NONE;
|
||||
|
||||
char *schema = read_schema(avrofile);
|
||||
char* schema = read_schema(avrofile);
|
||||
|
||||
if (schema)
|
||||
{
|
||||
avrofile->schema = maxavro_schema_alloc(schema);
|
||||
|
||||
if (avrofile->schema &&
|
||||
maxavro_read_sync(file, avrofile->sync) &&
|
||||
maxavro_read_datablock_start(avrofile))
|
||||
if (avrofile->schema
|
||||
&& maxavro_read_sync(file, avrofile->sync)
|
||||
&& maxavro_read_datablock_start(avrofile))
|
||||
{
|
||||
avrofile->header_end_pos = avrofile->block_start_pos;
|
||||
}
|
||||
@ -349,7 +354,7 @@ MAXAVRO_FILE* maxavro_file_open(const char* filename)
|
||||
* @param file File to check
|
||||
* @return The last error or MAXAVRO_ERR_NONE if no errors have occurred
|
||||
*/
|
||||
enum maxavro_error maxavro_get_error(MAXAVRO_FILE *file)
|
||||
enum maxavro_error maxavro_get_error(MAXAVRO_FILE* file)
|
||||
{
|
||||
return file->last_error;
|
||||
}
|
||||
@ -359,7 +364,7 @@ enum maxavro_error maxavro_get_error(MAXAVRO_FILE *file)
|
||||
* @param file File to check
|
||||
* @return Error in string form
|
||||
*/
|
||||
const char* maxavro_get_error_string(MAXAVRO_FILE *file)
|
||||
const char* maxavro_get_error_string(MAXAVRO_FILE* file)
|
||||
{
|
||||
switch (file->last_error)
|
||||
{
|
||||
@ -384,7 +389,7 @@ const char* maxavro_get_error_string(MAXAVRO_FILE *file)
|
||||
* @brief Close an avro file
|
||||
* @param file File to close
|
||||
*/
|
||||
void maxavro_file_close(MAXAVRO_FILE *file)
|
||||
void maxavro_file_close(MAXAVRO_FILE* file)
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
@ -405,10 +410,10 @@ void maxavro_file_close(MAXAVRO_FILE *file)
|
||||
* @param file File to read from
|
||||
* @return Binary header or NULL if an error occurred
|
||||
*/
|
||||
GWBUF* maxavro_file_binary_header(MAXAVRO_FILE *file)
|
||||
GWBUF* maxavro_file_binary_header(MAXAVRO_FILE* file)
|
||||
{
|
||||
long pos = file->header_end_pos;
|
||||
GWBUF *rval = NULL;
|
||||
GWBUF* rval = NULL;
|
||||
|
||||
if (fseek(file->file, 0, SEEK_SET) == 0)
|
||||
{
|
||||
@ -418,7 +423,8 @@ GWBUF* maxavro_file_binary_header(MAXAVRO_FILE *file)
|
||||
{
|
||||
if (ferror(file->file))
|
||||
{
|
||||
MXS_ERROR("Failed to read binary header: %d, %s", errno,
|
||||
MXS_ERROR("Failed to read binary header: %d, %s",
|
||||
errno,
|
||||
mxs_strerror(errno));
|
||||
}
|
||||
else if (feof(file->file))
|
||||
@ -440,7 +446,8 @@ GWBUF* maxavro_file_binary_header(MAXAVRO_FILE *file)
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Failed to read binary header: %d, %s", errno,
|
||||
MXS_ERROR("Failed to read binary header: %d, %s",
|
||||
errno,
|
||||
mxs_strerror(errno));
|
||||
}
|
||||
|
||||
|
@ -21,18 +21,18 @@
|
||||
*/
|
||||
|
||||
/** Reading primitives */
|
||||
bool maxavro_read_integer(MAXAVRO_FILE *file, uint64_t *val);
|
||||
char* maxavro_read_string(MAXAVRO_FILE *file, size_t *size);
|
||||
bool maxavro_skip_string(MAXAVRO_FILE* file);
|
||||
bool maxavro_read_float(MAXAVRO_FILE *file, float *dest);
|
||||
bool maxavro_read_double(MAXAVRO_FILE *file, double *dest);
|
||||
bool maxavro_read_integer(MAXAVRO_FILE* file, uint64_t* val);
|
||||
char* maxavro_read_string(MAXAVRO_FILE* file, size_t* size);
|
||||
bool maxavro_skip_string(MAXAVRO_FILE* file);
|
||||
bool maxavro_read_float(MAXAVRO_FILE* file, float* dest);
|
||||
bool maxavro_read_double(MAXAVRO_FILE* file, double* dest);
|
||||
|
||||
/** Only used when opening the file */
|
||||
bool maxavro_read_integer_from_file(MAXAVRO_FILE *file, uint64_t *val);
|
||||
bool maxavro_read_integer_from_file(MAXAVRO_FILE* file, uint64_t* val);
|
||||
|
||||
/** Reading complex types */
|
||||
MAXAVRO_MAP* maxavro_read_map_from_file(MAXAVRO_FILE *file);
|
||||
void maxavro_map_free(MAXAVRO_MAP *value);
|
||||
MAXAVRO_MAP* maxavro_read_map_from_file(MAXAVRO_FILE* file);
|
||||
void maxavro_map_free(MAXAVRO_MAP* value);
|
||||
|
||||
/**
|
||||
* The following functionality is not yet fully implemented
|
||||
@ -40,17 +40,17 @@ void maxavro_map_free(MAXAVRO_MAP *value);
|
||||
|
||||
/** Schema creation */
|
||||
MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json);
|
||||
void maxavro_schema_free(MAXAVRO_SCHEMA* schema);
|
||||
void maxavro_schema_free(MAXAVRO_SCHEMA* schema);
|
||||
|
||||
/** Data block generation */
|
||||
MAXAVRO_DATABLOCK* maxavro_datablock_allocate(MAXAVRO_FILE *file, size_t buffersize);
|
||||
void maxavro_datablock_free(MAXAVRO_DATABLOCK* block);
|
||||
bool maxavro_datablock_finalize(MAXAVRO_DATABLOCK* block);
|
||||
MAXAVRO_DATABLOCK* maxavro_datablock_allocate(MAXAVRO_FILE* file, size_t buffersize);
|
||||
void maxavro_datablock_free(MAXAVRO_DATABLOCK* block);
|
||||
bool maxavro_datablock_finalize(MAXAVRO_DATABLOCK* block);
|
||||
|
||||
/** Adding values to a datablock. The caller must ensure that the inserted
|
||||
* values conform to the file schema and that the required amount of fields
|
||||
* is added before finalizing the block. */
|
||||
bool maxavro_datablock_add_integer(MAXAVRO_DATABLOCK *file, uint64_t val);
|
||||
bool maxavro_datablock_add_string(MAXAVRO_DATABLOCK *file, const char* str);
|
||||
bool maxavro_datablock_add_float(MAXAVRO_DATABLOCK *file, float val);
|
||||
bool maxavro_datablock_add_double(MAXAVRO_DATABLOCK *file, double val);
|
||||
bool maxavro_datablock_add_integer(MAXAVRO_DATABLOCK* file, uint64_t val);
|
||||
bool maxavro_datablock_add_string(MAXAVRO_DATABLOCK* file, const char* str);
|
||||
bool maxavro_datablock_add_float(MAXAVRO_DATABLOCK* file, float val);
|
||||
bool maxavro_datablock_add_double(MAXAVRO_DATABLOCK* file, double val);
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include <maxscale/log.h>
|
||||
#include <errno.h>
|
||||
|
||||
bool maxavro_read_datablock_start(MAXAVRO_FILE *file);
|
||||
bool maxavro_verify_block(MAXAVRO_FILE *file);
|
||||
bool maxavro_read_datablock_start(MAXAVRO_FILE* file);
|
||||
bool maxavro_verify_block(MAXAVRO_FILE* file);
|
||||
const char* type_to_string(enum maxavro_value_type type);
|
||||
|
||||
/**
|
||||
@ -30,7 +30,7 @@ const char* type_to_string(enum maxavro_value_type type);
|
||||
* @param field_num Field index in the schema
|
||||
* @return JSON object or NULL if an error occurred
|
||||
*/
|
||||
static json_t* read_and_pack_value(MAXAVRO_FILE *file, MAXAVRO_SCHEMA_FIELD *field)
|
||||
static json_t* read_and_pack_value(MAXAVRO_FILE* file, MAXAVRO_SCHEMA_FIELD* field)
|
||||
{
|
||||
json_t* value = NULL;
|
||||
switch (field->type)
|
||||
@ -61,13 +61,13 @@ static json_t* read_and_pack_value(MAXAVRO_FILE *file, MAXAVRO_SCHEMA_FIELD *fie
|
||||
uint64_t val = 0;
|
||||
maxavro_read_integer(file, &val);
|
||||
|
||||
json_t *arr = field->extra;
|
||||
json_t* arr = field->extra;
|
||||
mxb_assert(arr);
|
||||
mxb_assert(json_is_array(arr));
|
||||
|
||||
if (json_array_size(arr) >= val)
|
||||
{
|
||||
json_t * symbol = json_array_get(arr, val);
|
||||
json_t* symbol = json_array_get(arr, val);
|
||||
mxb_assert(json_is_string(symbol));
|
||||
value = json_pack("s", json_string_value(symbol));
|
||||
}
|
||||
@ -85,6 +85,7 @@ static json_t* read_and_pack_value(MAXAVRO_FILE *file, MAXAVRO_SCHEMA_FIELD *fie
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MAXAVRO_TYPE_DOUBLE:
|
||||
{
|
||||
double d = 0;
|
||||
@ -99,7 +100,7 @@ static json_t* read_and_pack_value(MAXAVRO_FILE *file, MAXAVRO_SCHEMA_FIELD *fie
|
||||
case MAXAVRO_TYPE_STRING:
|
||||
{
|
||||
size_t len;
|
||||
char *str = maxavro_read_string(file, &len);
|
||||
char* str = maxavro_read_string(file, &len);
|
||||
if (str)
|
||||
{
|
||||
value = json_stringn(str, len);
|
||||
@ -115,7 +116,7 @@ static json_t* read_and_pack_value(MAXAVRO_FILE *file, MAXAVRO_SCHEMA_FIELD *fie
|
||||
return value;
|
||||
}
|
||||
|
||||
static void skip_value(MAXAVRO_FILE *file, enum maxavro_value_type type)
|
||||
static void skip_value(MAXAVRO_FILE* file, enum maxavro_value_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -156,7 +157,7 @@ static void skip_value(MAXAVRO_FILE *file, enum maxavro_value_type type)
|
||||
* @return JSON value or NULL if an error occurred. The caller must call
|
||||
* json_decref() on the returned value to free the allocated memory.
|
||||
*/
|
||||
json_t* maxavro_record_read_json(MAXAVRO_FILE *file)
|
||||
json_t* maxavro_record_read_json(MAXAVRO_FILE* file)
|
||||
{
|
||||
if (!file->metadata_read && !maxavro_read_datablock_start(file))
|
||||
{
|
||||
@ -185,7 +186,8 @@ json_t* maxavro_record_read_json(MAXAVRO_FILE *file)
|
||||
"file offset %ld, record number %lu.",
|
||||
file->schema->fields[i].name,
|
||||
type_to_string(file->schema->fields[i].type),
|
||||
pos, file->records_read);
|
||||
pos,
|
||||
file->records_read);
|
||||
json_decref(object);
|
||||
return NULL;
|
||||
}
|
||||
@ -199,7 +201,7 @@ json_t* maxavro_record_read_json(MAXAVRO_FILE *file)
|
||||
return object;
|
||||
}
|
||||
|
||||
static void skip_record(MAXAVRO_FILE *file)
|
||||
static void skip_record(MAXAVRO_FILE* file)
|
||||
{
|
||||
for (size_t i = 0; i < file->schema->num_fields; i++)
|
||||
{
|
||||
@ -216,7 +218,7 @@ static void skip_record(MAXAVRO_FILE *file)
|
||||
* @param file File to read from
|
||||
* @return True if reading the next block was successfully read
|
||||
*/
|
||||
bool maxavro_next_block(MAXAVRO_FILE *file)
|
||||
bool maxavro_next_block(MAXAVRO_FILE* file)
|
||||
{
|
||||
if (file->last_error == MAXAVRO_ERR_NONE)
|
||||
{
|
||||
@ -234,7 +236,7 @@ bool maxavro_next_block(MAXAVRO_FILE *file)
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
bool maxavro_record_seek(MAXAVRO_FILE *file, uint64_t offset)
|
||||
bool maxavro_record_seek(MAXAVRO_FILE* file, uint64_t offset)
|
||||
{
|
||||
bool rval = true;
|
||||
|
||||
@ -282,7 +284,7 @@ bool maxavro_record_seek(MAXAVRO_FILE *file, uint64_t offset)
|
||||
* of a data block
|
||||
* @return True if seeking to the offset was successful, false if an error occurred
|
||||
*/
|
||||
bool maxavro_record_set_pos(MAXAVRO_FILE *file, long pos)
|
||||
bool maxavro_record_set_pos(MAXAVRO_FILE* file, long pos)
|
||||
{
|
||||
fseek(file->file, pos - SYNC_MARKER_SIZE, SEEK_SET);
|
||||
return maxavro_verify_block(file) && maxavro_read_datablock_start(file);
|
||||
@ -298,9 +300,9 @@ bool maxavro_record_set_pos(MAXAVRO_FILE *file, long pos)
|
||||
* @return Buffer containing the complete binary data block or NULL if an error
|
||||
* occurred. Consult maxavro_get_error for more details.
|
||||
*/
|
||||
GWBUF* maxavro_record_read_binary(MAXAVRO_FILE *file)
|
||||
GWBUF* maxavro_record_read_binary(MAXAVRO_FILE* file)
|
||||
{
|
||||
GWBUF *rval = NULL;
|
||||
GWBUF* rval = NULL;
|
||||
|
||||
if (file->last_error == MAXAVRO_ERR_NONE)
|
||||
{
|
||||
@ -326,7 +328,9 @@ GWBUF* maxavro_record_read_binary(MAXAVRO_FILE *file)
|
||||
{
|
||||
if (ferror(file->file))
|
||||
{
|
||||
MXS_ERROR("Failed to read %ld bytes: %d, %s", data_size, errno,
|
||||
MXS_ERROR("Failed to read %ld bytes: %d, %s",
|
||||
data_size,
|
||||
errno,
|
||||
mxs_strerror(errno));
|
||||
file->last_error = MAXAVRO_ERR_IO;
|
||||
}
|
||||
@ -342,7 +346,8 @@ GWBUF* maxavro_record_read_binary(MAXAVRO_FILE *file)
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Attempting to read from a failed Avro file '%s', error is: %s",
|
||||
file->filename, maxavro_get_error_string(file));
|
||||
file->filename,
|
||||
maxavro_get_error_string(file));
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
@ -19,16 +19,16 @@
|
||||
|
||||
static const MAXAVRO_SCHEMA_FIELD types[MAXAVRO_TYPE_MAX] =
|
||||
{
|
||||
{"int", NULL, MAXAVRO_TYPE_INT},
|
||||
{"long", NULL, MAXAVRO_TYPE_LONG},
|
||||
{"float", NULL, MAXAVRO_TYPE_FLOAT},
|
||||
{"double", NULL, MAXAVRO_TYPE_DOUBLE},
|
||||
{"bool", NULL, MAXAVRO_TYPE_BOOL},
|
||||
{"bytes", NULL, MAXAVRO_TYPE_BYTES},
|
||||
{"string", NULL, MAXAVRO_TYPE_STRING},
|
||||
{"enum", NULL, MAXAVRO_TYPE_ENUM},
|
||||
{"null", NULL, MAXAVRO_TYPE_NULL},
|
||||
{NULL, NULL, MAXAVRO_TYPE_UNKNOWN}
|
||||
{"int", NULL, MAXAVRO_TYPE_INT },
|
||||
{"long", NULL, MAXAVRO_TYPE_LONG },
|
||||
{"float", NULL, MAXAVRO_TYPE_FLOAT },
|
||||
{"double", NULL, MAXAVRO_TYPE_DOUBLE },
|
||||
{"bool", NULL, MAXAVRO_TYPE_BOOL },
|
||||
{"bytes", NULL, MAXAVRO_TYPE_BYTES },
|
||||
{"string", NULL, MAXAVRO_TYPE_STRING },
|
||||
{"enum", NULL, MAXAVRO_TYPE_ENUM },
|
||||
{"null", NULL, MAXAVRO_TYPE_NULL },
|
||||
{NULL, NULL, MAXAVRO_TYPE_UNKNOWN}
|
||||
};
|
||||
/**
|
||||
* @brief Convert string to Avro value type
|
||||
@ -36,7 +36,7 @@ static const MAXAVRO_SCHEMA_FIELD types[MAXAVRO_TYPE_MAX] =
|
||||
* @param type Value string
|
||||
* @return Avro value type
|
||||
*/
|
||||
enum maxavro_value_type string_to_type(const char *str)
|
||||
enum maxavro_value_type string_to_type(const char* str)
|
||||
{
|
||||
for (int i = 0; types[i].name; i++)
|
||||
{
|
||||
@ -72,7 +72,7 @@ const char* type_to_string(enum maxavro_value_type type)
|
||||
* @param field The associated field
|
||||
* @return Type of the field
|
||||
*/
|
||||
static enum maxavro_value_type unpack_to_type(json_t *object,
|
||||
static enum maxavro_value_type unpack_to_type(json_t* object,
|
||||
MAXAVRO_SCHEMA_FIELD* field)
|
||||
{
|
||||
enum maxavro_value_type rval = MAXAVRO_TYPE_UNKNOWN;
|
||||
@ -80,25 +80,25 @@ static enum maxavro_value_type unpack_to_type(json_t *object,
|
||||
|
||||
if (json_is_object(object))
|
||||
{
|
||||
json_t *tmp = NULL;
|
||||
json_t* tmp = NULL;
|
||||
json_unpack(object, "{s:o}", "type", &tmp);
|
||||
type = tmp;
|
||||
}
|
||||
|
||||
if (json_is_array(object))
|
||||
{
|
||||
json_t *tmp = json_array_get(object, 0);
|
||||
json_t* tmp = json_array_get(object, 0);
|
||||
type = tmp;
|
||||
}
|
||||
|
||||
if (type && json_is_string(type))
|
||||
{
|
||||
const char *value = json_string_value(type);
|
||||
const char* value = json_string_value(type);
|
||||
rval = string_to_type(value);
|
||||
|
||||
if (rval == MAXAVRO_TYPE_ENUM)
|
||||
{
|
||||
json_t *tmp = NULL;
|
||||
json_t* tmp = NULL;
|
||||
json_unpack(object, "{s:o}", "symbols", &tmp);
|
||||
mxb_assert(json_is_array(tmp));
|
||||
json_incref(tmp);
|
||||
@ -122,11 +122,11 @@ MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json)
|
||||
{
|
||||
bool error = false;
|
||||
json_error_t err;
|
||||
json_t *schema = json_loads(json, 0, &err);
|
||||
json_t* schema = json_loads(json, 0, &err);
|
||||
|
||||
if (schema)
|
||||
{
|
||||
json_t *field_arr = NULL;
|
||||
json_t* field_arr = NULL;
|
||||
|
||||
if (json_unpack(schema, "{s:o}", "fields", &field_arr) == 0)
|
||||
{
|
||||
@ -136,9 +136,9 @@ MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json)
|
||||
|
||||
for (int i = 0; i < arr_size; i++)
|
||||
{
|
||||
json_t *object = json_array_get(field_arr, i);
|
||||
char *key;
|
||||
json_t *value_obj;
|
||||
json_t* object = json_array_get(field_arr, i);
|
||||
char* key;
|
||||
json_t* value_obj;
|
||||
|
||||
if (object && json_unpack(object, "{s:s s:o}", "name", &key, "type", &value_obj) == 0)
|
||||
{
|
||||
@ -186,7 +186,7 @@ MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json)
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void maxavro_schema_field_free(MAXAVRO_SCHEMA_FIELD *field)
|
||||
static void maxavro_schema_field_free(MAXAVRO_SCHEMA_FIELD* field)
|
||||
{
|
||||
if (field)
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ uint64_t maxavro_encode_integer(uint8_t* buffer, uint64_t val)
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
bool maxavro_write_integer(FILE *file, uint64_t val)
|
||||
bool maxavro_write_integer(FILE* file, uint64_t val)
|
||||
{
|
||||
uint8_t buffer[MAX_INTEGER_SIZE];
|
||||
uint8_t nbytes = maxavro_encode_integer(buffer, val);
|
||||
@ -68,7 +68,7 @@ uint64_t maxavro_encode_string(uint8_t* dest, const char* str)
|
||||
return slen + ilen;
|
||||
}
|
||||
|
||||
bool maxavro_write_string(FILE *file, const char* str)
|
||||
bool maxavro_write_string(FILE* file, const char* str)
|
||||
{
|
||||
uint64_t len = strlen(str);
|
||||
return maxavro_write_integer(file, len) && fwrite(str, 1, len, file) == len;
|
||||
@ -86,7 +86,7 @@ uint64_t maxavro_encode_float(uint8_t* dest, float val)
|
||||
return sizeof(val);
|
||||
}
|
||||
|
||||
bool maxavro_write_float(FILE *file, float val)
|
||||
bool maxavro_write_float(FILE* file, float val)
|
||||
{
|
||||
return fwrite(&val, 1, sizeof(val), file) == sizeof(val);
|
||||
}
|
||||
@ -103,7 +103,7 @@ uint64_t maxavro_encode_double(uint8_t* dest, double val)
|
||||
return sizeof(val);
|
||||
}
|
||||
|
||||
bool maxavro_write_double(FILE *file, double val)
|
||||
bool maxavro_write_double(FILE* file, double val)
|
||||
{
|
||||
return fwrite(&val, 1, sizeof(val), file) == sizeof(val);
|
||||
}
|
||||
@ -113,7 +113,7 @@ MAXAVRO_MAP* avro_map_start()
|
||||
return (MAXAVRO_MAP*)calloc(1, sizeof(MAXAVRO_MAP));
|
||||
}
|
||||
|
||||
uint64_t avro_map_encode(uint8_t *dest, MAXAVRO_MAP* map)
|
||||
uint64_t avro_map_encode(uint8_t* dest, MAXAVRO_MAP* map)
|
||||
{
|
||||
uint64_t len = maxavro_encode_integer(dest, map->blocks);
|
||||
|
||||
|
@ -31,7 +31,7 @@ static bool dump = false;
|
||||
|
||||
int check_file(const char* filename)
|
||||
{
|
||||
MAXAVRO_FILE *file = maxavro_file_open(filename);
|
||||
MAXAVRO_FILE* file = maxavro_file_open(filename);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
@ -67,7 +67,7 @@ int check_file(const char* filename)
|
||||
json_t* row;
|
||||
while (num_rows != 0 && (row = maxavro_record_read_json(file)))
|
||||
{
|
||||
char *json = json_dumps(row, JSON_PRESERVE_ORDER);
|
||||
char* json = json_dumps(row, JSON_PRESERVE_ORDER);
|
||||
if (json)
|
||||
{
|
||||
printf("%s\n", json);
|
||||
@ -87,8 +87,10 @@ int check_file(const char* filename)
|
||||
|
||||
if (verbose && !dump)
|
||||
{
|
||||
printf("Block %lu: %lu records, %lu bytes\n", file->blocks_read,
|
||||
file->records_in_block, file->buffer_size);
|
||||
printf("Block %lu: %lu records, %lu bytes\n",
|
||||
file->blocks_read,
|
||||
file->records_in_block,
|
||||
file->buffer_size);
|
||||
}
|
||||
}
|
||||
while (num_rows != 0 && maxavro_next_block(file));
|
||||
@ -97,13 +99,18 @@ int check_file(const char* filename)
|
||||
{
|
||||
printf("Failed to read next data block after data block %lu. "
|
||||
"Read %lu records and %lu bytes before failure.\n",
|
||||
file->blocks_read, file->records_read, file->bytes_read);
|
||||
file->blocks_read,
|
||||
file->records_read,
|
||||
file->bytes_read);
|
||||
rval = 1;
|
||||
}
|
||||
else if (!dump)
|
||||
{
|
||||
printf("%s: %lu blocks, %lu records and %lu bytes\n", filename,
|
||||
file->blocks_read, file->records_read, file->bytes_read);
|
||||
printf("%s: %lu blocks, %lu records and %lu bytes\n",
|
||||
filename,
|
||||
file->blocks_read,
|
||||
file->records_read,
|
||||
file->bytes_read);
|
||||
}
|
||||
|
||||
|
||||
@ -113,11 +120,11 @@ int check_file(const char* filename)
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"dump", no_argument, 0, 'd'},
|
||||
{"from", no_argument, 0, 'f'},
|
||||
{"count", no_argument, 0, 'c'},
|
||||
{0, 0, 0, 0}
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"dump", no_argument, 0, 'd'},
|
||||
{"from", no_argument, 0, 'f'},
|
||||
{"count", no_argument, 0, 'c'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
@ -139,12 +146,15 @@ int main(int argc, char** argv)
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
dump = true;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
seekto = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
num_rows = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
|
@ -18,18 +18,18 @@
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
const char *testfile = "test.db";
|
||||
const char *testschema = "";
|
||||
const char* testfile = "test.db";
|
||||
const char* testschema = "";
|
||||
|
||||
void write_file()
|
||||
{
|
||||
FILE *file = fopen(testfile, "wb");
|
||||
FILE* file = fopen(testfile, "wb");
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
MAXAVRO_FILE *file = maxavro_file_open(testfile);
|
||||
MAXAVRO_FILE* file = maxavro_file_open(testfile);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -50,27 +50,31 @@
|
||||
|
||||
#define MAX_PASSWORD_LEN 80
|
||||
|
||||
static int connectUsingUnixSocket(const char *socket);
|
||||
static int connectUsingInetSocket(const char *hostname, const char *port,
|
||||
const char *user, const char* password);
|
||||
static int setipaddress(struct in_addr *a, const char *p);
|
||||
static int connectUsingUnixSocket(const char* socket);
|
||||
static int connectUsingInetSocket(const char* hostname,
|
||||
const char* port,
|
||||
const char* user,
|
||||
const char* password);
|
||||
static int setipaddress(struct in_addr* a, const char* p);
|
||||
static bool authUnixSocket(int so);
|
||||
static bool authInetSocket(int so, const char *user, const char *password);
|
||||
static int sendCommand(int so, char *cmd);
|
||||
static void DoSource(int so, char *cmd);
|
||||
static bool authInetSocket(int so, const char* user, const char* password);
|
||||
static int sendCommand(int so, char* cmd);
|
||||
static void DoSource(int so, char* cmd);
|
||||
static void DoUsage(const char*);
|
||||
static int isquit(char *buf);
|
||||
static void PrintVersion(const char *progname);
|
||||
static void read_inifile(char **socket,
|
||||
char **hostname, char **port, char **user, char **passwd,
|
||||
int *editor);
|
||||
static bool getPassword(char *password, size_t length);
|
||||
static void rtrim(char *str);
|
||||
static int isquit(char* buf);
|
||||
static void PrintVersion(const char* progname);
|
||||
static void read_inifile(char** socket,
|
||||
char** hostname,
|
||||
char** port,
|
||||
char** user,
|
||||
char** passwd,
|
||||
int* editor);
|
||||
static bool getPassword(char* password, size_t length);
|
||||
static void rtrim(char* str);
|
||||
|
||||
#ifdef HISTORY
|
||||
|
||||
static char *
|
||||
prompt(EditLine *el __attribute__((__unused__)))
|
||||
static char* prompt(EditLine* el __attribute__ ((__unused__)))
|
||||
{
|
||||
static char prompt[] = "MaxScale> ";
|
||||
|
||||
@ -80,22 +84,22 @@ prompt(EditLine *el __attribute__((__unused__)))
|
||||
#endif
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"host", required_argument, 0, 'h'},
|
||||
{"user", required_argument, 0, 'u'},
|
||||
{"host", required_argument, 0, 'h'},
|
||||
{"user", required_argument, 0, 'u'},
|
||||
{"password", optional_argument, 0, 'p'},
|
||||
{"port", required_argument, 0, 'P'},
|
||||
{"socket", required_argument, 0, 'S'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"help", no_argument, 0, '?'},
|
||||
{"emacs", no_argument, 0, 'e'},
|
||||
{"vim", no_argument, 0, 'i'},
|
||||
{0, 0, 0, 0}
|
||||
{"port", required_argument, 0, 'P'},
|
||||
{"socket", required_argument, 0, 'S'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"help", no_argument, 0, '?'},
|
||||
{"emacs", no_argument, 0, 'e'},
|
||||
{"vim", no_argument, 0, 'i'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#define MAXADMIN_DEFAULT_HOST "localhost"
|
||||
#define MAXADMIN_DEFAULT_PORT "6603"
|
||||
#define MAXADMIN_DEFAULT_USER "admin"
|
||||
#define MAXADMIN_BUFFER_SIZE 2048
|
||||
#define MAXADMIN_BUFFER_SIZE 2048
|
||||
|
||||
static bool term_error = false;
|
||||
|
||||
@ -109,7 +113,7 @@ bool process_command(int so, char* buf)
|
||||
}
|
||||
else if (!strncasecmp(buf, "source", 6))
|
||||
{
|
||||
char *ptr;
|
||||
char* ptr;
|
||||
|
||||
/* Find the filename */
|
||||
ptr = &buf[strlen("source")];
|
||||
@ -134,13 +138,13 @@ bool process_command(int so, char* buf)
|
||||
void cmd_with_history(int so, char** argv, bool use_emacs)
|
||||
{
|
||||
#ifdef HISTORY
|
||||
char *buf;
|
||||
EditLine *el = NULL;
|
||||
Tokenizer *tok;
|
||||
History *hist;
|
||||
char* buf;
|
||||
EditLine* el = NULL;
|
||||
Tokenizer* tok;
|
||||
History* hist;
|
||||
HistEvent ev;
|
||||
|
||||
hist = history_init(); /* Init the builtin history */
|
||||
hist = history_init(); /* Init the builtin history */
|
||||
|
||||
/* Remember 100 events */
|
||||
history(hist, &ev, H_SETSIZE, 100);
|
||||
@ -148,21 +152,21 @@ void cmd_with_history(int so, char** argv, bool use_emacs)
|
||||
/* Don't enter duplicate commands to history */
|
||||
history(hist, &ev, H_SETUNIQUE, 1);
|
||||
|
||||
tok = tok_init(NULL); /* Initialize the tokenizer */
|
||||
tok = tok_init(NULL); /* Initialize the tokenizer */
|
||||
|
||||
/* Initialize editline */
|
||||
el = el_init(*argv, stdin, stdout, stderr);
|
||||
|
||||
if (use_emacs)
|
||||
{
|
||||
el_set(el, EL_EDITOR, "emacs"); /** Editor is emacs */
|
||||
el_set(el, EL_EDITOR, "emacs"); /** Editor is emacs */
|
||||
}
|
||||
else
|
||||
{
|
||||
el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
|
||||
el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
|
||||
}
|
||||
el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
|
||||
el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
|
||||
el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
|
||||
el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
|
||||
|
||||
/* Tell editline to use this history interface */
|
||||
el_set(el, EL_HIST, history, hist);
|
||||
@ -181,7 +185,7 @@ void cmd_with_history(int so, char** argv, bool use_emacs)
|
||||
|
||||
int num = 0;
|
||||
|
||||
while ((buf = (char *) el_gets(el, &num)))
|
||||
while ((buf = (char*) el_gets(el, &num)))
|
||||
{
|
||||
rtrim(buf);
|
||||
history(hist, &ev, H_ENTER, buf);
|
||||
@ -228,14 +232,13 @@ void cmd_no_history(int so)
|
||||
* @param argc Number of arguments
|
||||
* @param argv The command line arguments
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char *hostname = NULL;
|
||||
char *port = NULL;
|
||||
char *user = NULL;
|
||||
char *passwd = NULL;
|
||||
char *socket_path = NULL;
|
||||
char* hostname = NULL;
|
||||
char* port = NULL;
|
||||
char* user = NULL;
|
||||
char* passwd = NULL;
|
||||
char* socket_path = NULL;
|
||||
int use_emacs = 1;
|
||||
|
||||
read_inifile(&socket_path, &hostname, &port, &user, &passwd, &use_emacs);
|
||||
@ -245,8 +248,11 @@ main(int argc, char **argv)
|
||||
|
||||
int option_index = 0;
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "h:p::P:u:S:v?ei",
|
||||
long_options, &option_index)) >= 0)
|
||||
while ((c = getopt_long(argc,
|
||||
argv,
|
||||
"h:p::P:u:S:v?ei",
|
||||
long_options,
|
||||
&option_index)) >= 0)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -380,14 +386,14 @@ main(int argc, char **argv)
|
||||
if (optind < argc)
|
||||
{
|
||||
int i, len = 0;
|
||||
char *cmd;
|
||||
char* cmd;
|
||||
|
||||
for (i = optind; i < argc; i++)
|
||||
{
|
||||
len += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
cmd = malloc(len + (2 * argc)); // Allow for quotes
|
||||
cmd = malloc(len + (2 * argc)); // Allow for quotes
|
||||
strncpy(cmd, argv[optind], len + (2 * argc));
|
||||
for (i = optind + 1; i < argc; i++)
|
||||
{
|
||||
@ -433,8 +439,7 @@ main(int argc, char **argv)
|
||||
* @param socket_path The UNIX socket to connect to
|
||||
* @return The connected socket or -1 on error
|
||||
*/
|
||||
static int
|
||||
connectUsingUnixSocket(const char *socket_path)
|
||||
static int connectUsingUnixSocket(const char* socket_path)
|
||||
{
|
||||
int so = -1;
|
||||
|
||||
@ -446,7 +451,7 @@ connectUsingUnixSocket(const char *socket_path)
|
||||
local_addr.sun_family = AF_UNIX;
|
||||
strncpy(local_addr.sun_path, socket_path, sizeof(local_addr.sun_path) - 1);
|
||||
|
||||
if (connect(so, (struct sockaddr *) &local_addr, sizeof(local_addr)) == 0)
|
||||
if (connect(so, (struct sockaddr*) &local_addr, sizeof(local_addr)) == 0)
|
||||
{
|
||||
int keepalive = 1;
|
||||
if (setsockopt(so, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)))
|
||||
@ -473,8 +478,10 @@ connectUsingUnixSocket(const char *socket_path)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unable to connect to MaxScale at %s: %s\n",
|
||||
socket_path, strerror(errno));
|
||||
fprintf(stderr,
|
||||
"Unable to connect to MaxScale at %s: %s\n",
|
||||
socket_path,
|
||||
strerror(errno));
|
||||
close(so);
|
||||
so = -1;
|
||||
}
|
||||
@ -494,9 +501,10 @@ connectUsingUnixSocket(const char *socket_path)
|
||||
* @param port The port to use for the connection
|
||||
* @return The connected socket or -1 on error
|
||||
*/
|
||||
static int
|
||||
connectUsingInetSocket(const char *hostname, const char *port,
|
||||
const char *user, const char *passwd)
|
||||
static int connectUsingInetSocket(const char* hostname,
|
||||
const char* port,
|
||||
const char* user,
|
||||
const char* passwd)
|
||||
{
|
||||
int so;
|
||||
|
||||
@ -509,7 +517,7 @@ connectUsingInetSocket(const char *hostname, const char *port,
|
||||
setipaddress(&addr.sin_addr, hostname);
|
||||
addr.sin_port = htons(atoi(port));
|
||||
|
||||
if (connect(so, (struct sockaddr *) &addr, sizeof(addr)) == 0)
|
||||
if (connect(so, (struct sockaddr*) &addr, sizeof(addr)) == 0)
|
||||
{
|
||||
int keepalive = 1;
|
||||
if (setsockopt(so, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)))
|
||||
@ -525,8 +533,11 @@ connectUsingInetSocket(const char *hostname, const char *port,
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unable to connect to MaxScale at %s, %s: %s\n",
|
||||
hostname, port, strerror(errno));
|
||||
fprintf(stderr,
|
||||
"Unable to connect to MaxScale at %s, %s: %s\n",
|
||||
hostname,
|
||||
port,
|
||||
strerror(errno));
|
||||
close(so);
|
||||
so = -1;
|
||||
}
|
||||
@ -546,13 +557,12 @@ connectUsingInetSocket(const char *hostname, const char *port,
|
||||
* @param p The hostname to lookup
|
||||
* @return 1 on success, 0 on failure
|
||||
*/
|
||||
static int
|
||||
setipaddress(struct in_addr *a, const char *p)
|
||||
static int setipaddress(struct in_addr* a, const char* p)
|
||||
{
|
||||
|
||||
struct addrinfo *ai = NULL, hint;
|
||||
struct addrinfo* ai = NULL, hint;
|
||||
int rc;
|
||||
struct sockaddr_in * res_addr;
|
||||
struct sockaddr_in* res_addr;
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
@ -567,7 +577,7 @@ setipaddress(struct in_addr *a, const char *p)
|
||||
/* take the first one */
|
||||
if (ai != NULL)
|
||||
{
|
||||
res_addr = (struct sockaddr_in *) (ai->ai_addr);
|
||||
res_addr = (struct sockaddr_in*) (ai->ai_addr);
|
||||
memcpy(a, &res_addr->sin_addr, sizeof(struct in_addr));
|
||||
|
||||
freeaddrinfo(ai);
|
||||
@ -583,8 +593,7 @@ setipaddress(struct in_addr *a, const char *p)
|
||||
* @param so The socket connected to MaxScale
|
||||
* @return Non-zero of succesful authentication
|
||||
*/
|
||||
static bool
|
||||
authUnixSocket(int so)
|
||||
static bool authUnixSocket(int so)
|
||||
{
|
||||
char buf[MAXADMIN_AUTH_REPLY_LEN];
|
||||
|
||||
@ -600,11 +609,13 @@ authUnixSocket(int so)
|
||||
{
|
||||
uid_t id = geteuid();
|
||||
struct passwd* pw = getpwuid(id);
|
||||
fprintf(stderr, "Could connect to MaxScale, but was not authorized.\n"
|
||||
fprintf(stderr,
|
||||
"Could connect to MaxScale, but was not authorized.\n"
|
||||
"Check that the current user is added to the list of allowed users.\n"
|
||||
"To add this user to the list, execute:\n\n"
|
||||
"\tsudo maxadmin enable account %s\n\n"
|
||||
"This assumes that the root user account is enabled in MaxScale.\n", pw->pw_name);
|
||||
"This assumes that the root user account is enabled in MaxScale.\n",
|
||||
pw->pw_name);
|
||||
}
|
||||
|
||||
return authenticated;
|
||||
@ -618,8 +629,7 @@ authUnixSocket(int so)
|
||||
* @param password The password to authenticate with
|
||||
* @return Non-zero of succesful authentication
|
||||
*/
|
||||
static bool
|
||||
authInetSocket(int so, const char *user, const char *password)
|
||||
static bool authInetSocket(int so, const char* user, const char* password)
|
||||
{
|
||||
char buf[20];
|
||||
size_t len;
|
||||
@ -679,8 +689,7 @@ authInetSocket(int so, const char *user, const char *password)
|
||||
* @param cmd The command to send
|
||||
* @return 0 if the connection was closed
|
||||
*/
|
||||
static int
|
||||
sendCommand(int so, char *cmd)
|
||||
static int sendCommand(int so, char* cmd)
|
||||
{
|
||||
char buf[80];
|
||||
int i, j, newline = 1;
|
||||
@ -703,8 +712,8 @@ sendCommand(int so, char *cmd)
|
||||
{
|
||||
newline = 2;
|
||||
}
|
||||
else if ((newline == 2 && buf[j] == 'K' && j == i - 1) ||
|
||||
(j == i - 2 && buf[j] == 'O' && buf[j + 1] == 'K'))
|
||||
else if ((newline == 2 && buf[j] == 'K' && j == i - 1)
|
||||
|| (j == i - 2 && buf[j] == 'O' && buf[j + 1] == 'K'))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -735,16 +744,16 @@ sendCommand(int so, char *cmd)
|
||||
* @param so The socket connected to MaxScale
|
||||
* @param file The filename
|
||||
*/
|
||||
static void
|
||||
DoSource(int so, char *file)
|
||||
static void DoSource(int so, char* file)
|
||||
{
|
||||
char *ptr, *pe;
|
||||
char* ptr, * pe;
|
||||
char line[132];
|
||||
FILE *fp;
|
||||
FILE* fp;
|
||||
|
||||
if ((fp = fopen(file, "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to open command file '%s'.\n",
|
||||
fprintf(stderr,
|
||||
"Unable to open command file '%s'.\n",
|
||||
file);
|
||||
return;
|
||||
}
|
||||
@ -759,7 +768,7 @@ DoSource(int so, char *file)
|
||||
pe--;
|
||||
}
|
||||
|
||||
if (*ptr != '#' && *ptr != '\0') /* Comment or empty */
|
||||
if (*ptr != '#' && *ptr != '\0') /* Comment or empty */
|
||||
{
|
||||
if (!sendCommand(so, ptr))
|
||||
{
|
||||
@ -774,8 +783,7 @@ DoSource(int so, char *file)
|
||||
/**
|
||||
* Print version information
|
||||
*/
|
||||
static void
|
||||
PrintVersion(const char *progname)
|
||||
static void PrintVersion(const char* progname)
|
||||
{
|
||||
printf("%s Version %s\n", progname, MAXSCALE_VERSION);
|
||||
}
|
||||
@ -783,8 +791,7 @@ PrintVersion(const char *progname)
|
||||
/**
|
||||
* Display the --help text.
|
||||
*/
|
||||
static void
|
||||
DoUsage(const char *progname)
|
||||
static void DoUsage(const char* progname)
|
||||
{
|
||||
PrintVersion(progname);
|
||||
printf("The MaxScale administrative and monitor client.\n\n");
|
||||
@ -817,10 +824,9 @@ DoUsage(const char *progname)
|
||||
* @param buf The command buffer
|
||||
* @return Non-zero if the command should cause maxadmin to quit
|
||||
*/
|
||||
static int
|
||||
isquit(char *buf)
|
||||
static int isquit(char* buf)
|
||||
{
|
||||
char *ptr = buf;
|
||||
char* ptr = buf;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
@ -845,14 +851,13 @@ isquit(char *buf)
|
||||
*
|
||||
* @param str String to trim
|
||||
*/
|
||||
static void
|
||||
rtrim(char *str)
|
||||
static void rtrim(char* str)
|
||||
{
|
||||
char *ptr = str + strlen(str);
|
||||
char* ptr = str + strlen(str);
|
||||
|
||||
if (ptr > str) // step back from the terminating null
|
||||
if (ptr > str) // step back from the terminating null
|
||||
{
|
||||
ptr--; // If the string has more characters
|
||||
ptr--; // If the string has more characters
|
||||
}
|
||||
|
||||
while (ptr >= str && isspace(*ptr))
|
||||
@ -871,15 +876,17 @@ rtrim(char *str)
|
||||
* @param user Pointer to the user to be updated
|
||||
* @param passwd Pointer to the password to be updated
|
||||
*/
|
||||
static void
|
||||
read_inifile(char **socket,
|
||||
char **hostname, char** port, char **user, char **passwd,
|
||||
int* editor)
|
||||
static void read_inifile(char** socket,
|
||||
char** hostname,
|
||||
char** port,
|
||||
char** user,
|
||||
char** passwd,
|
||||
int* editor)
|
||||
{
|
||||
char pathname[400];
|
||||
char *home, *brkt;
|
||||
char *name, *value;
|
||||
FILE *fp;
|
||||
char* home, * brkt;
|
||||
char* name, * value;
|
||||
FILE* fp;
|
||||
char line[400];
|
||||
|
||||
if ((home = getenv("HOME")) == NULL)
|
||||
@ -938,21 +945,28 @@ read_inifile(char **socket,
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Unrecognised "
|
||||
"parameter '%s=%s' in .maxadmin file\n", name, value);
|
||||
fprintf(stderr,
|
||||
"WARNING: Unrecognised "
|
||||
"parameter '%s=%s' in .maxadmin file\n",
|
||||
name,
|
||||
value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Unrecognised "
|
||||
"parameter '%s' in .maxadmin file\n", name);
|
||||
fprintf(stderr,
|
||||
"WARNING: Unrecognised "
|
||||
"parameter '%s' in .maxadmin file\n",
|
||||
name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Expected name=value "
|
||||
fprintf(stderr,
|
||||
"WARNING: Expected name=value "
|
||||
"parameters in .maxadmin file but found "
|
||||
"'%s'.\n", line);
|
||||
"'%s'.\n",
|
||||
line);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
@ -966,7 +980,7 @@ read_inifile(char **socket,
|
||||
*
|
||||
* @return Whether the password was obtained.
|
||||
*/
|
||||
bool getPassword(char *passwd, size_t len)
|
||||
bool getPassword(char* passwd, size_t len)
|
||||
{
|
||||
bool err = false;
|
||||
struct termios tty_attr;
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
#define CDC_CONNECTOR_VERSION "1.0.0"
|
||||
|
||||
#define ERRBUF_SIZE 512
|
||||
#define ERRBUF_SIZE 512
|
||||
#define READBUF_SIZE 32 * 1024
|
||||
|
||||
static const char OK_RESPONSE[] = "OK\n";
|
||||
@ -49,7 +49,7 @@ static const char REQUEST_MSG[] = "REQUEST-DATA ";
|
||||
namespace
|
||||
{
|
||||
|
||||
static std::string bin2hex(const uint8_t *data, size_t len)
|
||||
static std::string bin2hex(const uint8_t* data, size_t len)
|
||||
{
|
||||
std::string result;
|
||||
static const char hexconvtab[] = "0123456789abcdef";
|
||||
@ -109,20 +109,20 @@ std::string json_to_string(json_t* json)
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Helper class for closing objects
|
||||
template <class T> class Closer
|
||||
template<class T>
|
||||
class Closer
|
||||
{
|
||||
public:
|
||||
|
||||
Closer(T t):
|
||||
m_t(t),
|
||||
m_close(true)
|
||||
Closer(T t)
|
||||
: m_t(t)
|
||||
, m_close(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -148,22 +148,23 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_t;
|
||||
T m_t;
|
||||
bool m_close;
|
||||
|
||||
void close(T t);
|
||||
};
|
||||
|
||||
template <> void Closer<struct addrinfo*>::close(struct addrinfo* ai)
|
||||
template<>
|
||||
void Closer<struct addrinfo*>::close(struct addrinfo* ai)
|
||||
{
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
template <> void Closer<int>::close(int fd)
|
||||
template<>
|
||||
void Closer<int>::close(int fd)
|
||||
{
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace CDC
|
||||
@ -177,14 +178,14 @@ Connection::Connection(const std::string& address,
|
||||
uint16_t port,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
int timeout) :
|
||||
m_fd(-1),
|
||||
m_port(port),
|
||||
m_address(address),
|
||||
m_user(user),
|
||||
m_password(password),
|
||||
m_timeout(timeout),
|
||||
m_connected(false)
|
||||
int timeout)
|
||||
: m_fd(-1)
|
||||
, m_port(port)
|
||||
, m_address(address)
|
||||
, m_user(user)
|
||||
, m_password(password)
|
||||
, m_timeout(timeout)
|
||||
, m_connected(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -207,7 +208,7 @@ bool Connection::connect(const std::string& table, const std::string& gtid)
|
||||
|
||||
m_error.clear();
|
||||
|
||||
struct addrinfo *ai = NULL, hint = {};
|
||||
struct addrinfo* ai = NULL, hint = {};
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
hint.ai_flags = AI_ALL;
|
||||
@ -247,8 +248,8 @@ bool Connection::connect(const std::string& table, const std::string& gtid)
|
||||
m_error = "Failed to connect: ";
|
||||
m_error += strerror_r(errno, err, sizeof(err));
|
||||
}
|
||||
else if ((fl = fcntl(fd, F_GETFL, 0)) == -1 ||
|
||||
fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1)
|
||||
else if ((fl = fcntl(fd, F_GETFL, 0)) == -1
|
||||
|| fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1)
|
||||
{
|
||||
char err[ERRBUF_SIZE];
|
||||
m_error = "Failed to set socket non-blocking: ";
|
||||
@ -337,7 +338,8 @@ void Connection::process_schema(json_t* json)
|
||||
type = json_object_get(v, "type");
|
||||
}
|
||||
std::string nameval = name ? json_string_value(name) : "";
|
||||
std::string typeval = type ? (json_is_string(type) ? json_string_value(type) : "varchar(50)") : "undefined";
|
||||
std::string typeval
|
||||
= type ? (json_is_string(type) ? json_string_value(type) : "varchar(50)") : "undefined";
|
||||
|
||||
if (json_is_integer(length))
|
||||
{
|
||||
@ -491,7 +493,6 @@ bool Connection::do_auth()
|
||||
buf[bytes] = '\0';
|
||||
m_error = "Authentication failed: ";
|
||||
m_error += bytes > 0 ? buf : "Request timed out";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -662,7 +663,6 @@ int Connection::wait_for_event(short events)
|
||||
|
||||
while ((rc = poll(&pfd, nfds, m_timeout * 1000)) < 0 && errno == EINTR)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if (rc > 0 && is_poll_error(pfd.revents))
|
||||
@ -681,7 +681,7 @@ int Connection::wait_for_event(short events)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int Connection::nointr_read(void *dest, size_t size)
|
||||
int Connection::nointr_read(void* dest, size_t size)
|
||||
{
|
||||
int n_bytes = 0;
|
||||
|
||||
@ -691,7 +691,6 @@ int Connection::nointr_read(void *dest, size_t size)
|
||||
|
||||
while ((rc = ::read(m_fd, dest, size)) < 0 && errno == EINTR)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if (rc == -1 && errno != EWOULDBLOCK && errno != EAGAIN)
|
||||
@ -710,7 +709,7 @@ int Connection::nointr_read(void *dest, size_t size)
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
int Connection::nointr_write(const void *src, size_t size)
|
||||
int Connection::nointr_write(const void* src, size_t size)
|
||||
{
|
||||
int rc = 0;
|
||||
size_t n_bytes = 0;
|
||||
@ -720,7 +719,6 @@ int Connection::nointr_write(const void *src, size_t size)
|
||||
{
|
||||
while ((rc = ::write(m_fd, ptr, size)) < 0 && errno == EINTR)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if (rc < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
|
||||
@ -741,5 +739,4 @@ int Connection::nointr_write(const void *src, size_t size)
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ const char* TIMEOUT = "Request timed out";
|
||||
class Row;
|
||||
typedef std::tr1::shared_ptr<Row> SRow;
|
||||
|
||||
typedef std::vector<std::string> ValueVector;
|
||||
typedef std::tr1::shared_ptr<ValueVector> SValueVector;
|
||||
typedef std::vector<std::string> ValueVector;
|
||||
typedef std::tr1::shared_ptr<ValueVector> SValueVector;
|
||||
typedef std::map<std::string, std::string> ValueMap;
|
||||
|
||||
// A class that represents a CDC connection
|
||||
@ -128,19 +128,19 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
int m_fd;
|
||||
uint16_t m_port;
|
||||
std::string m_address;
|
||||
std::string m_user;
|
||||
std::string m_password;
|
||||
std::string m_error;
|
||||
std::string m_schema;
|
||||
SValueVector m_keys;
|
||||
SValueVector m_types;
|
||||
int m_timeout;
|
||||
int m_fd;
|
||||
uint16_t m_port;
|
||||
std::string m_address;
|
||||
std::string m_user;
|
||||
std::string m_password;
|
||||
std::string m_error;
|
||||
std::string m_schema;
|
||||
SValueVector m_keys;
|
||||
SValueVector m_types;
|
||||
int m_timeout;
|
||||
std::deque<char> m_buffer;
|
||||
SRow m_first_row;
|
||||
bool m_connected;
|
||||
SRow m_first_row;
|
||||
bool m_connected;
|
||||
|
||||
bool do_auth();
|
||||
bool do_registration();
|
||||
@ -152,8 +152,8 @@ private:
|
||||
|
||||
// Lower-level functions
|
||||
int wait_for_event(short events);
|
||||
int nointr_read(void *dest, size_t size);
|
||||
int nointr_write(const void *src, size_t size);
|
||||
int nointr_read(void* dest, size_t size);
|
||||
int nointr_write(const void* src, size_t size);
|
||||
};
|
||||
|
||||
// Internal representation of a row, used via the Row type
|
||||
@ -210,7 +210,7 @@ public:
|
||||
s += value("domain");
|
||||
s += "-";
|
||||
s += value("server_id");
|
||||
s += "-";
|
||||
s += "-";
|
||||
s += value("sequence");
|
||||
return s;
|
||||
}
|
||||
@ -242,20 +242,18 @@ public:
|
||||
private:
|
||||
SValueVector m_keys;
|
||||
SValueVector m_types;
|
||||
ValueVector m_values;
|
||||
ValueVector m_values;
|
||||
|
||||
// Only a Connection should construct an InternalRow
|
||||
friend class Connection;
|
||||
|
||||
Row(SValueVector& keys,
|
||||
SValueVector& types,
|
||||
ValueVector& values):
|
||||
m_keys(keys),
|
||||
m_types(types)
|
||||
ValueVector& values)
|
||||
: m_keys(keys)
|
||||
, m_types(types)
|
||||
{
|
||||
m_values.swap(values);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -27,14 +27,14 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
"An example filter that does nothing",
|
||||
"V1.0.0",
|
||||
RCAP_TYPE_NONE,
|
||||
&ExampleFilter::s_object, // This is defined in the MaxScale filter template
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
&ExampleFilter::s_object, // This is defined in the MaxScale filter template
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{ "an_example_parameter", MXS_MODULE_PARAM_STRING, "a-default-value" },
|
||||
{ MXS_END_MODULE_PARAMS }
|
||||
{"an_example_parameter", MXS_MODULE_PARAM_STRING,"a-default-value"},
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/filter.hh>
|
||||
@ -20,7 +20,7 @@ class ExampleFilter : public maxscale::Filter<ExampleFilter, ExampleFilterSessio
|
||||
{
|
||||
// Prevent copy-constructor and assignment operator usage
|
||||
ExampleFilter(const ExampleFilter&);
|
||||
ExampleFilter& operator = (const ExampleFilter&);
|
||||
ExampleFilter& operator=(const ExampleFilter&);
|
||||
|
||||
public:
|
||||
~ExampleFilter();
|
||||
|
@ -26,7 +26,7 @@ ExampleFilterSession::~ExampleFilterSession()
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
ExampleFilterSession* ExampleFilterSession::create(MXS_SESSION* pSession, const ExampleFilter* pFilter)
|
||||
{
|
||||
return new ExampleFilterSession(pSession);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/filter.hh>
|
||||
@ -21,7 +21,7 @@ class ExampleFilterSession : public maxscale::FilterSession
|
||||
{
|
||||
// Prevent copy-constructor and assignment operator usage
|
||||
ExampleFilterSession(const ExampleFilterSession&);
|
||||
ExampleFilterSession& operator = (const ExampleFilterSession&);
|
||||
ExampleFilterSession& operator=(const ExampleFilterSession&);
|
||||
|
||||
public:
|
||||
~ExampleFilterSession();
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include <maxscale/query_classifier.h>
|
||||
#include <maxscale/router.h>
|
||||
|
||||
//#define DEBUG_RRROUTER
|
||||
// #define DEBUG_RRROUTER
|
||||
#undef DEBUG_RROUTER
|
||||
|
||||
#ifdef DEBUG_RRROUTER
|
||||
@ -60,22 +60,22 @@
|
||||
|
||||
/* This router handles different query types in a different manner. Some queries
|
||||
* require that a "write_backend" is set. */
|
||||
const uint32_t q_route_to_rr = (QUERY_TYPE_LOCAL_READ | QUERY_TYPE_READ |
|
||||
QUERY_TYPE_MASTER_READ | QUERY_TYPE_USERVAR_READ |
|
||||
QUERY_TYPE_SYSVAR_READ | QUERY_TYPE_GSYSVAR_READ |
|
||||
QUERY_TYPE_SHOW_DATABASES | QUERY_TYPE_SHOW_TABLES);
|
||||
const uint32_t q_route_to_rr = (QUERY_TYPE_LOCAL_READ | QUERY_TYPE_READ
|
||||
| QUERY_TYPE_MASTER_READ | QUERY_TYPE_USERVAR_READ
|
||||
| QUERY_TYPE_SYSVAR_READ | QUERY_TYPE_GSYSVAR_READ
|
||||
| QUERY_TYPE_SHOW_DATABASES | QUERY_TYPE_SHOW_TABLES);
|
||||
|
||||
const uint32_t q_route_to_all = (QUERY_TYPE_SESSION_WRITE | QUERY_TYPE_USERVAR_WRITE |
|
||||
QUERY_TYPE_GSYSVAR_WRITE | QUERY_TYPE_ENABLE_AUTOCOMMIT |
|
||||
QUERY_TYPE_DISABLE_AUTOCOMMIT);
|
||||
const uint32_t q_route_to_all = (QUERY_TYPE_SESSION_WRITE | QUERY_TYPE_USERVAR_WRITE
|
||||
| QUERY_TYPE_GSYSVAR_WRITE | QUERY_TYPE_ENABLE_AUTOCOMMIT
|
||||
| QUERY_TYPE_DISABLE_AUTOCOMMIT);
|
||||
|
||||
const uint32_t q_trx_begin = QUERY_TYPE_BEGIN_TRX;
|
||||
|
||||
const uint32_t q_trx_end = (QUERY_TYPE_ROLLBACK | QUERY_TYPE_COMMIT);
|
||||
|
||||
const uint32_t q_route_to_write = (QUERY_TYPE_WRITE | QUERY_TYPE_PREPARE_NAMED_STMT |
|
||||
QUERY_TYPE_PREPARE_STMT | QUERY_TYPE_EXEC_STMT |
|
||||
QUERY_TYPE_CREATE_TMP_TABLE | QUERY_TYPE_READ_TMP_TABLE);
|
||||
const uint32_t q_route_to_write = (QUERY_TYPE_WRITE | QUERY_TYPE_PREPARE_NAMED_STMT
|
||||
| QUERY_TYPE_PREPARE_STMT | QUERY_TYPE_EXEC_STMT
|
||||
| QUERY_TYPE_CREATE_TMP_TABLE | QUERY_TYPE_READ_TMP_TABLE);
|
||||
|
||||
const char MAX_BACKENDS[] = "max_backends";
|
||||
const char WRITE_BACKEND[] = "write_backend";
|
||||
@ -85,18 +85,18 @@ const char DUMMY[] = "dummy_setting";
|
||||
/* Enum setting definition example */
|
||||
static const MXS_ENUM_VALUE enum_example[] =
|
||||
{
|
||||
{"two", 2},
|
||||
{"two", 2},
|
||||
{"zero", 0},
|
||||
{NULL} /* Last must be NULL */
|
||||
{NULL} /* Last must be NULL */
|
||||
};
|
||||
|
||||
static modulecmd_arg_type_t custom_cmd_args[] =
|
||||
{
|
||||
{MODULECMD_ARG_STRING, "Example string"},
|
||||
{MODULECMD_ARG_STRING, "Example string" },
|
||||
{(MODULECMD_ARG_BOOLEAN | MODULECMD_ARG_OPTIONAL), "This is an optional bool parameter"}
|
||||
};
|
||||
|
||||
bool custom_cmd_example(const MODULECMD_ARG *argv, json_t** output);
|
||||
bool custom_cmd_example(const MODULECMD_ARG* argv, json_t** output);
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
@ -110,41 +110,44 @@ class RRRouterSession;
|
||||
class RRRouter : public MXS_ROUTER
|
||||
{
|
||||
private:
|
||||
SERVICE* m_service; /* Service this router is part of */
|
||||
SERVICE* m_service; /* Service this router is part of */
|
||||
/* Router settings */
|
||||
unsigned int m_max_backends; /* How many backend servers to use */
|
||||
SERVER* m_write_server; /* Where to send write etc. "unsafe" queries */
|
||||
bool m_print_on_routing; /* Print a message on every packet routed? */
|
||||
uint64_t m_example_enum; /* Not used */
|
||||
unsigned int m_max_backends; /* How many backend servers to use */
|
||||
SERVER* m_write_server; /* Where to send write etc. "unsafe" queries */
|
||||
bool m_print_on_routing;/* Print a message on every packet routed? */
|
||||
uint64_t m_example_enum; /* Not used */
|
||||
|
||||
void decide_target(RRRouterSession* rses, GWBUF* querybuf, DCB*& target, bool& route_to_all);
|
||||
public:
|
||||
/* Statistics, written to by multiple threads */
|
||||
volatile unsigned long int m_routing_s; /* Routing success */
|
||||
volatile unsigned long int m_routing_f; /* Routing fail */
|
||||
volatile unsigned long int m_routing_c; /* Client packets routed */
|
||||
volatile unsigned long int m_routing_s; /* Routing success */
|
||||
volatile unsigned long int m_routing_f; /* Routing fail */
|
||||
volatile unsigned long int m_routing_c; /* Client packets routed */
|
||||
|
||||
/* Methods */
|
||||
RRRouter(SERVICE* service);
|
||||
~RRRouter();
|
||||
RRRouterSession* create_session(MXS_SESSION* session);
|
||||
int route_query(RRRouterSession* rses, GWBUF* querybuf);
|
||||
void client_reply(RRRouterSession* rses, GWBUF* buf, DCB* backend_dcb);
|
||||
void handle_error(RRRouterSession* rses, GWBUF* message, DCB* problem_dcb,
|
||||
mxs_error_action_t action, bool* succp);
|
||||
int route_query(RRRouterSession* rses, GWBUF* querybuf);
|
||||
void client_reply(RRRouterSession* rses, GWBUF* buf, DCB* backend_dcb);
|
||||
void handle_error(RRRouterSession* rses,
|
||||
GWBUF* message,
|
||||
DCB* problem_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp);
|
||||
};
|
||||
|
||||
/* Every client connection has a corresponding session. */
|
||||
class RRRouterSession : public MXS_ROUTER_SESSION
|
||||
{
|
||||
public:
|
||||
bool m_closed; /* true when closeSession is called */
|
||||
DCB_VEC m_backend_dcbs; /* backends */
|
||||
DCB* m_write_dcb; /* write backend */
|
||||
DCB* m_client_dcb; /* client */
|
||||
unsigned int m_route_count; /* how many packets have been routed */
|
||||
bool m_on_transaction; /* Is the session in transaction mode? */
|
||||
unsigned int m_replies_to_ignore; /* Counts how many replies should be ignored. */
|
||||
bool m_closed; /* true when closeSession is called */
|
||||
DCB_VEC m_backend_dcbs; /* backends */
|
||||
DCB* m_write_dcb; /* write backend */
|
||||
DCB* m_client_dcb; /* client */
|
||||
unsigned int m_route_count; /* how many packets have been routed */
|
||||
bool m_on_transaction; /* Is the session in transaction mode? */
|
||||
unsigned int m_replies_to_ignore; /* Counts how many replies should be ignored. */
|
||||
|
||||
RRRouterSession(DCB_VEC&, DCB*, DCB*);
|
||||
~RRRouterSession();
|
||||
@ -193,7 +196,8 @@ RRRouterSession* RRRouter::create_session(MXS_SESSION* session)
|
||||
if (SERVER_REF_IS_ACTIVE(sref) && (backends.size() < m_max_backends))
|
||||
{
|
||||
/* Connect to server */
|
||||
DCB* conn = dcb_connect(sref->server, session,
|
||||
DCB* conn = dcb_connect(sref->server,
|
||||
session,
|
||||
sref->server->protocol);
|
||||
if (conn)
|
||||
{
|
||||
@ -201,7 +205,7 @@ RRRouterSession* RRRouter::create_session(MXS_SESSION* session)
|
||||
atomic_add(&sref->connections, 1);
|
||||
conn->service = session->service;
|
||||
backends.push_back(conn);
|
||||
} /* Any error by dcb_connect is reported by the function itself */
|
||||
} /* Any error by dcb_connect is reported by the function itself */
|
||||
}
|
||||
}
|
||||
if (m_write_server)
|
||||
@ -264,7 +268,8 @@ int RRRouter::route_query(RRRouterSession* rses, GWBUF* querybuf)
|
||||
if (print)
|
||||
{
|
||||
MXS_NOTICE("Routing statement of length %du to backend '%s'.",
|
||||
gwbuf_length(querybuf), target->server->name);
|
||||
gwbuf_length(querybuf),
|
||||
target->server->name);
|
||||
}
|
||||
/* Do not use dcb_write() to output to a dcb. dcb_write() is used only
|
||||
* for raw write in the procol modules. */
|
||||
@ -278,7 +283,8 @@ int RRRouter::route_query(RRRouterSession* rses, GWBUF* querybuf)
|
||||
if (print)
|
||||
{
|
||||
MXS_NOTICE("Routing statement of length %du to %d backends.",
|
||||
gwbuf_length(querybuf), n_targets);
|
||||
gwbuf_length(querybuf),
|
||||
n_targets);
|
||||
}
|
||||
int route_success = 0;
|
||||
for (unsigned int i = 0; i < rses->m_backend_dcbs.size(); i++)
|
||||
@ -344,8 +350,11 @@ void RRRouter::client_reply(RRRouterSession* rses, GWBUF* buf, DCB* backend_dcb)
|
||||
MXS_NOTICE("Replied to client.\n");
|
||||
}
|
||||
}
|
||||
void RRRouter::handle_error(RRRouterSession* rses, GWBUF* message, DCB* problem_dcb,
|
||||
mxs_error_action_t action, bool* succp)
|
||||
void RRRouter::handle_error(RRRouterSession* rses,
|
||||
GWBUF* message,
|
||||
DCB* problem_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp)
|
||||
{
|
||||
/* Don't handle same error twice on same DCB */
|
||||
if (problem_dcb->dcb_errhandle_called)
|
||||
@ -390,6 +399,7 @@ void RRRouter::handle_error(RRRouterSession* rses, GWBUF* message, DCB* problem_
|
||||
*succp = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ERRACT_NEW_CONNECTION:
|
||||
{
|
||||
/* React to a failed backend */
|
||||
@ -422,6 +432,7 @@ void RRRouter::handle_error(RRRouterSession* rses, GWBUF* message, DCB* problem_
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mxb_assert(!true);
|
||||
*succp = false;
|
||||
@ -509,21 +520,27 @@ void RRRouter::decide_target(RRRouterSession* rses, GWBUF* querybuf, DCB*& targe
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case MXS_COM_INIT_DB:
|
||||
query_types = q_route_to_all;
|
||||
RR_DEBUG("MYSQL_COM_INIT_DB");
|
||||
break;
|
||||
|
||||
case MXS_COM_QUIT:
|
||||
query_types = q_route_to_all;
|
||||
RR_DEBUG("MYSQL_COM_QUIT");
|
||||
break;
|
||||
|
||||
case MXS_COM_FIELD_LIST:
|
||||
query_types = q_route_to_rr;
|
||||
RR_DEBUG("MYSQL_COM_FIELD_LIST");
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TODO: Add support for other commands if needed. */
|
||||
/* This error message will only print the number of the cmd. */
|
||||
/*
|
||||
* TODO: Add support for other commands if needed.
|
||||
* This error message will only print the number of the cmd.
|
||||
*/
|
||||
MXS_ERROR("Received unexpected sql command type: '%d'.", cmd_type);
|
||||
break;
|
||||
}
|
||||
@ -567,22 +584,27 @@ void RRRouter::decide_target(RRRouterSession* rses, GWBUF* querybuf, DCB*& targe
|
||||
* The functions implementing the router module API. These do not need to be
|
||||
* "extern C", but they do need to be callable from C code.
|
||||
*/
|
||||
static MXS_ROUTER* createInstance(SERVICE* service, MXS_CONFIG_PARAMETER* params);
|
||||
static MXS_ROUTER* createInstance(SERVICE* service, MXS_CONFIG_PARAMETER* params);
|
||||
static MXS_ROUTER_SESSION* newSession(MXS_ROUTER* instance, MXS_SESSION* session);
|
||||
static void closeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session);
|
||||
static void freeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session);
|
||||
static int routeQuery(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* querybuf);
|
||||
static void diagnostics(MXS_ROUTER* instance, DCB* dcb);
|
||||
static json_t* diagnostics_json(const MXS_ROUTER* instance);
|
||||
static void clientReply(MXS_ROUTER* instance, MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* resultbuf, DCB* backend_dcb);
|
||||
static void handleError(MXS_ROUTER* instance, MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* errmsgbuf, DCB* backend_dcb, mxs_error_action_t action,
|
||||
static void closeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session);
|
||||
static void freeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session);
|
||||
static int routeQuery(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* querybuf);
|
||||
static void diagnostics(MXS_ROUTER* instance, DCB* dcb);
|
||||
static json_t* diagnostics_json(const MXS_ROUTER* instance);
|
||||
static void clientReply(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* resultbuf,
|
||||
DCB* backend_dcb);
|
||||
static void handleError(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* errmsgbuf,
|
||||
DCB* backend_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp);
|
||||
static uint64_t getCapabilities(MXS_ROUTER *instance);
|
||||
static uint64_t getCapabilities(MXS_ROUTER* instance);
|
||||
static void destroyInstance(MXS_ROUTER* instance);
|
||||
/* The next two entry points are usually optional. */
|
||||
static int process_init();
|
||||
static int process_init();
|
||||
static void process_finish();
|
||||
|
||||
/*
|
||||
@ -610,17 +632,17 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
|
||||
static MXS_MODULE moduleObject =
|
||||
{
|
||||
MXS_MODULE_API_ROUTER, /* Module type */
|
||||
MXS_MODULE_BETA_RELEASE, /* Release status */
|
||||
MXS_ROUTER_VERSION, /* Implemented module API version */
|
||||
"A simple round robin router", /* Description */
|
||||
"V1.1.0", /* Module version */
|
||||
MXS_MODULE_API_ROUTER, /* Module type */
|
||||
MXS_MODULE_BETA_RELEASE, /* Release status */
|
||||
MXS_ROUTER_VERSION, /* Implemented module API version */
|
||||
"A simple round robin router", /* Description */
|
||||
"V1.1.0", /* Module version */
|
||||
RCAP_TYPE_CONTIGUOUS_INPUT | RCAP_TYPE_RESULTSET_OUTPUT,
|
||||
&entryPoints, /* Defined above */
|
||||
process_init, /* Process init, can be null */
|
||||
process_finish, /* Process finish, can be null */
|
||||
NULL, /* Thread init */
|
||||
NULL, /* Thread finish */
|
||||
&entryPoints, /* Defined above */
|
||||
process_init, /* Process init, can be null */
|
||||
process_finish, /* Process finish, can be null */
|
||||
NULL, /* Thread init */
|
||||
NULL, /* Thread finish */
|
||||
{
|
||||
/* Next is an array of MODULE_PARAM structs, max 64 items. These define all
|
||||
* the possible parameters that this module accepts. This is required
|
||||
@ -630,15 +652,15 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
* Note that many common parameters, such as backend servers, are
|
||||
* already set to the upper level "service"-object.
|
||||
*/
|
||||
{ /* For simple types, only 3 of the 5 struct fields need to be
|
||||
* defined. */
|
||||
MAX_BACKENDS, /* Setting identifier in maxscale.cnf */
|
||||
{ /* For simple types, only 3 of the 5 struct fields need to be
|
||||
* defined. */
|
||||
MAX_BACKENDS, /* Setting identifier in maxscale.cnf */
|
||||
MXS_MODULE_PARAM_INT, /* Setting type */
|
||||
"0" /* Default value */
|
||||
},
|
||||
{PRINT_ON_ROUTING, MXS_MODULE_PARAM_BOOL, "false"},
|
||||
{WRITE_BACKEND, MXS_MODULE_PARAM_SERVER, NULL},
|
||||
{ /* Enum types require an array with allowed values. */
|
||||
{PRINT_ON_ROUTING, MXS_MODULE_PARAM_BOOL, "false"},
|
||||
{WRITE_BACKEND, MXS_MODULE_PARAM_SERVER, NULL },
|
||||
{ /* Enum types require an array with allowed values. */
|
||||
DUMMY,
|
||||
MXS_MODULE_PARAM_ENUM,
|
||||
"the_answer",
|
||||
@ -673,9 +695,12 @@ static MXS_ROUTER* createInstance(SERVICE* service, MXS_CONFIG_PARAMETER* params
|
||||
* the pointer. */
|
||||
|
||||
/* Register a custom command */
|
||||
if (!modulecmd_register_command("rrrouter", "test_command",
|
||||
MODULECMD_TYPE_ACTIVE, custom_cmd_example,
|
||||
2, custom_cmd_args,
|
||||
if (!modulecmd_register_command("rrrouter",
|
||||
"test_command",
|
||||
MODULECMD_TYPE_ACTIVE,
|
||||
custom_cmd_example,
|
||||
2,
|
||||
custom_cmd_args,
|
||||
"This is the command description"))
|
||||
{
|
||||
MXS_ERROR("Module command registration failed.");
|
||||
@ -804,8 +829,10 @@ static json_t* diagnostics_json(const MXS_ROUTER* instance)
|
||||
* @param backend_dcb The backend DCB (data source)
|
||||
* @param queue The GWBUF with reply data
|
||||
*/
|
||||
static void clientReply(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* queue,
|
||||
DCB* backend_dcb)
|
||||
static void clientReply(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* session,
|
||||
GWBUF* queue,
|
||||
DCB* backend_dcb)
|
||||
{
|
||||
RRRouter* router = static_cast<RRRouter*>(instance);
|
||||
RRRouterSession* rses = static_cast<RRRouterSession*>(session);
|
||||
@ -826,9 +853,12 @@ static void clientReply(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF
|
||||
* @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT
|
||||
* @param succp Output result of action, true if router can continue
|
||||
*/
|
||||
static void handleError(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session,
|
||||
GWBUF* message, DCB* problem_dcb,
|
||||
mxs_error_action_t action, bool* succp)
|
||||
static void handleError(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* session,
|
||||
GWBUF* message,
|
||||
DCB* problem_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp)
|
||||
{
|
||||
RRRouter* router = static_cast<RRRouter*>(instance);
|
||||
RRRouterSession* rses = static_cast<RRRouterSession*>(session);
|
||||
@ -845,7 +875,7 @@ static void handleError(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session,
|
||||
* @param instance The router instance
|
||||
* @return RCAP_TYPE_CONTIGUOUS_INPUT | RCAP_TYPE_STMT_OUTPUT
|
||||
*/
|
||||
static uint64_t getCapabilities(MXS_ROUTER *instance)
|
||||
static uint64_t getCapabilities(MXS_ROUTER* instance)
|
||||
{
|
||||
/* This router needs to parse client queries, so it should set RCAP_TYPE_CONTIGUOUS_INPUT.
|
||||
* For output, parsing is not required but counting SQL replies is. RCAP_TYPE_RESULTSET_OUTPUT
|
||||
@ -891,7 +921,7 @@ static void process_finish()
|
||||
* A function executed as a custom module command through MaxAdmin
|
||||
* @param argv The arguments
|
||||
*/
|
||||
bool custom_cmd_example(const MODULECMD_ARG *argv, json_t** output)
|
||||
bool custom_cmd_example(const MODULECMD_ARG* argv, json_t** output)
|
||||
{
|
||||
cout << MXS_MODULE_NAME << " wishes the Admin a good day.\n";
|
||||
int n_args = argv->argc;
|
||||
@ -909,12 +939,14 @@ bool custom_cmd_example(const MODULECMD_ARG *argv, json_t** output)
|
||||
val_str.assign(node.value.string);
|
||||
}
|
||||
break;
|
||||
|
||||
case MODULECMD_ARG_BOOLEAN:
|
||||
{
|
||||
type_str = "boolean";
|
||||
val_str.assign((node.value.boolean) ? "true" : "false");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
type_str = "other";
|
||||
@ -922,8 +954,8 @@ bool custom_cmd_example(const MODULECMD_ARG *argv, json_t** output)
|
||||
}
|
||||
break;
|
||||
}
|
||||
cout << "Argument " << i << ": type '" << type_str << "' value '" << val_str <<
|
||||
"'\n";
|
||||
cout << "Argument " << i << ": type '" << type_str << "' value '" << val_str
|
||||
<< "'\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -29,24 +29,26 @@
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
static MXS_FILTER *createInstance(const char *name, MXS_CONFIG_PARAMETER *params);
|
||||
static MXS_FILTER_SESSION *newSession(MXS_FILTER *instance, MXS_SESSION *session);
|
||||
static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
|
||||
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
|
||||
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
|
||||
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
|
||||
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
|
||||
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
|
||||
static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params);
|
||||
static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session);
|
||||
static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session);
|
||||
static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session);
|
||||
static void setDownstream(MXS_FILTER* instance,
|
||||
MXS_FILTER_SESSION* fsession,
|
||||
MXS_DOWNSTREAM* downstream);
|
||||
static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, GWBUF* queue);
|
||||
static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb);
|
||||
static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESSION* fsession);
|
||||
static uint64_t getCapabilities(MXS_FILTER* instance);
|
||||
static void destroyInstance(MXS_FILTER *instance);
|
||||
static void destroyInstance(MXS_FILTER* instance);
|
||||
|
||||
/**
|
||||
* A dummy instance structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
int sessions;
|
||||
const char* name;
|
||||
int sessions;
|
||||
} TEST_INSTANCE;
|
||||
|
||||
/**
|
||||
@ -55,7 +57,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
MXS_DOWNSTREAM down;
|
||||
int count;
|
||||
int count;
|
||||
} TEST_SESSION;
|
||||
|
||||
/**
|
||||
@ -75,9 +77,9 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
closeSession,
|
||||
freeSession,
|
||||
setDownstream,
|
||||
NULL, // No upstream requirement
|
||||
NULL, // No upstream requirement
|
||||
routeQuery,
|
||||
NULL, // No clientReply
|
||||
NULL, // No clientReply
|
||||
diagnostic,
|
||||
diagnostic_json,
|
||||
getCapabilities,
|
||||
@ -93,10 +95,10 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
"V2.0.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
@ -115,17 +117,16 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
*
|
||||
* @return The instance data for this new instance
|
||||
*/
|
||||
static MXS_FILTER *
|
||||
createInstance(const char *name, MXS_CONFIG_PARAMETER *params)
|
||||
static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params)
|
||||
{
|
||||
TEST_INSTANCE *my_instance;
|
||||
TEST_INSTANCE* my_instance;
|
||||
|
||||
if ((my_instance = MXS_CALLOC(1, sizeof(TEST_INSTANCE))) != NULL)
|
||||
{
|
||||
my_instance->sessions = 0;
|
||||
my_instance->name = name;
|
||||
}
|
||||
return (MXS_FILTER *)my_instance;
|
||||
return (MXS_FILTER*)my_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,11 +136,10 @@ createInstance(const char *name, MXS_CONFIG_PARAMETER *params)
|
||||
* @param session The session itself
|
||||
* @return Session specific data for this session
|
||||
*/
|
||||
static MXS_FILTER_SESSION *
|
||||
newSession(MXS_FILTER *instance, MXS_SESSION *session)
|
||||
static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session)
|
||||
{
|
||||
TEST_INSTANCE *my_instance = (TEST_INSTANCE *)instance;
|
||||
TEST_SESSION *my_session;
|
||||
TEST_INSTANCE* my_instance = (TEST_INSTANCE*)instance;
|
||||
TEST_SESSION* my_session;
|
||||
|
||||
if ((my_session = MXS_CALLOC(1, sizeof(TEST_SESSION))) != NULL)
|
||||
{
|
||||
@ -157,8 +157,7 @@ newSession(MXS_FILTER *instance, MXS_SESSION *session)
|
||||
* @param instance The filter instance data
|
||||
* @param session The session being closed
|
||||
*/
|
||||
static void
|
||||
closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
||||
static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
|
||||
{
|
||||
}
|
||||
|
||||
@ -168,8 +167,7 @@ closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
||||
* @param instance The filter instance data
|
||||
* @param session The session being closed
|
||||
*/
|
||||
static void
|
||||
freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
||||
static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
|
||||
{
|
||||
MXS_FREE(session);
|
||||
}
|
||||
@ -181,10 +179,9 @@ freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
||||
* @param session The session being closed
|
||||
* @param downstream The downstream filter or router
|
||||
*/
|
||||
static void
|
||||
setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *session, MXS_DOWNSTREAM *downstream)
|
||||
static void setDownstream(MXS_FILTER* instance, MXS_FILTER_SESSION* session, MXS_DOWNSTREAM* downstream)
|
||||
{
|
||||
TEST_SESSION *my_session = (TEST_SESSION *)session;
|
||||
TEST_SESSION* my_session = (TEST_SESSION*)session;
|
||||
|
||||
my_session->down = *downstream;
|
||||
}
|
||||
@ -199,17 +196,17 @@ setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *session, MXS_DOWNSTREAM
|
||||
* @param session The filter session
|
||||
* @param queue The query data
|
||||
*/
|
||||
static int
|
||||
routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
|
||||
static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue)
|
||||
{
|
||||
TEST_SESSION *my_session = (TEST_SESSION *)session;
|
||||
TEST_SESSION* my_session = (TEST_SESSION*)session;
|
||||
|
||||
if (modutil_is_SQL(queue))
|
||||
{
|
||||
my_session->count++;
|
||||
}
|
||||
return my_session->down.routeQuery(my_session->down.instance,
|
||||
my_session->down.session, queue);
|
||||
my_session->down.session,
|
||||
queue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,18 +220,23 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
|
||||
* @param fsession Filter session, may be NULL
|
||||
* @param dcb The DCB for diagnostic output
|
||||
*/
|
||||
static void
|
||||
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
|
||||
static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb)
|
||||
{
|
||||
TEST_INSTANCE *my_instance = (TEST_INSTANCE *)instance;
|
||||
TEST_SESSION *my_session = (TEST_SESSION *)fsession;
|
||||
TEST_INSTANCE* my_instance = (TEST_INSTANCE*)instance;
|
||||
TEST_SESSION* my_session = (TEST_SESSION*)fsession;
|
||||
|
||||
if (my_session)
|
||||
dcb_printf(dcb, "\t\tNo. of queries routed by filter: %d\n",
|
||||
{
|
||||
dcb_printf(dcb,
|
||||
"\t\tNo. of queries routed by filter: %d\n",
|
||||
my_session->count);
|
||||
}
|
||||
else
|
||||
dcb_printf(dcb, "\t\tNo. of sessions created: %d\n",
|
||||
{
|
||||
dcb_printf(dcb,
|
||||
"\t\tNo. of sessions created: %d\n",
|
||||
my_instance->sessions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -248,7 +250,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
|
||||
* @param fsession Filter session, may be NULL
|
||||
* @param dcb The DCB for diagnostic output
|
||||
*/
|
||||
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
|
||||
static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESSION* fsession)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -268,9 +270,9 @@ static uint64_t getCapabilities(MXS_FILTER* instance)
|
||||
*
|
||||
* @param The filter instance.
|
||||
*/
|
||||
static void destroyInstance(MXS_FILTER *instance)
|
||||
static void destroyInstance(MXS_FILTER* instance)
|
||||
{
|
||||
TEST_INSTANCE *cinstance = (TEST_INSTANCE *)instance;
|
||||
TEST_INSTANCE* cinstance = (TEST_INSTANCE*)instance;
|
||||
|
||||
MXS_INFO("Destroying filter %s", cinstance->name);
|
||||
}
|
||||
|
@ -34,51 +34,51 @@ static int test_read(DCB* dcb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_write(DCB *dcb, GWBUF* buf)
|
||||
static int test_write(DCB* dcb, GWBUF* buf)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_write_ready(DCB *dcb)
|
||||
static int test_write_ready(DCB* dcb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_error(DCB *dcb)
|
||||
static int test_error(DCB* dcb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_hangup(DCB *dcb)
|
||||
static int test_hangup(DCB* dcb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_accept(DCB *dcb)
|
||||
static int test_accept(DCB* dcb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_connect(struct dcb *dcb, struct server *srv, struct session *ses)
|
||||
static int test_connect(struct dcb* dcb, struct server* srv, struct session* ses)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_close(DCB *dcb)
|
||||
static int test_close(DCB* dcb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_listen(DCB *dcb, char *config)
|
||||
static int test_listen(DCB* dcb, char* config)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_auth(DCB* dcb, struct server *srv, struct session *ses, GWBUF *buf)
|
||||
static int test_auth(DCB* dcb, struct server* srv, struct session* ses, GWBUF* buf)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int test_session(DCB *dcb, void* data)
|
||||
static int test_session(DCB* dcb, void* data)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static char *test_default_auth()
|
||||
static char* test_default_auth()
|
||||
{
|
||||
return "NullAuthAllow";
|
||||
}
|
||||
static int test_connection_limit(DCB *dcb, int limit)
|
||||
static int test_connection_limit(DCB* dcb, int limit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -95,18 +95,18 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
static MXS_PROTOCOL MyObject =
|
||||
{
|
||||
test_read, /**< Read - EPOLLIN handler */
|
||||
test_write, /**< Write - data from gateway */
|
||||
test_write_ready, /**< WriteReady - EPOLLOUT handler */
|
||||
test_error, /**< Error - EPOLLERR handler */
|
||||
test_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
test_accept, /**< Accept */
|
||||
test_connect, /**< Connect */
|
||||
test_close, /**< Close */
|
||||
test_listen, /**< Create a listener */
|
||||
test_auth, /**< Authentication */
|
||||
test_default_auth, /**< Default authenticator */
|
||||
test_connection_limit, /**< Connection limit */
|
||||
test_read, /**< Read - EPOLLIN handler */
|
||||
test_write, /**< Write - data from gateway */
|
||||
test_write_ready, /**< WriteReady - EPOLLOUT handler */
|
||||
test_error, /**< Error - EPOLLERR handler */
|
||||
test_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
test_accept, /**< Accept */
|
||||
test_connect, /**< Connect */
|
||||
test_close, /**< Close */
|
||||
test_listen, /**< Create a listener */
|
||||
test_auth, /**< Authentication */
|
||||
test_default_auth, /**< Default authenticator */
|
||||
test_connection_limit, /**< Connection limit */
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@ -120,10 +120,10 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
"V1.1.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
|
@ -15,21 +15,21 @@
|
||||
#include <maxscale/router.h>
|
||||
#include <maxscale/modinfo.h>
|
||||
|
||||
static MXS_ROUTER *createInstance(SERVICE *service, MXS_CONFIG_PARAMETER* params);
|
||||
static MXS_ROUTER_SESSION *newSession(MXS_ROUTER *instance, MXS_SESSION *session);
|
||||
static void closeSession(MXS_ROUTER *instance, MXS_ROUTER_SESSION *session);
|
||||
static void freeSession(MXS_ROUTER *instance, MXS_ROUTER_SESSION *session);
|
||||
static int routeQuery(MXS_ROUTER *instance, MXS_ROUTER_SESSION *session, GWBUF *queue);
|
||||
static void clientReply(MXS_ROUTER *instance, MXS_ROUTER_SESSION *session, GWBUF *queue, DCB*);
|
||||
static void diagnostic(MXS_ROUTER *instance, DCB *dcb);
|
||||
static json_t* diagnostic_json(const MXS_ROUTER *instance);
|
||||
static uint64_t getCapabilities(MXS_ROUTER* instance);
|
||||
static void handleError(MXS_ROUTER *instance,
|
||||
MXS_ROUTER_SESSION *router_session,
|
||||
GWBUF *errbuf,
|
||||
DCB *backend_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool *succp);
|
||||
static MXS_ROUTER* createInstance(SERVICE* service, MXS_CONFIG_PARAMETER* params);
|
||||
static MXS_ROUTER_SESSION* newSession(MXS_ROUTER* instance, MXS_SESSION* session);
|
||||
static void closeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session);
|
||||
static void freeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session);
|
||||
static int routeQuery(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* queue);
|
||||
static void clientReply(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* queue, DCB*);
|
||||
static void diagnostic(MXS_ROUTER* instance, DCB* dcb);
|
||||
static json_t* diagnostic_json(const MXS_ROUTER* instance);
|
||||
static uint64_t getCapabilities(MXS_ROUTER* instance);
|
||||
static void handleError(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* errbuf,
|
||||
DCB* backend_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -73,10 +73,10 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
"V1.0.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
@ -94,7 +94,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
*
|
||||
* @return The instance data for this new instance
|
||||
*/
|
||||
static MXS_ROUTER* createInstance(SERVICE *service, MXS_CONFIG_PARAMETER* params)
|
||||
static MXS_ROUTER* createInstance(SERVICE* service, MXS_CONFIG_PARAMETER* params)
|
||||
{
|
||||
return (MXS_ROUTER*)MXS_MALLOC(sizeof(TESTROUTER));
|
||||
}
|
||||
@ -106,8 +106,7 @@ static MXS_ROUTER* createInstance(SERVICE *service, MXS_CONFIG_PARAMETER* params
|
||||
* @param session The session itself
|
||||
* @return Session specific data for this session
|
||||
*/
|
||||
static MXS_ROUTER_SESSION *
|
||||
newSession(MXS_ROUTER *instance, MXS_SESSION *session)
|
||||
static MXS_ROUTER_SESSION* newSession(MXS_ROUTER* instance, MXS_SESSION* session)
|
||||
{
|
||||
return (MXS_ROUTER_SESSION*)MXS_MALLOC(sizeof(TESTSESSION));
|
||||
}
|
||||
@ -119,8 +118,7 @@ newSession(MXS_ROUTER *instance, MXS_SESSION *session)
|
||||
* @param instance The router instance data
|
||||
* @param session The session being closed
|
||||
*/
|
||||
static void
|
||||
closeSession(MXS_ROUTER *instance, MXS_ROUTER_SESSION *session)
|
||||
static void closeSession(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session)
|
||||
{
|
||||
}
|
||||
|
||||
@ -130,8 +128,7 @@ static void freeSession(MXS_ROUTER* router_instance,
|
||||
MXS_FREE(router_client_session);
|
||||
}
|
||||
|
||||
static int
|
||||
routeQuery(MXS_ROUTER *instance, MXS_ROUTER_SESSION *session, GWBUF *queue)
|
||||
static int routeQuery(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* queue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -146,8 +143,7 @@ void clientReply(MXS_ROUTER* instance, MXS_ROUTER_SESSION* session, GWBUF* queue
|
||||
* @param instance The router instance
|
||||
* @param dcb The DCB for diagnostic output
|
||||
*/
|
||||
static void
|
||||
diagnostic(MXS_ROUTER *instance, DCB *dcb)
|
||||
static void diagnostic(MXS_ROUTER* instance, DCB* dcb)
|
||||
{
|
||||
}
|
||||
|
||||
@ -157,7 +153,7 @@ diagnostic(MXS_ROUTER *instance, DCB *dcb)
|
||||
* @param instance The router instance
|
||||
* @param dcb The DCB for diagnostic output
|
||||
*/
|
||||
static json_t* diagnostic_json(const MXS_ROUTER *instance)
|
||||
static json_t* diagnostic_json(const MXS_ROUTER* instance)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -168,11 +164,11 @@ static uint64_t getCapabilities(MXS_ROUTER* instance)
|
||||
}
|
||||
|
||||
|
||||
static void handleError(MXS_ROUTER *instance,
|
||||
MXS_ROUTER_SESSION *router_session,
|
||||
GWBUF *errbuf,
|
||||
DCB *backend_dcb,
|
||||
static void handleError(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* errbuf,
|
||||
DCB* backend_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool *succp)
|
||||
bool* succp)
|
||||
{
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <stdlib.h>
|
||||
@ -25,31 +25,31 @@ MXS_BEGIN_DECLS
|
||||
// "caller" arg temporarily disabled so that existing code
|
||||
// using the previous version of mxs_alloc etc. will continue
|
||||
// to compile.
|
||||
void *mxs_malloc(size_t size/*, const char *caller*/);
|
||||
void *mxs_calloc(size_t nmemb, size_t size/*, const char *caller*/);
|
||||
void *mxs_realloc(void *ptr, size_t size/*, const char *caller*/);
|
||||
void mxs_free(void *ptr/*, const char *caller*/);
|
||||
void* mxs_malloc(size_t size /*, const char *caller*/);
|
||||
void* mxs_calloc(size_t nmemb, size_t size /*, const char *caller*/);
|
||||
void* mxs_realloc(void* ptr, size_t size /*, const char *caller*/);
|
||||
void mxs_free(void* ptr /*, const char *caller*/);
|
||||
|
||||
char *mxs_strdup(const char *s/*, const char *caller*/);
|
||||
char *mxs_strndup(const char *s, size_t n/*, const char *caller*/);
|
||||
char* mxs_strdup(const char* s /*, const char *caller*/);
|
||||
char* mxs_strndup(const char* s, size_t n /*, const char *caller*/);
|
||||
|
||||
char *mxs_strdup_a(const char *s/*, const char *caller*/);
|
||||
char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/);
|
||||
char* mxs_strdup_a(const char* s /*, const char *caller*/);
|
||||
char* mxs_strndup_a(const char* s, size_t n /*, const char *caller*/);
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: USE these macros instead of the functions above.
|
||||
*/
|
||||
#define MXS_MALLOC(size) mxs_malloc(size/*, __func__*/)
|
||||
#define MXS_CALLOC(nmemb, size) mxs_calloc(nmemb, size/*, __func__*/)
|
||||
#define MXS_REALLOC(ptr, size) mxs_realloc(ptr, size/*, __func__*/)
|
||||
#define MXS_FREE(ptr) mxs_free(ptr/*, __func__*/)
|
||||
#define MXS_MALLOC(size) mxs_malloc(size /*, __func__*/)
|
||||
#define MXS_CALLOC(nmemb, size) mxs_calloc(nmemb, size /*, __func__*/)
|
||||
#define MXS_REALLOC(ptr, size) mxs_realloc(ptr, size /*, __func__*/)
|
||||
#define MXS_FREE(ptr) mxs_free(ptr /*, __func__*/)
|
||||
|
||||
#define MXS_STRDUP(s) mxs_strdup(s/*, __func__*/)
|
||||
#define MXS_STRNDUP(s, n) mxs_strndup(s, n/*, __func__*/)
|
||||
#define MXS_STRDUP(s) mxs_strdup(s /*, __func__*/)
|
||||
#define MXS_STRNDUP(s, n) mxs_strndup(s, n /*, __func__*/)
|
||||
|
||||
#define MXS_STRDUP_A(s) mxs_strdup_a(s/*, __func__*/)
|
||||
#define MXS_STRNDUP_A(s, n) mxs_strndup_a(s, n/*, __func__*/)
|
||||
#define MXS_STRDUP_A(s) mxs_strdup_a(s /*, __func__*/)
|
||||
#define MXS_STRNDUP_A(s, n) mxs_strndup_a(s, n /*, __func__*/)
|
||||
|
||||
|
||||
/**
|
||||
@ -58,7 +58,7 @@ char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/);
|
||||
* To be used in circumstances where a memory allocation failure
|
||||
* cannot - currently - be dealt with properly.
|
||||
*/
|
||||
#define MXS_ABORT_IF_NULL(p) do { if (!p) { abort(); } } while (false)
|
||||
#define MXS_ABORT_IF_NULL(p) do {if (!p) {abort();}} while (false)
|
||||
|
||||
/**
|
||||
* @brief Abort the process if the provided value is non-zero.
|
||||
@ -66,7 +66,7 @@ char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/);
|
||||
* To be used in circumstances where a memory allocation or other
|
||||
* fatal error cannot - currently - be dealt with properly.
|
||||
*/
|
||||
#define MXS_ABORT_IF_TRUE(b) do { if (b) { abort(); } } while (false)
|
||||
#define MXS_ABORT_IF_TRUE(b) do {if (b) {abort();}} while (false)
|
||||
|
||||
/**
|
||||
* @brief Abort the process if the provided value is zero.
|
||||
@ -74,6 +74,6 @@ char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/);
|
||||
* To be used in circumstances where a memory allocation or other
|
||||
* fatal error cannot - currently - be dealt with properly.
|
||||
*/
|
||||
#define MXS_ABORT_IF_FALSE(b) do { if (!b) { abort(); } } while (false)
|
||||
#define MXS_ABORT_IF_FALSE(b) do {if (!b) {abort();}} while (false)
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file authenticator.h
|
||||
@ -35,7 +35,7 @@ MXS_BEGIN_DECLS
|
||||
*/
|
||||
typedef enum authenticator_capability
|
||||
{
|
||||
ACAP_TYPE_ASYNC = 0x000100000000/**< Supports asynchronous access */
|
||||
ACAP_TYPE_ASYNC = 0x000100000000 /**< Supports asynchronous access */
|
||||
} authenticator_capability_t;
|
||||
|
||||
/** Maximum number of authenticator options */
|
||||
@ -89,15 +89,15 @@ struct servlistener;
|
||||
*/
|
||||
typedef struct mxs_authenticator
|
||||
{
|
||||
void* (*initialize)(char **options);
|
||||
void* (*initialize)(char** options);
|
||||
void* (*create)(void* instance);
|
||||
bool (*extract)(struct dcb *, GWBUF *);
|
||||
bool (*connectssl)(struct dcb *);
|
||||
int (*authenticate)(struct dcb *);
|
||||
void (*free)(struct dcb *);
|
||||
void (*destroy)(void *);
|
||||
int (*loadusers)(struct servlistener *);
|
||||
void (*diagnostic)(struct dcb*, struct servlistener *);
|
||||
bool (* extract)(struct dcb*, GWBUF*);
|
||||
bool (* connectssl)(struct dcb*);
|
||||
int (* authenticate)(struct dcb*);
|
||||
void (* free)(struct dcb*);
|
||||
void (* destroy)(void*);
|
||||
int (* loadusers)(struct servlistener*);
|
||||
void (* diagnostic)(struct dcb*, struct servlistener*);
|
||||
|
||||
/**
|
||||
* @brief Return diagnostic information about the authenticator
|
||||
@ -111,32 +111,38 @@ typedef struct mxs_authenticator
|
||||
*
|
||||
* @see jansson.h
|
||||
*/
|
||||
json_t* (*diagnostic_json)(const struct servlistener *listener);
|
||||
json_t* (*diagnostic_json)(const struct servlistener* listener);
|
||||
|
||||
/** This entry point was added to avoid calling authenticator functions
|
||||
* directly when a COM_CHANGE_USER command is executed. */
|
||||
int (*reauthenticate)(struct dcb *, const char *user,
|
||||
uint8_t *token, size_t token_len, /**< Client auth token */
|
||||
uint8_t *scramble, size_t scramble_len, /**< Scramble sent by MaxScale to client */
|
||||
uint8_t *output, size_t output_len); /**< Hashed client password used by backend protocols */
|
||||
int (* reauthenticate)(struct dcb*,
|
||||
const char* user,
|
||||
uint8_t* token,
|
||||
size_t token_len, /**< Client auth token */
|
||||
uint8_t* scramble,
|
||||
size_t scramble_len, /**< Scramble sent by MaxScale to client
|
||||
* */
|
||||
uint8_t* output,
|
||||
size_t output_len); /**< Hashed client password used by backend
|
||||
* protocols */
|
||||
} MXS_AUTHENTICATOR;
|
||||
|
||||
/** Return values for extract and authenticate entry points */
|
||||
#define MXS_AUTH_SUCCEEDED 0 /**< Authentication was successful */
|
||||
#define MXS_AUTH_FAILED 1 /**< Authentication failed */
|
||||
#define MXS_AUTH_FAILED_DB 2 /**< Authentication failed, database not found */
|
||||
#define MXS_AUTH_FAILED_SSL 3 /**< SSL authentication failed */
|
||||
#define MXS_AUTH_INCOMPLETE 4 /**< Authentication is not yet complete */
|
||||
#define MXS_AUTH_SSL_INCOMPLETE 5 /**< SSL connection is not yet complete */
|
||||
#define MXS_AUTH_SSL_COMPLETE 6 /**< SSL connection complete or not required */
|
||||
#define MXS_AUTH_NO_SESSION 7
|
||||
#define MXS_AUTH_BAD_HANDSHAKE 8 /**< Malformed client packet */
|
||||
#define MXS_AUTH_FAILED_WRONG_PASSWORD 9 /**< Client provided wrong password */
|
||||
#define MXS_AUTH_SUCCEEDED 0/**< Authentication was successful */
|
||||
#define MXS_AUTH_FAILED 1/**< Authentication failed */
|
||||
#define MXS_AUTH_FAILED_DB 2/**< Authentication failed, database not found */
|
||||
#define MXS_AUTH_FAILED_SSL 3/**< SSL authentication failed */
|
||||
#define MXS_AUTH_INCOMPLETE 4/**< Authentication is not yet complete */
|
||||
#define MXS_AUTH_SSL_INCOMPLETE 5/**< SSL connection is not yet complete */
|
||||
#define MXS_AUTH_SSL_COMPLETE 6/**< SSL connection complete or not required */
|
||||
#define MXS_AUTH_NO_SESSION 7
|
||||
#define MXS_AUTH_BAD_HANDSHAKE 8/**< Malformed client packet */
|
||||
#define MXS_AUTH_FAILED_WRONG_PASSWORD 9/**< Client provided wrong password */
|
||||
|
||||
/** Return values for the loadusers entry point */
|
||||
#define MXS_AUTH_LOADUSERS_OK 0 /**< Users loaded successfully */
|
||||
#define MXS_AUTH_LOADUSERS_ERROR 1 /**< Temporary error, service is started */
|
||||
#define MXS_AUTH_LOADUSERS_FATAL 2 /**< Fatal error, service is not started */
|
||||
#define MXS_AUTH_LOADUSERS_OK 0 /**< Users loaded successfully */
|
||||
#define MXS_AUTH_LOADUSERS_ERROR 1 /**< Temporary error, service is started */
|
||||
#define MXS_AUTH_LOADUSERS_FATAL 2 /**< Fatal error, service is not started */
|
||||
|
||||
/**
|
||||
* Authentication states
|
||||
@ -151,35 +157,64 @@ typedef struct mxs_authenticator
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MXS_AUTH_STATE_INIT, /**< Initial authentication state */
|
||||
MXS_AUTH_STATE_PENDING_CONNECT,/**< Connection creation is underway */
|
||||
MXS_AUTH_STATE_CONNECTED, /**< Network connection to server created */
|
||||
MXS_AUTH_STATE_MESSAGE_READ, /**< Read a authentication message from the server */
|
||||
MXS_AUTH_STATE_RESPONSE_SENT, /**< Responded to the read authentication message */
|
||||
MXS_AUTH_STATE_FAILED, /**< Authentication failed */
|
||||
MXS_AUTH_STATE_HANDSHAKE_FAILED, /**< Authentication failed immediately */
|
||||
MXS_AUTH_STATE_COMPLETE /**< Authentication is complete */
|
||||
MXS_AUTH_STATE_INIT, /**< Initial authentication state */
|
||||
MXS_AUTH_STATE_PENDING_CONNECT, /**< Connection creation is underway */
|
||||
MXS_AUTH_STATE_CONNECTED, /**< Network connection to server created */
|
||||
MXS_AUTH_STATE_MESSAGE_READ, /**< Read a authentication message from the server */
|
||||
MXS_AUTH_STATE_RESPONSE_SENT, /**< Responded to the read authentication message */
|
||||
MXS_AUTH_STATE_FAILED, /**< Authentication failed */
|
||||
MXS_AUTH_STATE_HANDSHAKE_FAILED,/**< Authentication failed immediately */
|
||||
MXS_AUTH_STATE_COMPLETE /**< Authentication is complete */
|
||||
} mxs_auth_state_t;
|
||||
|
||||
#define STRPROTOCOLSTATE(s) ((s) == MXS_AUTH_STATE_INIT ? "MXS_AUTH_STATE_INIT" : \
|
||||
((s) == MXS_AUTH_STATE_PENDING_CONNECT ? "MXS_AUTH_STATE_PENDING_CONNECT" : \
|
||||
((s) == MXS_AUTH_STATE_CONNECTED ? "MXS_AUTH_STATE_CONNECTED" : \
|
||||
((s) == MXS_AUTH_STATE_MESSAGE_READ ? "MXS_AUTH_STATE_MESSAGE_READ" : \
|
||||
((s) == MXS_AUTH_STATE_RESPONSE_SENT ? "MXS_AUTH_STATE_RESPONSE_SENT" : \
|
||||
((s) == MXS_AUTH_STATE_FAILED ? "MXS_AUTH_STATE_FAILED" : \
|
||||
((s) == MXS_AUTH_STATE_HANDSHAKE_FAILED ? "MXS_AUTH_STATE_HANDSHAKE_FAILED" : \
|
||||
((s) == MXS_AUTH_STATE_COMPLETE ? "MXS_AUTH_STATE_COMPLETE" : \
|
||||
"UNKNOWN AUTH STATE"))))))))
|
||||
#define STRPROTOCOLSTATE(s) \
|
||||
((s) == MXS_AUTH_STATE_INIT ? "MXS_AUTH_STATE_INIT" \
|
||||
: ((s) == MXS_AUTH_STATE_PENDING_CONNECT ? "MXS_AUTH_STATE_PENDING_CONNECT" \
|
||||
: ((s) \
|
||||
== MXS_AUTH_STATE_CONNECTED ? \
|
||||
"MXS_AUTH_STATE_CONNECTED" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
MXS_AUTH_STATE_MESSAGE_READ \
|
||||
? \
|
||||
"MXS_AUTH_STATE_MESSAGE_READ" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
MXS_AUTH_STATE_RESPONSE_SENT \
|
||||
? \
|
||||
"MXS_AUTH_STATE_RESPONSE_SENT" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
MXS_AUTH_STATE_FAILED \
|
||||
? \
|
||||
"MXS_AUTH_STATE_FAILED" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
MXS_AUTH_STATE_HANDSHAKE_FAILED \
|
||||
? \
|
||||
"MXS_AUTH_STATE_HANDSHAKE_FAILED" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
MXS_AUTH_STATE_COMPLETE \
|
||||
? \
|
||||
"MXS_AUTH_STATE_COMPLETE" \
|
||||
: \
|
||||
"UNKNOWN AUTH STATE"))))))))
|
||||
|
||||
/**
|
||||
* The MXS_AUTHENTICATOR version data. The following should be updated whenever
|
||||
* the MXS_AUTHENTICATOR structure is changed. See the rules defined in modinfo.h
|
||||
* that define how these numbers should change.
|
||||
*/
|
||||
#define MXS_AUTHENTICATOR_VERSION {2, 1, 0}
|
||||
#define MXS_AUTHENTICATOR_VERSION {2, 1, 0}
|
||||
|
||||
|
||||
bool authenticator_init(void **instance, const char *authenticator, const char *options);
|
||||
const char* get_default_authenticator(const char *protocol);
|
||||
bool authenticator_init(void** instance, const char* authenticator, const char* options);
|
||||
const char* get_default_authenticator(const char* protocol);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -29,7 +29,7 @@ namespace maxscale
|
||||
class Backend
|
||||
{
|
||||
Backend(const Backend&);
|
||||
Backend& operator =(const Backend&);
|
||||
Backend& operator=(const Backend&);
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -329,9 +329,9 @@ private:
|
||||
*/
|
||||
enum backend_state
|
||||
{
|
||||
IN_USE = 0x01, /**< Backend has been taken into use */
|
||||
WAITING_RESULT = 0x02, /**< Waiting for a reply */
|
||||
FATAL_FAILURE = 0x04 /**< Backend references that should be dropped */
|
||||
IN_USE = 0x01, /**< Backend has been taken into use */
|
||||
WAITING_RESULT = 0x02, /**< Waiting for a reply */
|
||||
FATAL_FAILURE = 0x04 /**< Backend references that should be dropped */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -349,16 +349,16 @@ private:
|
||||
void set_state(backend_state state);
|
||||
|
||||
|
||||
bool m_closed; /**< True if a connection has been opened and closed */
|
||||
SERVER_REF* m_backend; /**< Backend server */
|
||||
DCB* m_dcb; /**< Backend DCB */
|
||||
mxs::Buffer m_pending_cmd; /**< Pending commands */
|
||||
int m_state; /**< State of the backend */
|
||||
SessionCommandList m_session_commands; /**< List of session commands that are
|
||||
* to be executed on this backend server */
|
||||
std::string m_uri; /**< The combined address and port */
|
||||
bool m_closed; /**< True if a connection has been opened and closed */
|
||||
SERVER_REF* m_backend; /**< Backend server */
|
||||
DCB* m_dcb; /**< Backend DCB */
|
||||
mxs::Buffer m_pending_cmd; /**< Pending commands */
|
||||
int m_state; /**< State of the backend */
|
||||
SessionCommandList m_session_commands; /**< List of session commands that are
|
||||
* to be executed on this backend server */
|
||||
std::string m_uri; /**< The combined address and port */
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Backend> SBackend;
|
||||
typedef std::list<SBackend> BackendList;
|
||||
typedef std::list<SBackend> BackendList;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file buffer.h Definitions relating the gateway buffer manipulation facilities.
|
||||
@ -43,34 +43,34 @@ struct server;
|
||||
*/
|
||||
typedef struct buf_property
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
struct buf_property *next;
|
||||
char* name;
|
||||
char* value;
|
||||
struct buf_property* next;
|
||||
} BUF_PROPERTY;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_TYPE_UNDEFINED = 0,
|
||||
GWBUF_TYPE_HTTP = (1 << 0),
|
||||
GWBUF_TYPE_IGNORABLE = (1 << 1),
|
||||
GWBUF_TYPE_COLLECT_RESULT = (1 << 2),
|
||||
GWBUF_TYPE_RESULT = (1 << 3),
|
||||
GWBUF_TYPE_REPLY_OK = (1 << 4),
|
||||
GWBUF_TYPE_UNDEFINED = 0,
|
||||
GWBUF_TYPE_HTTP = (1 << 0),
|
||||
GWBUF_TYPE_IGNORABLE = (1 << 1),
|
||||
GWBUF_TYPE_COLLECT_RESULT = (1 << 2),
|
||||
GWBUF_TYPE_RESULT = (1 << 3),
|
||||
GWBUF_TYPE_REPLY_OK = (1 << 4),
|
||||
} gwbuf_type_t;
|
||||
|
||||
#define GWBUF_IS_TYPE_UNDEFINED(b) ((b)->gwbuf_type == 0)
|
||||
#define GWBUF_IS_IGNORABLE(b) ((b)->gwbuf_type & GWBUF_TYPE_IGNORABLE)
|
||||
#define GWBUF_IS_COLLECTED_RESULT(b) ((b)->gwbuf_type & GWBUF_TYPE_RESULT)
|
||||
#define GWBUF_SHOULD_COLLECT_RESULT(b) ((b)->gwbuf_type & GWBUF_TYPE_COLLECT_RESULT)
|
||||
#define GWBUF_IS_REPLY_OK(b) ((b)->gwbuf_type & GWBUF_TYPE_REPLY_OK)
|
||||
#define GWBUF_IS_TYPE_UNDEFINED(b) ((b)->gwbuf_type == 0)
|
||||
#define GWBUF_IS_IGNORABLE(b) ((b)->gwbuf_type & GWBUF_TYPE_IGNORABLE)
|
||||
#define GWBUF_IS_COLLECTED_RESULT(b) ((b)->gwbuf_type & GWBUF_TYPE_RESULT)
|
||||
#define GWBUF_SHOULD_COLLECT_RESULT(b) ((b)->gwbuf_type & GWBUF_TYPE_COLLECT_RESULT)
|
||||
#define GWBUF_IS_REPLY_OK(b) ((b)->gwbuf_type & GWBUF_TYPE_REPLY_OK)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_INFO_NONE = 0x0,
|
||||
GWBUF_INFO_PARSED = 0x1
|
||||
GWBUF_INFO_NONE = 0x0,
|
||||
GWBUF_INFO_PARSED = 0x1
|
||||
} gwbuf_info_t;
|
||||
|
||||
#define GWBUF_IS_PARSED(b) (b->sbuf->info & GWBUF_INFO_PARSED)
|
||||
#define GWBUF_IS_PARSED(b) (b->sbuf->info & GWBUF_INFO_PARSED)
|
||||
|
||||
/**
|
||||
* A structure for cleaning up memory allocations of structures which are
|
||||
@ -89,7 +89,7 @@ struct buffer_object_st
|
||||
{
|
||||
bufobj_id_t bo_id;
|
||||
void* bo_data;
|
||||
void (*bo_donefun_fp)(void *);
|
||||
void (* bo_donefun_fp)(void*);
|
||||
buffer_object_t* bo_next;
|
||||
};
|
||||
|
||||
@ -100,10 +100,10 @@ struct buffer_object_st
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
buffer_object_t *bufobj; /*< List of objects referred to by GWBUF */
|
||||
int32_t refcount; /*< Reference count on the buffer */
|
||||
uint32_t info; /*< Info bits */
|
||||
unsigned char data[1]; /*< Actual memory that was allocated */
|
||||
buffer_object_t* bufobj; /*< List of objects referred to by GWBUF */
|
||||
int32_t refcount; /*< Reference count on the buffer */
|
||||
uint32_t info; /*< Info bits */
|
||||
unsigned char data[1]; /*< Actual memory that was allocated */
|
||||
} SHARED_BUF;
|
||||
|
||||
/**
|
||||
@ -116,51 +116,55 @@ typedef struct
|
||||
*/
|
||||
typedef struct gwbuf
|
||||
{
|
||||
struct gwbuf *next; /*< Next buffer in a linked chain of buffers */
|
||||
struct gwbuf *tail; /*< Last buffer in a linked chain of buffers */
|
||||
void *start; /*< Start of the valid data */
|
||||
void *end; /*< First byte after the valid data */
|
||||
SHARED_BUF *sbuf; /*< The shared buffer with the real data */
|
||||
HINT *hint; /*< Hint data for this buffer */
|
||||
BUF_PROPERTY *properties; /*< Buffer properties */
|
||||
struct server *server; /*< The target server where the buffer is executed */
|
||||
uint32_t gwbuf_type; /*< buffer's data type information */
|
||||
struct gwbuf* next; /*< Next buffer in a linked chain of buffers */
|
||||
struct gwbuf* tail; /*< Last buffer in a linked chain of buffers */
|
||||
void* start; /*< Start of the valid data */
|
||||
void* end; /*< First byte after the valid data */
|
||||
SHARED_BUF* sbuf; /*< The shared buffer with the real data */
|
||||
HINT* hint; /*< Hint data for this buffer */
|
||||
BUF_PROPERTY* properties; /*< Buffer properties */
|
||||
struct server* server; /*< The target server where the buffer is executed */
|
||||
uint32_t gwbuf_type; /*< buffer's data type information */
|
||||
} GWBUF;
|
||||
|
||||
/*<
|
||||
* Macros to access the data in the buffers
|
||||
*/
|
||||
/*< First valid, unconsumed byte in the buffer */
|
||||
#define GWBUF_DATA(b) ((uint8_t*)(b)->start)
|
||||
#define GWBUF_DATA(b) ((uint8_t*)(b)->start)
|
||||
|
||||
/*< Number of bytes in the individual buffer */
|
||||
#define GWBUF_LENGTH(b) ((size_t)((char *)(b)->end - (char *)(b)->start))
|
||||
#define GWBUF_LENGTH(b) ((size_t)((char*)(b)->end - (char*)(b)->start))
|
||||
|
||||
/*< Return the byte at offset byte from the start of the unconsumed portion of the buffer */
|
||||
#define GWBUF_DATA_CHAR(b, byte) (GWBUF_LENGTH(b) < ((byte)+1) ? -1 : *(((char *)(b)->start)+4))
|
||||
#define GWBUF_DATA_CHAR(b, byte) (GWBUF_LENGTH(b) < ((byte) + 1) ? -1 : *(((char*)(b)->start) + 4))
|
||||
|
||||
/*< Check that the data in a buffer has the SQL marker*/
|
||||
#define GWBUF_IS_SQL(b) (0x03 == GWBUF_DATA_CHAR(b,4))
|
||||
#define GWBUF_IS_SQL(b) (0x03 == GWBUF_DATA_CHAR(b, 4))
|
||||
|
||||
/*< Check whether the buffer is contiguous*/
|
||||
#define GWBUF_IS_CONTIGUOUS(b) (((b) == NULL) || ((b)->next == NULL))
|
||||
|
||||
/*< True if all bytes in the buffer have been consumed */
|
||||
#define GWBUF_EMPTY(b) ((char *)(b)->start >= (char *)(b)->end)
|
||||
#define GWBUF_EMPTY(b) ((char*)(b)->start >= (char*)(b)->end)
|
||||
|
||||
/*< Consume a number of bytes in the buffer */
|
||||
#define GWBUF_CONSUME(b, bytes) ((b)->start = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->end : (void *)((char *)(b)->start + (bytes)));
|
||||
#define GWBUF_CONSUME(b, \
|
||||
bytes) ((b)->start = bytes \
|
||||
> ((char*)(b)->end \
|
||||
- (char*)(b)->start) ? (b)->end : (void*)((char*)(b)->start + (bytes)));
|
||||
|
||||
/*< Check if a given pointer is within the buffer */
|
||||
#define GWBUF_POINTER_IN_BUFFER (ptr, b)\
|
||||
((char *)(ptr) >= (char *)(b)->start && (char *)(ptr) < (char *)(b)->end)
|
||||
#define GWBUF_POINTER_IN_BUFFER \
|
||||
(ptr, b) \
|
||||
((char*)(ptr) >= (char*)(b)->start && (char*)(ptr) < (char*)(b)->end)
|
||||
|
||||
/*< Consume a complete buffer */
|
||||
#define GWBUF_CONSUME_ALL(b) gwbuf_consume((b), GWBUF_LENGTH((b)))
|
||||
#define GWBUF_CONSUME_ALL(b) gwbuf_consume((b), GWBUF_LENGTH((b)))
|
||||
|
||||
#define GWBUF_RTRIM(b, bytes)\
|
||||
((b)->end = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->start : \
|
||||
(void *)((char *)(b)->end - (bytes)));
|
||||
#define GWBUF_RTRIM(b, bytes) \
|
||||
((b)->end = bytes > ((char*)(b)->end - (char*)(b)->start) ? (b)->start \
|
||||
: (void*)((char*)(b)->end - (bytes)));
|
||||
|
||||
#define GWBUF_TYPE(b) (b)->gwbuf_type
|
||||
/*<
|
||||
@ -175,7 +179,7 @@ typedef struct gwbuf
|
||||
* @return Pointer to the buffer structure or NULL if memory could not
|
||||
* be allocated.
|
||||
*/
|
||||
extern GWBUF *gwbuf_alloc(unsigned int size);
|
||||
extern GWBUF* gwbuf_alloc(unsigned int size);
|
||||
|
||||
/**
|
||||
* Allocate a new gateway buffer structure of specified size and load with data.
|
||||
@ -186,14 +190,14 @@ extern GWBUF *gwbuf_alloc(unsigned int size);
|
||||
* @return Pointer to the buffer structure or NULL if memory could not
|
||||
* be allocated.
|
||||
*/
|
||||
extern GWBUF *gwbuf_alloc_and_load(unsigned int size, const void *data);
|
||||
extern GWBUF* gwbuf_alloc_and_load(unsigned int size, const void* data);
|
||||
|
||||
/**
|
||||
* Free a chain of gateway buffers
|
||||
*
|
||||
* @param buf The head of the list of buffers to free
|
||||
*/
|
||||
extern void gwbuf_free(GWBUF *buf);
|
||||
extern void gwbuf_free(GWBUF* buf);
|
||||
|
||||
/**
|
||||
* Clone a GWBUF. Note that if the GWBUF is actually a list of
|
||||
@ -205,7 +209,7 @@ extern void gwbuf_free(GWBUF *buf);
|
||||
* @return The cloned GWBUF, or NULL if @buf was NULL or if any part
|
||||
* of @buf could not be cloned.
|
||||
*/
|
||||
extern GWBUF *gwbuf_clone(GWBUF *buf);
|
||||
extern GWBUF* gwbuf_clone(GWBUF* buf);
|
||||
|
||||
/**
|
||||
* @brief Deep clone a GWBUF
|
||||
@ -253,7 +257,7 @@ extern int gwbuf_compare(const GWBUF* lhs, const GWBUF* rhs);
|
||||
*
|
||||
* @return The new head of the linked list
|
||||
*/
|
||||
extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail);
|
||||
extern GWBUF* gwbuf_append(GWBUF* head, GWBUF* tail);
|
||||
|
||||
/**
|
||||
* @brief Consume data from buffer chain
|
||||
@ -268,7 +272,7 @@ extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail);
|
||||
*
|
||||
* @return The head of the linked list or NULL if everything was consumed
|
||||
*/
|
||||
extern GWBUF *gwbuf_consume(GWBUF *head, unsigned int length);
|
||||
extern GWBUF* gwbuf_consume(GWBUF* head, unsigned int length);
|
||||
|
||||
/**
|
||||
* Trim bytes from the end of a GWBUF structure that may be the first
|
||||
@ -280,7 +284,7 @@ extern GWBUF *gwbuf_consume(GWBUF *head, unsigned int length);
|
||||
*
|
||||
* @return The buffer chain or NULL if buffer chain now empty
|
||||
*/
|
||||
extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length);
|
||||
extern GWBUF* gwbuf_rtrim(GWBUF* head, unsigned int length);
|
||||
|
||||
/**
|
||||
* Return the number of bytes of data in the linked list.
|
||||
@ -289,7 +293,7 @@ extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length);
|
||||
*
|
||||
* @return The number of bytes of data in the linked list
|
||||
*/
|
||||
extern unsigned int gwbuf_length(const GWBUF *head);
|
||||
extern unsigned int gwbuf_length(const GWBUF* head);
|
||||
|
||||
/**
|
||||
* Return the number of individual buffers in the linked list.
|
||||
@ -300,7 +304,7 @@ extern unsigned int gwbuf_length(const GWBUF *head);
|
||||
*
|
||||
* @return The number of bytes of data in the linked list
|
||||
*/
|
||||
extern int gwbuf_count(const GWBUF *head);
|
||||
extern int gwbuf_count(const GWBUF* head);
|
||||
|
||||
/**
|
||||
* @brief Copy bytes from a buffer
|
||||
@ -315,7 +319,7 @@ extern int gwbuf_count(const GWBUF *head);
|
||||
*
|
||||
* @return Number of bytes copied.
|
||||
*/
|
||||
extern size_t gwbuf_copy_data(const GWBUF *buffer, size_t offset, size_t bytes, uint8_t* dest);
|
||||
extern size_t gwbuf_copy_data(const GWBUF* buffer, size_t offset, size_t bytes, uint8_t* dest);
|
||||
|
||||
/**
|
||||
* @brief Split a buffer in two
|
||||
@ -328,7 +332,7 @@ extern size_t gwbuf_copy_data(const GWBUF *buffer, size_t offset, size_t bytes,
|
||||
*
|
||||
* @return Head of the buffer chain.
|
||||
*/
|
||||
extern GWBUF *gwbuf_split(GWBUF **buf, size_t length);
|
||||
extern GWBUF* gwbuf_split(GWBUF** buf, size_t length);
|
||||
|
||||
/**
|
||||
* Set given type to all buffers on the list.
|
||||
@ -336,7 +340,7 @@ extern GWBUF *gwbuf_split(GWBUF **buf, size_t length);
|
||||
* @param buf The shared buffer
|
||||
* @param type Type to be added, mask of @c gwbuf_type_t values.
|
||||
*/
|
||||
extern void gwbuf_set_type(GWBUF *head, uint32_t type);
|
||||
extern void gwbuf_set_type(GWBUF* head, uint32_t type);
|
||||
|
||||
/**
|
||||
* Add a property to a buffer.
|
||||
@ -347,7 +351,7 @@ extern void gwbuf_set_type(GWBUF *head, uint32_t type);
|
||||
*
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
extern bool gwbuf_add_property(GWBUF *buf, const char *name, const char *value);
|
||||
extern bool gwbuf_add_property(GWBUF* buf, const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* Return the value of a buffer property
|
||||
@ -357,7 +361,7 @@ extern bool gwbuf_add_property(GWBUF *buf, const char *name, const char *value);
|
||||
*
|
||||
* @return The property value or NULL if the property was not found.
|
||||
*/
|
||||
extern char *gwbuf_get_property(GWBUF *buf, const char *name);
|
||||
extern char* gwbuf_get_property(GWBUF* buf, const char* name);
|
||||
|
||||
/**
|
||||
* Convert a chain of GWBUF structures into a single GWBUF structure
|
||||
@ -368,7 +372,7 @@ extern char *gwbuf_get_property(GWBUF *buf, const char *name);
|
||||
*
|
||||
* @attention Never returns NULL, memory allocation failures abort the process
|
||||
*/
|
||||
extern GWBUF* gwbuf_make_contiguous(GWBUF *buf);
|
||||
extern GWBUF* gwbuf_make_contiguous(GWBUF* buf);
|
||||
|
||||
/**
|
||||
* Add a buffer object to GWBUF buffer.
|
||||
@ -380,8 +384,8 @@ extern GWBUF* gwbuf_make_contiguous(GWBUF *buf);
|
||||
*/
|
||||
void gwbuf_add_buffer_object(GWBUF* buf,
|
||||
bufobj_id_t id,
|
||||
void* data,
|
||||
void (*donefun_fp)(void *));
|
||||
void* data,
|
||||
void (* donefun_fp)(void*));
|
||||
|
||||
/**
|
||||
* Search buffer object which matches with the id.
|
||||
@ -391,9 +395,9 @@ void gwbuf_add_buffer_object(GWBUF* buf,
|
||||
*
|
||||
* @return Searched buffer object or NULL if not found
|
||||
*/
|
||||
void *gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id);
|
||||
#if defined(BUFFER_TRACE)
|
||||
extern void dprintAllBuffers(void *pdcb);
|
||||
void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id);
|
||||
#if defined (BUFFER_TRACE)
|
||||
extern void dprintAllBuffers(void* pdcb);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -414,6 +418,6 @@ void gwbuf_hexdump(GWBUF* buffer, int log_level);
|
||||
* @return if total buffer length is bigger than offset then return
|
||||
* the offset byte pointer, otherwise return null
|
||||
*/
|
||||
extern uint8_t *gwbuf_byte_pointer(GWBUF* buffer, size_t offset);
|
||||
extern uint8_t* gwbuf_byte_pointer(GWBUF* buffer, size_t offset);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <algorithm>
|
||||
@ -32,7 +32,6 @@ struct default_delete<GWBUF>
|
||||
gwbuf_free(pBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace maxscale
|
||||
@ -57,12 +56,12 @@ public:
|
||||
// pointer_type : The type of a pointer to an element, either "uint8_t*" or "const uint8_t*".
|
||||
// reference_type: The type of a reference to an element, either "uint8_t&" or "const uint8_t&".
|
||||
template<class buf_type, class pointer_type, class reference_type>
|
||||
class iterator_base : public std::iterator <
|
||||
std::forward_iterator_tag, // The type of the iterator
|
||||
uint8_t, // The type of the elems
|
||||
std::ptrdiff_t, // Difference between two its
|
||||
pointer_type, // The type of pointer to an elem
|
||||
reference_type > // The reference type of an elem
|
||||
class iterator_base : public std::iterator<
|
||||
std::forward_iterator_tag // The type of the iterator
|
||||
, uint8_t // The type of the elems
|
||||
, std::ptrdiff_t // Difference between two its
|
||||
, pointer_type // The type of pointer to an elem
|
||||
, reference_type> // The reference type of an elem
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -84,7 +83,8 @@ public:
|
||||
: m_pBuffer(pBuffer)
|
||||
, m_i(m_pBuffer ? GWBUF_DATA(m_pBuffer) : NULL)
|
||||
, m_end(m_pBuffer ? (m_i + GWBUF_LENGTH(m_pBuffer)) : NULL)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
void advance()
|
||||
{
|
||||
@ -140,7 +140,8 @@ public:
|
||||
public:
|
||||
explicit iterator(GWBUF* pBuffer = NULL)
|
||||
: iterator_base_typedef(pBuffer)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
iterator& operator++()
|
||||
{
|
||||
@ -155,12 +156,12 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool operator == (const iterator& rhs) const
|
||||
bool operator==(const iterator& rhs) const
|
||||
{
|
||||
return eq(rhs);
|
||||
}
|
||||
|
||||
bool operator != (const iterator& rhs) const
|
||||
bool operator!=(const iterator& rhs) const
|
||||
{
|
||||
return neq(rhs);
|
||||
}
|
||||
@ -183,11 +184,13 @@ public:
|
||||
public:
|
||||
explicit const_iterator(const GWBUF* pBuffer = NULL)
|
||||
: const_iterator_base_typedef(pBuffer)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const Buffer::iterator& rhs)
|
||||
: const_iterator_base_typedef(rhs.m_pBuffer)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator& operator++()
|
||||
{
|
||||
@ -202,12 +205,12 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool operator == (const const_iterator& rhs) const
|
||||
bool operator==(const const_iterator& rhs) const
|
||||
{
|
||||
return eq(rhs);
|
||||
}
|
||||
|
||||
bool operator != (const const_iterator& rhs) const
|
||||
bool operator!=(const const_iterator& rhs) const
|
||||
{
|
||||
return neq(rhs);
|
||||
}
|
||||
@ -224,7 +227,8 @@ public:
|
||||
*/
|
||||
Buffer()
|
||||
: m_pBuffer(NULL)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
@ -275,7 +279,8 @@ public:
|
||||
*/
|
||||
Buffer(GWBUF* pBuffer)
|
||||
: m_pBuffer(pBuffer)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a buffer of specified size.
|
||||
@ -353,7 +358,7 @@ public:
|
||||
*
|
||||
* @see Buffer::copy_from
|
||||
*/
|
||||
Buffer& operator = (const Buffer& rhs)
|
||||
Buffer& operator=(const Buffer& rhs)
|
||||
{
|
||||
Buffer temp(rhs);
|
||||
swap(temp);
|
||||
@ -366,7 +371,7 @@ public:
|
||||
*
|
||||
* @param rhs The @c Buffer to be moves.
|
||||
*/
|
||||
Buffer& operator = (Buffer&& rhs)
|
||||
Buffer& operator=(Buffer&& rhs)
|
||||
{
|
||||
reset();
|
||||
swap(rhs);
|
||||
@ -626,7 +631,7 @@ public:
|
||||
*
|
||||
* @attention Invalidates all iterators.
|
||||
*/
|
||||
GWBUF** operator & ()
|
||||
GWBUF** operator&()
|
||||
{
|
||||
reset();
|
||||
return &m_pBuffer;
|
||||
@ -689,10 +694,10 @@ public:
|
||||
|
||||
private:
|
||||
// To prevent @c Buffer from being created on the heap.
|
||||
void* operator new(size_t); // standard new
|
||||
void* operator new(size_t, void*); // placement new
|
||||
void* operator new[](size_t); // array new
|
||||
void* operator new[](size_t, void*); // placement array new
|
||||
void* operator new(size_t); // standard new
|
||||
void* operator new(size_t, void*); // placement new
|
||||
void* operator new[](size_t); // array new
|
||||
void* operator new[](size_t, void*);// placement array new
|
||||
|
||||
private:
|
||||
GWBUF* m_pBuffer;
|
||||
@ -703,7 +708,7 @@ private:
|
||||
*
|
||||
* @return True if equal, false otherwise.
|
||||
*/
|
||||
inline bool operator == (const Buffer& lhs, const Buffer& rhs)
|
||||
inline bool operator==(const Buffer& lhs, const Buffer& rhs)
|
||||
{
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
@ -713,7 +718,7 @@ inline bool operator == (const Buffer& lhs, const Buffer& rhs)
|
||||
*
|
||||
* @return True if equal, false otherwise.
|
||||
*/
|
||||
inline bool operator == (const Buffer& lhs, const GWBUF& rhs)
|
||||
inline bool operator==(const Buffer& lhs, const GWBUF& rhs)
|
||||
{
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
@ -723,7 +728,7 @@ inline bool operator == (const Buffer& lhs, const GWBUF& rhs)
|
||||
*
|
||||
* @return True if un-equal, false otherwise.
|
||||
*/
|
||||
inline bool operator != (const Buffer& lhs, const Buffer& rhs)
|
||||
inline bool operator!=(const Buffer& lhs, const Buffer& rhs)
|
||||
{
|
||||
return !lhs.eq(rhs);
|
||||
}
|
||||
@ -733,9 +738,8 @@ inline bool operator != (const Buffer& lhs, const Buffer& rhs)
|
||||
*
|
||||
* @return True if un-equal, false otherwise.
|
||||
*/
|
||||
inline bool operator != (const Buffer& lhs, const GWBUF& rhs)
|
||||
inline bool operator!=(const Buffer& lhs, const GWBUF& rhs)
|
||||
{
|
||||
return !lhs.eq(rhs);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file ccdefs.hh
|
||||
@ -18,7 +18,7 @@
|
||||
* This file is to be included first by all C++ headers.
|
||||
*/
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
#if !defined (__cplusplus)
|
||||
#error This file is only to be included by C++ code.
|
||||
#endif
|
||||
|
||||
@ -57,8 +57,8 @@ namespace mxs = maxscale;
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#define MXS_EXCEPTION_GUARD(statement)\
|
||||
do { try { statement; }\
|
||||
catch (const std::bad_alloc&) { MXS_OOM(); }\
|
||||
catch (const std::exception& x) { MXS_ERROR("Caught standard exception: %s", x.what()); }\
|
||||
catch (...) { MXS_ERROR("Caught unknown exception."); } } while (false)
|
||||
#define MXS_EXCEPTION_GUARD(statement) \
|
||||
do {try {statement;} \
|
||||
catch (const std::bad_alloc&) {MXS_OOM();} \
|
||||
catch (const std::exception& x) {MXS_ERROR("Caught standard exception: %s", x.what());} \
|
||||
catch (...) {MXS_ERROR("Caught unknown exception.");}} while (false)
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file cdefs.h
|
||||
@ -48,7 +48,7 @@
|
||||
*
|
||||
* @note This a macro, so the arguments will be evaluated more than once.
|
||||
*/
|
||||
#define MXS_MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||
#define MXS_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
/**
|
||||
* Returns the larger of two items.
|
||||
@ -60,7 +60,7 @@
|
||||
*
|
||||
* @note This a macro, so the arguments will be evaluated more than once.
|
||||
*/
|
||||
#define MXS_MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
#define MXS_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/**
|
||||
* Define function attributes
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/config.h The configuration handling elements
|
||||
@ -44,11 +44,11 @@ MXS_BEGIN_DECLS
|
||||
#define DEFAULT_ADMIN_HTTP_PORT 8989
|
||||
#define DEFAULT_ADMIN_HOST "127.0.0.1"
|
||||
|
||||
#define RELEASE_STR_LENGTH 256
|
||||
#define SYSNAME_LEN 256
|
||||
#define MAX_ADMIN_USER_LEN 1024
|
||||
#define MAX_ADMIN_PW_LEN 1024
|
||||
#define MAX_ADMIN_HOST_LEN 1024
|
||||
#define RELEASE_STR_LENGTH 256
|
||||
#define SYSNAME_LEN 256
|
||||
#define MAX_ADMIN_USER_LEN 1024
|
||||
#define MAX_ADMIN_PW_LEN 1024
|
||||
#define MAX_ADMIN_HOST_LEN 1024
|
||||
|
||||
/** JSON Pointers to key parts of JSON objects */
|
||||
#define MXS_JSON_PTR_DATA "/data"
|
||||
@ -220,9 +220,9 @@ extern const char CN_LOG_TO_SHM[];
|
||||
*/
|
||||
typedef struct config_parameter
|
||||
{
|
||||
char *name; /**< The name of the parameter */
|
||||
char *value; /**< The value of the parameter */
|
||||
struct config_parameter *next; /**< Next pointer in the linked list */
|
||||
char* name; /**< The name of the parameter */
|
||||
char* value; /**< The value of the parameter */
|
||||
struct config_parameter* next; /**< Next pointer in the linked list */
|
||||
} MXS_CONFIG_PARAMETER;
|
||||
|
||||
/**
|
||||
@ -231,10 +231,10 @@ typedef struct config_parameter
|
||||
*/
|
||||
typedef struct config_context
|
||||
{
|
||||
char *object; /**< The name of the object being configured */
|
||||
MXS_CONFIG_PARAMETER *parameters; /**< The list of parameter values */
|
||||
bool was_persisted; /**< True if this object was persisted */
|
||||
struct config_context *next; /**< Next pointer in the linked list */
|
||||
char* object; /**< The name of the object being configured */
|
||||
MXS_CONFIG_PARAMETER* parameters; /**< The list of parameter values */
|
||||
bool was_persisted; /**< True if this object was persisted */
|
||||
struct config_context* next; /**< Next pointer in the linked list */
|
||||
} CONFIG_CONTEXT;
|
||||
|
||||
/**
|
||||
@ -242,47 +242,53 @@ typedef struct config_context
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
bool config_check; /**< Only check config */
|
||||
int n_threads; /**< Number of polling threads */
|
||||
size_t thread_stack_size; /**< The stack size of each worker thread */
|
||||
char *version_string; /**< The version string of embedded db library */
|
||||
char release_string[RELEASE_STR_LENGTH]; /**< The release name string of the system */
|
||||
char sysname[SYSNAME_LEN]; /**< The OS name of the system */
|
||||
uint8_t mac_sha1[SHA_DIGEST_LENGTH]; /**< The SHA1 digest of an interface MAC address */
|
||||
unsigned int n_nbpoll; /**< Tune number of non-blocking polls */
|
||||
unsigned int pollsleep; /**< Wait time in blocking polls */
|
||||
int syslog; /**< Log to syslog */
|
||||
int maxlog; /**< Log to MaxScale's own logs */
|
||||
unsigned int auth_conn_timeout; /**< Connection timeout for the user authentication */
|
||||
unsigned int auth_read_timeout; /**< Read timeout for the user authentication */
|
||||
unsigned int auth_write_timeout; /**< Write timeout for the user authentication */
|
||||
bool skip_permission_checks; /**< Skip service and monitor permission checks */
|
||||
int32_t passive; /**< True if MaxScale is in passive mode */
|
||||
int64_t promoted_at; /**< Time when this Maxscale instance was
|
||||
* promoted from a passive to an active */
|
||||
char qc_name[PATH_MAX]; /**< The name of the query classifier to load */
|
||||
char* qc_args; /**< Arguments for the query classifier */
|
||||
QC_CACHE_PROPERTIES qc_cache_properties; /**< The query classifier cache properties. */
|
||||
qc_sql_mode_t qc_sql_mode; /**< The query classifier sql mode */
|
||||
char admin_host[MAX_ADMIN_HOST_LEN]; /**< Admin interface host */
|
||||
uint16_t admin_port; /**< Admin interface port */
|
||||
bool admin_auth; /**< Admin interface authentication */
|
||||
bool admin_enabled; /**< Admin interface is enabled */
|
||||
bool admin_log_auth_failures; /**< Log admin interface authentication failures */
|
||||
char admin_ssl_key[PATH_MAX]; /**< Admin SSL key */
|
||||
char admin_ssl_cert[PATH_MAX]; /**< Admin SSL cert */
|
||||
char admin_ssl_ca_cert[PATH_MAX]; /**< Admin SSL CA cert */
|
||||
int query_retries; /**< Number of times a interrupted query is retried */
|
||||
time_t query_retry_timeout; /**< Timeout for query retries */
|
||||
bool substitute_variables; /**< Should environment variables be substituted */
|
||||
char* local_address; /**< Local address to use when connecting */
|
||||
time_t users_refresh_time; /**< How often the users can be refreshed */
|
||||
uint64_t writeq_high_water; /**< High water mark of dcb write queue */
|
||||
uint64_t writeq_low_water; /**< Low water mark of dcb write queue */
|
||||
char peer_hosts[MAX_ADMIN_HOST_LEN]; /**< The protocol, address and port for peers (currently only one) */
|
||||
char peer_user[MAX_ADMIN_HOST_LEN]; /**< Username for maxscale-to-maxscale traffic */
|
||||
char peer_password[MAX_ADMIN_HOST_LEN]; /**< Password for maxscale-to-maxscale traffic */
|
||||
mxb_log_target_t log_target; /**< Log type */
|
||||
bool config_check; /**< Only check config */
|
||||
int n_threads; /**< Number of polling threads */
|
||||
size_t thread_stack_size; /**< The stack size of each worker thread */
|
||||
char* version_string; /**< The version string of embedded db library */
|
||||
char release_string[RELEASE_STR_LENGTH]; /**< The release name string of the system */
|
||||
char sysname[SYSNAME_LEN]; /**< The OS name of the system */
|
||||
uint8_t mac_sha1[SHA_DIGEST_LENGTH]; /**< The SHA1 digest of an interface MAC address
|
||||
* */
|
||||
unsigned int n_nbpoll; /**< Tune number of non-blocking polls */
|
||||
unsigned int pollsleep; /**< Wait time in blocking polls */
|
||||
int syslog; /**< Log to syslog */
|
||||
int maxlog; /**< Log to MaxScale's own logs */
|
||||
unsigned int auth_conn_timeout; /**< Connection timeout for the user
|
||||
* authentication */
|
||||
unsigned int auth_read_timeout; /**< Read timeout for the user authentication */
|
||||
unsigned int auth_write_timeout; /**< Write timeout for the user authentication */
|
||||
bool skip_permission_checks; /**< Skip service and monitor permission checks */
|
||||
int32_t passive; /**< True if MaxScale is in passive mode */
|
||||
int64_t promoted_at; /**< Time when this Maxscale instance was
|
||||
* promoted from a passive to an active */
|
||||
char qc_name[PATH_MAX]; /**< The name of the query classifier to load */
|
||||
char* qc_args; /**< Arguments for the query classifier */
|
||||
QC_CACHE_PROPERTIES qc_cache_properties; /**< The query classifier cache properties. */
|
||||
qc_sql_mode_t qc_sql_mode; /**< The query classifier sql mode */
|
||||
char admin_host[MAX_ADMIN_HOST_LEN]; /**< Admin interface host */
|
||||
uint16_t admin_port; /**< Admin interface port */
|
||||
bool admin_auth; /**< Admin interface authentication */
|
||||
bool admin_enabled; /**< Admin interface is enabled */
|
||||
bool admin_log_auth_failures; /**< Log admin interface authentication failures
|
||||
* */
|
||||
char admin_ssl_key[PATH_MAX]; /**< Admin SSL key */
|
||||
char admin_ssl_cert[PATH_MAX]; /**< Admin SSL cert */
|
||||
char admin_ssl_ca_cert[PATH_MAX]; /**< Admin SSL CA cert */
|
||||
int query_retries; /**< Number of times a interrupted query is
|
||||
* retried */
|
||||
time_t query_retry_timeout; /**< Timeout for query retries */
|
||||
bool substitute_variables; /**< Should environment variables be substituted
|
||||
* */
|
||||
char* local_address; /**< Local address to use when connecting */
|
||||
time_t users_refresh_time; /**< How often the users can be refreshed */
|
||||
uint64_t writeq_high_water; /**< High water mark of dcb write queue */
|
||||
uint64_t writeq_low_water; /**< Low water mark of dcb write queue */
|
||||
char peer_hosts[MAX_ADMIN_HOST_LEN]; /**< The protocol, address and port for peers
|
||||
* (currently only one) */
|
||||
char peer_user[MAX_ADMIN_HOST_LEN]; /**< Username for maxscale-to-maxscale traffic */
|
||||
char peer_password[MAX_ADMIN_HOST_LEN]; /**< Password for maxscale-to-maxscale traffic */
|
||||
mxb_log_target_t log_target; /**< Log type */
|
||||
} MXS_CONFIG;
|
||||
|
||||
/**
|
||||
@ -307,7 +313,7 @@ MXS_CONFIG_PARAMETER* config_get_param(MXS_CONFIG_PARAMETER* params, const char*
|
||||
* @param key Parameter name
|
||||
* @return True if the parameter is an SSL parameter
|
||||
*/
|
||||
bool config_is_ssl_parameter(const char *key);
|
||||
bool config_is_ssl_parameter(const char* key);
|
||||
|
||||
/**
|
||||
* @brief Check if a configuration parameter is valid
|
||||
@ -323,8 +329,10 @@ bool config_is_ssl_parameter(const char *key);
|
||||
*
|
||||
* @return True if the configuration parameter is valid
|
||||
*/
|
||||
bool config_param_is_valid(const MXS_MODULE_PARAM *params, const char *key,
|
||||
const char *value, const CONFIG_CONTEXT *context);
|
||||
bool config_param_is_valid(const MXS_MODULE_PARAM* params,
|
||||
const char* key,
|
||||
const char* value,
|
||||
const CONFIG_CONTEXT* context);
|
||||
|
||||
/**
|
||||
* @brief Get a boolean value
|
||||
@ -338,7 +346,7 @@ bool config_param_is_valid(const MXS_MODULE_PARAM *params, const char *key,
|
||||
*
|
||||
* @return The value as a boolean or false if none was found
|
||||
*/
|
||||
bool config_get_bool(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
bool config_get_bool(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Get an integer value
|
||||
@ -350,7 +358,7 @@ bool config_get_bool(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
*
|
||||
* @return The integer value of the parameter or 0 if no parameter was found
|
||||
*/
|
||||
int config_get_integer(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
int config_get_integer(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Get a size in bytes
|
||||
@ -366,7 +374,7 @@ int config_get_integer(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
*
|
||||
* @return Number of bytes or 0 if no parameter was found
|
||||
*/
|
||||
uint64_t config_get_size(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
uint64_t config_get_size(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Get a string value
|
||||
@ -376,7 +384,7 @@ uint64_t config_get_size(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
*
|
||||
* @return The raw string value or an empty string if no parameter was found
|
||||
*/
|
||||
const char* config_get_string(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
const char* config_get_string(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Get a enumeration value
|
||||
@ -391,8 +399,9 @@ const char* config_get_string(const MXS_CONFIG_PARAMETER *params, const char *ke
|
||||
* detected. If -1 is used, config_get_param() should be used to detect whether
|
||||
* the parameter exists
|
||||
*/
|
||||
int config_get_enum(const MXS_CONFIG_PARAMETER *params, const char *key,
|
||||
const MXS_ENUM_VALUE *values);
|
||||
int config_get_enum(const MXS_CONFIG_PARAMETER* params,
|
||||
const char* key,
|
||||
const MXS_ENUM_VALUE* values);
|
||||
|
||||
/**
|
||||
* @brief Get a service value
|
||||
@ -402,7 +411,7 @@ int config_get_enum(const MXS_CONFIG_PARAMETER *params, const char *key,
|
||||
*
|
||||
* @return Pointer to configured service
|
||||
*/
|
||||
struct service* config_get_service(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
struct service* config_get_service(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Get a server value
|
||||
@ -412,7 +421,7 @@ struct service* config_get_service(const MXS_CONFIG_PARAMETER *params, const cha
|
||||
*
|
||||
* @return Pointer to configured server
|
||||
*/
|
||||
struct server* config_get_server(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
struct server* config_get_server(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Get an array of servers. The caller should free the produced array,
|
||||
@ -423,7 +432,8 @@ struct server* config_get_server(const MXS_CONFIG_PARAMETER *params, const char
|
||||
* @param output Where to save the output
|
||||
* @return How many servers were found, equal to output array size
|
||||
*/
|
||||
int config_get_server_list(const MXS_CONFIG_PARAMETER *params, const char *key,
|
||||
int config_get_server_list(const MXS_CONFIG_PARAMETER* params,
|
||||
const char* key,
|
||||
struct server*** output);
|
||||
|
||||
/**
|
||||
@ -437,8 +447,9 @@ int config_get_server_list(const MXS_CONFIG_PARAMETER *params, const char *key,
|
||||
* nothing is written. If NULL, the parameter is ignored.
|
||||
* @return Compiled regex code on success, NULL otherwise
|
||||
*/
|
||||
pcre2_code* config_get_compiled_regex(const MXS_CONFIG_PARAMETER *params,
|
||||
const char *key, uint32_t options,
|
||||
pcre2_code* config_get_compiled_regex(const MXS_CONFIG_PARAMETER* params,
|
||||
const char* key,
|
||||
uint32_t options,
|
||||
uint32_t* output_ovec_size);
|
||||
|
||||
/**
|
||||
@ -459,9 +470,11 @@ pcre2_code* config_get_compiled_regex(const MXS_CONFIG_PARAMETER *params,
|
||||
* @return True, if all patterns given by @c keys were successfully compiled.
|
||||
* False otherwise.
|
||||
*/
|
||||
bool config_get_compiled_regexes(const MXS_CONFIG_PARAMETER *params,
|
||||
const char* keys[], int keys_size,
|
||||
uint32_t options, uint32_t* out_ovec_size,
|
||||
bool config_get_compiled_regexes(const MXS_CONFIG_PARAMETER* params,
|
||||
const char* keys[],
|
||||
int keys_size,
|
||||
uint32_t options,
|
||||
uint32_t* out_ovec_size,
|
||||
pcre2_code** out_codes[]);
|
||||
/**
|
||||
* Parse a list of server names and write the results in an array of strings
|
||||
@ -478,7 +491,7 @@ bool config_get_compiled_regexes(const MXS_CONFIG_PARAMETER *params,
|
||||
* @return How many servers were found and set into the array. 0 on error or if
|
||||
* none were found.
|
||||
*/
|
||||
int config_parse_server_list(const char *servers, char ***output_array);
|
||||
int config_parse_server_list(const char* servers, char*** output_array);
|
||||
|
||||
/**
|
||||
* @brief Get copy of parameter value if it is defined
|
||||
@ -494,7 +507,7 @@ int config_parse_server_list(const char *servers, char ***output_array);
|
||||
* @note The use of this function should be avoided after startup as the function
|
||||
* will abort the process if memory allocation fails.
|
||||
*/
|
||||
char* config_copy_string(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
char* config_copy_string(const MXS_CONFIG_PARAMETER* params, const char* key);
|
||||
|
||||
/**
|
||||
* @brief Convert string truth value
|
||||
@ -507,7 +520,7 @@ char* config_copy_string(const MXS_CONFIG_PARAMETER *params, const char *key);
|
||||
* @return 1 if @c value is true, 0 if value is false and -1 if the value is not
|
||||
* a valid truth value
|
||||
*/
|
||||
int config_truth_value(const char *value);
|
||||
int config_truth_value(const char* value);
|
||||
|
||||
/**
|
||||
* @brief Get worker thread count
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/config.h>
|
||||
|
||||
@ -34,5 +34,4 @@ public:
|
||||
private:
|
||||
CONFIG_CONTEXT m_ctx = {(char*)""};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/log.h>
|
||||
@ -29,7 +29,7 @@ namespace maxscale
|
||||
class CustomParser
|
||||
{
|
||||
CustomParser(const CustomParser&);
|
||||
CustomParser& operator = (const CustomParser&);
|
||||
CustomParser& operator=(const CustomParser&);
|
||||
|
||||
public:
|
||||
typedef int32_t token_t;
|
||||
@ -64,7 +64,10 @@ protected:
|
||||
{
|
||||
#ifdef MXS_CP_LOG_UNEXPECTED_AND_EXHAUSTED
|
||||
MXS_NOTICE("Custom parser: In statement '%.*s', unexpected token at '%.*s'.",
|
||||
(int)m_len, m_pSql, (int)(m_pEnd - m_pI), m_pI);
|
||||
(int)m_len,
|
||||
m_pSql,
|
||||
(int)(m_pEnd - m_pI),
|
||||
m_pI);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -102,7 +105,7 @@ protected:
|
||||
*/
|
||||
static bool is_number(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,9 +123,8 @@ protected:
|
||||
|
||||
char lc = uc + ('a' - 'A');
|
||||
|
||||
return
|
||||
((m_pI + offset) < m_pEnd) &&
|
||||
((*(m_pI + offset) == uc) || (*(m_pI + offset) == lc));
|
||||
return ((m_pI + offset) < m_pEnd)
|
||||
&& ((*(m_pI + offset) == uc) || (*(m_pI + offset) == lc));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,7 +178,7 @@ protected:
|
||||
static char toupper(char c)
|
||||
{
|
||||
// Significantly faster than library version.
|
||||
return (c >= 'a' && c <='z') ? c - ('a' - 'A') : c;
|
||||
return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,7 +213,8 @@ protected:
|
||||
|
||||
if (zWord == pEnd)
|
||||
{
|
||||
if ((pI == m_pEnd) || (!isalpha(*pI))) // Handwritten isalpha not faster than library version.
|
||||
if ((pI == m_pEnd) || (!isalpha(*pI))) // Handwritten isalpha not faster than library
|
||||
// version.
|
||||
{
|
||||
m_pI = pI;
|
||||
}
|
||||
@ -234,5 +237,4 @@ protected:
|
||||
const char* m_pI;
|
||||
const char* m_pEnd;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file dcb.h The Descriptor Control Block
|
||||
@ -45,12 +45,12 @@ struct dcb;
|
||||
*/
|
||||
typedef struct dcbstats
|
||||
{
|
||||
int n_reads; /*< Number of reads on this descriptor */
|
||||
int n_writes; /*< Number of writes on this descriptor */
|
||||
int n_accepts; /*< Number of accepts on this descriptor */
|
||||
int n_buffered; /*< Number of buffered writes */
|
||||
int n_high_water; /*< Number of crosses of high water mark */
|
||||
int n_low_water; /*< Number of crosses of low water mark */
|
||||
int n_reads; /*< Number of reads on this descriptor */
|
||||
int n_writes; /*< Number of writes on this descriptor */
|
||||
int n_accepts; /*< Number of accepts on this descriptor */
|
||||
int n_buffered; /*< Number of buffered writes */
|
||||
int n_high_water; /*< Number of crosses of high water mark */
|
||||
int n_low_water; /*< Number of crosses of low water mark */
|
||||
} DCBSTATS;
|
||||
|
||||
#define DCBSTATS_INIT {0}
|
||||
@ -66,12 +66,29 @@ typedef enum
|
||||
DCB_STATE_NOPOLLING, /*< Removed from poll mask */
|
||||
} dcb_state_t;
|
||||
|
||||
#define STRDCBSTATE(s) ((s) == DCB_STATE_ALLOC ? "DCB_STATE_ALLOC" : \
|
||||
((s) == DCB_STATE_POLLING ? "DCB_STATE_POLLING" : \
|
||||
((s) == DCB_STATE_LISTENING ? "DCB_STATE_LISTENING" : \
|
||||
((s) == DCB_STATE_DISCONNECTED ? "DCB_STATE_DISCONNECTED" : \
|
||||
((s) == DCB_STATE_NOPOLLING ? "DCB_STATE_NOPOLLING" : \
|
||||
((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN"))))))
|
||||
#define STRDCBSTATE(s) \
|
||||
((s) == DCB_STATE_ALLOC ? "DCB_STATE_ALLOC" \
|
||||
: ((s) == DCB_STATE_POLLING ? "DCB_STATE_POLLING" \
|
||||
: ((s) == DCB_STATE_LISTENING ? "DCB_STATE_LISTENING" \
|
||||
: ((s) \
|
||||
== \
|
||||
DCB_STATE_DISCONNECTED \
|
||||
? \
|
||||
"DCB_STATE_DISCONNECTED" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
DCB_STATE_NOPOLLING \
|
||||
? \
|
||||
"DCB_STATE_NOPOLLING" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
DCB_STATE_UNDEFINED \
|
||||
? \
|
||||
"DCB_STATE_UNDEFINED" \
|
||||
: \
|
||||
"DCB_STATE_UNKNOWN"))))))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -81,16 +98,28 @@ typedef enum
|
||||
DCB_ROLE_INTERNAL /*< Internal DCB not connected to the outside */
|
||||
} dcb_role_t;
|
||||
|
||||
#define STRDCBROLE(r) ((r) == DCB_ROLE_SERVICE_LISTENER ? "DCB_ROLE_SERVICE_LISTENER" : \
|
||||
((r) == DCB_ROLE_CLIENT_HANDLER ? "DCB_ROLE_CLIENT_HANDLER" : \
|
||||
((r) == DCB_ROLE_BACKEND_HANDLER ? "DCB_ROLE_BACKEND_HANDLER" : \
|
||||
((r) == DCB_ROLE_INTERNAL ? "DCB_ROLE_INTERNAL" : \
|
||||
"UNKNOWN DCB ROLE"))))
|
||||
#define STRDCBROLE(r) \
|
||||
((r) == DCB_ROLE_SERVICE_LISTENER ? "DCB_ROLE_SERVICE_LISTENER" \
|
||||
: ((r) == DCB_ROLE_CLIENT_HANDLER ? "DCB_ROLE_CLIENT_HANDLER" \
|
||||
: ((r) \
|
||||
== DCB_ROLE_BACKEND_HANDLER ? \
|
||||
"DCB_ROLE_BACKEND_HANDLER" \
|
||||
: (( \
|
||||
r) \
|
||||
== \
|
||||
DCB_ROLE_INTERNAL \
|
||||
? \
|
||||
"DCB_ROLE_INTERNAL" \
|
||||
: \
|
||||
"UNKNOWN DCB ROLE"))))
|
||||
|
||||
#define DCB_STRTYPE(dcb) (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER ? "Client DCB" : \
|
||||
dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER ? "Backend DCB" : \
|
||||
dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER ? "Listener DCB" : \
|
||||
dcb->dcb_role == DCB_ROLE_INTERNAL ? "Internal DCB" : "Unknown DCB")
|
||||
#define DCB_STRTYPE(dcb) \
|
||||
(dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER ? "Client DCB" \
|
||||
: dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER ? "Backend DCB" \
|
||||
: dcb->dcb_role \
|
||||
== DCB_ROLE_SERVICE_LISTENER ? "Listener DCB" \
|
||||
: \
|
||||
dcb->dcb_role == DCB_ROLE_INTERNAL ? "Internal DCB" : "Unknown DCB")
|
||||
|
||||
/**
|
||||
* Callback reasons for the DCB callback mechanism.
|
||||
@ -111,10 +140,10 @@ typedef enum
|
||||
*/
|
||||
typedef struct dcb_callback
|
||||
{
|
||||
DCB_REASON reason; /*< The reason for the callback */
|
||||
int (*cb)(struct dcb *dcb, DCB_REASON reason, void *userdata);
|
||||
void *userdata; /*< User data to be sent in the callback */
|
||||
struct dcb_callback *next; /*< Next callback for this DCB */
|
||||
DCB_REASON reason; /*< The reason for the callback */
|
||||
int (* cb)(struct dcb* dcb, DCB_REASON reason, void* userdata);
|
||||
void* userdata; /*< User data to be sent in the callback */
|
||||
struct dcb_callback* next; /*< Next callback for this DCB */
|
||||
} DCB_CALLBACK;
|
||||
|
||||
/**
|
||||
@ -145,59 +174,61 @@ typedef enum
|
||||
*/
|
||||
typedef struct dcb
|
||||
{
|
||||
MXB_POLL_DATA poll;
|
||||
bool dcb_errhandle_called; /*< this can be called only once */
|
||||
dcb_role_t dcb_role;
|
||||
int fd; /**< The descriptor */
|
||||
dcb_state_t state; /**< Current descriptor state */
|
||||
SSL_STATE ssl_state; /**< Current state of SSL if in use */
|
||||
int flags; /**< DCB flags */
|
||||
char *remote; /**< Address of remote end */
|
||||
char *user; /**< User name for connection */
|
||||
struct sockaddr_storage ip; /**< remote IPv4/IPv6 address */
|
||||
char *protoname; /**< Name of the protocol */
|
||||
void *protocol; /**< The protocol specific state */
|
||||
size_t protocol_packet_length; /**< How long the protocol specific packet is */
|
||||
size_t protocol_bytes_processed; /**< How many bytes of a packet have been read */
|
||||
struct session *session; /**< The owning session */
|
||||
struct servlistener *listener; /**< For a client DCB, the listener data */
|
||||
MXS_PROTOCOL func; /**< The protocol functions for this descriptor */
|
||||
MXS_AUTHENTICATOR authfunc; /**< The authenticator functions for this descriptor */
|
||||
uint32_t writeqlen; /**< Current number of byes in the write queue */
|
||||
uint32_t high_water; /**< High water mark of write queue */
|
||||
uint32_t low_water; /**< Low water mark of write queue */
|
||||
GWBUF *writeq; /**< Write Data Queue */
|
||||
GWBUF *delayq; /**< Delay Backend Write Data Queue */
|
||||
GWBUF *readq; /**< Read queue for storing incomplete reads */
|
||||
GWBUF *fakeq; /**< Fake event queue for generated events */
|
||||
uint32_t fake_event; /**< Fake event to be delivered to handler */
|
||||
MXB_POLL_DATA poll;
|
||||
bool dcb_errhandle_called; /*< this can be called only once */
|
||||
dcb_role_t dcb_role;
|
||||
int fd; /**< The descriptor */
|
||||
dcb_state_t state; /**< Current descriptor state */
|
||||
SSL_STATE ssl_state; /**< Current state of SSL if in use */
|
||||
int flags; /**< DCB flags */
|
||||
char* remote; /**< Address of remote end */
|
||||
char* user; /**< User name for connection */
|
||||
struct sockaddr_storage ip; /**< remote IPv4/IPv6 address */
|
||||
char* protoname; /**< Name of the protocol */
|
||||
void* protocol; /**< The protocol specific state */
|
||||
size_t protocol_packet_length; /**< How long the protocol specific packet is */
|
||||
size_t protocol_bytes_processed; /**< How many bytes of a packet have been read */
|
||||
struct session* session; /**< The owning session */
|
||||
struct servlistener* listener; /**< For a client DCB, the listener data */
|
||||
MXS_PROTOCOL func; /**< The protocol functions for this descriptor */
|
||||
MXS_AUTHENTICATOR authfunc; /**< The authenticator functions for this descriptor
|
||||
* */
|
||||
uint32_t writeqlen; /**< Current number of byes in the write queue */
|
||||
uint32_t high_water; /**< High water mark of write queue */
|
||||
uint32_t low_water; /**< Low water mark of write queue */
|
||||
GWBUF* writeq; /**< Write Data Queue */
|
||||
GWBUF* delayq; /**< Delay Backend Write Data Queue */
|
||||
GWBUF* readq; /**< Read queue for storing incomplete reads */
|
||||
GWBUF* fakeq; /**< Fake event queue for generated events */
|
||||
uint32_t fake_event; /**< Fake event to be delivered to handler */
|
||||
|
||||
DCBSTATS stats; /**< DCB related statistics */
|
||||
struct dcb *nextpersistent; /**< Next DCB in the persistent pool for SERVER */
|
||||
time_t persistentstart; /**< 0: Not in the persistent pool.
|
||||
-1: Evicted from the persistent pool and being closed.
|
||||
non-0: Time when placed in the persistent pool.
|
||||
*/
|
||||
struct service *service; /**< The related service */
|
||||
void *data; /**< Specific client data, shared between DCBs of this session */
|
||||
void *authenticator_data; /**< The authenticator data for this DCB */
|
||||
DCB_CALLBACK *callbacks; /**< The list of callbacks for the DCB */
|
||||
int64_t last_read; /*< Last time the DCB received data */
|
||||
struct server *server; /**< The associated backend server */
|
||||
SSL* ssl; /*< SSL struct for connection */
|
||||
bool ssl_read_want_read; /*< Flag */
|
||||
DCBSTATS stats; /**< DCB related statistics */
|
||||
struct dcb* nextpersistent; /**< Next DCB in the persistent pool for SERVER */
|
||||
time_t persistentstart; /**< 0: Not in the persistent pool.
|
||||
* -1: Evicted from the persistent pool and being closed.
|
||||
* non-0: Time when placed in the persistent pool.
|
||||
*/
|
||||
struct service* service; /**< The related service */
|
||||
void* data; /**< Specific client data, shared between DCBs of this session */
|
||||
void* authenticator_data; /**< The authenticator data for this DCB */
|
||||
DCB_CALLBACK* callbacks; /**< The list of callbacks for the DCB */
|
||||
int64_t last_read; /*< Last time the DCB received data */
|
||||
struct server* server; /**< The associated backend server */
|
||||
SSL* ssl; /*< SSL struct for connection */
|
||||
bool ssl_read_want_read; /*< Flag */
|
||||
bool ssl_read_want_write; /*< Flag */
|
||||
bool ssl_write_want_read; /*< Flag */
|
||||
bool ssl_write_want_write; /*< Flag */
|
||||
bool was_persistent; /**< Whether this DCB was in the persistent pool */
|
||||
bool high_water_reached; /** High water mark reached, to determine whether need release throttle */
|
||||
bool ssl_write_want_write; /*< Flag */
|
||||
bool was_persistent; /**< Whether this DCB was in the persistent pool */
|
||||
bool high_water_reached; /** High water mark reached, to determine whether need release
|
||||
* throttle */
|
||||
struct
|
||||
{
|
||||
struct dcb *next; /**< Next DCB in owning thread's list */
|
||||
struct dcb *tail; /**< Last DCB in owning thread's list */
|
||||
} thread;
|
||||
uint32_t n_close; /** How many times dcb_close has been called. */
|
||||
char *path; /** If a Unix socket, the path it was bound to. */
|
||||
struct dcb* next; /**< Next DCB in owning thread's list */
|
||||
struct dcb* tail; /**< Last DCB in owning thread's list */
|
||||
} thread;
|
||||
uint32_t n_close; /** How many times dcb_close has been called. */
|
||||
char* path; /** If a Unix socket, the path it was bound to. */
|
||||
} DCB;
|
||||
|
||||
/**
|
||||
@ -213,14 +244,14 @@ typedef enum
|
||||
} DCB_USAGE;
|
||||
|
||||
/* A few useful macros */
|
||||
#define DCB_SESSION(x) (x)->session
|
||||
#define DCB_PROTOCOL(x, type) (type *)((x)->protocol)
|
||||
#define DCB_WRITEQLEN(x) (x)->writeqlen
|
||||
#define DCB_SET_LOW_WATER(x, lo) (x)->low_water = (lo);
|
||||
#define DCB_SET_HIGH_WATER(x, hi) (x)->low_water = (hi);
|
||||
#define DCB_BELOW_LOW_WATER(x) ((x)->low_water && (x)->writeqlen < (x)->low_water)
|
||||
#define DCB_ABOVE_HIGH_WATER(x) ((x)->high_water && (x)->writeqlen > (x)->high_water)
|
||||
#define DCB_THROTTLING_ENABLED(x) ((x)->high_water && (x)->low_water)
|
||||
#define DCB_SESSION(x) (x)->session
|
||||
#define DCB_PROTOCOL(x, type) (type*)((x)->protocol)
|
||||
#define DCB_WRITEQLEN(x) (x)->writeqlen
|
||||
#define DCB_SET_LOW_WATER(x, lo) (x)->low_water = (lo);
|
||||
#define DCB_SET_HIGH_WATER(x, hi) (x)->low_water = (hi);
|
||||
#define DCB_BELOW_LOW_WATER(x) ((x)->low_water && (x)->writeqlen < (x)->low_water)
|
||||
#define DCB_ABOVE_HIGH_WATER(x) ((x)->high_water && (x)->writeqlen > (x)->high_water)
|
||||
#define DCB_THROTTLING_ENABLED(x) ((x)->high_water && (x)->low_water)
|
||||
/**
|
||||
* @brief DCB system initialization function
|
||||
*
|
||||
@ -228,13 +259,13 @@ typedef enum
|
||||
*/
|
||||
void dcb_global_init();
|
||||
|
||||
int dcb_write(DCB *, GWBUF *);
|
||||
DCB *dcb_accept(DCB *listener);
|
||||
DCB *dcb_alloc(dcb_role_t, struct servlistener *);
|
||||
DCB *dcb_connect(struct server *, struct session *, const char *);
|
||||
int dcb_read(DCB *, GWBUF **, int);
|
||||
int dcb_drain_writeq(DCB *);
|
||||
void dcb_close(DCB *);
|
||||
int dcb_write(DCB*, GWBUF*);
|
||||
DCB* dcb_accept(DCB* listener);
|
||||
DCB* dcb_alloc(dcb_role_t, struct servlistener*);
|
||||
DCB* dcb_connect(struct server*, struct session*, const char*);
|
||||
int dcb_read(DCB*, GWBUF**, int);
|
||||
int dcb_drain_writeq(DCB*);
|
||||
void dcb_close(DCB*);
|
||||
|
||||
/**
|
||||
* @brief Close DCB in the thread that owns it.
|
||||
@ -244,30 +275,35 @@ void dcb_close(DCB *);
|
||||
* @note Even if the calling thread owns the dcb, the closing will
|
||||
* still be made via the event loop.
|
||||
*/
|
||||
void dcb_close_in_owning_thread(DCB *dcb);
|
||||
void dcb_close_in_owning_thread(DCB* dcb);
|
||||
|
||||
void printAllDCBs(); /* Debug to print all DCB in the system */
|
||||
void printDCB(DCB *); /* Debug print routine */
|
||||
void dprintDCBList(DCB *); /* Debug print DCB list statistics */
|
||||
void dprintAllDCBs(DCB *); /* Debug to print all DCB in the system */
|
||||
void dprintOneDCB(DCB *, DCB *); /* Debug to print one DCB */
|
||||
void dprintDCB(DCB *, DCB *); /* Debug to print a DCB in the system */
|
||||
void dListDCBs(DCB *); /* List all DCBs in the system */
|
||||
void dListClients(DCB *); /* List al the client DCBs */
|
||||
const char *gw_dcb_state2string(dcb_state_t); /* DCB state to string */
|
||||
void dcb_printf(DCB *, const char *, ...) __attribute__((format(printf, 2, 3))); /* DCB version of printf */
|
||||
int dcb_add_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *), void *);
|
||||
int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *), void *);
|
||||
int dcb_count_by_usage(DCB_USAGE); /* Return counts of DCBs */
|
||||
int dcb_persistent_clean_count(DCB *, int, bool); /* Clean persistent and return count */
|
||||
void dcb_hangup_foreach (struct server* server);
|
||||
void printAllDCBs(); /* Debug to print all DCB in
|
||||
* the system */
|
||||
void printDCB(DCB*); /* Debug print routine */
|
||||
void dprintDCBList(DCB*); /* Debug print DCB list
|
||||
* statistics */
|
||||
void dprintAllDCBs(DCB*); /* Debug to print all DCB in
|
||||
* the system */
|
||||
void dprintOneDCB(DCB*, DCB*); /* Debug to print one DCB */
|
||||
void dprintDCB(DCB*, DCB*); /* Debug to print a DCB in the
|
||||
* system */
|
||||
void dListDCBs(DCB*); /* List all DCBs in the system
|
||||
* */
|
||||
void dListClients(DCB*); /* List al the client DCBs */
|
||||
const char* gw_dcb_state2string(dcb_state_t); /* DCB state to string */
|
||||
void dcb_printf(DCB*, const char*, ...) __attribute__ ((format(printf, 2, 3))); /* DCB version of printf */
|
||||
int dcb_add_callback(DCB*, DCB_REASON, int (*)(struct dcb*, DCB_REASON, void*), void*);
|
||||
int dcb_remove_callback(DCB*, DCB_REASON, int (*)(struct dcb*, DCB_REASON, void*), void*);
|
||||
int dcb_count_by_usage(DCB_USAGE); /* Return counts of DCBs */
|
||||
int dcb_persistent_clean_count(DCB*, int, bool); /* Clean persistent and return count */
|
||||
void dcb_hangup_foreach(struct server* server);
|
||||
uint64_t dcb_get_session_id(DCB* dcb);
|
||||
char *dcb_role_name(DCB *); /* Return the name of a role */
|
||||
int dcb_accept_SSL(DCB* dcb);
|
||||
int dcb_connect_SSL(DCB* dcb);
|
||||
int dcb_listen(DCB *listener, const char *config, const char *protocol_name);
|
||||
void dcb_enable_session_timeouts();
|
||||
void dcb_process_idle_sessions(int thr);
|
||||
char* dcb_role_name(DCB*); /* Return the name of a role */
|
||||
int dcb_accept_SSL(DCB* dcb);
|
||||
int dcb_connect_SSL(DCB* dcb);
|
||||
int dcb_listen(DCB* listener, const char* config, const char* protocol_name);
|
||||
void dcb_enable_session_timeouts();
|
||||
void dcb_process_idle_sessions(int thr);
|
||||
|
||||
/**
|
||||
* @brief Append a buffer the DCB's readqueue
|
||||
@ -278,7 +314,7 @@ void dcb_process_idle_sessions(int thr);
|
||||
* @param dcb The DCB to be appended to.
|
||||
* @param buffer The buffer to append.
|
||||
*/
|
||||
static inline void dcb_readq_append(DCB *dcb, GWBUF *buffer)
|
||||
static inline void dcb_readq_append(DCB* dcb, GWBUF* buffer)
|
||||
{
|
||||
dcb->readq = gwbuf_append(dcb->readq, buffer);
|
||||
}
|
||||
@ -321,7 +357,7 @@ static unsigned int dcb_readq_length(DCB* dcb)
|
||||
* @param dcb The DCB to be prepended to.
|
||||
* @param buffer The buffer to prepend
|
||||
*/
|
||||
static inline void dcb_readq_prepend(DCB *dcb, GWBUF *buffer)
|
||||
static inline void dcb_readq_prepend(DCB* dcb, GWBUF* buffer)
|
||||
{
|
||||
dcb->readq = gwbuf_append(buffer, dcb->readq);
|
||||
}
|
||||
@ -349,7 +385,7 @@ static GWBUF* dcb_readq_release(DCB* dcb)
|
||||
* @param dcb The DCB to be reset.
|
||||
* @param buffer The buffer to reset with
|
||||
*/
|
||||
static inline void dcb_readq_set(DCB *dcb, GWBUF *buffer)
|
||||
static inline void dcb_readq_set(DCB* dcb, GWBUF* buffer)
|
||||
{
|
||||
if (dcb->readq)
|
||||
{
|
||||
@ -377,7 +413,7 @@ static inline void dcb_readq_set(DCB *dcb, GWBUF *buffer)
|
||||
* @param data User provided data passed as the second parameter to @c func
|
||||
* @return True if all DCBs were iterated, false if the callback returned false
|
||||
*/
|
||||
bool dcb_foreach(bool (*func)(DCB *dcb, void *data), void *data);
|
||||
bool dcb_foreach(bool (* func)(DCB* dcb, void* data), void* data);
|
||||
|
||||
/**
|
||||
* @brief Call a function for each connected DCB on the current worker
|
||||
@ -388,7 +424,7 @@ bool dcb_foreach(bool (*func)(DCB *dcb, void *data), void *data);
|
||||
*
|
||||
* @param data User provided data passed as the second parameter to @c func
|
||||
*/
|
||||
void dcb_foreach_local(bool (*func)(DCB *dcb, void *data), void *data);
|
||||
void dcb_foreach_local(bool (* func)(DCB* dcb, void* data), void* data);
|
||||
|
||||
/**
|
||||
* @brief Return the port number this DCB is connected to
|
||||
@ -396,7 +432,7 @@ void dcb_foreach_local(bool (*func)(DCB *dcb, void *data), void *data);
|
||||
* @param dcb DCB to inspect
|
||||
* @return Port number the DCB is connected to or -1 if information is not available
|
||||
*/
|
||||
int dcb_get_port(const DCB *dcb);
|
||||
int dcb_get_port(const DCB* dcb);
|
||||
|
||||
/**
|
||||
* @brief Return the DCB currently being handled by the calling thread.
|
||||
@ -418,8 +454,8 @@ json_t* dcb_to_json(DCB* dcb);
|
||||
/**
|
||||
* DCB flags values
|
||||
*/
|
||||
#define DCBF_HUNG 0x0002 /*< Hangup has been dispatched */
|
||||
#define DCBF_REPLIED 0x0004 /*< DCB was written to */
|
||||
#define DCBF_HUNG 0x0002 /*< Hangup has been dispatched */
|
||||
#define DCBF_REPLIED 0x0004 /*< DCB was written to */
|
||||
|
||||
#define DCB_REPLIED(d) ((d)->flags & DCBF_REPLIED)
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
@ -20,8 +20,8 @@ MXS_BEGIN_DECLS
|
||||
|
||||
|
||||
EVP_CIPHER_CTX* mxs_evp_cipher_ctx_alloc();
|
||||
void mxs_evp_cipher_ctx_free(EVP_CIPHER_CTX* ctx);
|
||||
uint8_t* mxs_evp_cipher_ctx_buf(EVP_CIPHER_CTX* ctx);
|
||||
uint8_t* mxs_evp_cipher_ctx_oiv(EVP_CIPHER_CTX* ctx);
|
||||
void mxs_evp_cipher_ctx_free(EVP_CIPHER_CTX* ctx);
|
||||
uint8_t* mxs_evp_cipher_ctx_buf(EVP_CIPHER_CTX* ctx);
|
||||
uint8_t* mxs_evp_cipher_ctx_oiv(EVP_CIPHER_CTX* ctx);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <syslog.h>
|
||||
@ -62,13 +62,13 @@ namespace event
|
||||
|
||||
enum id_t
|
||||
{
|
||||
AUTHENTICATION_FAILURE /**< Authentication failure */
|
||||
AUTHENTICATION_FAILURE /**< Authentication failure */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DEFAULT_FACILITY = LOG_USER,
|
||||
DEFAULT_LEVEL = LOG_WARNING
|
||||
DEFAULT_LEVEL = LOG_WARNING
|
||||
};
|
||||
|
||||
/**
|
||||
@ -155,11 +155,12 @@ int32_t get_log_level(id_t id);
|
||||
*/
|
||||
void log(id_t event_id,
|
||||
const char* modname,
|
||||
const char* file, int line, const char* function,
|
||||
const char* format, ...) mxs_attribute((format(printf, 6, 7)));
|
||||
|
||||
const char* file,
|
||||
int line,
|
||||
const char* function,
|
||||
const char* format,
|
||||
...) mxs_attribute((format(printf, 6, 7)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,5 +171,5 @@ void log(id_t event_id,
|
||||
* @param ... Formatting string specific additional arguments.
|
||||
*
|
||||
*/
|
||||
#define MXS_LOG_EVENT(event_id, format, ...)\
|
||||
#define MXS_LOG_EVENT(event_id, format, ...) \
|
||||
maxscale::event::log(event_id, MXS_MODULE_NAME, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/filter.h - The public filter interface
|
||||
@ -88,7 +88,7 @@ typedef struct mxs_filter_object
|
||||
*
|
||||
* @return New filter instance on NULL on error
|
||||
*/
|
||||
MXS_FILTER *(*createInstance)(const char *name, MXS_CONFIG_PARAMETER *params);
|
||||
MXS_FILTER*(*createInstance)(const char* name, MXS_CONFIG_PARAMETER* params);
|
||||
|
||||
/**
|
||||
* Called to create a new user session within the filter
|
||||
@ -103,7 +103,7 @@ typedef struct mxs_filter_object
|
||||
*
|
||||
* @return New filter session or NULL on error
|
||||
*/
|
||||
MXS_FILTER_SESSION *(*newSession)(MXS_FILTER *instance, MXS_SESSION *session);
|
||||
MXS_FILTER_SESSION*(*newSession)(MXS_FILTER * instance, MXS_SESSION* session);
|
||||
|
||||
/**
|
||||
* @brief Called when a session is closed
|
||||
@ -113,7 +113,7 @@ typedef struct mxs_filter_object
|
||||
* @param instance Filter instance
|
||||
* @param fsession Filter session
|
||||
*/
|
||||
void (*closeSession)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession);
|
||||
void (* closeSession)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession);
|
||||
|
||||
/**
|
||||
* @brief Called when a session is freed
|
||||
@ -123,7 +123,7 @@ typedef struct mxs_filter_object
|
||||
* @param instance Filter instance
|
||||
* @param fsession Filter session
|
||||
*/
|
||||
void (*freeSession)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession);
|
||||
void (* freeSession)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession);
|
||||
|
||||
/**
|
||||
* @brief Sets the downstream component of the filter pipeline
|
||||
@ -131,7 +131,7 @@ typedef struct mxs_filter_object
|
||||
* @param instance Filter instance
|
||||
* @param fsession Filter session
|
||||
*/
|
||||
void (*setDownstream)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
|
||||
void (* setDownstream)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, MXS_DOWNSTREAM* downstream);
|
||||
|
||||
/**
|
||||
* @brief Sets the upstream component of the filter pipeline
|
||||
@ -139,7 +139,7 @@ typedef struct mxs_filter_object
|
||||
* @param instance Filter instance
|
||||
* @param fsession Filter session
|
||||
*/
|
||||
void (*setUpstream)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *downstream);
|
||||
void (* setUpstream)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, MXS_UPSTREAM* downstream);
|
||||
|
||||
/**
|
||||
* @brief Called on each query that requires routing
|
||||
@ -153,7 +153,7 @@ typedef struct mxs_filter_object
|
||||
* @return If successful, the function returns 1. If an error occurs
|
||||
* and the session should be closed, the function returns 0.
|
||||
*/
|
||||
int32_t (*routeQuery)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
|
||||
int32_t (* routeQuery)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, GWBUF* queue);
|
||||
|
||||
/**
|
||||
* @brief Called for each reply packet
|
||||
@ -167,7 +167,7 @@ typedef struct mxs_filter_object
|
||||
* @return If successful, the function returns 1. If an error occurs
|
||||
* and the session should be closed, the function returns 0.
|
||||
*/
|
||||
int32_t (*clientReply)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
|
||||
int32_t (* clientReply)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, GWBUF* queue);
|
||||
|
||||
/**
|
||||
* @brief Called for diagnostic output
|
||||
@ -176,7 +176,7 @@ typedef struct mxs_filter_object
|
||||
* @param fsession Filter session, NULL if general information about the filter is queried
|
||||
* @param dcb DCB where the diagnostic information should be written
|
||||
*/
|
||||
void (*diagnostics)(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
|
||||
void (* diagnostics)(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb);
|
||||
|
||||
/**
|
||||
* @brief Called for diagnostic output
|
||||
@ -188,7 +188,7 @@ typedef struct mxs_filter_object
|
||||
*
|
||||
* @see jansson.h
|
||||
*/
|
||||
json_t* (*diagnostics_json)(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
|
||||
json_t* (*diagnostics_json)(const MXS_FILTER * instance, const MXS_FILTER_SESSION* fsession);
|
||||
|
||||
/**
|
||||
* @brief Called to obtain the capabilities of the filter
|
||||
@ -197,15 +197,14 @@ typedef struct mxs_filter_object
|
||||
*
|
||||
* @see routing.h
|
||||
*/
|
||||
uint64_t (*getCapabilities)(MXS_FILTER *instance);
|
||||
uint64_t (* getCapabilities)(MXS_FILTER* instance);
|
||||
|
||||
/**
|
||||
* @brief Called for destroying a filter instance
|
||||
*
|
||||
* @param instance Filter instance
|
||||
*/
|
||||
void (*destroyInstance)(MXS_FILTER *instance);
|
||||
|
||||
void (* destroyInstance)(MXS_FILTER* instance);
|
||||
} MXS_FILTER_OBJECT;
|
||||
|
||||
/**
|
||||
@ -213,7 +212,7 @@ typedef struct mxs_filter_object
|
||||
* is changed these values must be updated in line with the rules in the
|
||||
* file modinfo.h.
|
||||
*/
|
||||
#define MXS_FILTER_VERSION {4, 0, 0}
|
||||
#define MXS_FILTER_VERSION {4, 0, 0}
|
||||
|
||||
/**
|
||||
* MXS_FILTER_DEF represents a filter definition from the configuration file.
|
||||
@ -263,7 +262,7 @@ MXS_FILTER* filter_def_get_instance(const MXS_FILTER_DEF* filter_def);
|
||||
|
||||
typedef enum filter_capability
|
||||
{
|
||||
FCAP_TYPE_NONE = 0x0 // TODO: remove once filter capabilities are defined
|
||||
FCAP_TYPE_NONE = 0x0 // TODO: remove once filter capabilities are defined
|
||||
} filter_capability_t;
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/filter.h>
|
||||
@ -48,7 +48,8 @@ public:
|
||||
|
||||
Downstream(const MXS_DOWNSTREAM& down)
|
||||
: m_data(down)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a packet from the client to the next component
|
||||
@ -83,7 +84,8 @@ public:
|
||||
|
||||
Upstream(const MXS_UPSTREAM& up)
|
||||
: m_data(up)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a packet from the backend to the next component
|
||||
@ -147,7 +149,7 @@ public:
|
||||
*
|
||||
* @param pDcb The dcb where the diagnostics should be written.
|
||||
*/
|
||||
void diagnostics(DCB *pDcb);
|
||||
void diagnostics(DCB* pDcb);
|
||||
|
||||
/**
|
||||
* Called for obtaining diagnostics about the filter session.
|
||||
@ -170,9 +172,9 @@ protected:
|
||||
}
|
||||
|
||||
protected:
|
||||
MXS_SESSION* m_pSession; /*< The MXS_SESSION this filter session is associated with. */
|
||||
Downstream m_down; /*< The downstream component. */
|
||||
Upstream m_up; /*< The upstream component. */
|
||||
MXS_SESSION* m_pSession; /*< The MXS_SESSION this filter session is associated with. */
|
||||
Downstream m_down; /*< The downstream component. */
|
||||
Upstream m_up; /*< The upstream component. */
|
||||
};
|
||||
|
||||
|
||||
@ -373,5 +375,4 @@ MXS_FILTER_OBJECT Filter<FilterType, FilterSessionType>::s_object =
|
||||
&Filter<FilterType, FilterSessionType>::getCapabilities,
|
||||
&Filter<FilterType, FilterSessionType>::destroyInstance,
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file hint.h The generic hint data that may be attached to buffers
|
||||
@ -28,19 +28,43 @@ typedef enum
|
||||
HINT_ROUTE_TO_MASTER = 1,
|
||||
HINT_ROUTE_TO_SLAVE,
|
||||
HINT_ROUTE_TO_NAMED_SERVER,
|
||||
HINT_ROUTE_TO_UPTODATE_SERVER, /*< not supported by RWSplit and HintRouter */
|
||||
HINT_ROUTE_TO_ALL, /*< not supported by RWSplit, supported by HintRouter */
|
||||
HINT_ROUTE_TO_UPTODATE_SERVER, /*< not supported by RWSplit and HintRouter */
|
||||
HINT_ROUTE_TO_ALL, /*< not supported by RWSplit, supported by HintRouter */
|
||||
HINT_ROUTE_TO_LAST_USED,
|
||||
HINT_PARAMETER
|
||||
} HINT_TYPE;
|
||||
|
||||
#define STRHINTTYPE(t) (t == HINT_ROUTE_TO_MASTER ? "HINT_ROUTE_TO_MASTER" : \
|
||||
((t) == HINT_ROUTE_TO_SLAVE ? "HINT_ROUTE_TO_SLAVE" : \
|
||||
((t) == HINT_ROUTE_TO_NAMED_SERVER ? "HINT_ROUTE_TO_NAMED_SERVER" : \
|
||||
((t) == HINT_ROUTE_TO_UPTODATE_SERVER ? "HINT_ROUTE_TO_UPTODATE_SERVER" : \
|
||||
((t) == HINT_ROUTE_TO_ALL ? "HINT_ROUTE_TO_ALL" : \
|
||||
((t) == HINT_ROUTE_TO_LAST_USED ? "HINT_ROUTE_TO_LAST_USED" :\
|
||||
((t) == HINT_PARAMETER ? "HINT_PARAMETER" : "UNKNOWN HINT TYPE")))))))
|
||||
#define STRHINTTYPE(t) \
|
||||
(t == HINT_ROUTE_TO_MASTER ? "HINT_ROUTE_TO_MASTER" \
|
||||
: ((t) == HINT_ROUTE_TO_SLAVE ? "HINT_ROUTE_TO_SLAVE" \
|
||||
: ((t) \
|
||||
== HINT_ROUTE_TO_NAMED_SERVER ? \
|
||||
"HINT_ROUTE_TO_NAMED_SERVER" \
|
||||
: ((t) \
|
||||
== \
|
||||
HINT_ROUTE_TO_UPTODATE_SERVER \
|
||||
? \
|
||||
"HINT_ROUTE_TO_UPTODATE_SERVER" \
|
||||
: (( \
|
||||
t) \
|
||||
== \
|
||||
HINT_ROUTE_TO_ALL \
|
||||
? \
|
||||
"HINT_ROUTE_TO_ALL" \
|
||||
: (( \
|
||||
t) \
|
||||
== \
|
||||
HINT_ROUTE_TO_LAST_USED \
|
||||
? \
|
||||
"HINT_ROUTE_TO_LAST_USED" \
|
||||
: (( \
|
||||
t) \
|
||||
== \
|
||||
HINT_PARAMETER \
|
||||
? \
|
||||
"HINT_PARAMETER" \
|
||||
: \
|
||||
"UNKNOWN HINT TYPE")))))))
|
||||
|
||||
/**
|
||||
* A generic hint.
|
||||
@ -51,19 +75,19 @@ typedef enum
|
||||
*/
|
||||
typedef struct hint
|
||||
{
|
||||
HINT_TYPE type; /*< The Type of hint */
|
||||
void *data; /*< Type specific data */
|
||||
void *value; /*< Parameter value for hint */
|
||||
unsigned int dsize; /*< Size of the hint data */
|
||||
struct hint *next; /*< Another hint for this buffer */
|
||||
HINT_TYPE type; /*< The Type of hint */
|
||||
void* data; /*< Type specific data */
|
||||
void* value; /*< Parameter value for hint */
|
||||
unsigned int dsize; /*< Size of the hint data */
|
||||
struct hint* next; /*< Another hint for this buffer */
|
||||
} HINT;
|
||||
|
||||
HINT *hint_alloc(HINT_TYPE, void *, unsigned int);
|
||||
HINT *hint_create_parameter(HINT *, char *, const char *);
|
||||
HINT *hint_create_route(HINT *, HINT_TYPE, const char *);
|
||||
HINT *hint_splice(HINT *head, HINT *list);
|
||||
void hint_free(HINT *);
|
||||
HINT *hint_dup(const HINT *);
|
||||
bool hint_exists(HINT **, HINT_TYPE);
|
||||
HINT* hint_alloc(HINT_TYPE, void*, unsigned int);
|
||||
HINT* hint_create_parameter(HINT*, char*, const char*);
|
||||
HINT* hint_create_route(HINT*, HINT_TYPE, const char*);
|
||||
HINT* hint_splice(HINT* head, HINT* list);
|
||||
void hint_free(HINT*);
|
||||
HINT* hint_dup(const HINT*);
|
||||
bool hint_exists(HINT * *, HINT_TYPE);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file housekeeper.h A mechanism to have task run periodically
|
||||
@ -30,7 +30,7 @@ MXS_BEGIN_DECLS
|
||||
* executed again at a later point in time. If the function returns false,
|
||||
* the task is removed.
|
||||
*/
|
||||
typedef bool (*TASKFN)(void *data);
|
||||
typedef bool (* TASKFN)(void* data);
|
||||
|
||||
/**
|
||||
* Initialises the housekeeper mechanism.
|
||||
@ -70,21 +70,21 @@ void hkfinish();
|
||||
* @param data Data passed to function as the parameter
|
||||
* @param frequency Frequency of execution
|
||||
*/
|
||||
void hktask_add(const char *name, TASKFN func, void *data, int frequency);
|
||||
void hktask_add(const char* name, TASKFN func, void* data, int frequency);
|
||||
|
||||
/**
|
||||
* @brief Remove all tasks with this name
|
||||
*
|
||||
* @param name Task name
|
||||
*/
|
||||
void hktask_remove(const char *name);
|
||||
void hktask_remove(const char* name);
|
||||
|
||||
/**
|
||||
* @brief Show the tasks that are scheduled for the house keeper
|
||||
*
|
||||
* @param pDcb The DCB to send to output
|
||||
*/
|
||||
void hkshow_tasks(DCB *pdcb);
|
||||
void hkshow_tasks(DCB* pdcb);
|
||||
|
||||
/**
|
||||
* @brief Show tasks as JSON resource
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -26,7 +26,7 @@ static inline std::string http_get_date()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
struct tm tm;
|
||||
char buf[200]; // Enough to store all dates
|
||||
char buf[200]; // Enough to store all dates
|
||||
|
||||
gmtime_r(&now, &tm);
|
||||
strftime(buf, sizeof(buf), "%a, %d %b %y %T GMT", &tm);
|
||||
@ -44,7 +44,7 @@ static inline std::string http_get_date()
|
||||
static inline std::string http_to_date(time_t t)
|
||||
{
|
||||
struct tm tm;
|
||||
char buf[200]; // Enough to store all dates
|
||||
char buf[200]; // Enough to store all dates
|
||||
|
||||
gmtime_r(&t, &tm);
|
||||
strftime(buf, sizeof(buf), "%a, %d %b %Y %T GMT", &tm);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -33,7 +33,6 @@ struct default_delete<json_t>
|
||||
json_decref(pJson);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace maxscale
|
||||
@ -99,10 +98,8 @@ static inline std::string json_to_string(json_t* json)
|
||||
default:
|
||||
mxb_assert(false);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file Helper functions for creating JSON API conforming objects
|
||||
@ -24,19 +24,19 @@
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
/** Resource endpoints */
|
||||
#define MXS_JSON_API_SERVERS "/servers/"
|
||||
#define MXS_JSON_API_SERVICES "/services/"
|
||||
#define MXS_JSON_API_FILTERS "/filters/"
|
||||
#define MXS_JSON_API_MONITORS "/monitors/"
|
||||
#define MXS_JSON_API_SESSIONS "/sessions/"
|
||||
#define MXS_JSON_API_MAXSCALE "/maxscale/"
|
||||
#define MXS_JSON_API_THREADS "/maxscale/threads/"
|
||||
#define MXS_JSON_API_LOGS "/maxscale/logs/"
|
||||
#define MXS_JSON_API_TASKS "/maxscale/tasks/"
|
||||
#define MXS_JSON_API_MODULES "/maxscale/modules/"
|
||||
#define MXS_JSON_API_QC_STATS "/maxscale/qc_stats/"
|
||||
#define MXS_JSON_API_QC "/maxscale/query_classifier/"
|
||||
#define MXS_JSON_API_USERS "/users/"
|
||||
#define MXS_JSON_API_SERVERS "/servers/"
|
||||
#define MXS_JSON_API_SERVICES "/services/"
|
||||
#define MXS_JSON_API_FILTERS "/filters/"
|
||||
#define MXS_JSON_API_MONITORS "/monitors/"
|
||||
#define MXS_JSON_API_SESSIONS "/sessions/"
|
||||
#define MXS_JSON_API_MAXSCALE "/maxscale/"
|
||||
#define MXS_JSON_API_THREADS "/maxscale/threads/"
|
||||
#define MXS_JSON_API_LOGS "/maxscale/logs/"
|
||||
#define MXS_JSON_API_TASKS "/maxscale/tasks/"
|
||||
#define MXS_JSON_API_MODULES "/maxscale/modules/"
|
||||
#define MXS_JSON_API_QC_STATS "/maxscale/qc_stats/"
|
||||
#define MXS_JSON_API_QC "/maxscale/query_classifier/"
|
||||
#define MXS_JSON_API_USERS "/users/"
|
||||
|
||||
/**
|
||||
* @brief Create a JSON object
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file limits.h
|
||||
@ -42,14 +42,14 @@ MXS_BEGIN_DECLS
|
||||
*
|
||||
* The value used when setting SO_RCVBUF of client sockets.
|
||||
*/
|
||||
#define MXS_CLIENT_SO_RCVBUF (128 * 1024)
|
||||
#define MXS_CLIENT_SO_RCVBUF (128 * 1024)
|
||||
|
||||
/**
|
||||
* MXS_CLIENT_SO_SNDBUF
|
||||
*
|
||||
* The value used when setting SO_SNDBUF of client sockets.
|
||||
*/
|
||||
#define MXS_CLIENT_SO_SNDBUF (128 * 1024)
|
||||
#define MXS_CLIENT_SO_SNDBUF (128 * 1024)
|
||||
|
||||
/**
|
||||
* MXS_MAX_NW_READ_BUFFER_SIZE
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file listener.h
|
||||
@ -34,21 +34,22 @@ struct service;
|
||||
*/
|
||||
typedef struct servlistener
|
||||
{
|
||||
char *name; /**< Name of the listener */
|
||||
char *protocol; /**< Protocol module to load */
|
||||
unsigned short port; /**< Port to listen on */
|
||||
char *address; /**< Address to listen with */
|
||||
char *authenticator; /**< Name of authenticator */
|
||||
char *auth_options; /**< Authenticator options */
|
||||
void *auth_instance; /**< Authenticator instance created in MXS_AUTHENTICATOR::initialize() */
|
||||
SSL_LISTENER *ssl; /**< Structure of SSL data or NULL */
|
||||
struct dcb *listener; /**< The DCB for the listener */
|
||||
struct users *users; /**< The user data for this listener */
|
||||
struct service* service; /**< The service which used by this listener */
|
||||
SPINLOCK lock;
|
||||
int active; /**< True if the port has not been deleted */
|
||||
struct servlistener *next; /**< Next service protocol */
|
||||
} SERV_LISTENER; // TODO: Rename to LISTENER
|
||||
char* name; /**< Name of the listener */
|
||||
char* protocol; /**< Protocol module to load */
|
||||
unsigned short port; /**< Port to listen on */
|
||||
char* address; /**< Address to listen with */
|
||||
char* authenticator;/**< Name of authenticator */
|
||||
char* auth_options; /**< Authenticator options */
|
||||
void* auth_instance;/**< Authenticator instance created in MXS_AUTHENTICATOR::initialize()
|
||||
* */
|
||||
SSL_LISTENER* ssl; /**< Structure of SSL data or NULL */
|
||||
struct dcb* listener; /**< The DCB for the listener */
|
||||
struct users* users; /**< The user data for this listener */
|
||||
struct service* service; /**< The service which used by this listener */
|
||||
SPINLOCK lock;
|
||||
int active; /**< True if the port has not been deleted */
|
||||
struct servlistener* next; /**< Next service protocol */
|
||||
} SERV_LISTENER; // TODO: Rename to LISTENER
|
||||
|
||||
typedef struct listener_iterator
|
||||
{
|
||||
@ -65,7 +66,7 @@ typedef struct listener_iterator
|
||||
* @param listener Listener to serialize
|
||||
* @return True if the serialization of the listener was successful, false if it fails
|
||||
*/
|
||||
bool listener_serialize(const SERV_LISTENER *listener);
|
||||
bool listener_serialize(const SERV_LISTENER* listener);
|
||||
|
||||
/**
|
||||
* @brief Convert listener to JSON
|
||||
@ -76,12 +77,17 @@ bool listener_serialize(const SERV_LISTENER *listener);
|
||||
*/
|
||||
json_t* listener_to_json(const SERV_LISTENER* listener);
|
||||
|
||||
SERV_LISTENER* listener_alloc(struct service* service, const char* name, const char *protocol,
|
||||
const char *address, unsigned short port, const char *authenticator,
|
||||
const char* auth_options, SSL_LISTENER *ssl);
|
||||
SERV_LISTENER* listener_alloc(struct service* service,
|
||||
const char* name,
|
||||
const char* protocol,
|
||||
const char* address,
|
||||
unsigned short port,
|
||||
const char* authenticator,
|
||||
const char* auth_options,
|
||||
SSL_LISTENER* ssl);
|
||||
void listener_free(SERV_LISTENER* listener);
|
||||
int listener_set_ssl_version(SSL_LISTENER *ssl_listener, const char* version);
|
||||
void listener_set_certificates(SSL_LISTENER *ssl_listener, char* cert, char* key, char* ca_cert);
|
||||
int listener_set_ssl_version(SSL_LISTENER* ssl_listener, const char* version);
|
||||
void listener_set_certificates(SSL_LISTENER* ssl_listener, char* cert, char* key, char* ca_cert);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
@ -24,11 +24,11 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#if !defined(MXS_MODULE_NAME)
|
||||
#if !defined (MXS_MODULE_NAME)
|
||||
#define MXS_MODULE_NAME NULL
|
||||
#endif
|
||||
|
||||
#if !defined(MXB_MODULE_NAME)
|
||||
#if !defined (MXB_MODULE_NAME)
|
||||
#define MXB_MODULE_NAME MXS_MODULE_NAME
|
||||
#endif
|
||||
|
||||
@ -50,9 +50,9 @@ typedef MXB_LOG_THROTTLING MXS_LOG_THROTTLING;
|
||||
*/
|
||||
bool mxs_log_init(const char* ident, const char* logdir, mxs_log_target_t target);
|
||||
|
||||
#define mxs_log_finish mxb_log_finish
|
||||
#define mxs_log_message mxb_log_message
|
||||
#define mxs_log_rotate mxb_log_rotate
|
||||
#define mxs_log_finish mxb_log_finish
|
||||
#define mxs_log_message mxb_log_message
|
||||
#define mxs_log_rotate mxb_log_rotate
|
||||
|
||||
#define mxs_log_get_throttling mxb_log_get_throttling
|
||||
#define mxs_log_is_priority_enabled mxb_log_is_priority_enabled
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <mysql.h>
|
||||
@ -95,9 +95,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
SizesAndName(int64_t total,
|
||||
int64_t used,
|
||||
int64_t available,
|
||||
SizesAndName(int64_t total,
|
||||
int64_t used,
|
||||
int64_t available,
|
||||
const std::string& name)
|
||||
: Sizes(total, used, available)
|
||||
, m_name(name)
|
||||
@ -127,9 +127,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
SizesAndPaths(int64_t total,
|
||||
int64_t used,
|
||||
int64_t available,
|
||||
SizesAndPaths(int64_t total,
|
||||
int64_t used,
|
||||
int64_t available,
|
||||
const std::string& path)
|
||||
: Sizes(total, used, available)
|
||||
{
|
||||
@ -190,8 +190,5 @@ int get_info_by_path(MYSQL* pMysql, std::map<std::string, disk::SizesAndName>* p
|
||||
* version is too old or the plugin @c DISKS has not been installed.
|
||||
*/
|
||||
int get_info_by_disk(MYSQL* pMysql, std::map<std::string, disk::SizesAndPaths>* pInfo);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,26 +10,26 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <maxscale/paths.h>
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#define MAXADMIN_DEFAULT_SOCKET MXS_DEFAULT_MAXADMIN_SOCKET
|
||||
#define MAXADMIN_DEFAULT_SOCKET MXS_DEFAULT_MAXADMIN_SOCKET
|
||||
|
||||
#define MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG_LEN 7
|
||||
#define MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG "default"
|
||||
|
||||
#define MAXADMIN_AUTH_REPLY_LEN 6
|
||||
#define MAXADMIN_AUTH_FAILED_REPLY "FAILED"
|
||||
#define MAXADMIN_AUTH_SUCCESS_REPLY "OK----"
|
||||
#define MAXADMIN_AUTH_REPLY_LEN 6
|
||||
#define MAXADMIN_AUTH_FAILED_REPLY "FAILED"
|
||||
#define MAXADMIN_AUTH_SUCCESS_REPLY "OK----"
|
||||
|
||||
#define MAXADMIN_AUTH_USER_PROMPT "USER"
|
||||
#define MAXADMIN_AUTH_USER_PROMPT_LEN 4
|
||||
#define MAXADMIN_AUTH_USER_PROMPT "USER"
|
||||
#define MAXADMIN_AUTH_USER_PROMPT_LEN 4
|
||||
|
||||
#define MAXADMIN_AUTH_PASSWORD_PROMPT "PASSWORD"
|
||||
#define MAXADMIN_AUTH_PASSWORD_PROMPT_LEN 8
|
||||
#define MAXADMIN_AUTH_PASSWORD_PROMPT "PASSWORD"
|
||||
#define MAXADMIN_AUTH_PASSWORD_PROMPT_LEN 8
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,11 +10,11 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/maxscale.h Some general definitions for MaxScale
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file modinfo.h The module information interface
|
||||
@ -67,32 +67,32 @@ typedef enum
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
} MXS_MODULE_VERSION;
|
||||
|
||||
enum mxs_module_param_type
|
||||
{
|
||||
MXS_MODULE_PARAM_COUNT, /**< Non-negative number */
|
||||
MXS_MODULE_PARAM_INT, /**< Integer number */
|
||||
MXS_MODULE_PARAM_SIZE, /**< Size in bytes */
|
||||
MXS_MODULE_PARAM_BOOL, /**< Boolean value */
|
||||
MXS_MODULE_PARAM_STRING, /**< String value */
|
||||
MXS_MODULE_PARAM_QUOTEDSTRING, /**< String enclosed in '"':s */
|
||||
MXS_MODULE_PARAM_ENUM, /**< Enumeration of string values */
|
||||
MXS_MODULE_PARAM_PATH, /**< Path to a file or a directory */
|
||||
MXS_MODULE_PARAM_SERVICE, /**< Service name */
|
||||
MXS_MODULE_PARAM_SERVER, /**< Server name */
|
||||
MXS_MODULE_PARAM_SERVERLIST, /**< List of server names, separated by ',' */
|
||||
MXS_MODULE_PARAM_REGEX /**< A regex string enclosed in '/' */
|
||||
MXS_MODULE_PARAM_COUNT, /**< Non-negative number */
|
||||
MXS_MODULE_PARAM_INT, /**< Integer number */
|
||||
MXS_MODULE_PARAM_SIZE, /**< Size in bytes */
|
||||
MXS_MODULE_PARAM_BOOL, /**< Boolean value */
|
||||
MXS_MODULE_PARAM_STRING, /**< String value */
|
||||
MXS_MODULE_PARAM_QUOTEDSTRING, /**< String enclosed in '"':s */
|
||||
MXS_MODULE_PARAM_ENUM, /**< Enumeration of string values */
|
||||
MXS_MODULE_PARAM_PATH, /**< Path to a file or a directory */
|
||||
MXS_MODULE_PARAM_SERVICE, /**< Service name */
|
||||
MXS_MODULE_PARAM_SERVER, /**< Server name */
|
||||
MXS_MODULE_PARAM_SERVERLIST, /**< List of server names, separated by ',' */
|
||||
MXS_MODULE_PARAM_REGEX /**< A regex string enclosed in '/' */
|
||||
};
|
||||
|
||||
/** Maximum and minimum values for integer types */
|
||||
#define MXS_MODULE_PARAM_COUNT_MAX "2147483647"
|
||||
#define MXS_MODULE_PARAM_COUNT_MIN "0"
|
||||
#define MXS_MODULE_PARAM_INT_MAX "2147483647"
|
||||
#define MXS_MODULE_PARAM_INT_MIN "-2147483647"
|
||||
#define MXS_MODULE_PARAM_INT_MAX "2147483647"
|
||||
#define MXS_MODULE_PARAM_INT_MIN "-2147483647"
|
||||
|
||||
/** Parameter options
|
||||
*
|
||||
@ -101,34 +101,35 @@ enum mxs_module_param_type
|
||||
enum mxs_module_param_options
|
||||
{
|
||||
MXS_MODULE_OPT_NONE = 0,
|
||||
MXS_MODULE_OPT_REQUIRED = (1 << 0), /**< A required parameter */
|
||||
MXS_MODULE_OPT_PATH_X_OK = (1 << 1), /**< PATH: Execute permission to path required */
|
||||
MXS_MODULE_OPT_PATH_R_OK = (1 << 2), /**< PATH: Read permission to path required */
|
||||
MXS_MODULE_OPT_PATH_W_OK = (1 << 3), /**< PATH: Write permission to path required */
|
||||
MXS_MODULE_OPT_PATH_F_OK = (1 << 4), /**< PATH: Path must exist */
|
||||
MXS_MODULE_OPT_PATH_CREAT = (1 << 5), /**< PATH: Create path if it doesn't exist */
|
||||
MXS_MODULE_OPT_ENUM_UNIQUE = (1 << 6), /**< ENUM: Only one value can be defined */
|
||||
MXS_MODULE_OPT_REQUIRED = (1 << 0), /**< A required parameter */
|
||||
MXS_MODULE_OPT_PATH_X_OK = (1 << 1), /**< PATH: Execute permission to path required */
|
||||
MXS_MODULE_OPT_PATH_R_OK = (1 << 2), /**< PATH: Read permission to path required */
|
||||
MXS_MODULE_OPT_PATH_W_OK = (1 << 3), /**< PATH: Write permission to path required */
|
||||
MXS_MODULE_OPT_PATH_F_OK = (1 << 4), /**< PATH: Path must exist */
|
||||
MXS_MODULE_OPT_PATH_CREAT = (1 << 5), /**< PATH: Create path if it doesn't exist */
|
||||
MXS_MODULE_OPT_ENUM_UNIQUE = (1 << 6), /**< ENUM: Only one value can be defined */
|
||||
|
||||
/**< Parameter is deprecated: Causes a warning to be logged if the parameter
|
||||
* is used but will not cause a configuration error. */
|
||||
MXS_MODULE_OPT_DEPRECATED = (1 << 7),
|
||||
MXS_MODULE_OPT_DEPRECATED = (1 << 7),
|
||||
};
|
||||
|
||||
/** String to enum value mappings */
|
||||
typedef struct mxs_enum_value
|
||||
{
|
||||
const char *name; /**< Name of the enum value */
|
||||
const char* name; /**< Name of the enum value */
|
||||
uint64_t enum_value; /**< The integer value of the enum */
|
||||
} MXS_ENUM_VALUE;
|
||||
|
||||
/** Module parameter declaration */
|
||||
typedef struct mxs_module_param
|
||||
{
|
||||
const char *name; /**< Name of the parameter */
|
||||
enum mxs_module_param_type type; /**< Type of the parameter */
|
||||
const char *default_value; /**< Default value for the parameter, NULL for no default value */
|
||||
uint64_t options; /**< Parameter options */
|
||||
const MXS_ENUM_VALUE *accepted_values; /**< Only for enum values */
|
||||
const char* name; /**< Name of the parameter */
|
||||
enum mxs_module_param_type type; /**< Type of the parameter */
|
||||
const char* default_value; /**< Default value for the parameter, NULL for no default
|
||||
* value */
|
||||
uint64_t options; /**< Parameter options */
|
||||
const MXS_ENUM_VALUE* accepted_values; /**< Only for enum values */
|
||||
} MXS_MODULE_PARAM;
|
||||
|
||||
/** Maximum number of parameters that modules can declare */
|
||||
@ -139,26 +140,26 @@ typedef struct mxs_module_param
|
||||
*/
|
||||
typedef struct mxs_module
|
||||
{
|
||||
MXS_MODULE_API modapi; /**< Module API type */
|
||||
MXS_MODULE_STATUS status; /**< Module development status */
|
||||
MXS_MODULE_VERSION api_version; /**< Module API version */
|
||||
const char *description; /**< Module description */
|
||||
const char *version; /**< Module version */
|
||||
uint64_t module_capabilities; /**< Declared module capabilities */
|
||||
void *module_object; /**< Module type specific API implementation */
|
||||
MXS_MODULE_API modapi; /**< Module API type */
|
||||
MXS_MODULE_STATUS status; /**< Module development status */
|
||||
MXS_MODULE_VERSION api_version; /**< Module API version */
|
||||
const char* description; /**< Module description */
|
||||
const char* version; /**< Module version */
|
||||
uint64_t module_capabilities; /**< Declared module capabilities */
|
||||
void* module_object; /**< Module type specific API implementation */
|
||||
/**
|
||||
* If non-NULL, this function is called once at process startup. If the
|
||||
* function fails, MariaDB MaxScale will not start.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int (*process_init)();
|
||||
int (* process_init)();
|
||||
|
||||
/**
|
||||
* If non-NULL, this function is called once at process shutdown, provided
|
||||
* the call to @c init succeeded.
|
||||
*/
|
||||
void (*process_finish)();
|
||||
void (* process_finish)();
|
||||
|
||||
/**
|
||||
* If non-NULL, this function is called once at the startup of every new thread.
|
||||
@ -168,7 +169,7 @@ typedef struct mxs_module
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int (*thread_init)();
|
||||
int (* thread_init)();
|
||||
|
||||
/**
|
||||
* If non-NULL, this function is called when a thread terminates, provided the
|
||||
@ -176,9 +177,9 @@ typedef struct mxs_module
|
||||
*
|
||||
* @attention This function is *not* called for the thread where @c init is called.
|
||||
*/
|
||||
void (*thread_finish)();
|
||||
void (* thread_finish)();
|
||||
|
||||
MXS_MODULE_PARAM parameters[MXS_MODULE_PARAM_MAX + 1]; /**< Declared parameters */
|
||||
MXS_MODULE_PARAM parameters[MXS_MODULE_PARAM_MAX + 1]; /**< Declared parameters */
|
||||
} MXS_MODULE;
|
||||
|
||||
/**
|
||||
@ -231,28 +232,40 @@ static inline const char* mxs_module_param_type_to_string(enum mxs_module_param_
|
||||
{
|
||||
case MXS_MODULE_PARAM_COUNT:
|
||||
return "count";
|
||||
|
||||
case MXS_MODULE_PARAM_INT:
|
||||
return "int";
|
||||
|
||||
case MXS_MODULE_PARAM_SIZE:
|
||||
return "size";
|
||||
|
||||
case MXS_MODULE_PARAM_BOOL:
|
||||
return "bool";
|
||||
|
||||
case MXS_MODULE_PARAM_STRING:
|
||||
return "string";
|
||||
|
||||
case MXS_MODULE_PARAM_QUOTEDSTRING:
|
||||
return "quoted string";
|
||||
|
||||
case MXS_MODULE_PARAM_ENUM:
|
||||
return "enum";
|
||||
|
||||
case MXS_MODULE_PARAM_PATH:
|
||||
return "path";
|
||||
|
||||
case MXS_MODULE_PARAM_SERVICE:
|
||||
return "service";
|
||||
|
||||
case MXS_MODULE_PARAM_SERVER:
|
||||
return "server";
|
||||
|
||||
case MXS_MODULE_PARAM_SERVERLIST:
|
||||
return "serverlist";
|
||||
|
||||
case MXS_MODULE_PARAM_REGEX:
|
||||
return "regular expression";
|
||||
|
||||
default:
|
||||
mxb_assert(!true);
|
||||
return "unknown";
|
||||
@ -265,16 +278,22 @@ static inline const char* mxs_module_api_to_string(MXS_MODULE_API type)
|
||||
{
|
||||
case MXS_MODULE_API_PROTOCOL:
|
||||
return "protocol";
|
||||
|
||||
case MXS_MODULE_API_ROUTER:
|
||||
return "router";
|
||||
|
||||
case MXS_MODULE_API_MONITOR:
|
||||
return "monitor";
|
||||
|
||||
case MXS_MODULE_API_FILTER:
|
||||
return "filter";
|
||||
|
||||
case MXS_MODULE_API_AUTHENTICATOR:
|
||||
return "authenticator";
|
||||
|
||||
case MXS_MODULE_API_QUERY_CLASSIFIER:
|
||||
return "query_classifier";
|
||||
|
||||
default:
|
||||
mxb_assert(!true);
|
||||
return "unknown";
|
||||
@ -287,14 +306,19 @@ static inline const char* mxs_module_status_to_string(MXS_MODULE_STATUS type)
|
||||
{
|
||||
case MXS_MODULE_IN_DEVELOPMENT:
|
||||
return "In development";
|
||||
|
||||
case MXS_MODULE_ALPHA_RELEASE:
|
||||
return "Alpha";
|
||||
|
||||
case MXS_MODULE_BETA_RELEASE:
|
||||
return "Beta";
|
||||
|
||||
case MXS_MODULE_GA:
|
||||
return "GA";
|
||||
|
||||
case MXS_MODULE_EXPERIMENTAL:
|
||||
return "Experimental";
|
||||
|
||||
default:
|
||||
mxb_assert(!true);
|
||||
return "Unknown";
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file module_command.h Module driven commands
|
||||
@ -44,8 +44,8 @@ MXS_BEGIN_DECLS
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t type; /**< The argument type and options */
|
||||
const char *description; /**< The argument description */
|
||||
uint64_t type; /**< The argument type and options */
|
||||
const char* description;/**< The argument description */
|
||||
} modulecmd_arg_type_t;
|
||||
|
||||
/**
|
||||
@ -53,15 +53,15 @@ typedef struct
|
||||
* the modulecmd_arg_type_t type's @c value member. An argument can be of
|
||||
* only one type.
|
||||
*/
|
||||
#define MODULECMD_ARG_NONE 0 /**< Empty argument */
|
||||
#define MODULECMD_ARG_STRING 1 /**< String */
|
||||
#define MODULECMD_ARG_BOOLEAN 2 /**< Boolean value */
|
||||
#define MODULECMD_ARG_SERVICE 3 /**< Service */
|
||||
#define MODULECMD_ARG_SERVER 4 /**< Server */
|
||||
#define MODULECMD_ARG_SESSION 6 /**< Session */
|
||||
#define MODULECMD_ARG_DCB 8 /**< DCB */
|
||||
#define MODULECMD_ARG_MONITOR 9 /**< Monitor */
|
||||
#define MODULECMD_ARG_FILTER 10 /**< Filter */
|
||||
#define MODULECMD_ARG_NONE 0 /**< Empty argument */
|
||||
#define MODULECMD_ARG_STRING 1 /**< String */
|
||||
#define MODULECMD_ARG_BOOLEAN 2 /**< Boolean value */
|
||||
#define MODULECMD_ARG_SERVICE 3 /**< Service */
|
||||
#define MODULECMD_ARG_SERVER 4 /**< Server */
|
||||
#define MODULECMD_ARG_SESSION 6 /**< Session */
|
||||
#define MODULECMD_ARG_DCB 8 /**< DCB */
|
||||
#define MODULECMD_ARG_MONITOR 9 /**< Monitor */
|
||||
#define MODULECMD_ARG_FILTER 10 /**< Filter */
|
||||
|
||||
/** What type of an action does the command perform? */
|
||||
enum modulecmd_type
|
||||
@ -73,31 +73,31 @@ enum modulecmd_type
|
||||
/**
|
||||
* Options for arguments, bits 9 through 32
|
||||
*/
|
||||
#define MODULECMD_ARG_OPTIONAL (1 << 8) /**< The argument is optional */
|
||||
#define MODULECMD_ARG_NAME_MATCHES_DOMAIN (1 << 9) /**< Argument module name must match domain name */
|
||||
#define MODULECMD_ARG_OPTIONAL (1 << 8) /**< The argument is optional */
|
||||
#define MODULECMD_ARG_NAME_MATCHES_DOMAIN (1 << 9) /**< Argument module name must match domain name */
|
||||
|
||||
/**
|
||||
* Helper macros
|
||||
*/
|
||||
#define MODULECMD_GET_TYPE(t) ((t)->type & 0xff)
|
||||
#define MODULECMD_ARG_IS_REQUIRED(t) (((t)->type & MODULECMD_ARG_OPTIONAL) == 0)
|
||||
#define MODULECMD_GET_TYPE(t) ((t)->type & 0xff)
|
||||
#define MODULECMD_ARG_IS_REQUIRED(t) (((t)->type & MODULECMD_ARG_OPTIONAL) == 0)
|
||||
#define MODULECMD_ALLOW_NAME_MISMATCH(t) (((t)->type & MODULECMD_ARG_NAME_MATCHES_DOMAIN) == 0)
|
||||
#define MODULECMD_ARG_PRESENT(t) (MODULECMD_GET_TYPE(t) != MODULECMD_ARG_NONE)
|
||||
#define MODULECMD_ARG_PRESENT(t) (MODULECMD_GET_TYPE(t) != MODULECMD_ARG_NONE)
|
||||
|
||||
/** Argument list node */
|
||||
struct arg_node
|
||||
{
|
||||
modulecmd_arg_type_t type;
|
||||
modulecmd_arg_type_t type;
|
||||
union
|
||||
{
|
||||
char *string;
|
||||
bool boolean;
|
||||
SERVICE *service;
|
||||
SERVER *server;
|
||||
MXS_SESSION *session;
|
||||
DCB *dcb;
|
||||
MXS_MONITOR *monitor;
|
||||
MXS_FILTER_DEF *filter;
|
||||
char* string;
|
||||
bool boolean;
|
||||
SERVICE* service;
|
||||
SERVER* server;
|
||||
MXS_SESSION* session;
|
||||
DCB* dcb;
|
||||
MXS_MONITOR* monitor;
|
||||
MXS_FILTER_DEF* filter;
|
||||
} value;
|
||||
};
|
||||
|
||||
@ -105,7 +105,7 @@ struct arg_node
|
||||
typedef struct
|
||||
{
|
||||
int argc;
|
||||
struct arg_node *argv;
|
||||
struct arg_node* argv;
|
||||
} MODULECMD_ARG;
|
||||
|
||||
/**
|
||||
@ -129,22 +129,22 @@ typedef struct
|
||||
*
|
||||
* @return True on success, false on error
|
||||
*/
|
||||
typedef bool (*MODULECMDFN)(const MODULECMD_ARG *argv, json_t** output);
|
||||
typedef bool (* MODULECMDFN)(const MODULECMD_ARG* argv, json_t** output);
|
||||
|
||||
/**
|
||||
* A registered command
|
||||
*/
|
||||
typedef struct modulecmd
|
||||
{
|
||||
char *identifier; /**< Unique identifier */
|
||||
char *domain; /**< Command domain */
|
||||
char *description; /**< Command description */
|
||||
enum modulecmd_type type; /**< Command type, either active or passive */
|
||||
MODULECMDFN func; /**< The registered function */
|
||||
int arg_count_min; /**< Minimum number of arguments */
|
||||
int arg_count_max; /**< Maximum number of arguments */
|
||||
modulecmd_arg_type_t *arg_types; /**< Argument types */
|
||||
struct modulecmd *next; /**< Next command */
|
||||
char* identifier; /**< Unique identifier */
|
||||
char* domain; /**< Command domain */
|
||||
char* description; /**< Command description */
|
||||
enum modulecmd_type type; /**< Command type, either active or passive */
|
||||
MODULECMDFN func; /**< The registered function */
|
||||
int arg_count_min;/**< Minimum number of arguments */
|
||||
int arg_count_max;/**< Maximum number of arguments */
|
||||
modulecmd_arg_type_t* arg_types; /**< Argument types */
|
||||
struct modulecmd* next; /**< Next command */
|
||||
} MODULECMD;
|
||||
|
||||
/** Check if the module command can modify the data/state of the module */
|
||||
@ -164,10 +164,13 @@ typedef struct modulecmd
|
||||
*
|
||||
* @return True if the module was successfully registered, false on error
|
||||
*/
|
||||
bool modulecmd_register_command(const char *domain, const char *identifier,
|
||||
enum modulecmd_type type, MODULECMDFN entry_point,
|
||||
int argc, modulecmd_arg_type_t *argv,
|
||||
const char *description);
|
||||
bool modulecmd_register_command(const char* domain,
|
||||
const char* identifier,
|
||||
enum modulecmd_type type,
|
||||
MODULECMDFN entry_point,
|
||||
int argc,
|
||||
modulecmd_arg_type_t* argv,
|
||||
const char* description);
|
||||
|
||||
/**
|
||||
* @brief Find a registered command
|
||||
@ -176,7 +179,7 @@ bool modulecmd_register_command(const char *domain, const char *identifier,
|
||||
* @param identifier Command identifier
|
||||
* @return Registered command or NULL if no command was found
|
||||
*/
|
||||
const MODULECMD* modulecmd_find_command(const char *domain, const char *identifier);
|
||||
const MODULECMD* modulecmd_find_command(const char* domain, const char* identifier);
|
||||
|
||||
/**
|
||||
* @brief Parse arguments for a command
|
||||
@ -199,13 +202,13 @@ const MODULECMD* modulecmd_find_command(const char *domain, const char *identifi
|
||||
* @param argv Argument list in string format of size @c argc
|
||||
* @return Parsed arguments or NULL on error
|
||||
*/
|
||||
MODULECMD_ARG* modulecmd_arg_parse(const MODULECMD *cmd, int argc, const void **argv);
|
||||
MODULECMD_ARG* modulecmd_arg_parse(const MODULECMD* cmd, int argc, const void** argv);
|
||||
|
||||
/**
|
||||
* @brief Free parsed arguments returned by modulecmd_arg_parse
|
||||
* @param arg Arguments to free
|
||||
*/
|
||||
void modulecmd_arg_free(MODULECMD_ARG *arg);
|
||||
void modulecmd_arg_free(MODULECMD_ARG* arg);
|
||||
|
||||
/**
|
||||
* @brief Check if an optional argument was defined
|
||||
@ -217,7 +220,7 @@ void modulecmd_arg_free(MODULECMD_ARG *arg);
|
||||
* @param idx Index of the argument, starts at 0
|
||||
* @return True if the optional argument is present
|
||||
*/
|
||||
bool modulecmd_arg_is_present(const MODULECMD_ARG *arg, int idx);
|
||||
bool modulecmd_arg_is_present(const MODULECMD_ARG* arg, int idx);
|
||||
|
||||
/**
|
||||
* @brief Call a registered command
|
||||
@ -232,7 +235,7 @@ bool modulecmd_arg_is_present(const MODULECMD_ARG *arg, int idx);
|
||||
*
|
||||
* @return True on success, false on error
|
||||
*/
|
||||
bool modulecmd_call_command(const MODULECMD *cmd, const MODULECMD_ARG *args, json_t** output);
|
||||
bool modulecmd_call_command(const MODULECMD* cmd, const MODULECMD_ARG* args, json_t** output);
|
||||
|
||||
/**
|
||||
* @brief Set the current error message
|
||||
@ -243,7 +246,7 @@ bool modulecmd_call_command(const MODULECMD *cmd, const MODULECMD_ARG *args, jso
|
||||
* @param format Format string
|
||||
* @param ... Format string arguments
|
||||
*/
|
||||
void modulecmd_set_error(const char *format, ...) mxs_attribute((format (printf, 1, 2)));
|
||||
void modulecmd_set_error(const char* format, ...) mxs_attribute((format (printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* @brief Get the latest error generated by the modulecmd system
|
||||
@ -282,8 +285,10 @@ json_t* modulecmd_get_json_error();
|
||||
* @return True on success, false on PCRE2 error. Use modulecmd_get_error()
|
||||
* to retrieve the error.
|
||||
*/
|
||||
bool modulecmd_foreach(const char *domain_re, const char *ident_re,
|
||||
bool(*fn)(const MODULECMD *cmd, void *data), void *data);
|
||||
bool modulecmd_foreach(const char* domain_re,
|
||||
const char* ident_re,
|
||||
bool (* fn)(const MODULECMD* cmd, void* data),
|
||||
void* data);
|
||||
|
||||
/**
|
||||
* @brief Return argument type as string
|
||||
@ -294,6 +299,6 @@ bool modulecmd_foreach(const char *domain_re, const char *ident_re,
|
||||
* @param type Type to convert
|
||||
* @return New string or NULL on memory allocation error
|
||||
*/
|
||||
const char* modulecmd_argtype_to_str(modulecmd_arg_type_t *type);
|
||||
const char* modulecmd_argtype_to_str(modulecmd_arg_type_t* type);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file modutil.h A set of useful routines for module writers
|
||||
@ -24,34 +24,34 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#define PTR_IS_RESULTSET(b) (b[0] == 0x01 && b[1] == 0x0 && b[2] == 0x0 && b[3] == 0x01)
|
||||
#define PTR_IS_EOF(b) (b[0] == 0x05 && b[1] == 0x0 && b[2] == 0x0 && b[4] == 0xfe)
|
||||
#define PTR_IS_OK(b) (b[4] == 0x00)
|
||||
#define PTR_IS_ERR(b) (b[4] == 0xff)
|
||||
#define PTR_IS_RESULTSET(b) (b[0] == 0x01 && b[1] == 0x0 && b[2] == 0x0 && b[3] == 0x01)
|
||||
#define PTR_IS_EOF(b) (b[0] == 0x05 && b[1] == 0x0 && b[2] == 0x0 && b[4] == 0xfe)
|
||||
#define PTR_IS_OK(b) (b[4] == 0x00)
|
||||
#define PTR_IS_ERR(b) (b[4] == 0xff)
|
||||
#define PTR_IS_LOCAL_INFILE(b) (b[4] == 0xfb)
|
||||
#define IS_FULL_RESPONSE(buf) (modutil_count_signal_packets(buf,0,0) == 2)
|
||||
#define IS_FULL_RESPONSE(buf) (modutil_count_signal_packets(buf, 0, 0) == 2)
|
||||
|
||||
extern int modutil_is_SQL(GWBUF *);
|
||||
extern int modutil_is_SQL_prepare(GWBUF *);
|
||||
extern int modutil_extract_SQL(GWBUF *, char **, int *);
|
||||
extern int modutil_MySQL_Query(GWBUF *, char **, int *, int *);
|
||||
extern char* modutil_get_SQL(GWBUF *);
|
||||
extern GWBUF* modutil_replace_SQL(GWBUF *, char *);
|
||||
extern char* modutil_get_query(GWBUF* buf);
|
||||
extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *);
|
||||
GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf);
|
||||
GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf);
|
||||
int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing);
|
||||
void modutil_reply_parse_error(DCB* backend_dcb, char* errstr, uint32_t flags);
|
||||
void modutil_reply_auth_error(DCB* backend_dcb, char* errstr, uint32_t flags);
|
||||
int modutil_count_statements(GWBUF* buffer);
|
||||
int modutil_count_packets(GWBUF* buffer);
|
||||
GWBUF* modutil_create_query(const char* query);
|
||||
GWBUF* modutil_create_mysql_err_msg(int packet_number,
|
||||
int affected_rows,
|
||||
int merrno,
|
||||
const char *statemsg,
|
||||
const char *msg);
|
||||
extern int modutil_is_SQL(GWBUF*);
|
||||
extern int modutil_is_SQL_prepare(GWBUF*);
|
||||
extern int modutil_extract_SQL(GWBUF*, char**, int*);
|
||||
extern int modutil_MySQL_Query(GWBUF*, char**, int*, int*);
|
||||
extern char* modutil_get_SQL(GWBUF*);
|
||||
extern GWBUF* modutil_replace_SQL(GWBUF*, char*);
|
||||
extern char* modutil_get_query(GWBUF* buf);
|
||||
extern int modutil_send_mysql_err_packet(DCB*, int, int, int, const char*, const char*);
|
||||
GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf);
|
||||
GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf);
|
||||
int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing);
|
||||
void modutil_reply_parse_error(DCB* backend_dcb, char* errstr, uint32_t flags);
|
||||
void modutil_reply_auth_error(DCB* backend_dcb, char* errstr, uint32_t flags);
|
||||
int modutil_count_statements(GWBUF* buffer);
|
||||
int modutil_count_packets(GWBUF* buffer);
|
||||
GWBUF* modutil_create_query(const char* query);
|
||||
GWBUF* modutil_create_mysql_err_msg(int packet_number,
|
||||
int affected_rows,
|
||||
int merrno,
|
||||
const char* statemsg,
|
||||
const char* msg);
|
||||
|
||||
/** Struct used for tracking the state inside the modutil functions */
|
||||
typedef struct
|
||||
@ -82,7 +82,7 @@ typedef struct
|
||||
*
|
||||
* @return Total number of EOF and ERR packets including the ones already found
|
||||
*/
|
||||
int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more, modutil_state* state);
|
||||
int modutil_count_signal_packets(GWBUF* reply, int n_found, bool* more, modutil_state* state);
|
||||
|
||||
mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* string);
|
||||
|
||||
@ -111,13 +111,13 @@ char* modutil_MySQL_bypass_whitespace(char* sql, size_t len);
|
||||
* @param dcb The backend DCB where the COM_PING is written
|
||||
* @return True if command was successfully sent
|
||||
*/
|
||||
bool modutil_ignorable_ping(DCB *dcb);
|
||||
bool modutil_ignorable_ping(DCB* dcb);
|
||||
|
||||
/** Character and token searching functions */
|
||||
char* strnchr_esc(char* ptr, char c, int len);
|
||||
char* strnchr_esc_mysql(char* ptr, char c, int len);
|
||||
bool is_mysql_statement_end(const char* start, int len);
|
||||
bool is_mysql_sp_end(const char* start, int len);
|
||||
bool is_mysql_statement_end(const char* start, int len);
|
||||
bool is_mysql_sp_end(const char* start, int len);
|
||||
char* modutil_get_canonical(GWBUF* querybuf);
|
||||
|
||||
// TODO: Move modutil out of the core
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file modutil.hh C++ additions/alternatives for modutil.h functions
|
||||
@ -27,5 +27,4 @@ namespace maxscale
|
||||
std::string extract_sql(GWBUF* buffer, size_t len = -1);
|
||||
|
||||
std::string get_canonical(GWBUF* querybuf);
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/monitor.h - The public monitor interface
|
||||
@ -79,7 +79,7 @@ typedef struct mxs_monitor_api
|
||||
* @return Pointer to the monitor specific data. Will be stored
|
||||
* in @c monitor->handle.
|
||||
*/
|
||||
MXS_MONITOR_INSTANCE *(*createInstance)(MXS_MONITOR *monitor);
|
||||
MXS_MONITOR_INSTANCE*(*createInstance)(MXS_MONITOR * monitor);
|
||||
|
||||
/**
|
||||
* @brief Destroy the monitor.
|
||||
@ -90,7 +90,7 @@ typedef struct mxs_monitor_api
|
||||
*
|
||||
* @param monitor The monitor object.
|
||||
*/
|
||||
void (*destroyInstance)(MXS_MONITOR_INSTANCE *monitor);
|
||||
void (* destroyInstance)(MXS_MONITOR_INSTANCE* monitor);
|
||||
|
||||
/**
|
||||
* @brief Start the monitor
|
||||
@ -104,8 +104,8 @@ typedef struct mxs_monitor_api
|
||||
*
|
||||
* @return True, if the monitor could be started, false otherwise.
|
||||
*/
|
||||
bool (*startMonitor)(MXS_MONITOR_INSTANCE *monitor,
|
||||
const MXS_CONFIG_PARAMETER *params);
|
||||
bool (* startMonitor)(MXS_MONITOR_INSTANCE* monitor,
|
||||
const MXS_CONFIG_PARAMETER* params);
|
||||
|
||||
/**
|
||||
* @brief Stop the monitor
|
||||
@ -115,7 +115,7 @@ typedef struct mxs_monitor_api
|
||||
*
|
||||
* @param monitor The monitor object
|
||||
*/
|
||||
void (*stopMonitor)(MXS_MONITOR_INSTANCE *monitor);
|
||||
void (* stopMonitor)(MXS_MONITOR_INSTANCE* monitor);
|
||||
|
||||
/**
|
||||
* @brief Write diagnostic information to a DCB.
|
||||
@ -123,7 +123,7 @@ typedef struct mxs_monitor_api
|
||||
* @param monitor The monitor object.
|
||||
* @param dcb The dcb to write to.
|
||||
*/
|
||||
void (*diagnostics)(const MXS_MONITOR_INSTANCE* monitor, DCB* dcb);
|
||||
void (* diagnostics)(const MXS_MONITOR_INSTANCE* monitor, DCB* dcb);
|
||||
|
||||
/**
|
||||
* @brief Return diagnostic information about the monitor
|
||||
@ -134,7 +134,7 @@ typedef struct mxs_monitor_api
|
||||
*
|
||||
* @see jansson.h
|
||||
*/
|
||||
json_t* (*diagnostics_json)(const MXS_MONITOR_INSTANCE *monitor);
|
||||
json_t* (*diagnostics_json)(const MXS_MONITOR_INSTANCE * monitor);
|
||||
} MXS_MONITOR_API;
|
||||
|
||||
/**
|
||||
@ -153,13 +153,13 @@ typedef struct mxs_monitor_api
|
||||
*/
|
||||
typedef enum monitor_capability
|
||||
{
|
||||
MCAP_TYPE_NONE = 0x0 // TODO: remove once monitor capabilities are defined
|
||||
MCAP_TYPE_NONE = 0x0 // TODO: remove once monitor capabilities are defined
|
||||
} monitor_capability_t;
|
||||
|
||||
/** Monitor's poll frequency */
|
||||
#define MXS_MON_BASE_INTERVAL_MS 100
|
||||
|
||||
#define MXS_MONITOR_DEFAULT_ID 1UL // unsigned long value
|
||||
#define MXS_MONITOR_DEFAULT_ID 1UL // unsigned long value
|
||||
|
||||
#define MAX_MONITOR_USER_LEN 512
|
||||
#define MAX_MONITOR_PASSWORD_LEN 512
|
||||
@ -186,28 +186,28 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
UNDEFINED_EVENT = 0,
|
||||
MASTER_DOWN_EVENT = (1 << 0), /**< master_down */
|
||||
MASTER_UP_EVENT = (1 << 1), /**< master_up */
|
||||
SLAVE_DOWN_EVENT = (1 << 2), /**< slave_down */
|
||||
SLAVE_UP_EVENT = (1 << 3), /**< slave_up */
|
||||
SERVER_DOWN_EVENT = (1 << 4), /**< server_down */
|
||||
SERVER_UP_EVENT = (1 << 5), /**< server_up */
|
||||
SYNCED_DOWN_EVENT = (1 << 6), /**< synced_down */
|
||||
SYNCED_UP_EVENT = (1 << 7), /**< synced_up */
|
||||
DONOR_DOWN_EVENT = (1 << 8), /**< donor_down */
|
||||
DONOR_UP_EVENT = (1 << 9), /**< donor_up */
|
||||
NDB_DOWN_EVENT = (1 << 10), /**< ndb_down */
|
||||
NDB_UP_EVENT = (1 << 11), /**< ndb_up */
|
||||
LOST_MASTER_EVENT = (1 << 12), /**< lost_master */
|
||||
LOST_SLAVE_EVENT = (1 << 13), /**< lost_slave */
|
||||
LOST_SYNCED_EVENT = (1 << 14), /**< lost_synced */
|
||||
LOST_DONOR_EVENT = (1 << 15), /**< lost_donor */
|
||||
LOST_NDB_EVENT = (1 << 16), /**< lost_ndb */
|
||||
NEW_MASTER_EVENT = (1 << 17), /**< new_master */
|
||||
NEW_SLAVE_EVENT = (1 << 18), /**< new_slave */
|
||||
NEW_SYNCED_EVENT = (1 << 19), /**< new_synced */
|
||||
NEW_DONOR_EVENT = (1 << 20), /**< new_donor */
|
||||
NEW_NDB_EVENT = (1 << 21), /**< new_ndb */
|
||||
MASTER_DOWN_EVENT = (1 << 0), /**< master_down */
|
||||
MASTER_UP_EVENT = (1 << 1), /**< master_up */
|
||||
SLAVE_DOWN_EVENT = (1 << 2), /**< slave_down */
|
||||
SLAVE_UP_EVENT = (1 << 3), /**< slave_up */
|
||||
SERVER_DOWN_EVENT = (1 << 4), /**< server_down */
|
||||
SERVER_UP_EVENT = (1 << 5), /**< server_up */
|
||||
SYNCED_DOWN_EVENT = (1 << 6), /**< synced_down */
|
||||
SYNCED_UP_EVENT = (1 << 7), /**< synced_up */
|
||||
DONOR_DOWN_EVENT = (1 << 8), /**< donor_down */
|
||||
DONOR_UP_EVENT = (1 << 9), /**< donor_up */
|
||||
NDB_DOWN_EVENT = (1 << 10), /**< ndb_down */
|
||||
NDB_UP_EVENT = (1 << 11), /**< ndb_up */
|
||||
LOST_MASTER_EVENT = (1 << 12), /**< lost_master */
|
||||
LOST_SLAVE_EVENT = (1 << 13), /**< lost_slave */
|
||||
LOST_SYNCED_EVENT = (1 << 14), /**< lost_synced */
|
||||
LOST_DONOR_EVENT = (1 << 15), /**< lost_donor */
|
||||
LOST_NDB_EVENT = (1 << 16), /**< lost_ndb */
|
||||
NEW_MASTER_EVENT = (1 << 17), /**< new_master */
|
||||
NEW_SLAVE_EVENT = (1 << 18), /**< new_slave */
|
||||
NEW_SYNCED_EVENT = (1 << 19), /**< new_synced */
|
||||
NEW_DONOR_EVENT = (1 << 20), /**< new_donor */
|
||||
NEW_NDB_EVENT = (1 << 21), /**< new_ndb */
|
||||
} mxs_monitor_event_t;
|
||||
|
||||
/**
|
||||
@ -215,14 +215,14 @@ typedef enum
|
||||
*/
|
||||
typedef struct monitored_server
|
||||
{
|
||||
SERVER *server; /**< The server being monitored */
|
||||
MYSQL *con; /**< The MySQL connection */
|
||||
bool log_version_err;
|
||||
int mon_err_count;
|
||||
uint64_t mon_prev_status; /**< Status before starting the current monitor loop */
|
||||
uint64_t pending_status; /**< Status during current monitor loop */
|
||||
int64_t disk_space_checked; /**< When was the disk space checked the last time */
|
||||
struct monitored_server *next; /**< The next server in the list */
|
||||
SERVER* server;/**< The server being monitored */
|
||||
MYSQL* con; /**< The MySQL connection */
|
||||
bool log_version_err;
|
||||
int mon_err_count;
|
||||
uint64_t mon_prev_status; /**< Status before starting the current monitor loop */
|
||||
uint64_t pending_status; /**< Status during current monitor loop */
|
||||
int64_t disk_space_checked;/**< When was the disk space checked the last time */
|
||||
struct monitored_server* next; /**< The next server in the list */
|
||||
} MXS_MONITORED_SERVER;
|
||||
|
||||
/**
|
||||
@ -230,39 +230,46 @@ typedef struct monitored_server
|
||||
*/
|
||||
struct mxs_monitor
|
||||
{
|
||||
char *name; /**< The name of the monitor module */
|
||||
char user[MAX_MONITOR_USER_LEN]; /*< Monitor username */
|
||||
char password[MAX_MONITOR_PASSWORD_LEN]; /*< Monitor password */
|
||||
SPINLOCK lock;
|
||||
MXS_CONFIG_PARAMETER* parameters; /*< configuration parameters */
|
||||
MXS_MONITORED_SERVER* monitored_servers; /*< List of servers the monitor monitors */
|
||||
monitor_state_t state; /**< The state of the monitor. This should ONLY be written to by the admin
|
||||
* thread. */
|
||||
int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */
|
||||
int connect_attempts; /**< How many times a connection is attempted */
|
||||
int read_timeout; /**< Timeout in seconds to read from the server.
|
||||
* There are retries and the total effective timeout
|
||||
* value is three times the option value.
|
||||
*/
|
||||
int write_timeout; /**< Timeout in seconds for each attempt to write to the server.
|
||||
* There are retries and the total effective timeout value is
|
||||
* two times the option value.
|
||||
*/
|
||||
MXS_MONITOR_API *api; /**< The monitor api */
|
||||
char *module_name; /**< Name of the monitor module */
|
||||
MXS_MONITOR_INSTANCE *instance; /**< Instance returned from startMonitor */
|
||||
size_t interval; /**< The monitor interval */
|
||||
int check_maintenance_flag; /**< Set when admin requests a maintenance status change. */
|
||||
bool active; /**< True if monitor is active */
|
||||
time_t journal_max_age; /**< Maximum age of journal file */
|
||||
uint32_t script_timeout; /**< Timeout in seconds for the monitor scripts */
|
||||
const char* script; /**< Launchable script. */
|
||||
uint64_t events; /**< Enabled monitor events. */
|
||||
uint8_t journal_hash[SHA_DIGEST_LENGTH]; /**< SHA1 hash of the latest written journal */
|
||||
MxsDiskSpaceThreshold* disk_space_threshold; /**< Disk space thresholds */
|
||||
int64_t disk_space_check_interval; /**< How often should a disk space check be made at most. */
|
||||
uint64_t ticks; /**< Number of performed monitoring intervals */
|
||||
struct mxs_monitor *next; /**< Next monitor in the linked list */
|
||||
char* name; /**< The name of the monitor module */
|
||||
char user[MAX_MONITOR_USER_LEN]; /*< Monitor username */
|
||||
char password[MAX_MONITOR_PASSWORD_LEN]; /*< Monitor password */
|
||||
SPINLOCK lock;
|
||||
MXS_CONFIG_PARAMETER* parameters; /*< configuration parameters */
|
||||
MXS_MONITORED_SERVER* monitored_servers; /*< List of servers the monitor monitors */
|
||||
monitor_state_t state; /**< The state of the monitor. This should ONLY be
|
||||
* written to by the admin
|
||||
* thread. */
|
||||
int connect_timeout; /**< Connect timeout in seconds for
|
||||
* mysql_real_connect */
|
||||
int connect_attempts; /**< How many times a connection is attempted */
|
||||
int read_timeout; /**< Timeout in seconds to read from the server.
|
||||
* There are retries and the total effective
|
||||
*timeout
|
||||
* value is three times the option value.
|
||||
*/
|
||||
int write_timeout; /**< Timeout in seconds for each attempt to write
|
||||
* to the server.
|
||||
* There are retries and the total effective
|
||||
*timeout value is
|
||||
* two times the option value.
|
||||
*/
|
||||
MXS_MONITOR_API* api; /**< The monitor api */
|
||||
char* module_name; /**< Name of the monitor module */
|
||||
MXS_MONITOR_INSTANCE* instance; /**< Instance returned from startMonitor */
|
||||
size_t interval; /**< The monitor interval */
|
||||
int check_maintenance_flag; /**< Set when admin requests a maintenance status
|
||||
* change. */
|
||||
bool active; /**< True if monitor is active */
|
||||
time_t journal_max_age; /**< Maximum age of journal file */
|
||||
uint32_t script_timeout; /**< Timeout in seconds for the monitor scripts */
|
||||
const char* script; /**< Launchable script. */
|
||||
uint64_t events; /**< Enabled monitor events. */
|
||||
uint8_t journal_hash[SHA_DIGEST_LENGTH]; /**< SHA1 hash of the latest written journal */
|
||||
MxsDiskSpaceThreshold* disk_space_threshold; /**< Disk space thresholds */
|
||||
int64_t disk_space_check_interval; /**< How often should a disk space check be made
|
||||
* at most. */
|
||||
uint64_t ticks; /**< Number of performed monitoring intervals */
|
||||
struct mxs_monitor* next; /**< Next monitor in the linked list */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -281,17 +288,17 @@ extern const char CN_SCRIPT_TIMEOUT[];
|
||||
|
||||
bool check_monitor_permissions(MXS_MONITOR* monitor, const char* query);
|
||||
|
||||
void monitor_clear_pending_status(MXS_MONITORED_SERVER *ptr, uint64_t bit);
|
||||
void monitor_set_pending_status(MXS_MONITORED_SERVER *ptr, uint64_t bit);
|
||||
void monitor_check_maintenance_requests(MXS_MONITOR *monitor);
|
||||
void monitor_clear_pending_status(MXS_MONITORED_SERVER* ptr, uint64_t bit);
|
||||
void monitor_set_pending_status(MXS_MONITORED_SERVER* ptr, uint64_t bit);
|
||||
void monitor_check_maintenance_requests(MXS_MONITOR* monitor);
|
||||
|
||||
bool mon_status_changed(MXS_MONITORED_SERVER* mon_srv);
|
||||
bool mon_print_fail_status(MXS_MONITORED_SERVER* mon_srv);
|
||||
|
||||
mxs_connect_result_t mon_ping_or_connect_to_db(MXS_MONITOR* mon, MXS_MONITORED_SERVER *database);
|
||||
bool mon_connection_is_ok(mxs_connect_result_t connect_result);
|
||||
void mon_log_connect_error(MXS_MONITORED_SERVER* database, mxs_connect_result_t rval);
|
||||
const char* mon_get_event_name(mxs_monitor_event_t event);
|
||||
mxs_connect_result_t mon_ping_or_connect_to_db(MXS_MONITOR* mon, MXS_MONITORED_SERVER* database);
|
||||
bool mon_connection_is_ok(mxs_connect_result_t connect_result);
|
||||
void mon_log_connect_error(MXS_MONITORED_SERVER* database, mxs_connect_result_t rval);
|
||||
const char* mon_get_event_name(mxs_monitor_event_t event);
|
||||
|
||||
/**
|
||||
* Alter monitor parameters
|
||||
@ -318,7 +325,7 @@ void mon_alter_parameter(MXS_MONITOR* monitor, const char* key, const char* valu
|
||||
* @param script Script to execute or NULL for no script
|
||||
* @param events Enabled events
|
||||
*/
|
||||
void mon_process_state_changes(MXS_MONITOR *monitor, const char *script, uint64_t events);
|
||||
void mon_process_state_changes(MXS_MONITOR* monitor, const char* script, uint64_t events);
|
||||
|
||||
/**
|
||||
* @brief Hangup connections to failed servers
|
||||
@ -327,7 +334,7 @@ void mon_process_state_changes(MXS_MONITOR *monitor, const char *script, uint64_
|
||||
*
|
||||
* @param monitor Monitor object
|
||||
*/
|
||||
void mon_hangup_failed_servers(MXS_MONITOR *monitor);
|
||||
void mon_hangup_failed_servers(MXS_MONITOR* monitor);
|
||||
|
||||
/**
|
||||
* @brief Report query errors
|
||||
@ -371,7 +378,7 @@ json_t* monitor_relations_to_server(const SERVER* server, const char* host);
|
||||
* @param monitor Monitor to journal
|
||||
* @param master The current master server or NULL if no master exists
|
||||
*/
|
||||
void store_server_journal(MXS_MONITOR *monitor, MXS_MONITORED_SERVER *master);
|
||||
void store_server_journal(MXS_MONITOR* monitor, MXS_MONITORED_SERVER* master);
|
||||
|
||||
/**
|
||||
* @brief Load a journal of server states
|
||||
@ -379,7 +386,7 @@ void store_server_journal(MXS_MONITOR *monitor, MXS_MONITORED_SERVER *master);
|
||||
* @param monitor Monitor where journal is loaded
|
||||
* @param master Set to point to the current master
|
||||
*/
|
||||
void load_server_journal(MXS_MONITOR *monitor, MXS_MONITORED_SERVER **master);
|
||||
void load_server_journal(MXS_MONITOR* monitor, MXS_MONITORED_SERVER** master);
|
||||
|
||||
/**
|
||||
* Find the monitored server representing the server.
|
||||
@ -401,7 +408,9 @@ MXS_MONITORED_SERVER* mon_get_monitored_server(const MXS_MONITOR* mon, SERVER* s
|
||||
* elements. The output must contain NULL before calling this function.
|
||||
* @return Output array size.
|
||||
*/
|
||||
int mon_config_get_servers(const MXS_CONFIG_PARAMETER* params, const char* key, const MXS_MONITOR* mon,
|
||||
int mon_config_get_servers(const MXS_CONFIG_PARAMETER* params,
|
||||
const char* key,
|
||||
const MXS_MONITOR* mon,
|
||||
MXS_MONITORED_SERVER*** monitored_array_out);
|
||||
|
||||
/**
|
||||
@ -412,6 +421,6 @@ int mon_config_get_servers(const MXS_CONFIG_PARAMETER* params, const char* key,
|
||||
*
|
||||
* @return True, if the provided string is valid and the threshold could be set.
|
||||
*/
|
||||
bool monitor_set_disk_space_threshold(MXS_MONITOR *monitor, const char *disk_space_threshold);
|
||||
bool monitor_set_disk_space_threshold(MXS_MONITOR* monitor, const char* disk_space_threshold);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -22,12 +22,12 @@
|
||||
namespace maxscale
|
||||
{
|
||||
|
||||
class MonitorInstance : public MXS_MONITOR_INSTANCE
|
||||
class MonitorInstance : public MXS_MONITOR_INSTANCE
|
||||
, protected maxbase::Worker
|
||||
{
|
||||
public:
|
||||
MonitorInstance(const MonitorInstance&) = delete;
|
||||
MonitorInstance& operator = (const MonitorInstance&) = delete;
|
||||
MonitorInstance& operator=(const MonitorInstance&) = delete;
|
||||
|
||||
virtual ~MonitorInstance();
|
||||
|
||||
@ -204,8 +204,8 @@ protected:
|
||||
*/
|
||||
virtual void process_state_changes();
|
||||
|
||||
MXS_MONITOR* m_monitor; /**< The generic monitor structure. */
|
||||
MXS_MONITORED_SERVER* m_master; /**< Master server */
|
||||
MXS_MONITOR* m_monitor; /**< The generic monitor structure. */
|
||||
MXS_MONITORED_SERVER* m_master; /**< Master server */
|
||||
|
||||
private:
|
||||
std::atomic<bool> m_thread_running; /**< Thread state. Only visible inside MonitorInstance. */
|
||||
@ -225,7 +225,7 @@ class MonitorInstanceSimple : public MonitorInstance
|
||||
{
|
||||
public:
|
||||
MonitorInstanceSimple(const MonitorInstanceSimple&) = delete;
|
||||
MonitorInstanceSimple& operator = (const MonitorInstanceSimple&) = delete;
|
||||
MonitorInstanceSimple& operator=(const MonitorInstanceSimple&) = delete;
|
||||
|
||||
protected:
|
||||
MonitorInstanceSimple(MXS_MONITOR* pMonitor)
|
||||
@ -271,7 +271,7 @@ private:
|
||||
* @c update_server_status() will *not* be called.
|
||||
* - After the call, update the error count of the server if it is down.
|
||||
*/
|
||||
void tick(); // final
|
||||
void tick(); // final
|
||||
};
|
||||
|
||||
/**
|
||||
@ -285,7 +285,7 @@ class MonitorApi
|
||||
public:
|
||||
MonitorApi() = delete;
|
||||
MonitorApi(const MonitorApi&) = delete;
|
||||
MonitorApi& operator = (const MonitorApi&) = delete;
|
||||
MonitorApi& operator=(const MonitorApi&) = delete;
|
||||
|
||||
static MXS_MONITOR_INSTANCE* createInstance(MXS_MONITOR* pMonitor)
|
||||
{
|
||||
@ -349,5 +349,4 @@ MXS_MONITOR_API MonitorApi<MonitorInstance>::s_api =
|
||||
* @return The host and port of the monitor or an empty string and 0 if an error occurred
|
||||
*/
|
||||
std::pair<std::string, int> mon_get_external_master(const std::string& name);
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file mysql_binlog.h - Extracting information from binary logs
|
||||
@ -27,44 +27,44 @@ MXS_BEGIN_DECLS
|
||||
#define GTID_MAX_LEN 64
|
||||
|
||||
/** Table map column types */
|
||||
#define TABLE_COL_TYPE_DECIMAL 0x00
|
||||
#define TABLE_COL_TYPE_TINY 0x01
|
||||
#define TABLE_COL_TYPE_SHORT 0x02
|
||||
#define TABLE_COL_TYPE_LONG 0x03
|
||||
#define TABLE_COL_TYPE_FLOAT 0x04
|
||||
#define TABLE_COL_TYPE_DOUBLE 0x05
|
||||
#define TABLE_COL_TYPE_NULL 0x06
|
||||
#define TABLE_COL_TYPE_TIMESTAMP 0x07
|
||||
#define TABLE_COL_TYPE_LONGLONG 0x08
|
||||
#define TABLE_COL_TYPE_INT24 0x09
|
||||
#define TABLE_COL_TYPE_DATE 0x0a
|
||||
#define TABLE_COL_TYPE_TIME 0x0b
|
||||
#define TABLE_COL_TYPE_DATETIME 0x0c
|
||||
#define TABLE_COL_TYPE_YEAR 0x0d
|
||||
#define TABLE_COL_TYPE_NEWDATE 0x0e
|
||||
#define TABLE_COL_TYPE_VARCHAR 0x0f
|
||||
#define TABLE_COL_TYPE_BIT 0x10
|
||||
#define TABLE_COL_TYPE_TIMESTAMP2 0x11
|
||||
#define TABLE_COL_TYPE_DATETIME2 0x12
|
||||
#define TABLE_COL_TYPE_TIME2 0x13
|
||||
#define TABLE_COL_TYPE_NEWDECIMAL 0xf6
|
||||
#define TABLE_COL_TYPE_ENUM 0xf7
|
||||
#define TABLE_COL_TYPE_SET 0xf8
|
||||
#define TABLE_COL_TYPE_TINY_BLOB 0xf9
|
||||
#define TABLE_COL_TYPE_DECIMAL 0x00
|
||||
#define TABLE_COL_TYPE_TINY 0x01
|
||||
#define TABLE_COL_TYPE_SHORT 0x02
|
||||
#define TABLE_COL_TYPE_LONG 0x03
|
||||
#define TABLE_COL_TYPE_FLOAT 0x04
|
||||
#define TABLE_COL_TYPE_DOUBLE 0x05
|
||||
#define TABLE_COL_TYPE_NULL 0x06
|
||||
#define TABLE_COL_TYPE_TIMESTAMP 0x07
|
||||
#define TABLE_COL_TYPE_LONGLONG 0x08
|
||||
#define TABLE_COL_TYPE_INT24 0x09
|
||||
#define TABLE_COL_TYPE_DATE 0x0a
|
||||
#define TABLE_COL_TYPE_TIME 0x0b
|
||||
#define TABLE_COL_TYPE_DATETIME 0x0c
|
||||
#define TABLE_COL_TYPE_YEAR 0x0d
|
||||
#define TABLE_COL_TYPE_NEWDATE 0x0e
|
||||
#define TABLE_COL_TYPE_VARCHAR 0x0f
|
||||
#define TABLE_COL_TYPE_BIT 0x10
|
||||
#define TABLE_COL_TYPE_TIMESTAMP2 0x11
|
||||
#define TABLE_COL_TYPE_DATETIME2 0x12
|
||||
#define TABLE_COL_TYPE_TIME2 0x13
|
||||
#define TABLE_COL_TYPE_NEWDECIMAL 0xf6
|
||||
#define TABLE_COL_TYPE_ENUM 0xf7
|
||||
#define TABLE_COL_TYPE_SET 0xf8
|
||||
#define TABLE_COL_TYPE_TINY_BLOB 0xf9
|
||||
#define TABLE_COL_TYPE_MEDIUM_BLOB 0xfa
|
||||
#define TABLE_COL_TYPE_LONG_BLOB 0xfb
|
||||
#define TABLE_COL_TYPE_BLOB 0xfc
|
||||
#define TABLE_COL_TYPE_VAR_STRING 0xfd
|
||||
#define TABLE_COL_TYPE_STRING 0xfe
|
||||
#define TABLE_COL_TYPE_GEOMETRY 0xff
|
||||
#define TABLE_COL_TYPE_LONG_BLOB 0xfb
|
||||
#define TABLE_COL_TYPE_BLOB 0xfc
|
||||
#define TABLE_COL_TYPE_VAR_STRING 0xfd
|
||||
#define TABLE_COL_TYPE_STRING 0xfe
|
||||
#define TABLE_COL_TYPE_GEOMETRY 0xff
|
||||
|
||||
/**
|
||||
* RBR row event flags
|
||||
*/
|
||||
#define ROW_EVENT_END_STATEMENT 0x0001
|
||||
#define ROW_EVENT_NO_FKCHECK 0x0002
|
||||
#define ROW_EVENT_NO_UKCHECK 0x0004
|
||||
#define ROW_EVENT_HAS_COLUMNS 0x0008
|
||||
#define ROW_EVENT_NO_FKCHECK 0x0002
|
||||
#define ROW_EVENT_NO_UKCHECK 0x0004
|
||||
#define ROW_EVENT_HAS_COLUMNS 0x0008
|
||||
|
||||
/** The table ID used for end of statement row events */
|
||||
#define TABLE_DUMMY_ID 0x00ffffff
|
||||
@ -85,13 +85,17 @@ bool column_is_decimal(uint8_t type);
|
||||
bool fixed_string_is_enum(uint8_t type);
|
||||
|
||||
/** Value unpacking */
|
||||
size_t unpack_temporal_value(uint8_t type, uint8_t *ptr, uint8_t* metadata, int length, struct tm *tm);
|
||||
size_t unpack_enum(uint8_t *ptr, uint8_t *metadata, uint8_t *dest);
|
||||
size_t unpack_numeric_field(uint8_t *ptr, uint8_t type, uint8_t* metadata, uint8_t* val);
|
||||
size_t unpack_bit(uint8_t *ptr, uint8_t *null_mask, uint32_t col_count,
|
||||
uint32_t curr_col_index, uint8_t *metadata, uint64_t *dest);
|
||||
size_t unpack_decimal_field(uint8_t *ptr, uint8_t *metadata, double *val_float);
|
||||
size_t unpack_temporal_value(uint8_t type, uint8_t* ptr, uint8_t* metadata, int length, struct tm* tm);
|
||||
size_t unpack_enum(uint8_t* ptr, uint8_t* metadata, uint8_t* dest);
|
||||
size_t unpack_numeric_field(uint8_t* ptr, uint8_t type, uint8_t* metadata, uint8_t* val);
|
||||
size_t unpack_bit(uint8_t* ptr,
|
||||
uint8_t* null_mask,
|
||||
uint32_t col_count,
|
||||
uint32_t curr_col_index,
|
||||
uint8_t* metadata,
|
||||
uint64_t* dest);
|
||||
size_t unpack_decimal_field(uint8_t* ptr, uint8_t* metadata, double* val_float);
|
||||
|
||||
void format_temporal_value(char *str, size_t size, uint8_t type, struct tm *tm);
|
||||
void format_temporal_value(char* str, size_t size, uint8_t type, struct tm* tm);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <stdlib.h>
|
||||
@ -21,13 +21,13 @@
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
/** Length-encoded integers */
|
||||
size_t mxs_leint_bytes(const uint8_t* ptr);
|
||||
size_t mxs_leint_bytes(const uint8_t* ptr);
|
||||
uint64_t mxs_leint_value(const uint8_t* c);
|
||||
uint64_t mxs_leint_consume(uint8_t ** c);
|
||||
uint64_t mxs_leint_consume(uint8_t** c);
|
||||
|
||||
/** Length-encoded strings */
|
||||
char* mxs_lestr_consume_dup(uint8_t** c);
|
||||
char* mxs_lestr_consume(uint8_t** c, size_t *size);
|
||||
char* mxs_lestr_consume(uint8_t** c, size_t* size);
|
||||
|
||||
/**
|
||||
* Creates a connection to a MySQL database engine. If necessary, initializes SSL.
|
||||
@ -39,7 +39,7 @@ char* mxs_lestr_consume(uint8_t** c, size_t *size);
|
||||
*
|
||||
* @return New connection or NULL on error
|
||||
*/
|
||||
MYSQL* mxs_mysql_real_connect(MYSQL *mysql, SERVER *server, const char *user, const char *passwd);
|
||||
MYSQL* mxs_mysql_real_connect(MYSQL* mysql, SERVER* server, const char* user, const char* passwd);
|
||||
|
||||
/**
|
||||
* Check if the MYSQL error number is a connection error
|
||||
@ -71,7 +71,7 @@ int mxs_mysql_query(MYSQL* conn, const char* query);
|
||||
*
|
||||
* @note The string is modified in place.
|
||||
*/
|
||||
bool mxs_mysql_trim_quotes(char *s);
|
||||
bool mxs_mysql_trim_quotes(char* s);
|
||||
|
||||
/**
|
||||
* Helper function for getting values by field name
|
||||
@ -87,8 +87,8 @@ const char* mxs_mysql_get_value(MYSQL_RES* result, MYSQL_ROW row, const char* ke
|
||||
|
||||
typedef enum mxs_pcre_quote_approach
|
||||
{
|
||||
MXS_PCRE_QUOTE_VERBATIM, /*<! Quote all PCRE characters. */
|
||||
MXS_PCRE_QUOTE_WILDCARD /*<! Quote all PCRE characters, except % that is converted into .*. */
|
||||
MXS_PCRE_QUOTE_VERBATIM, /*<! Quote all PCRE characters. */
|
||||
MXS_PCRE_QUOTE_WILDCARD /*<! Quote all PCRE characters, except % that is converted into .*. */
|
||||
} mxs_pcre_quote_approach_t;
|
||||
|
||||
typedef enum mxs_mysql_name_kind
|
||||
@ -119,8 +119,8 @@ typedef enum mxs_mysql_name_kind
|
||||
*
|
||||
* @return Whether or not the name contains a wildcard.
|
||||
*/
|
||||
mxs_mysql_name_kind_t mxs_mysql_name_to_pcre(char *pcre,
|
||||
const char *mysql,
|
||||
mxs_mysql_name_kind_t mxs_mysql_name_to_pcre(char* pcre,
|
||||
const char* mysql,
|
||||
mxs_pcre_quote_approach_t approach);
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file pcre2.h - Utility functions for regular expression matching
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#if defined(PCRE2_CODE_UNIT_WIDTH)
|
||||
#if defined (PCRE2_CODE_UNIT_WIDTH)
|
||||
#error PCRE2_CODE_UNIT_WIDTH already defined. Do not define, and include <maxscale/pcre2.h>.
|
||||
#else
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
@ -33,8 +33,8 @@ MXS_BEGIN_DECLS
|
||||
* Print an error message explaining an error code.
|
||||
* @param errorcode value returned by pcre2 functions
|
||||
*/
|
||||
#define MXS_PCRE2_PRINT_ERROR(errorcode)\
|
||||
mxs_pcre2_print_error(errorcode, MXS_MODULE_NAME, __FILE__,__LINE__, __func__)
|
||||
#define MXS_PCRE2_PRINT_ERROR(errorcode) \
|
||||
mxs_pcre2_print_error(errorcode, MXS_MODULE_NAME, __FILE__, __LINE__, __func__)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -43,16 +43,24 @@ typedef enum
|
||||
MXS_PCRE2_ERROR
|
||||
} mxs_pcre2_result_t;
|
||||
|
||||
mxs_pcre2_result_t mxs_pcre2_substitute(pcre2_code *re, const char *subject,
|
||||
const char *replace, char** dest, size_t* size);
|
||||
mxs_pcre2_result_t mxs_pcre2_simple_match(const char* pattern, const char* subject,
|
||||
int options, int* error);
|
||||
mxs_pcre2_result_t mxs_pcre2_substitute(pcre2_code* re,
|
||||
const char* subject,
|
||||
const char* replace,
|
||||
char** dest,
|
||||
size_t* size);
|
||||
mxs_pcre2_result_t mxs_pcre2_simple_match(const char* pattern,
|
||||
const char* subject,
|
||||
int options,
|
||||
int* error);
|
||||
/**
|
||||
* Print an error message explaining an error code. Best used through the macro
|
||||
* MXS_PCRE2_PRINT_ERROR
|
||||
*/
|
||||
void mxs_pcre2_print_error(int errorcode, const char *module_name, const char *filename,
|
||||
int line_num, const char* func_name);
|
||||
void mxs_pcre2_print_error(int errorcode,
|
||||
const char* module_name,
|
||||
const char* filename,
|
||||
int line_num,
|
||||
const char* func_name);
|
||||
|
||||
/**
|
||||
* Check that @c subject is valid. A valid subject matches @c re_match yet does
|
||||
@ -72,8 +80,11 @@ void mxs_pcre2_print_error(int errorcode, const char *module_name, const char *f
|
||||
* @return True, if subject is considered valid. False if subject is not valid or
|
||||
* an error occurred.
|
||||
*/
|
||||
bool mxs_pcre2_check_match_exclude(pcre2_code* re_match, pcre2_code* re_exclude,
|
||||
pcre2_match_data* md, const char* subject,
|
||||
int length, const char* calling_module);
|
||||
bool mxs_pcre2_check_match_exclude(pcre2_code* re_match,
|
||||
pcre2_code* re_exclude,
|
||||
pcre2_match_data* md,
|
||||
const char* subject,
|
||||
int length,
|
||||
const char* calling_module);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/pcre2.h>
|
||||
@ -62,5 +62,4 @@ struct CloserTraits<pcre2_match_data*>
|
||||
pData = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/poll.h - The public poll interface
|
||||
@ -55,7 +55,7 @@ int64_t poll_get_stat(POLL_STAT stat);
|
||||
*
|
||||
* @param dcb DCB to emulate an EPOLLOUT event for
|
||||
*/
|
||||
void poll_fake_hangup_event(DCB *dcb);
|
||||
void poll_fake_hangup_event(DCB* dcb);
|
||||
|
||||
/*
|
||||
* Insert a fake write completion event for a DCB into the polling
|
||||
@ -70,7 +70,7 @@ void poll_fake_hangup_event(DCB *dcb);
|
||||
*
|
||||
* @param dcb DCB to emulate an EPOLLOUT event for
|
||||
*/
|
||||
void poll_fake_write_event(DCB *dcb);
|
||||
void poll_fake_write_event(DCB* dcb);
|
||||
|
||||
/*
|
||||
* Insert a fake read completion event for a DCB into the polling
|
||||
@ -85,7 +85,7 @@ void poll_fake_write_event(DCB *dcb);
|
||||
*
|
||||
* @param dcb DCB to emulate an EPOLLIN event for
|
||||
*/
|
||||
void poll_fake_read_event(DCB *dcb);
|
||||
void poll_fake_read_event(DCB* dcb);
|
||||
|
||||
/**
|
||||
* Add a DCB to the set of descriptors within the polling
|
||||
@ -94,7 +94,7 @@ void poll_fake_read_event(DCB *dcb);
|
||||
* @param dcb The descriptor to add to the poll
|
||||
* @return -1 on error or 0 on success
|
||||
*/
|
||||
int poll_add_dcb(DCB *);
|
||||
int poll_add_dcb(DCB*);
|
||||
|
||||
/**
|
||||
* Remove a descriptor from the set of descriptors within the
|
||||
@ -103,7 +103,7 @@ int poll_add_dcb(DCB *);
|
||||
* @param dcb The descriptor to remove
|
||||
* @return -1 on error or 0 on success; actually always 0
|
||||
*/
|
||||
int poll_remove_dcb(DCB *);
|
||||
int poll_remove_dcb(DCB*);
|
||||
|
||||
/**
|
||||
* Add given GWBUF to DCB's readqueue and add a pending EPOLLIN event for DCB.
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file protocol.h
|
||||
@ -40,7 +40,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @return 1 on success, 0 on error
|
||||
*/
|
||||
int32_t (*read)(struct dcb* dcb);
|
||||
int32_t (* read)(struct dcb* dcb);
|
||||
|
||||
/**
|
||||
* Write data to a network socket
|
||||
@ -50,7 +50,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @return 1 on success, 0 on error
|
||||
*/
|
||||
int32_t (*write)(struct dcb* dcb, GWBUF* buffer);
|
||||
int32_t (* write)(struct dcb* dcb, GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* EPOLLOUT handler, used to write buffered data
|
||||
@ -61,7 +61,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*write_ready)(struct dcb* dcb);
|
||||
int32_t (* write_ready)(struct dcb* dcb);
|
||||
|
||||
/**
|
||||
* EPOLLERR handler
|
||||
@ -72,7 +72,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*error)(struct dcb* dcb);
|
||||
int32_t (* error)(struct dcb* dcb);
|
||||
|
||||
/**
|
||||
* EPOLLHUP and EPOLLRDHUP handler
|
||||
@ -83,7 +83,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*hangup)(struct dcb* dcb);
|
||||
int32_t (* hangup)(struct dcb* dcb);
|
||||
|
||||
/**
|
||||
* Accept a connection, only for client side protocol modules
|
||||
@ -94,7 +94,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*accept)(struct dcb* dcb);
|
||||
int32_t (* accept)(struct dcb* dcb);
|
||||
|
||||
/**
|
||||
* Connect to a server, only for backend side protocol modules
|
||||
@ -105,7 +105,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @return The opened file descriptor or DCBFD_CLOSED on error
|
||||
*/
|
||||
int32_t (*connect)(struct dcb* dcb, struct server* server, struct session* session);
|
||||
int32_t (* connect)(struct dcb* dcb, struct server* server, struct session* session);
|
||||
|
||||
/**
|
||||
* Free protocol data allocated in the connect handler
|
||||
@ -116,7 +116,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*close)(struct dcb* dcb);
|
||||
int32_t (* close)(struct dcb* dcb);
|
||||
|
||||
/**
|
||||
* Listen on a network socket, only for client side protocol modules
|
||||
@ -126,7 +126,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @return 1 on success, 0 on error
|
||||
*/
|
||||
int32_t (*listen)(struct dcb* dcb, char* address);
|
||||
int32_t (* listen)(struct dcb* dcb, char* address);
|
||||
|
||||
/**
|
||||
* Perform user re-authentication
|
||||
@ -140,7 +140,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*auth)(struct dcb* dcb, struct server* server, struct session* session, GWBUF* buffer);
|
||||
int32_t (* auth)(struct dcb* dcb, struct server* server, struct session* session, GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* Returns the name of the default authenticator module for this protocol
|
||||
@ -159,7 +159,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @note Currently the return value is ignored
|
||||
*/
|
||||
int32_t (*connlimit)(struct dcb* dcb, int limit);
|
||||
int32_t (* connlimit)(struct dcb* dcb, int limit);
|
||||
|
||||
/**
|
||||
* Check if the connection has been fully established, used by connection pooling
|
||||
@ -168,7 +168,7 @@ typedef struct mxs_protocol
|
||||
*
|
||||
* @return True if the connection is fully established and can be pooled
|
||||
*/
|
||||
bool (*established)(struct dcb* );
|
||||
bool (* established)(struct dcb*);
|
||||
|
||||
/**
|
||||
* Provide JSON formatted diagnostics about a DCB
|
||||
@ -178,7 +178,6 @@ typedef struct mxs_protocol
|
||||
* @return JSON representation of the DCB
|
||||
*/
|
||||
json_t* (*diagnostics_json)(struct dcb* dcb);
|
||||
|
||||
} MXS_PROTOCOL;
|
||||
|
||||
/**
|
||||
@ -186,7 +185,7 @@ typedef struct mxs_protocol
|
||||
* the MXS_PROTOCOL structure is changed. See the rules defined in modinfo.h
|
||||
* that define how these numbers should change.
|
||||
*/
|
||||
#define MXS_PROTOCOL_VERSION {2, 0, 0}
|
||||
#define MXS_PROTOCOL_VERSION {2, 0, 0}
|
||||
|
||||
/**
|
||||
* Specifies capabilities specific for protocol.
|
||||
@ -198,7 +197,7 @@ typedef struct mxs_protocol
|
||||
*/
|
||||
typedef enum protocol_capability
|
||||
{
|
||||
PCAP_TYPE_NONE = 0x0 // TODO: remove once protocol capabilities are defined
|
||||
PCAP_TYPE_NONE = 0x0 // TODO: remove once protocol capabilities are defined
|
||||
} protocol_capability_t;
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#include <maxscale/protocol/mysql.h>
|
||||
|
||||
/** A DCB-like client abstraction which ignores responses */
|
||||
class LocalClient: public MXB_POLL_DATA
|
||||
class LocalClient : public MXB_POLL_DATA
|
||||
{
|
||||
LocalClient(const LocalClient&);
|
||||
LocalClient& operator=(const LocalClient&);
|
||||
@ -61,19 +61,19 @@ private:
|
||||
static LocalClient* create(MYSQL_session* session, MySQLProtocol* proto, const char* ip, uint64_t port);
|
||||
LocalClient(MYSQL_session* session, MySQLProtocol* proto, int fd);
|
||||
static uint32_t poll_handler(MXB_POLL_DATA* data, MXB_WORKER* worker, uint32_t events);
|
||||
void process(uint32_t events);
|
||||
GWBUF* read_complete_packet();
|
||||
void drain_queue();
|
||||
void error();
|
||||
void close();
|
||||
void process(uint32_t events);
|
||||
GWBUF* read_complete_packet();
|
||||
void drain_queue();
|
||||
void error();
|
||||
void close();
|
||||
|
||||
/** Client states */
|
||||
enum vc_state
|
||||
{
|
||||
VC_WAITING_HANDSHAKE, // Initial state
|
||||
VC_RESPONSE_SENT, // Handshake received and response sent
|
||||
VC_OK, // Authentication is complete, ready for queries
|
||||
VC_ERROR // Something went wrong
|
||||
VC_WAITING_HANDSHAKE, // Initial state
|
||||
VC_RESPONSE_SENT, // Handshake received and response sent
|
||||
VC_OK, // Authentication is complete, ready for queries
|
||||
VC_ERROR // Something went wrong
|
||||
};
|
||||
|
||||
vc_state m_state;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
@ -43,10 +43,10 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#define MYSQL_HEADER_LEN 4
|
||||
#define MYSQL_CHECKSUM_LEN 4
|
||||
#define MYSQL_EOF_PACKET_LEN 9
|
||||
#define MYSQL_OK_PACKET_MIN_LEN 11
|
||||
#define MYSQL_HEADER_LEN 4
|
||||
#define MYSQL_CHECKSUM_LEN 4
|
||||
#define MYSQL_EOF_PACKET_LEN 9
|
||||
#define MYSQL_OK_PACKET_MIN_LEN 11
|
||||
#define MYSQL_ERR_PACKET_MIN_LEN 9
|
||||
|
||||
/**
|
||||
@ -58,14 +58,14 @@ MXS_BEGIN_DECLS
|
||||
#define MYSQL_CHARSET_OFFSET 12
|
||||
#define MYSQL_CLIENT_CAP_OFFSET 4
|
||||
#define MYSQL_CLIENT_CAP_SIZE 4
|
||||
#define MARIADB_CAP_OFFSET MYSQL_CHARSET_OFFSET + 19
|
||||
#define MARIADB_CAP_OFFSET MYSQL_CHARSET_OFFSET + 19
|
||||
|
||||
#define GW_MYSQL_PROTOCOL_VERSION 10 // version is 10
|
||||
#define GW_MYSQL_PROTOCOL_VERSION 10 // version is 10
|
||||
#define GW_MYSQL_HANDSHAKE_FILLER 0x00
|
||||
#define GW_MYSQL_SERVER_LANGUAGE 0x08
|
||||
#define GW_MYSQL_MAX_PACKET_LEN 0xffffffL
|
||||
#define GW_MYSQL_SCRAMBLE_SIZE 20
|
||||
#define GW_SCRAMBLE_LENGTH_323 8
|
||||
#define GW_MYSQL_SERVER_LANGUAGE 0x08
|
||||
#define GW_MYSQL_MAX_PACKET_LEN 0xffffffL
|
||||
#define GW_MYSQL_SCRAMBLE_SIZE 20
|
||||
#define GW_SCRAMBLE_LENGTH_323 8
|
||||
|
||||
/**
|
||||
* Prepared statement payload response offsets for a COM_STMT_PREPARE response:
|
||||
@ -106,23 +106,23 @@ MXS_BEGIN_DECLS
|
||||
#define MYSQL_DATABASE_MAXLEN 128
|
||||
#define MYSQL_TABLE_MAXLEN 64
|
||||
|
||||
#define GW_NOINTR_CALL(A) do { errno = 0; A; } while (errno == EINTR)
|
||||
#define COM_QUIT_PACKET_SIZE (4+1)
|
||||
#define GW_NOINTR_CALL(A) do {errno = 0; A;} while (errno == EINTR)
|
||||
#define COM_QUIT_PACKET_SIZE (4 + 1)
|
||||
struct dcb;
|
||||
|
||||
typedef enum
|
||||
typedef enum
|
||||
{
|
||||
TX_EMPTY = 0, ///< "none of the below"
|
||||
TX_EXPLICIT = 1, ///< an explicit transaction is active
|
||||
TX_IMPLICIT = 2, ///< an implicit transaction is active
|
||||
TX_READ_TRX = 4, ///< transactional reads were done
|
||||
TX_READ_UNSAFE = 8, ///< non-transaction reads were done
|
||||
TX_WRITE_TRX = 16, ///< transactional writes were done
|
||||
TX_WRITE_UNSAFE = 32, ///< non-transactional writes were done
|
||||
TX_STMT_UNSAFE = 64, ///< "unsafe" (non-deterministic like UUID()) stmts
|
||||
TX_RESULT_SET = 128, ///< result-set was sent
|
||||
TX_WITH_SNAPSHOT= 256, ///< WITH CONSISTENT SNAPSHOT was used
|
||||
TX_LOCKED_TABLES= 512 ///< LOCK TABLES is active
|
||||
TX_EMPTY = 0, ///< "none of the below"
|
||||
TX_EXPLICIT = 1, ///< an explicit transaction is active
|
||||
TX_IMPLICIT = 2, ///< an implicit transaction is active
|
||||
TX_READ_TRX = 4, ///< transactional reads were done
|
||||
TX_READ_UNSAFE = 8, ///< non-transaction reads were done
|
||||
TX_WRITE_TRX = 16, ///< transactional writes were done
|
||||
TX_WRITE_UNSAFE = 32, ///< non-transactional writes were done
|
||||
TX_STMT_UNSAFE = 64, ///< "unsafe" (non-deterministic like UUID()) stmts
|
||||
TX_RESULT_SET = 128, ///< result-set was sent
|
||||
TX_WITH_SNAPSHOT = 256, ///< WITH CONSISTENT SNAPSHOT was used
|
||||
TX_LOCKED_TABLES = 512 ///< LOCK TABLES is active
|
||||
} mysql_tx_state_t;
|
||||
|
||||
typedef enum
|
||||
@ -139,114 +139,117 @@ typedef enum
|
||||
*/
|
||||
typedef struct mysql_session
|
||||
{
|
||||
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /*< SHA1(password) */
|
||||
char user[MYSQL_USER_MAXLEN + 1]; /*< username */
|
||||
char db[MYSQL_DATABASE_MAXLEN + 1]; /*< database */
|
||||
int auth_token_len; /*< token length */
|
||||
uint8_t *auth_token; /*< token */
|
||||
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /*< SHA1(password) */
|
||||
char user[MYSQL_USER_MAXLEN + 1]; /*< username */
|
||||
char db[MYSQL_DATABASE_MAXLEN + 1]; /*< database */
|
||||
int auth_token_len; /*< token length */
|
||||
uint8_t* auth_token; /*< token */
|
||||
} MYSQL_session;
|
||||
|
||||
/** Protocol packing macros. */
|
||||
#define gw_mysql_set_byte2(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); } while (0)
|
||||
#define gw_mysql_set_byte3(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); } while (0)
|
||||
#define gw_mysql_set_byte4(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); \
|
||||
(__buffer)[3]= (uint8_t)(((__int) >> 24) & 0xFF); } while (0)
|
||||
#define gw_mysql_set_byte2(__buffer, __int) \
|
||||
do { \
|
||||
(__buffer)[0] = (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1] = (uint8_t)(((__int) >> 8) & 0xFF);} while (0)
|
||||
#define gw_mysql_set_byte3(__buffer, __int) \
|
||||
do { \
|
||||
(__buffer)[0] = (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1] = (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2] = (uint8_t)(((__int) >> 16) & 0xFF);} while (0)
|
||||
#define gw_mysql_set_byte4(__buffer, __int) \
|
||||
do { \
|
||||
(__buffer)[0] = (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1] = (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2] = (uint8_t)(((__int) >> 16) & 0xFF); \
|
||||
(__buffer)[3] = (uint8_t)(((__int) >> 24) & 0xFF);} while (0)
|
||||
|
||||
/** Protocol unpacking macros. */
|
||||
#define gw_mysql_get_byte2(__buffer) \
|
||||
(uint16_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8))
|
||||
(uint16_t)((__buffer)[0] \
|
||||
| ((__buffer)[1] << 8))
|
||||
#define gw_mysql_get_byte3(__buffer) \
|
||||
(uint32_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8) | \
|
||||
((__buffer)[2] << 16))
|
||||
(uint32_t)((__buffer)[0] \
|
||||
| ((__buffer)[1] << 8) \
|
||||
| ((__buffer)[2] << 16))
|
||||
#define gw_mysql_get_byte4(__buffer) \
|
||||
(uint32_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8) | \
|
||||
((__buffer)[2] << 16) | \
|
||||
((__buffer)[3] << 24))
|
||||
(uint32_t)((__buffer)[0] \
|
||||
| ((__buffer)[1] << 8) \
|
||||
| ((__buffer)[2] << 16) \
|
||||
| ((__buffer)[3] << 24))
|
||||
#define gw_mysql_get_byte8(__buffer) \
|
||||
((uint64_t)(__buffer)[0] | \
|
||||
((uint64_t)(__buffer)[1] << 8) | \
|
||||
((uint64_t)(__buffer)[2] << 16) | \
|
||||
((uint64_t)(__buffer)[3] << 24) | \
|
||||
((uint64_t)(__buffer)[4] << 32) | \
|
||||
((uint64_t)(__buffer)[5] << 40) | \
|
||||
((uint64_t)(__buffer)[6] << 48) | \
|
||||
((uint64_t)(__buffer)[7] << 56))
|
||||
((uint64_t)(__buffer)[0] \
|
||||
| ((uint64_t)(__buffer)[1] << 8) \
|
||||
| ((uint64_t)(__buffer)[2] << 16) \
|
||||
| ((uint64_t)(__buffer)[3] << 24) \
|
||||
| ((uint64_t)(__buffer)[4] << 32) \
|
||||
| ((uint64_t)(__buffer)[5] << 40) \
|
||||
| ((uint64_t)(__buffer)[6] << 48) \
|
||||
| ((uint64_t)(__buffer)[7] << 56))
|
||||
|
||||
/** MySQL protocol constants */
|
||||
typedef enum
|
||||
{
|
||||
GW_MYSQL_CAPABILITIES_NONE = 0,
|
||||
GW_MYSQL_CAPABILITIES_NONE = 0,
|
||||
/** This is sent by pre-10.2 clients */
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_MYSQL = (1 << 0),
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS = (1 << 1),
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG = (1 << 2),
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB = (1 << 3),
|
||||
GW_MYSQL_CAPABILITIES_NO_SCHEMA = (1 << 4),
|
||||
GW_MYSQL_CAPABILITIES_COMPRESS = (1 << 5),
|
||||
GW_MYSQL_CAPABILITIES_ODBC = (1 << 6),
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES = (1 << 7),
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SPACE = (1 << 8),
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41 = (1 << 9),
|
||||
GW_MYSQL_CAPABILITIES_INTERACTIVE = (1 << 10),
|
||||
GW_MYSQL_CAPABILITIES_SSL = (1 << 11),
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SIGPIPE = (1 << 12),
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS = (1 << 13),
|
||||
GW_MYSQL_CAPABILITIES_RESERVED = (1 << 14),
|
||||
GW_MYSQL_CAPABILITIES_SECURE_CONNECTION = (1 << 15),
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS = (1 << 16),
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS = (1 << 17),
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS = (1 << 18),
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH = (1 << 19),
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_ATTRS = (1 << 20),
|
||||
GW_MYSQL_CAPABILITIES_AUTH_LENENC_DATA = (1 << 21),
|
||||
GW_MYSQL_CAPABILITIES_EXPIRE_PASSWORD = (1 << 22),
|
||||
GW_MYSQL_CAPABILITIES_SESSION_TRACK = (1 << 23),
|
||||
GW_MYSQL_CAPABILITIES_DEPRECATE_EOF = (1 << 24),
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_MYSQL = (1 << 0),
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS = (1 << 1),
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG = (1 << 2),
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB = (1 << 3),
|
||||
GW_MYSQL_CAPABILITIES_NO_SCHEMA = (1 << 4),
|
||||
GW_MYSQL_CAPABILITIES_COMPRESS = (1 << 5),
|
||||
GW_MYSQL_CAPABILITIES_ODBC = (1 << 6),
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES = (1 << 7),
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SPACE = (1 << 8),
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41 = (1 << 9),
|
||||
GW_MYSQL_CAPABILITIES_INTERACTIVE = (1 << 10),
|
||||
GW_MYSQL_CAPABILITIES_SSL = (1 << 11),
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SIGPIPE = (1 << 12),
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS = (1 << 13),
|
||||
GW_MYSQL_CAPABILITIES_RESERVED = (1 << 14),
|
||||
GW_MYSQL_CAPABILITIES_SECURE_CONNECTION = (1 << 15),
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS = (1 << 16),
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS = (1 << 17),
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS = (1 << 18),
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH = (1 << 19),
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_ATTRS = (1 << 20),
|
||||
GW_MYSQL_CAPABILITIES_AUTH_LENENC_DATA = (1 << 21),
|
||||
GW_MYSQL_CAPABILITIES_EXPIRE_PASSWORD = (1 << 22),
|
||||
GW_MYSQL_CAPABILITIES_SESSION_TRACK = (1 << 23),
|
||||
GW_MYSQL_CAPABILITIES_DEPRECATE_EOF = (1 << 24),
|
||||
GW_MYSQL_CAPABILITIES_SSL_VERIFY_SERVER_CERT = (1 << 30),
|
||||
GW_MYSQL_CAPABILITIES_REMEMBER_OPTIONS = (1 << 31),
|
||||
GW_MYSQL_CAPABILITIES_CLIENT = (
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_MYSQL |
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS |
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG |
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB |
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES |
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH |
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS |
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41 |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_SECURE_CONNECTION),
|
||||
GW_MYSQL_CAPABILITIES_REMEMBER_OPTIONS = (1 << 31),
|
||||
GW_MYSQL_CAPABILITIES_CLIENT = (
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_MYSQL
|
||||
| GW_MYSQL_CAPABILITIES_FOUND_ROWS
|
||||
| GW_MYSQL_CAPABILITIES_LONG_FLAG
|
||||
| GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB
|
||||
| GW_MYSQL_CAPABILITIES_LOCAL_FILES
|
||||
| GW_MYSQL_CAPABILITIES_PLUGIN_AUTH
|
||||
| GW_MYSQL_CAPABILITIES_TRANSACTIONS
|
||||
| GW_MYSQL_CAPABILITIES_PROTOCOL_41
|
||||
| GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS
|
||||
| GW_MYSQL_CAPABILITIES_MULTI_RESULTS
|
||||
| GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS
|
||||
| GW_MYSQL_CAPABILITIES_SECURE_CONNECTION),
|
||||
GW_MYSQL_CAPABILITIES_SERVER = (
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_MYSQL |
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS |
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG |
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB |
|
||||
GW_MYSQL_CAPABILITIES_NO_SCHEMA |
|
||||
GW_MYSQL_CAPABILITIES_ODBC |
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES |
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SPACE |
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41 |
|
||||
GW_MYSQL_CAPABILITIES_INTERACTIVE |
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SIGPIPE |
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS |
|
||||
GW_MYSQL_CAPABILITIES_RESERVED |
|
||||
GW_MYSQL_CAPABILITIES_SECURE_CONNECTION |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH),
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_MYSQL
|
||||
| GW_MYSQL_CAPABILITIES_FOUND_ROWS
|
||||
| GW_MYSQL_CAPABILITIES_LONG_FLAG
|
||||
| GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB
|
||||
| GW_MYSQL_CAPABILITIES_NO_SCHEMA
|
||||
| GW_MYSQL_CAPABILITIES_ODBC
|
||||
| GW_MYSQL_CAPABILITIES_LOCAL_FILES
|
||||
| GW_MYSQL_CAPABILITIES_IGNORE_SPACE
|
||||
| GW_MYSQL_CAPABILITIES_PROTOCOL_41
|
||||
| GW_MYSQL_CAPABILITIES_INTERACTIVE
|
||||
| GW_MYSQL_CAPABILITIES_IGNORE_SIGPIPE
|
||||
| GW_MYSQL_CAPABILITIES_TRANSACTIONS
|
||||
| GW_MYSQL_CAPABILITIES_RESERVED
|
||||
| GW_MYSQL_CAPABILITIES_SECURE_CONNECTION
|
||||
| GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS
|
||||
| GW_MYSQL_CAPABILITIES_MULTI_RESULTS
|
||||
| GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS
|
||||
| GW_MYSQL_CAPABILITIES_PLUGIN_AUTH),
|
||||
} gw_mysql_capabilities_t;
|
||||
|
||||
/**
|
||||
@ -286,19 +289,19 @@ typedef enum
|
||||
MXS_COM_TABLE_DUMP,
|
||||
MXS_COM_CONNECT_OUT = 20,
|
||||
MXS_COM_REGISTER_SLAVE,
|
||||
MXS_COM_STMT_PREPARE = 22,
|
||||
MXS_COM_STMT_EXECUTE = 23,
|
||||
MXS_COM_STMT_PREPARE = 22,
|
||||
MXS_COM_STMT_EXECUTE = 23,
|
||||
MXS_COM_STMT_SEND_LONG_DATA = 24,
|
||||
MXS_COM_STMT_CLOSE = 25,
|
||||
MXS_COM_STMT_RESET = 26,
|
||||
MXS_COM_SET_OPTION = 27,
|
||||
MXS_COM_STMT_FETCH = 28,
|
||||
MXS_COM_STMT_BULK_EXECUTE = 0xfa,
|
||||
MXS_COM_STMT_CLOSE = 25,
|
||||
MXS_COM_STMT_RESET = 26,
|
||||
MXS_COM_SET_OPTION = 27,
|
||||
MXS_COM_STMT_FETCH = 28,
|
||||
MXS_COM_STMT_BULK_EXECUTE = 0xfa,
|
||||
MXS_COM_DAEMON,
|
||||
MXS_COM_END
|
||||
} mxs_mysql_cmd_t;
|
||||
|
||||
static const mxs_mysql_cmd_t MXS_COM_UNDEFINED = (mxs_mysql_cmd_t) - 1;
|
||||
static const mxs_mysql_cmd_t MXS_COM_UNDEFINED = (mxs_mysql_cmd_t) -1;
|
||||
|
||||
/**
|
||||
* A GWBUF property with this name will contain the latest GTID in string form.
|
||||
@ -314,23 +317,25 @@ static const char* const MXS_LAST_GTID = "last_gtid";
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int fd; /*< The socket descriptor */
|
||||
struct dcb* owner_dcb; /*< The DCB of the socket we are running on */
|
||||
mxs_mysql_cmd_t current_command; /*< Current command being executed */
|
||||
mxs_auth_state_t protocol_auth_state; /*< Authentication status */
|
||||
mysql_protocol_state_t protocol_state; /*< Protocol struct status */
|
||||
uint8_t scramble[MYSQL_SCRAMBLE_LEN]; /*< server scramble, created or received */
|
||||
uint32_t server_capabilities; /*< server capabilities, created or received */
|
||||
uint32_t client_capabilities; /*< client capabilities, created or received */
|
||||
uint32_t extra_capabilities; /*< MariaDB 10.2 capabilities */
|
||||
uint64_t thread_id; /*< MySQL Thread ID. Send only 32bits in handshake. */
|
||||
unsigned int charset; /*< MySQL character set at connect time */
|
||||
int ignore_replies; /*< How many replies should be discarded */
|
||||
GWBUF* stored_query; /*< Temporarily stored queries */
|
||||
bool collect_result; /*< Collect the next result set as one buffer */
|
||||
int fd; /*< The socket descriptor */
|
||||
struct dcb* owner_dcb; /*< The DCB of the socket we are running on */
|
||||
mxs_mysql_cmd_t current_command; /*< Current command being executed */
|
||||
mxs_auth_state_t protocol_auth_state; /*< Authentication status */
|
||||
mysql_protocol_state_t protocol_state; /*< Protocol struct status */
|
||||
uint8_t scramble[MYSQL_SCRAMBLE_LEN];/*< server scramble, created or received */
|
||||
uint32_t server_capabilities; /*< server capabilities, created or received */
|
||||
uint32_t client_capabilities; /*< client capabilities, created or received */
|
||||
uint32_t extra_capabilities; /*< MariaDB 10.2 capabilities */
|
||||
uint64_t thread_id; /*< MySQL Thread ID. Send only 32bits in handshake. */
|
||||
unsigned int charset; /*< MySQL character set at connect time */
|
||||
int ignore_replies; /*< How many replies should be discarded */
|
||||
GWBUF* stored_query; /*< Temporarily stored queries */
|
||||
bool collect_result; /*< Collect the next result set as one buffer */
|
||||
bool changing_user;
|
||||
uint32_t num_eof_packets; /*< Encountered eof packet number, used for check packet type */
|
||||
bool large_query; /*< Whether to ignore the command byte of the next packet*/
|
||||
uint32_t num_eof_packets; /*< Encountered eof packet number, used for check
|
||||
* packet type */
|
||||
bool large_query; /*< Whether to ignore the command byte of the next
|
||||
* packet*/
|
||||
} MySQLProtocol;
|
||||
|
||||
typedef struct
|
||||
@ -346,7 +351,7 @@ typedef struct
|
||||
#define MYSQL_REPLY_OK 0x00
|
||||
#define MYSQL_REPLY_EOF 0xfe
|
||||
#define MYSQL_REPLY_LOCAL_INFILE 0xfb
|
||||
#define MYSQL_REPLY_AUTHSWITCHREQUEST 0xfe /**< Only sent during authentication */
|
||||
#define MYSQL_REPLY_AUTHSWITCHREQUEST 0xfe /**< Only sent during authentication */
|
||||
|
||||
static inline mxs_mysql_cmd_t MYSQL_GET_COMMAND(const uint8_t* header)
|
||||
{
|
||||
@ -368,10 +373,10 @@ static inline uint32_t MYSQL_GET_PACKET_LEN(const GWBUF* buffer)
|
||||
return MYSQL_GET_PAYLOAD_LEN(GWBUF_DATA(buffer)) + MYSQL_HEADER_LEN;
|
||||
}
|
||||
|
||||
#define MYSQL_GET_ERRCODE(payload) (gw_mysql_get_byte2(&payload[5]))
|
||||
#define MYSQL_GET_STMTOK_NPARAM(payload) (gw_mysql_get_byte2(&payload[9]))
|
||||
#define MYSQL_GET_STMTOK_NATTR(payload) (gw_mysql_get_byte2(&payload[11]))
|
||||
#define MYSQL_GET_NATTR(payload) ((int)payload[4])
|
||||
#define MYSQL_GET_ERRCODE(payload) (gw_mysql_get_byte2(&payload[5]))
|
||||
#define MYSQL_GET_STMTOK_NPARAM(payload) (gw_mysql_get_byte2(&payload[9]))
|
||||
#define MYSQL_GET_STMTOK_NATTR(payload) (gw_mysql_get_byte2(&payload[11]))
|
||||
#define MYSQL_GET_NATTR(payload) ((int)payload[4])
|
||||
|
||||
static inline bool MYSQL_IS_ERROR_PACKET(const uint8_t* header)
|
||||
{
|
||||
@ -380,8 +385,8 @@ static inline bool MYSQL_IS_ERROR_PACKET(const uint8_t* header)
|
||||
|
||||
static inline bool MYSQL_IS_COM_QUIT(const uint8_t* header)
|
||||
{
|
||||
return MYSQL_GET_COMMAND(header) == MXS_COM_QUIT &&
|
||||
MYSQL_GET_PAYLOAD_LEN(header) == 1;
|
||||
return MYSQL_GET_COMMAND(header) == MXS_COM_QUIT
|
||||
&& MYSQL_GET_PAYLOAD_LEN(header) == 1;
|
||||
}
|
||||
|
||||
static inline bool MYSQL_IS_COM_INIT_DB(const uint8_t* header)
|
||||
@ -430,7 +435,7 @@ bool mysql_protocol_done(DCB* dcb);
|
||||
*
|
||||
* @return String representation of the state
|
||||
*/
|
||||
const char *gw_mysql_protocol_state2string(int state);
|
||||
const char* gw_mysql_protocol_state2string(int state);
|
||||
|
||||
/**
|
||||
* Set current command being executed
|
||||
@ -444,20 +449,20 @@ void mysql_protocol_set_current_command(DCB* dcb, mxs_mysql_cmd_t cmd);
|
||||
|
||||
GWBUF* mysql_create_com_quit(GWBUF* bufparam, int sequence);
|
||||
GWBUF* mysql_create_custom_error(int sequence, int affected_rows, const char* msg);
|
||||
GWBUF *mysql_create_standard_error(int sequence, int error_number, const char *msg);
|
||||
GWBUF* mysql_create_standard_error(int sequence, int error_number, const char* msg);
|
||||
|
||||
int mysql_send_com_quit(DCB* dcb, int sequence, GWBUF* buf);
|
||||
int mysql_send_custom_error(DCB *dcb, int sequence, int affected_rows, const char* msg);
|
||||
int mysql_send_standard_error(DCB *dcb, int sequence, int errnum, const char *msg);
|
||||
int mysql_send_auth_error(DCB *dcb, int sequence, int affected_rows, const char* msg);
|
||||
int mysql_send_custom_error(DCB* dcb, int sequence, int affected_rows, const char* msg);
|
||||
int mysql_send_standard_error(DCB* dcb, int sequence, int errnum, const char* msg);
|
||||
int mysql_send_auth_error(DCB* dcb, int sequence, int affected_rows, const char* msg);
|
||||
|
||||
char* create_auth_fail_str(char *username, char *hostaddr, bool password, char *db, int);
|
||||
char* create_auth_fail_str(char* username, char* hostaddr, bool password, char* db, int);
|
||||
|
||||
void init_response_status(GWBUF* buf, uint8_t cmd, int* npackets, size_t* nbytes);
|
||||
bool read_complete_packet(DCB *dcb, GWBUF **readbuf);
|
||||
bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session);
|
||||
void mxs_mysql_get_session_track_info(GWBUF *buff, MySQLProtocol *proto);
|
||||
mysql_tx_state_t parse_trx_state(const char *str);
|
||||
void init_response_status(GWBUF* buf, uint8_t cmd, int* npackets, size_t* nbytes);
|
||||
bool read_complete_packet(DCB* dcb, GWBUF** readbuf);
|
||||
bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session);
|
||||
void mxs_mysql_get_session_track_info(GWBUF* buff, MySQLProtocol* proto);
|
||||
mysql_tx_state_t parse_trx_state(const char* str);
|
||||
|
||||
/**
|
||||
* Decode server handshake
|
||||
@ -468,7 +473,7 @@ mysql_tx_state_t parse_trx_state(const char *str);
|
||||
* @return 0 on success, -1 on failure
|
||||
*
|
||||
*/
|
||||
int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload);
|
||||
int gw_decode_mysql_server_handshake(MySQLProtocol* conn, uint8_t* payload);
|
||||
|
||||
/**
|
||||
* Create a response to the server handshake
|
||||
@ -481,14 +486,17 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload);
|
||||
*
|
||||
* @return Generated response packet
|
||||
*/
|
||||
GWBUF* gw_generate_auth_response(MYSQL_session* client, MySQLProtocol *conn,
|
||||
bool with_ssl, bool ssl_established, uint64_t service_capabilities);
|
||||
GWBUF* gw_generate_auth_response(MYSQL_session* client,
|
||||
MySQLProtocol* conn,
|
||||
bool with_ssl,
|
||||
bool ssl_established,
|
||||
uint64_t service_capabilities);
|
||||
|
||||
/** Read the backend server's handshake */
|
||||
bool gw_read_backend_handshake(DCB *dcb, GWBUF *buffer);
|
||||
bool gw_read_backend_handshake(DCB* dcb, GWBUF* buffer);
|
||||
|
||||
/** Send the server handshake response packet to the backend server */
|
||||
mxs_auth_state_t gw_send_backend_auth(DCB *dcb);
|
||||
mxs_auth_state_t gw_send_backend_auth(DCB* dcb);
|
||||
|
||||
/** Sends a response for an AuthSwitchRequest to the default auth plugin */
|
||||
int send_mysql_native_password_response(DCB* dcb);
|
||||
@ -497,7 +505,7 @@ int send_mysql_native_password_response(DCB* dcb);
|
||||
bool send_auth_switch_request_packet(DCB* dcb);
|
||||
|
||||
/** Write an OK packet to a DCB */
|
||||
int mxs_mysql_send_ok(DCB *dcb, int sequence, uint8_t affected_rows, const char* message);
|
||||
int mxs_mysql_send_ok(DCB* dcb, int sequence, uint8_t affected_rows, const char* message);
|
||||
|
||||
/**
|
||||
* @brief Check if the buffer contains an OK packet
|
||||
@ -505,7 +513,7 @@ int mxs_mysql_send_ok(DCB *dcb, int sequence, uint8_t affected_rows, const char*
|
||||
* @param buffer Buffer containing a complete MySQL packet
|
||||
* @return True if the buffer contains an OK packet
|
||||
*/
|
||||
bool mxs_mysql_is_ok_packet(GWBUF *buffer);
|
||||
bool mxs_mysql_is_ok_packet(GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* @brief Check if the buffer contains an ERR packet
|
||||
@ -513,7 +521,7 @@ bool mxs_mysql_is_ok_packet(GWBUF *buffer);
|
||||
* @param buffer Buffer containing a complete MySQL packet
|
||||
* @return True if the buffer contains an ERR packet
|
||||
*/
|
||||
bool mxs_mysql_is_err_packet(GWBUF *buffer);
|
||||
bool mxs_mysql_is_err_packet(GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* @brief Check if a buffer contains a result set
|
||||
@ -522,7 +530,7 @@ bool mxs_mysql_is_err_packet(GWBUF *buffer);
|
||||
*
|
||||
* @return True if the @c buffer contains the start of a result set
|
||||
*/
|
||||
bool mxs_mysql_is_result_set(GWBUF *buffer);
|
||||
bool mxs_mysql_is_result_set(GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* @brief Check if the buffer contains a LOCAL INFILE request
|
||||
@ -531,7 +539,7 @@ bool mxs_mysql_is_result_set(GWBUF *buffer);
|
||||
*
|
||||
* @return True if the buffer contains a LOCAL INFILE request
|
||||
*/
|
||||
bool mxs_mysql_is_local_infile(GWBUF *buffer);
|
||||
bool mxs_mysql_is_local_infile(GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* @brief Check if the buffer contains a prepared statement OK packet
|
||||
@ -540,7 +548,7 @@ bool mxs_mysql_is_local_infile(GWBUF *buffer);
|
||||
*
|
||||
* @return True if the @c buffer contains a prepared statement OK packet
|
||||
*/
|
||||
bool mxs_mysql_is_prep_stmt_ok(GWBUF *buffer);
|
||||
bool mxs_mysql_is_prep_stmt_ok(GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* Is this a binary protocol command
|
||||
@ -558,7 +566,7 @@ bool mxs_mysql_is_ps_command(uint8_t cmd);
|
||||
*
|
||||
* @return True if more results are expected
|
||||
*/
|
||||
bool mxs_mysql_more_results_after_ok(GWBUF *buffer);
|
||||
bool mxs_mysql_more_results_after_ok(GWBUF* buffer);
|
||||
|
||||
/** Get current command for a session */
|
||||
mxs_mysql_cmd_t mxs_mysql_current_command(MXS_SESSION* session);
|
||||
@ -570,8 +578,10 @@ mxs_mysql_cmd_t mxs_mysql_current_command(MXS_SESSION* session);
|
||||
* @param npackets Pointer where the number of packets is stored
|
||||
* @param nbytes Pointer where number of bytes is stored
|
||||
*/
|
||||
void mysql_num_response_packets(GWBUF *buf, uint8_t cmd,
|
||||
int* npackets, size_t *nbytes);
|
||||
void mysql_num_response_packets(GWBUF* buf,
|
||||
uint8_t cmd,
|
||||
int* npackets,
|
||||
size_t* nbytes);
|
||||
|
||||
/**
|
||||
* @brief Return current database of the session
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <maxbase/jansson.h>
|
||||
@ -25,8 +25,8 @@ MXS_BEGIN_DECLS
|
||||
*/
|
||||
typedef enum qc_init_kind
|
||||
{
|
||||
QC_INIT_SELF = 0x01, /*< Initialize/finalize the query classifier itself. */
|
||||
QC_INIT_PLUGIN = 0x02, /*< Initialize/finalize the plugin. */
|
||||
QC_INIT_SELF = 0x01, /*< Initialize/finalize the query classifier itself. */
|
||||
QC_INIT_PLUGIN = 0x02, /*< Initialize/finalize the plugin. */
|
||||
QC_INIT_BOTH = 0x03
|
||||
} qc_init_kind_t;
|
||||
|
||||
@ -36,8 +36,8 @@ typedef enum qc_init_kind
|
||||
*/
|
||||
typedef enum qc_sql_mode
|
||||
{
|
||||
QC_SQL_MODE_DEFAULT, /*< Assume the statements are MariaDB SQL. */
|
||||
QC_SQL_MODE_ORACLE /*< Assume the statements are PL/SQL. */
|
||||
QC_SQL_MODE_DEFAULT, /*< Assume the statements are MariaDB SQL. */
|
||||
QC_SQL_MODE_ORACLE /*< Assume the statements are PL/SQL. */
|
||||
} qc_sql_mode_t;
|
||||
|
||||
/**
|
||||
@ -45,13 +45,13 @@ typedef enum qc_sql_mode
|
||||
*/
|
||||
typedef enum qc_collect_info
|
||||
{
|
||||
QC_COLLECT_ESSENTIALS = 0x00, /*< Collect only the base minimum. */
|
||||
QC_COLLECT_TABLES = 0x01, /*< Collect table names. */
|
||||
QC_COLLECT_DATABASES = 0x02, /*< Collect database names. */
|
||||
QC_COLLECT_FIELDS = 0x04, /*< Collect field information. */
|
||||
QC_COLLECT_FUNCTIONS = 0x08, /*< Collect function information. */
|
||||
QC_COLLECT_ESSENTIALS = 0x00, /*< Collect only the base minimum. */
|
||||
QC_COLLECT_TABLES = 0x01, /*< Collect table names. */
|
||||
QC_COLLECT_DATABASES = 0x02, /*< Collect database names. */
|
||||
QC_COLLECT_FIELDS = 0x04, /*< Collect field information. */
|
||||
QC_COLLECT_FUNCTIONS = 0x08, /*< Collect function information. */
|
||||
|
||||
QC_COLLECT_ALL = (QC_COLLECT_TABLES|QC_COLLECT_DATABASES|QC_COLLECT_FIELDS|QC_COLLECT_FUNCTIONS)
|
||||
QC_COLLECT_ALL = (QC_COLLECT_TABLES | QC_COLLECT_DATABASES | QC_COLLECT_FIELDS | QC_COLLECT_FUNCTIONS)
|
||||
} qc_collect_info_t;
|
||||
/**
|
||||
* qc_query_type_t defines bits that provide information about a
|
||||
@ -61,32 +61,32 @@ typedef enum qc_collect_info
|
||||
*/
|
||||
typedef enum qc_query_type
|
||||
{
|
||||
QUERY_TYPE_UNKNOWN = 0x000000, /*< Initial value, can't be tested bitwisely */
|
||||
QUERY_TYPE_LOCAL_READ = 0x000001, /*< Read non-database data, execute in MaxScale:any */
|
||||
QUERY_TYPE_READ = 0x000002, /*< Read database data:any */
|
||||
QUERY_TYPE_WRITE = 0x000004, /*< Master data will be modified:master */
|
||||
QUERY_TYPE_MASTER_READ = 0x000008, /*< Read from the master:master */
|
||||
QUERY_TYPE_SESSION_WRITE = 0x000010, /*< Session data will be modified:master or all */
|
||||
QUERY_TYPE_USERVAR_WRITE = 0x000020, /*< Write a user variable:master or all */
|
||||
QUERY_TYPE_USERVAR_READ = 0x000040, /*< Read a user variable:master or any */
|
||||
QUERY_TYPE_SYSVAR_READ = 0x000080, /*< Read a system variable:master or any */
|
||||
QUERY_TYPE_UNKNOWN = 0x000000, /*< Initial value, can't be tested bitwisely */
|
||||
QUERY_TYPE_LOCAL_READ = 0x000001, /*< Read non-database data, execute in MaxScale:any */
|
||||
QUERY_TYPE_READ = 0x000002, /*< Read database data:any */
|
||||
QUERY_TYPE_WRITE = 0x000004, /*< Master data will be modified:master */
|
||||
QUERY_TYPE_MASTER_READ = 0x000008, /*< Read from the master:master */
|
||||
QUERY_TYPE_SESSION_WRITE = 0x000010, /*< Session data will be modified:master or all */
|
||||
QUERY_TYPE_USERVAR_WRITE = 0x000020, /*< Write a user variable:master or all */
|
||||
QUERY_TYPE_USERVAR_READ = 0x000040, /*< Read a user variable:master or any */
|
||||
QUERY_TYPE_SYSVAR_READ = 0x000080, /*< Read a system variable:master or any */
|
||||
/** Not implemented yet */
|
||||
//QUERY_TYPE_SYSVAR_WRITE = 0x000100, /*< Write a system variable:master or all */
|
||||
QUERY_TYPE_GSYSVAR_READ = 0x000200, /*< Read global system variable:master or any */
|
||||
QUERY_TYPE_GSYSVAR_WRITE = 0x000400, /*< Write global system variable:master or all */
|
||||
QUERY_TYPE_BEGIN_TRX = 0x000800, /*< BEGIN or START TRANSACTION */
|
||||
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x001000, /*< SET autocommit=1 */
|
||||
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x002000, /*< SET autocommit=0 */
|
||||
QUERY_TYPE_ROLLBACK = 0x004000, /*< ROLLBACK */
|
||||
QUERY_TYPE_COMMIT = 0x008000, /*< COMMIT */
|
||||
QUERY_TYPE_PREPARE_NAMED_STMT = 0x010000, /*< Prepared stmt with name from user:all */
|
||||
QUERY_TYPE_PREPARE_STMT = 0x020000, /*< Prepared stmt with id provided by server:all */
|
||||
QUERY_TYPE_EXEC_STMT = 0x040000, /*< Execute prepared statement:master or any */
|
||||
QUERY_TYPE_CREATE_TMP_TABLE = 0x080000, /*< Create temporary table:master (could be all) */
|
||||
QUERY_TYPE_READ_TMP_TABLE = 0x100000, /*< Read temporary table:master (could be any) */
|
||||
QUERY_TYPE_SHOW_DATABASES = 0x200000, /*< Show list of databases */
|
||||
QUERY_TYPE_SHOW_TABLES = 0x400000, /*< Show list of tables */
|
||||
QUERY_TYPE_DEALLOC_PREPARE = 0x1000000 /*< Dealloc named prepare stmt:all */
|
||||
// QUERY_TYPE_SYSVAR_WRITE = 0x000100, /*< Write a system variable:master or all */
|
||||
QUERY_TYPE_GSYSVAR_READ = 0x000200, /*< Read global system variable:master or any */
|
||||
QUERY_TYPE_GSYSVAR_WRITE = 0x000400, /*< Write global system variable:master or all */
|
||||
QUERY_TYPE_BEGIN_TRX = 0x000800, /*< BEGIN or START TRANSACTION */
|
||||
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x001000, /*< SET autocommit=1 */
|
||||
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x002000, /*< SET autocommit=0 */
|
||||
QUERY_TYPE_ROLLBACK = 0x004000, /*< ROLLBACK */
|
||||
QUERY_TYPE_COMMIT = 0x008000, /*< COMMIT */
|
||||
QUERY_TYPE_PREPARE_NAMED_STMT = 0x010000, /*< Prepared stmt with name from user:all */
|
||||
QUERY_TYPE_PREPARE_STMT = 0x020000, /*< Prepared stmt with id provided by server:all */
|
||||
QUERY_TYPE_EXEC_STMT = 0x040000, /*< Execute prepared statement:master or any */
|
||||
QUERY_TYPE_CREATE_TMP_TABLE = 0x080000, /*< Create temporary table:master (could be all) */
|
||||
QUERY_TYPE_READ_TMP_TABLE = 0x100000, /*< Read temporary table:master (could be any) */
|
||||
QUERY_TYPE_SHOW_DATABASES = 0x200000, /*< Show list of databases */
|
||||
QUERY_TYPE_SHOW_TABLES = 0x400000, /*< Show list of tables */
|
||||
QUERY_TYPE_DEALLOC_PREPARE = 0x1000000 /*< Dealloc named prepare stmt:all */
|
||||
} qc_query_type_t;
|
||||
|
||||
/**
|
||||
@ -120,10 +120,10 @@ typedef enum qc_query_op
|
||||
*/
|
||||
typedef enum qc_parse_result
|
||||
{
|
||||
QC_QUERY_INVALID = 0, /*< The query was not recognized or could not be parsed. */
|
||||
QC_QUERY_TOKENIZED = 1, /*< The query was classified based on tokens; incompletely classified. */
|
||||
QC_QUERY_PARTIALLY_PARSED = 2, /*< The query was only partially parsed; incompletely classified. */
|
||||
QC_QUERY_PARSED = 3 /*< The query was fully parsed; completely classified. */
|
||||
QC_QUERY_INVALID = 0, /*< The query was not recognized or could not be parsed. */
|
||||
QC_QUERY_TOKENIZED = 1, /*< The query was classified based on tokens; incompletely classified. */
|
||||
QC_QUERY_PARTIALLY_PARSED = 2, /*< The query was only partially parsed; incompletely classified. */
|
||||
QC_QUERY_PARSED = 3 /*< The query was fully parsed; completely classified. */
|
||||
} qc_parse_result_t;
|
||||
|
||||
/**
|
||||
@ -141,9 +141,9 @@ typedef struct qc_field_info
|
||||
*/
|
||||
typedef struct qc_function_info
|
||||
{
|
||||
char* name; /** Name of function. */
|
||||
QC_FIELD_INFO* fields; /** What fields the function accesses. */
|
||||
uint32_t n_fields; /** The number of fields in @c fields. */
|
||||
char* name; /** Name of function. */
|
||||
QC_FIELD_INFO* fields; /** What fields the function accesses. */
|
||||
uint32_t n_fields;/** The number of fields in @c fields. */
|
||||
} QC_FUNCTION_INFO;
|
||||
|
||||
/**
|
||||
@ -182,7 +182,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the query classifier could be setup, otherwise
|
||||
* some specific error code.
|
||||
*/
|
||||
int32_t (*qc_setup)(qc_sql_mode_t sql_mode, const char* args);
|
||||
int32_t (* qc_setup)(qc_sql_mode_t sql_mode, const char* args);
|
||||
|
||||
/**
|
||||
* Called once at process startup, after @c qc_setup has successfully
|
||||
@ -190,24 +190,24 @@ typedef struct query_classifier
|
||||
*
|
||||
* @return QC_RESULT_OK, if the process initialization succeeded.
|
||||
*/
|
||||
int32_t (*qc_process_init)(void);
|
||||
int32_t (* qc_process_init)(void);
|
||||
|
||||
/**
|
||||
* Called once at process shutdown.
|
||||
*/
|
||||
void (*qc_process_end)(void);
|
||||
void (* qc_process_end)(void);
|
||||
|
||||
/**
|
||||
* Called once per each thread.
|
||||
*
|
||||
* @return QC_RESULT_OK, if the thread initialization succeeded.
|
||||
*/
|
||||
int32_t (*qc_thread_init)(void);
|
||||
int32_t (* qc_thread_init)(void);
|
||||
|
||||
/**
|
||||
* Called once when a thread finishes.
|
||||
*/
|
||||
void (*qc_thread_end)(void);
|
||||
void (* qc_thread_end)(void);
|
||||
|
||||
/**
|
||||
* Called to explicitly parse a statement.
|
||||
@ -221,7 +221,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_parse)(GWBUF* stmt, uint32_t collect, int32_t* result);
|
||||
int32_t (* qc_parse)(GWBUF* stmt, uint32_t collect, int32_t* result);
|
||||
|
||||
/**
|
||||
* Reports the type of the statement.
|
||||
@ -233,7 +233,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_type_mask)(GWBUF* stmt, uint32_t* type);
|
||||
int32_t (* qc_get_type_mask)(GWBUF* stmt, uint32_t* type);
|
||||
|
||||
/**
|
||||
* Reports the operation of the statement.
|
||||
@ -245,7 +245,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_operation)(GWBUF* stmt, int32_t* op);
|
||||
int32_t (* qc_get_operation)(GWBUF* stmt, int32_t* op);
|
||||
|
||||
/**
|
||||
* Reports the name of a created table.
|
||||
@ -257,7 +257,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_created_table_name)(GWBUF* stmt, char** name);
|
||||
int32_t (* qc_get_created_table_name)(GWBUF* stmt, char** name);
|
||||
|
||||
/**
|
||||
* Reports whether a statement is a "DROP TABLE ..." statement.
|
||||
@ -269,7 +269,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_is_drop_table_query)(GWBUF* stmt, int32_t* is_drop_table);
|
||||
int32_t (* qc_is_drop_table_query)(GWBUF* stmt, int32_t* is_drop_table);
|
||||
|
||||
/**
|
||||
* Returns all table names.
|
||||
@ -284,7 +284,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_table_names)(GWBUF* stmt, int32_t full_names, char*** names, int32_t *n_names);
|
||||
int32_t (* qc_get_table_names)(GWBUF* stmt, int32_t full_names, char*** names, int32_t* n_names);
|
||||
|
||||
/**
|
||||
* The canonical version of a statement.
|
||||
@ -296,7 +296,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_canonical)(GWBUF* stmt, char** canonical);
|
||||
int32_t (* qc_get_canonical)(GWBUF* stmt, char** canonical);
|
||||
|
||||
/**
|
||||
* Reports whether the statement has a where clause.
|
||||
@ -308,7 +308,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_query_has_clause)(GWBUF* stmt, int32_t* has_clause);
|
||||
int32_t (* qc_query_has_clause)(GWBUF* stmt, int32_t* has_clause);
|
||||
|
||||
/**
|
||||
* Reports the database names.
|
||||
@ -322,7 +322,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_database_names)(GWBUF* stmt, char*** names, int32_t* size);
|
||||
int32_t (* qc_get_database_names)(GWBUF* stmt, char*** names, int32_t* size);
|
||||
|
||||
/**
|
||||
* Reports the prepare name.
|
||||
@ -334,7 +334,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_prepare_name)(GWBUF* stmt, char** name);
|
||||
int32_t (* qc_get_prepare_name)(GWBUF* stmt, char** name);
|
||||
|
||||
/**
|
||||
* Reports field information.
|
||||
@ -346,7 +346,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_field_info)(GWBUF* stmt, const QC_FIELD_INFO** infos, uint32_t* n_infos);
|
||||
int32_t (* qc_get_field_info)(GWBUF* stmt, const QC_FIELD_INFO** infos, uint32_t* n_infos);
|
||||
|
||||
/**
|
||||
* The canonical version of a statement.
|
||||
@ -358,7 +358,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_function_info)(GWBUF* stmt, const QC_FUNCTION_INFO** infos, uint32_t* n_infos);
|
||||
int32_t (* qc_get_function_info)(GWBUF* stmt, const QC_FUNCTION_INFO** infos, uint32_t* n_infos);
|
||||
|
||||
/**
|
||||
* Return the preparable statement of a PREPARE statement.
|
||||
@ -375,7 +375,7 @@ typedef struct query_classifier
|
||||
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
|
||||
* exhaustion or equivalent.
|
||||
*/
|
||||
int32_t (*qc_get_preparable_stmt)(GWBUF* stmt, GWBUF** preparable_stmt);
|
||||
int32_t (* qc_get_preparable_stmt)(GWBUF* stmt, GWBUF** preparable_stmt);
|
||||
|
||||
/**
|
||||
* Set the version of the server. The version may affect how a statement
|
||||
@ -385,7 +385,7 @@ typedef struct query_classifier
|
||||
* @param version Version encoded as MariaDB encodes the version, i.e.:
|
||||
* version = major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
void (*qc_set_server_version)(uint64_t version);
|
||||
void (* qc_set_server_version)(uint64_t version);
|
||||
|
||||
/**
|
||||
* Get the thread specific version assumed of the server. If the version has
|
||||
@ -394,7 +394,7 @@ typedef struct query_classifier
|
||||
* @param version The version encoded as MariaDB encodes the version, i.e.:
|
||||
* version = major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
void (*qc_get_server_version)(uint64_t* version);
|
||||
void (* qc_get_server_version)(uint64_t* version);
|
||||
|
||||
/**
|
||||
* Gets the sql mode of the *calling* thread.
|
||||
@ -403,7 +403,7 @@ typedef struct query_classifier
|
||||
*
|
||||
* @return QC_RESULT_OK
|
||||
*/
|
||||
int32_t (*qc_get_sql_mode)(qc_sql_mode_t* sql_mode);
|
||||
int32_t (* qc_get_sql_mode)(qc_sql_mode_t* sql_mode);
|
||||
|
||||
/**
|
||||
* Sets the sql mode for the *calling* thread.
|
||||
@ -412,7 +412,7 @@ typedef struct query_classifier
|
||||
*
|
||||
* @return QC_RESULT_OK if @sql_mode is valid, otherwise QC_RESULT_ERROR.
|
||||
*/
|
||||
int32_t (*qc_set_sql_mode)(qc_sql_mode_t sql_mode);
|
||||
int32_t (* qc_set_sql_mode)(qc_sql_mode_t sql_mode);
|
||||
|
||||
/**
|
||||
* Dups the provided info object. After having been dupped, the info object
|
||||
@ -422,7 +422,7 @@ typedef struct query_classifier
|
||||
*
|
||||
* @return The same info that was provided as argument.
|
||||
*/
|
||||
QC_STMT_INFO* (*qc_info_dup)(QC_STMT_INFO* info);
|
||||
QC_STMT_INFO* (*qc_info_dup)(QC_STMT_INFO * info);
|
||||
|
||||
/**
|
||||
* Closes a dupped info object. After the info object has been closed, it must
|
||||
@ -430,7 +430,7 @@ typedef struct query_classifier
|
||||
*
|
||||
* @param info The info to be closed.
|
||||
*/
|
||||
void (*qc_info_close)(QC_STMT_INFO* info);
|
||||
void (* qc_info_close)(QC_STMT_INFO* info);
|
||||
} QUERY_CLASSIFIER;
|
||||
|
||||
/**
|
||||
@ -438,7 +438,7 @@ typedef struct query_classifier
|
||||
*/
|
||||
typedef struct QC_CACHE_PROPERTIES
|
||||
{
|
||||
int64_t max_size; /** The maximum size of the cache. */
|
||||
int64_t max_size; /** The maximum size of the cache. */
|
||||
} QC_CACHE_PROPERTIES;
|
||||
|
||||
/**
|
||||
@ -446,11 +446,11 @@ typedef struct QC_CACHE_PROPERTIES
|
||||
*/
|
||||
typedef struct QC_CACHE_STATS
|
||||
{
|
||||
int64_t size; /** The current size of the cache. */
|
||||
int64_t inserts; /** The number of inserts. */
|
||||
int64_t hits; /** The number of hits. */
|
||||
int64_t misses; /** The number of misses. */
|
||||
int64_t evictions; /** The number of evictions. */
|
||||
int64_t size; /** The current size of the cache. */
|
||||
int64_t inserts; /** The number of inserts. */
|
||||
int64_t hits; /** The number of hits. */
|
||||
int64_t misses; /** The number of misses. */
|
||||
int64_t evictions; /** The number of evictions. */
|
||||
} QC_CACHE_STATS;
|
||||
|
||||
/**
|
||||
@ -475,7 +475,8 @@ typedef struct QC_CACHE_STATS
|
||||
*/
|
||||
bool qc_setup(const QC_CACHE_PROPERTIES* cache_properties,
|
||||
qc_sql_mode_t sql_mode,
|
||||
const char* plugin_name, const char* plugin_args);
|
||||
const char* plugin_name,
|
||||
const char* plugin_args);
|
||||
|
||||
/**
|
||||
* Loads and setups the default query classifier, and performs
|
||||
@ -497,8 +498,8 @@ bool qc_setup(const QC_CACHE_PROPERTIES* cache_properties,
|
||||
*/
|
||||
bool qc_init(const QC_CACHE_PROPERTIES* cache_properties,
|
||||
qc_sql_mode_t sql_mode,
|
||||
const char* plugin_name,
|
||||
const char* plugin_args);
|
||||
const char* plugin_name,
|
||||
const char* plugin_args);
|
||||
|
||||
/**
|
||||
* Performs thread and process finalization.
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <string>
|
||||
@ -27,7 +27,7 @@ namespace maxscale
|
||||
class QueryClassifier
|
||||
{
|
||||
QueryClassifier(const QueryClassifier&) = delete;
|
||||
QueryClassifier& operator = (const QueryClassifier&) = delete;
|
||||
QueryClassifier& operator=(const QueryClassifier&) = delete;
|
||||
|
||||
public:
|
||||
class RouteInfo
|
||||
@ -35,7 +35,7 @@ public:
|
||||
public:
|
||||
RouteInfo();
|
||||
RouteInfo(uint32_t target,
|
||||
uint8_t command,
|
||||
uint8_t command,
|
||||
uint32_t type_mask,
|
||||
uint32_t stmt_id);
|
||||
|
||||
@ -92,10 +92,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_target; /**< Route target type, TARGET_UNDEFINED for unknown */
|
||||
uint8_t m_command; /**< The command byte, 0xff for unknown commands */
|
||||
uint32_t m_type_mask; /**< The query type, QUERY_TYPE_UNKNOWN for unknown types*/
|
||||
uint32_t m_stmt_id; /**< Prepared statement ID, 0 for unknown */
|
||||
uint32_t m_target; /**< Route target type, TARGET_UNDEFINED for unknown */
|
||||
uint8_t m_command; /**< The command byte, 0xff for unknown commands */
|
||||
uint32_t m_type_mask; /**< The query type, QUERY_TYPE_UNKNOWN for unknown types*/
|
||||
uint32_t m_stmt_id; /**< Prepared statement ID, 0 for unknown */
|
||||
};
|
||||
|
||||
class Handler
|
||||
@ -123,39 +123,39 @@ public:
|
||||
|
||||
static bool target_is_master(uint32_t t)
|
||||
{
|
||||
return (t & TARGET_MASTER);
|
||||
return t & TARGET_MASTER;
|
||||
}
|
||||
|
||||
static bool target_is_slave(uint32_t t)
|
||||
{
|
||||
return (t & TARGET_SLAVE);
|
||||
return t & TARGET_SLAVE;
|
||||
}
|
||||
|
||||
static bool target_is_named_server(uint32_t t)
|
||||
{
|
||||
return (t & TARGET_NAMED_SERVER);
|
||||
return t & TARGET_NAMED_SERVER;
|
||||
}
|
||||
|
||||
static bool target_is_all(uint32_t t)
|
||||
{
|
||||
return (t & TARGET_ALL);
|
||||
return t & TARGET_ALL;
|
||||
}
|
||||
|
||||
static bool target_is_rlag_max(uint32_t t)
|
||||
{
|
||||
return (t & TARGET_RLAG_MAX);
|
||||
return t & TARGET_RLAG_MAX;
|
||||
}
|
||||
|
||||
static bool target_is_last_used(uint32_t t)
|
||||
{
|
||||
return (t & TARGET_LAST_USED);
|
||||
return t & TARGET_LAST_USED;
|
||||
}
|
||||
|
||||
enum current_target_t
|
||||
{
|
||||
CURRENT_TARGET_UNDEFINED, /**< Current target has not been set. */
|
||||
CURRENT_TARGET_MASTER, /**< Current target is master */
|
||||
CURRENT_TARGET_SLAVE /**< Current target is a slave */
|
||||
CURRENT_TARGET_UNDEFINED, /**< Current target has not been set. */
|
||||
CURRENT_TARGET_MASTER, /**< Current target is master */
|
||||
CURRENT_TARGET_SLAVE /**< Current target is a slave */
|
||||
};
|
||||
|
||||
/** States of a LOAD DATA LOCAL INFILE */
|
||||
@ -355,23 +355,22 @@ private:
|
||||
return m_pSession;
|
||||
}
|
||||
|
||||
void log_transaction_status(GWBUF *querybuf, uint32_t qtype);
|
||||
void log_transaction_status(GWBUF* querybuf, uint32_t qtype);
|
||||
|
||||
static uint32_t determine_query_type(GWBUF *querybuf, int command);
|
||||
static uint32_t determine_query_type(GWBUF* querybuf, int command);
|
||||
|
||||
void check_create_tmp_table(GWBUF *querybuf, uint32_t type);
|
||||
void check_create_tmp_table(GWBUF* querybuf, uint32_t type);
|
||||
|
||||
bool is_read_tmp_table(GWBUF *querybuf, uint32_t qtype);
|
||||
bool is_read_tmp_table(GWBUF* querybuf, uint32_t qtype);
|
||||
|
||||
void check_drop_tmp_table(GWBUF *querybuf);
|
||||
void check_drop_tmp_table(GWBUF* querybuf);
|
||||
|
||||
bool check_for_multi_stmt(GWBUF *buf, uint8_t packet_type);
|
||||
bool check_for_multi_stmt(GWBUF* buf, uint8_t packet_type);
|
||||
|
||||
current_target_t
|
||||
handle_multi_temp_and_load(QueryClassifier::current_target_t current_target,
|
||||
GWBUF *querybuf,
|
||||
uint8_t packet_type,
|
||||
uint32_t *qtype);
|
||||
current_target_t handle_multi_temp_and_load(QueryClassifier::current_target_t current_target,
|
||||
GWBUF* querybuf,
|
||||
uint8_t packet_type,
|
||||
uint32_t* qtype);
|
||||
|
||||
private:
|
||||
class PSManager;
|
||||
@ -387,16 +386,15 @@ private:
|
||||
Handler* m_pHandler;
|
||||
MXS_SESSION* m_pSession;
|
||||
mxs_target_t m_use_sql_variables_in;
|
||||
load_data_state_t m_load_data_state; /**< The LOAD DATA state */
|
||||
uint64_t m_load_data_sent; /**< How much data has been sent */
|
||||
load_data_state_t m_load_data_state; /**< The LOAD DATA state */
|
||||
uint64_t m_load_data_sent; /**< How much data has been sent */
|
||||
bool m_have_tmp_tables;
|
||||
TableSet m_tmp_tables; /**< Set of temporary tables */
|
||||
bool m_large_query; /**< Set to true when processing payloads >= 2^24 bytes */
|
||||
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
|
||||
TableSet m_tmp_tables; /**< Set of temporary tables */
|
||||
bool m_large_query; /**< Set to true when processing payloads >= 2^24 bytes */
|
||||
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
|
||||
SPSManager m_sPs_manager;
|
||||
HandleMap m_ps_handles; /** External ID to internal ID */
|
||||
HandleMap m_ps_handles; /** External ID to internal ID */
|
||||
RouteInfo m_route_info;
|
||||
bool m_trx_is_read_only;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
void write(DCB* dcb);
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_columns;
|
||||
std::vector<std::string> m_columns;
|
||||
std::vector<std::vector<std::string>> m_rows;
|
||||
|
||||
ResultSet(std::initializer_list<std::string> names);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file router.h - The query router public interface definition
|
||||
@ -94,7 +94,7 @@ typedef struct mxs_router_object
|
||||
*
|
||||
* @return New router instance on NULL on error
|
||||
*/
|
||||
MXS_ROUTER *(*createInstance)(SERVICE* service, MXS_CONFIG_PARAMETER* params);
|
||||
MXS_ROUTER*(*createInstance)(SERVICE * service, MXS_CONFIG_PARAMETER* params);
|
||||
|
||||
/**
|
||||
* Called to create a new user session within the router
|
||||
@ -109,7 +109,7 @@ typedef struct mxs_router_object
|
||||
*
|
||||
* @return New router session or NULL on error
|
||||
*/
|
||||
MXS_ROUTER_SESSION *(*newSession)(MXS_ROUTER *instance, MXS_SESSION *session);
|
||||
MXS_ROUTER_SESSION*(*newSession)(MXS_ROUTER * instance, MXS_SESSION* session);
|
||||
|
||||
/**
|
||||
* @brief Called when a session is closed
|
||||
@ -119,7 +119,7 @@ typedef struct mxs_router_object
|
||||
* @param instance Router instance
|
||||
* @param router_session Router session
|
||||
*/
|
||||
void (*closeSession)(MXS_ROUTER *instance, MXS_ROUTER_SESSION *router_session);
|
||||
void (* closeSession)(MXS_ROUTER* instance, MXS_ROUTER_SESSION* router_session);
|
||||
|
||||
/**
|
||||
* @brief Called when a session is freed
|
||||
@ -129,7 +129,7 @@ typedef struct mxs_router_object
|
||||
* @param instance Router instance
|
||||
* @param router_session Router session
|
||||
*/
|
||||
void (*freeSession)(MXS_ROUTER *instance, MXS_ROUTER_SESSION *router_session);
|
||||
void (* freeSession)(MXS_ROUTER* instance, MXS_ROUTER_SESSION* router_session);
|
||||
|
||||
/**
|
||||
* @brief Called on each query that requires routing
|
||||
@ -143,7 +143,7 @@ typedef struct mxs_router_object
|
||||
* @return If successful, the function returns 1. If an error occurs
|
||||
* and the session should be closed, the function returns 0.
|
||||
*/
|
||||
int32_t (*routeQuery)(MXS_ROUTER *instance, MXS_ROUTER_SESSION *router_session, GWBUF *queue);
|
||||
int32_t (* routeQuery)(MXS_ROUTER* instance, MXS_ROUTER_SESSION* router_session, GWBUF* queue);
|
||||
|
||||
|
||||
/**
|
||||
@ -152,7 +152,7 @@ typedef struct mxs_router_object
|
||||
* @param instance Router instance
|
||||
* @param dcb DCB where the diagnostic information should be written
|
||||
*/
|
||||
void (*diagnostics)(MXS_ROUTER *instance, DCB *dcb);
|
||||
void (* diagnostics)(MXS_ROUTER* instance, DCB* dcb);
|
||||
|
||||
/**
|
||||
* @brief Called for diagnostic output
|
||||
@ -163,7 +163,7 @@ typedef struct mxs_router_object
|
||||
*
|
||||
* @see jansson.h
|
||||
*/
|
||||
json_t* (*diagnostics_json)(const MXS_ROUTER *instance);
|
||||
json_t* (*diagnostics_json)(const MXS_ROUTER * instance);
|
||||
|
||||
/**
|
||||
* @brief Called for each reply packet
|
||||
@ -175,8 +175,10 @@ typedef struct mxs_router_object
|
||||
* @param queue Response from the server
|
||||
* @param backend_dcb The backend DCB which responded to the query
|
||||
*/
|
||||
void (*clientReply)(MXS_ROUTER* instance, MXS_ROUTER_SESSION *router_session,
|
||||
GWBUF *queue, DCB *backend_dcb);
|
||||
void (* clientReply)(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* queue,
|
||||
DCB* backend_dcb);
|
||||
|
||||
/**
|
||||
* @brief Called when a backend DCB has failed
|
||||
@ -189,12 +191,12 @@ typedef struct mxs_router_object
|
||||
*
|
||||
* @param succp Pointer to a `bool` which should be set to true for success or false for error
|
||||
*/
|
||||
void (*handleError)(MXS_ROUTER *instance,
|
||||
MXS_ROUTER_SESSION *router_session,
|
||||
GWBUF *errmsgbuf,
|
||||
DCB *backend_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp);
|
||||
void (* handleError)(MXS_ROUTER* instance,
|
||||
MXS_ROUTER_SESSION* router_session,
|
||||
GWBUF* errmsgbuf,
|
||||
DCB* backend_dcb,
|
||||
mxs_error_action_t action,
|
||||
bool* succp);
|
||||
|
||||
/**
|
||||
* @brief Called to obtain the capabilities of the router
|
||||
@ -203,14 +205,14 @@ typedef struct mxs_router_object
|
||||
*
|
||||
* @see routing.h
|
||||
*/
|
||||
uint64_t (*getCapabilities)(MXS_ROUTER *instance);
|
||||
uint64_t (* getCapabilities)(MXS_ROUTER* instance);
|
||||
|
||||
/**
|
||||
* @brief Called for destroying a router instance
|
||||
*
|
||||
* @param instance Router instance
|
||||
*/
|
||||
void (*destroyInstance)(MXS_ROUTER *instance);
|
||||
void (* destroyInstance)(MXS_ROUTER* instance);
|
||||
|
||||
/**
|
||||
* @brief Configure router instance at runtime
|
||||
@ -231,8 +233,7 @@ typedef struct mxs_router_object
|
||||
* failed. If reconfiguration failed, the state of the router
|
||||
* instance should not be modified.
|
||||
*/
|
||||
bool (*configureInstance)(MXS_ROUTER *instance, MXS_CONFIG_PARAMETER* params);
|
||||
|
||||
bool (* configureInstance)(MXS_ROUTER* instance, MXS_CONFIG_PARAMETER* params);
|
||||
} MXS_ROUTER_OBJECT;
|
||||
|
||||
/**
|
||||
@ -240,7 +241,7 @@ typedef struct mxs_router_object
|
||||
* must update these versions numbers in accordance with the rules in
|
||||
* modinfo.h.
|
||||
*/
|
||||
#define MXS_ROUTER_VERSION { 4, 0, 0 }
|
||||
#define MXS_ROUTER_VERSION {4, 0, 0}
|
||||
|
||||
/**
|
||||
* Specifies capabilities specific for routers. Common capabilities
|
||||
@ -253,11 +254,11 @@ typedef struct mxs_router_object
|
||||
*/
|
||||
typedef enum router_capability
|
||||
{
|
||||
RCAP_TYPE_NO_RSESSION = 0x00010000, /**< Router does not use router sessions */
|
||||
RCAP_TYPE_NO_USERS_INIT = 0x00020000, /**< Prevent the loading of authenticator
|
||||
users when the service is started */
|
||||
RCAP_TYPE_NO_AUTH = 0x00040000, /**< No `user` or `password` parameter required */
|
||||
RCAP_TYPE_RUNTIME_CONFIG = 0x00080000, /**< Router supports runtime cofiguration */
|
||||
RCAP_TYPE_NO_RSESSION = 0x00010000, /**< Router does not use router sessions */
|
||||
RCAP_TYPE_NO_USERS_INIT = 0x00020000, /**< Prevent the loading of authenticator
|
||||
* users when the service is started */
|
||||
RCAP_TYPE_NO_AUTH = 0x00040000, /**< No `user` or `password` parameter required */
|
||||
RCAP_TYPE_RUNTIME_CONFIG = 0x00080000, /**< Router supports runtime cofiguration */
|
||||
} mxs_router_capability_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/router.h>
|
||||
@ -66,16 +66,16 @@ public:
|
||||
* @param action The context.
|
||||
* @param pSuccess On output, if false, the session will be terminated.
|
||||
*/
|
||||
void handleError(GWBUF* pMessage,
|
||||
DCB* pProblem,
|
||||
void handleError(GWBUF* pMessage,
|
||||
DCB* pProblem,
|
||||
mxs_error_action_t action,
|
||||
bool* pSuccess);
|
||||
bool* pSuccess);
|
||||
|
||||
protected:
|
||||
RouterSession(MXS_SESSION* pSession);
|
||||
|
||||
protected:
|
||||
MXS_SESSION* m_pSession; /*< The MXS_SESSION this router session is associated with. */
|
||||
MXS_SESSION* m_pSession; /*< The MXS_SESSION this router session is associated with. */
|
||||
};
|
||||
|
||||
|
||||
@ -205,12 +205,12 @@ public:
|
||||
MXS_EXCEPTION_GUARD(pRouter_session->clientReply(pPacket, pBackend));
|
||||
}
|
||||
|
||||
static void handleError(MXS_ROUTER* pInstance,
|
||||
static void handleError(MXS_ROUTER* pInstance,
|
||||
MXS_ROUTER_SESSION* pData,
|
||||
GWBUF* pMessage,
|
||||
DCB* pProblem,
|
||||
mxs_error_action_t action,
|
||||
bool* pSuccess)
|
||||
GWBUF* pMessage,
|
||||
DCB* pProblem,
|
||||
mxs_error_action_t action,
|
||||
bool* pSuccess)
|
||||
{
|
||||
RouterSessionType* pRouter_session = static_cast<RouterSessionType*>(pData);
|
||||
|
||||
@ -246,7 +246,7 @@ public:
|
||||
static MXS_ROUTER_OBJECT s_object;
|
||||
|
||||
protected:
|
||||
Router(SERVICE *pService)
|
||||
Router(SERVICE* pService)
|
||||
: m_pService(pService)
|
||||
{
|
||||
}
|
||||
@ -271,6 +271,4 @@ MXS_ROUTER_OBJECT Router<RouterType, RouterSessionType>::s_object =
|
||||
&Router<RouterType, RouterSessionType>::destroyInstance,
|
||||
&Router<RouterType, RouterSessionType>::configure,
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file routing.h - Common definitions and declarations for routers and filters.
|
||||
@ -39,23 +39,22 @@ MXS_BEGIN_DECLS
|
||||
typedef enum routing_capability
|
||||
{
|
||||
/**< Statements are delivered one per buffer. */
|
||||
RCAP_TYPE_STMT_INPUT = 0x0001, /* 0b0000000000000001 */
|
||||
RCAP_TYPE_STMT_INPUT = 0x0001, /* 0b0000000000000001 */
|
||||
/**< Each delivered buffer is contiguous; implies RCAP_TYPE_STMT_INPUT. */
|
||||
RCAP_TYPE_CONTIGUOUS_INPUT = 0x0003, /* 0b0000000000000011 */
|
||||
RCAP_TYPE_CONTIGUOUS_INPUT = 0x0003, /* 0b0000000000000011 */
|
||||
/**< The transaction state and autocommit mode of the session are tracked;
|
||||
implies RCAP_TYPE_CONTIGUOUS_INPUT and RCAP_TYPE_STMT_INPUT. */
|
||||
RCAP_TYPE_TRANSACTION_TRACKING = 0x0007, /* 0b0000000000000111 */
|
||||
* implies RCAP_TYPE_CONTIGUOUS_INPUT and RCAP_TYPE_STMT_INPUT. */
|
||||
RCAP_TYPE_TRANSACTION_TRACKING = 0x0007, /* 0b0000000000000111 */
|
||||
/**< Responses are delivered one per buffer. */
|
||||
RCAP_TYPE_STMT_OUTPUT = 0x0010, /* 0b0000000000010000 */
|
||||
RCAP_TYPE_STMT_OUTPUT = 0x0010, /* 0b0000000000010000 */
|
||||
/**< Each delivered buffer is contiguous; implies RCAP_TYPE_STMT_OUTPUT. */
|
||||
RCAP_TYPE_CONTIGUOUS_OUTPUT = 0x0030, /* 0b0000000000110000 */
|
||||
RCAP_TYPE_CONTIGUOUS_OUTPUT = 0x0030, /* 0b0000000000110000 */
|
||||
/** Result sets are delivered in one buffer; implies RCAP_TYPE_STMT_OUTPUT. */
|
||||
RCAP_TYPE_RESULTSET_OUTPUT = 0x0050, /* 0b0000000001110000 */
|
||||
RCAP_TYPE_RESULTSET_OUTPUT = 0x0050, /* 0b0000000001110000 */
|
||||
/** Results are delivered as a set of complete packets */
|
||||
RCAP_TYPE_PACKET_OUTPUT = 0x0080, /* 0b0000000010000000 */
|
||||
RCAP_TYPE_PACKET_OUTPUT = 0x0080, /* 0b0000000010000000 */
|
||||
/** Track session state changes, implies packet output */
|
||||
RCAP_TYPE_SESSION_STATE_TRACKING = 0x0180, /* 0b0000000011000000 */
|
||||
|
||||
RCAP_TYPE_SESSION_STATE_TRACKING = 0x0180, /* 0b0000000011000000 */
|
||||
} mxs_routing_capability_t;
|
||||
|
||||
#define RCAP_TYPE_NONE 0
|
||||
@ -74,4 +73,3 @@ static inline bool rcap_type_required(uint64_t capabilities, uint64_t type)
|
||||
}
|
||||
|
||||
MXS_END_DECLS
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <maxbase/worker.h>
|
||||
@ -81,7 +81,7 @@ size_t mxs_rworker_broadcast_message(uint32_t msg_id, intptr_t arg1, intptr_t ar
|
||||
* @return The number of messages posted; if less that ne number of workers
|
||||
* then some postings failed.
|
||||
*/
|
||||
size_t mxs_rworker_broadcast(void (*cb)(void* data), void* data);
|
||||
size_t mxs_rworker_broadcast(void (* cb)(void* data), void* data);
|
||||
|
||||
/**
|
||||
* Add a session to the current routing worker's session container. Currently
|
||||
@ -133,7 +133,7 @@ uint64_t mxs_rworker_create_key();
|
||||
* required. This function is called by mxs_rworker_delete_data
|
||||
* when the data is deleted.
|
||||
*/
|
||||
void mxs_rworker_set_data(uint64_t key, void* data, void (*callback)(void*));
|
||||
void mxs_rworker_set_data(uint64_t key, void* data, void (* callback)(void*));
|
||||
|
||||
/**
|
||||
* Get local data from current worker
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -34,7 +34,7 @@ class RoutingWorker : public mxb::Worker
|
||||
, private MXB_POLL_DATA
|
||||
{
|
||||
RoutingWorker(const RoutingWorker&) = delete;
|
||||
RoutingWorker& operator = (const RoutingWorker&) = delete;
|
||||
RoutingWorker& operator=(const RoutingWorker&) = delete;
|
||||
|
||||
public:
|
||||
enum
|
||||
@ -45,8 +45,8 @@ public:
|
||||
typedef Registry<MXS_SESSION> SessionsById;
|
||||
typedef std::vector<DCB*> Zombies;
|
||||
|
||||
typedef std::unordered_map<uint64_t, void*> LocalData;
|
||||
typedef std::unordered_map<uint64_t, void(*)(void*)> DataDeleters;
|
||||
typedef std::unordered_map<uint64_t, void*> LocalData;
|
||||
typedef std::unordered_map<uint64_t, void (*)(void*)> DataDeleters;
|
||||
|
||||
/**
|
||||
* Initialize the routing worker mechanism.
|
||||
@ -345,7 +345,7 @@ public:
|
||||
* @param key Key acquired with create_local_data
|
||||
* @param data Data to store
|
||||
*/
|
||||
void set_data(uint64_t key, void* data, void (*callback)(void*))
|
||||
void set_data(uint64_t key, void* data, void (* callback)(void*))
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
@ -426,33 +426,33 @@ public:
|
||||
static std::unique_ptr<json_t> get_qc_stats_as_json(const char* zHost, int id);
|
||||
|
||||
private:
|
||||
const int m_id; /*< The id of the worker. */
|
||||
SessionsById m_sessions; /*< A mapping of session_id->MXS_SESSION. The map
|
||||
* should contain sessions exclusive to this
|
||||
* worker and not e.g. listener sessions. For now,
|
||||
* it's up to the protocol to decide whether a new
|
||||
* session is added to the map. */
|
||||
Zombies m_zombies; /*< DCBs to be deleted. */
|
||||
LocalData m_local_data; /*< Data local to this worker */
|
||||
DataDeleters m_data_deleters; /*< Delete functions for the local data */
|
||||
const int m_id; /*< The id of the worker. */
|
||||
SessionsById m_sessions; /*< A mapping of session_id->MXS_SESSION. The map
|
||||
* should contain sessions exclusive to this
|
||||
* worker and not e.g. listener sessions. For now,
|
||||
* it's up to the protocol to decide whether a new
|
||||
* session is added to the map. */
|
||||
Zombies m_zombies; /*< DCBs to be deleted. */
|
||||
LocalData m_local_data; /*< Data local to this worker */
|
||||
DataDeleters m_data_deleters; /*< Delete functions for the local data */
|
||||
|
||||
RoutingWorker();
|
||||
virtual ~RoutingWorker();
|
||||
|
||||
static RoutingWorker* create(int epoll_listener_fd);
|
||||
|
||||
bool pre_run(); // override
|
||||
void post_run(); // override
|
||||
void epoll_tick(); // override
|
||||
bool pre_run(); // override
|
||||
void post_run(); // override
|
||||
void epoll_tick(); // override
|
||||
|
||||
void delete_zombies();
|
||||
|
||||
static uint32_t epoll_instance_handler(MXB_POLL_DATA* data, MXB_WORKER* worker, uint32_t events);
|
||||
uint32_t handle_epoll_events(uint32_t events);
|
||||
uint32_t handle_epoll_events(uint32_t events);
|
||||
};
|
||||
|
||||
// Data local to a routing worker
|
||||
template <class T>
|
||||
template<class T>
|
||||
class rworker_local
|
||||
{
|
||||
public:
|
||||
@ -461,15 +461,15 @@ public:
|
||||
rworker_local& operator=(const rworker_local&) = delete;
|
||||
|
||||
// Default initialized
|
||||
rworker_local():
|
||||
m_handle(mxs_rworker_create_key())
|
||||
rworker_local()
|
||||
: m_handle(mxs_rworker_create_key())
|
||||
{
|
||||
}
|
||||
|
||||
// Copy-constructed
|
||||
rworker_local(const T& t):
|
||||
m_handle(mxs_rworker_create_key()),
|
||||
m_value(t)
|
||||
rworker_local(const T& t)
|
||||
: m_handle(mxs_rworker_create_key())
|
||||
, m_value(t)
|
||||
{
|
||||
}
|
||||
|
||||
@ -510,9 +510,9 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
uint64_t m_handle; // The handle to the worker local data
|
||||
typename std::remove_const<T>::type m_value; // The master value, never used directly
|
||||
mutable std::mutex m_lock; // Protects the master value
|
||||
uint64_t m_handle; // The handle to the worker local data
|
||||
typename std::remove_const<T>::type m_value; // The master value, never used directly
|
||||
mutable std::mutex m_lock; // Protects the master value
|
||||
|
||||
private:
|
||||
|
||||
@ -554,7 +554,6 @@ private:
|
||||
delete static_cast<T*>(data);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/secrets.h - MaxScale config file password decryption
|
||||
@ -22,6 +22,6 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
char *decrypt_password(const char *);
|
||||
char* decrypt_password(const char*);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file server.h
|
||||
@ -142,21 +142,21 @@ typedef struct server
|
||||
DCB** persistent; /**< List of unused persistent connections to the server */
|
||||
uint8_t charset; /**< Server character set. Read from backend and sent to client. */
|
||||
// Statistics and events
|
||||
SERVER_STATS stats; /**< The server statistics, e.g. number of connections */
|
||||
int persistmax; /**< Maximum pool size actually achieved since startup */
|
||||
int last_event; /**< The last event that occurred on this server */
|
||||
int64_t triggered_at; /**< Time when the last event was triggered */
|
||||
SERVER_STATS stats; /**< The server statistics, e.g. number of connections */
|
||||
int persistmax; /**< Maximum pool size actually achieved since startup */
|
||||
int last_event; /**< The last event that occurred on this server */
|
||||
int64_t triggered_at; /**< Time when the last event was triggered */
|
||||
// Status descriptors. Updated automatically by a monitor or manually by the admin
|
||||
uint64_t status; /**< Current status flag bitmap */
|
||||
int maint_request; /**< Is admin requesting Maintenance=ON/OFF on the
|
||||
uint64_t status; /**< Current status flag bitmap */
|
||||
int maint_request; /**< Is admin requesting Maintenance=ON/OFF on the
|
||||
* server? */
|
||||
char version_string[MAX_SERVER_VERSION_LEN]; /**< Server version string as given by backend */
|
||||
uint64_t version; /**< Server version numeric representation */
|
||||
server_type_t server_type; /**< Server type (MariaDB or MySQL), deduced from
|
||||
* version string */
|
||||
long node_id; /**< Node id, server_id for M/S or local_index for
|
||||
long node_id; /**< Node id, server_id for M/S or local_index for
|
||||
* Galera */
|
||||
int rlag; /**< Replication Lag for Master/Slave replication
|
||||
int rlag; /**< Replication Lag for Master/Slave replication
|
||||
* */
|
||||
unsigned long node_ts; /**< Last timestamp set from M/S monitor module */
|
||||
long master_id; /**< Master server id of this node */
|
||||
@ -196,33 +196,33 @@ typedef struct server
|
||||
(server_is_master(s) ? "RUNNING MASTER" \
|
||||
: (server_is_slave(s) ? "RUNNING SLAVE" \
|
||||
: (server_is_joined(s) ? "RUNNING JOINED" \
|
||||
: (server_is_ndb(s) ? \
|
||||
"RUNNING NDB" \
|
||||
: (( \
|
||||
server_is_running( \
|
||||
s) \
|
||||
&& \
|
||||
server_is_in_maint( \
|
||||
s)) \
|
||||
? \
|
||||
"RUNNING MAINTENANCE" \
|
||||
: ( \
|
||||
server_is_relay( \
|
||||
s) \
|
||||
? \
|
||||
"RUNNING RELAY" \
|
||||
: ( \
|
||||
server_is_usable( \
|
||||
s) \
|
||||
? \
|
||||
"RUNNING (only)" \
|
||||
: ( \
|
||||
server_is_down( \
|
||||
s) \
|
||||
? \
|
||||
"DOWN" \
|
||||
: \
|
||||
"UNKNOWN STATUS"))))))))
|
||||
: (server_is_ndb(s) \
|
||||
? "RUNNING NDB" \
|
||||
: (( \
|
||||
server_is_running( \
|
||||
s) \
|
||||
&& \
|
||||
server_is_in_maint( \
|
||||
s)) \
|
||||
? \
|
||||
"RUNNING MAINTENANCE" \
|
||||
: ( \
|
||||
server_is_relay( \
|
||||
s) \
|
||||
? \
|
||||
"RUNNING RELAY" \
|
||||
: ( \
|
||||
server_is_usable( \
|
||||
s) \
|
||||
? \
|
||||
"RUNNING (only)" \
|
||||
: ( \
|
||||
server_is_down( \
|
||||
s) \
|
||||
? \
|
||||
"DOWN" \
|
||||
: \
|
||||
"UNKNOWN STATUS"))))))))
|
||||
|
||||
/**
|
||||
* Is the server valid and active?
|
||||
@ -447,7 +447,7 @@ bool server_remove_parameter(SERVER* server, const char* name);
|
||||
* @param name Parameter to set
|
||||
* @param value Value of parameter
|
||||
*/
|
||||
void server_set_parameter(SERVER *server, const char *name, const char *value);
|
||||
void server_set_parameter(SERVER* server, const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* @brief Check if a server points to a local MaxScale service
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -19,6 +19,6 @@
|
||||
|
||||
namespace maxscale
|
||||
{
|
||||
bool server_set_status(SERVER *server, int bit, std::string* errmsg_out = NULL);
|
||||
bool server_clear_status(SERVER *server, int bit, std::string* errmsg_out = NULL);
|
||||
bool server_set_status(SERVER* server, int bit, std::string* errmsg_out = NULL);
|
||||
bool server_clear_status(SERVER* server, int bit, std::string* errmsg_out = NULL);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file service.h
|
||||
@ -43,10 +43,10 @@ struct mxs_router;
|
||||
struct mxs_router_object;
|
||||
struct users;
|
||||
|
||||
#define MAX_SERVICE_USER_LEN 1024
|
||||
#define MAX_SERVICE_USER_LEN 1024
|
||||
#define MAX_SERVICE_PASSWORD_LEN 1024
|
||||
#define MAX_SERVICE_WEIGHTBY_LEN 1024
|
||||
#define MAX_SERVICE_VERSION_LEN 1024
|
||||
#define MAX_SERVICE_VERSION_LEN 1024
|
||||
|
||||
/**
|
||||
* The service statistics structure
|
||||
@ -61,11 +61,11 @@ typedef struct
|
||||
|
||||
typedef struct server_ref_t
|
||||
{
|
||||
struct server_ref_t *next; /**< Next server reference */
|
||||
SERVER* server; /**< The actual server */
|
||||
double inv_weight; /**< Inverse of weight in the range [0..1], 0 is best. */
|
||||
int connections; /**< Number of connections created through this reference */
|
||||
bool active; /**< Whether this reference is valid and in use*/
|
||||
struct server_ref_t* next; /**< Next server reference */
|
||||
SERVER* server; /**< The actual server */
|
||||
double inv_weight; /**< Inverse of weight in the range [0..1], 0 is best. */
|
||||
int connections; /**< Number of connections created through this reference */
|
||||
bool active; /**< Whether this reference is valid and in use*/
|
||||
} SERVER_REF;
|
||||
|
||||
/** Returns true if the two server "scores" are within 1/(see code) of each other.
|
||||
@ -76,14 +76,14 @@ typedef struct server_ref_t
|
||||
*/
|
||||
inline bool almost_equal_server_scores(double lhs, double rhs)
|
||||
{
|
||||
constexpr double div = 100; // within 1% of each other.
|
||||
constexpr double div = 100; // within 1% of each other.
|
||||
return std::abs(lhs - rhs) < std::abs(std::max(lhs, rhs)) * (1 / div);
|
||||
}
|
||||
|
||||
/** Macro to check whether a SERVER_REF is active */
|
||||
#define SERVER_REF_IS_ACTIVE(ref) (ref->active && server_is_active(ref->server))
|
||||
|
||||
#define SERVICE_MAX_RETRY_INTERVAL 3600 /*< The maximum interval between service start retries */
|
||||
#define SERVICE_MAX_RETRY_INTERVAL 3600 /*< The maximum interval between service start retries */
|
||||
|
||||
/** Value of service timeout if timeout checks are disabled */
|
||||
#define SERVICE_NO_SESSION_TIMEOUT 0
|
||||
@ -95,8 +95,8 @@ inline bool almost_equal_server_scores(double lhs, double rhs)
|
||||
#define SERVICE_PARAM_UNINIT -1
|
||||
|
||||
/* Refresh rate limits for load users from database */
|
||||
#define USERS_REFRESH_TIME_DEFAULT 30 /* Allowed time interval (in seconds) after last update*/
|
||||
#define USERS_REFRESH_TIME_MIN 10 /* Minimum allowed time interval (in seconds)*/
|
||||
#define USERS_REFRESH_TIME_DEFAULT 30 /* Allowed time interval (in seconds) after last update*/
|
||||
#define USERS_REFRESH_TIME_MIN 10 /* Minimum allowed time interval (in seconds)*/
|
||||
|
||||
/** Default timeout values used by the connections which fetch user authentication data */
|
||||
#define DEFAULT_AUTH_CONNECT_TIMEOUT 3
|
||||
@ -112,38 +112,57 @@ inline bool almost_equal_server_scores(double lhs, double rhs)
|
||||
*/
|
||||
typedef struct service
|
||||
{
|
||||
const char* name; /**< The service name */
|
||||
int state; /**< The service state */
|
||||
int client_count; /**< Number of connected clients */
|
||||
int max_connections; /**< Maximum client connections */
|
||||
SERV_LISTENER *ports; /**< Linked list of ports and protocols
|
||||
* that this service will listen on */
|
||||
const char* routerModule; /**< Name of router module to use */
|
||||
struct mxs_router_object *router; /**< The router we are using */
|
||||
struct mxs_router *router_instance;/**< The router instance for this service */
|
||||
char version_string[MAX_SERVICE_VERSION_LEN]; /**< version string for this service listeners */
|
||||
SERVER_REF *dbref; /**< server references */
|
||||
int n_dbref; /**< Number of server references */
|
||||
char user[MAX_SERVICE_USER_LEN]; /**< The user name to use to extract information */
|
||||
char password[MAX_SERVICE_PASSWORD_LEN]; /**< The authentication data requied */
|
||||
SERVICE_STATS stats; /**< The service statistics */
|
||||
bool enable_root; /**< Allow root user access */
|
||||
bool localhost_match_wildcard_host; /**< Match localhost against wildcard */
|
||||
MXS_CONFIG_PARAMETER* svc_config_param;/**< list of config params and values */
|
||||
int svc_config_version; /**< Version number of configuration */
|
||||
bool svc_do_shutdown; /**< tells the service to exit loops etc. */
|
||||
bool users_from_all; /**< Load users from one server or all of them */
|
||||
bool strip_db_esc; /**< Remove the '\' characters from database names
|
||||
* when querying them from the server. MySQL Workbench seems
|
||||
* to escape at least the underscore character. */
|
||||
int64_t conn_idle_timeout; /**< Session timeout in seconds */
|
||||
char weightby[MAX_SERVICE_WEIGHTBY_LEN]; /**< Service weighting parameter name */
|
||||
bool retry_start; /**< If starting of the service should be retried later */
|
||||
bool log_auth_warnings; /**< Log authentication failures and warnings */
|
||||
uint64_t capabilities; /**< The capabilities of the service, @see enum routing_capability */
|
||||
int max_retry_interval; /**< Maximum retry interval */
|
||||
bool session_track_trx_state; /**< Get transaction state via session track mechanism */
|
||||
int active; /**< Whether the service is still active */
|
||||
const char* name; /**< The service name */
|
||||
int state; /**< The service state */
|
||||
int client_count; /**< Number of connected clients */
|
||||
int max_connections; /**< Maximum client connections */
|
||||
SERV_LISTENER* ports; /**< Linked list of ports and
|
||||
* protocols
|
||||
* that this service will listen on */
|
||||
const char* routerModule; /**< Name of router module to use */
|
||||
struct mxs_router_object* router; /**< The router we are using */
|
||||
struct mxs_router* router_instance; /**< The router instance for this
|
||||
* service */
|
||||
char version_string[MAX_SERVICE_VERSION_LEN]; /**< version string for this service
|
||||
* listeners */
|
||||
SERVER_REF* dbref; /**< server references */
|
||||
int n_dbref; /**< Number of server references */
|
||||
char user[MAX_SERVICE_USER_LEN]; /**< The user name to use to extract
|
||||
* information */
|
||||
char password[MAX_SERVICE_PASSWORD_LEN]; /**< The authentication data requied
|
||||
* */
|
||||
SERVICE_STATS stats; /**< The service statistics */
|
||||
bool enable_root; /**< Allow root user access */
|
||||
bool localhost_match_wildcard_host; /**< Match localhost against wildcard
|
||||
* */
|
||||
MXS_CONFIG_PARAMETER* svc_config_param; /**< list of config params and values
|
||||
* */
|
||||
int svc_config_version; /**< Version number of configuration
|
||||
* */
|
||||
bool svc_do_shutdown; /**< tells the service to exit loops
|
||||
* etc. */
|
||||
bool users_from_all; /**< Load users from one server or all
|
||||
* of them */
|
||||
bool strip_db_esc; /**< Remove the '\' characters from
|
||||
* database names
|
||||
* when querying them from the server.
|
||||
*MySQL Workbench seems
|
||||
* to escape at least the underscore
|
||||
*character. */
|
||||
int64_t conn_idle_timeout; /**< Session timeout in seconds */
|
||||
char weightby[MAX_SERVICE_WEIGHTBY_LEN]; /**< Service weighting parameter name
|
||||
* */
|
||||
bool retry_start; /**< If starting of the service should
|
||||
* be retried later */
|
||||
bool log_auth_warnings; /**< Log authentication failures and
|
||||
* warnings */
|
||||
uint64_t capabilities; /**< The capabilities of the service,
|
||||
* @see enum routing_capability */
|
||||
int max_retry_interval; /**< Maximum retry interval */
|
||||
bool session_track_trx_state; /**< Get transaction state via session
|
||||
* track mechanism */
|
||||
int active; /**< Whether the service is still
|
||||
* active */
|
||||
} SERVICE;
|
||||
|
||||
typedef enum count_spec_t
|
||||
@ -154,10 +173,10 @@ typedef enum count_spec_t
|
||||
COUNT_ATMOST
|
||||
} count_spec_t;
|
||||
|
||||
#define SERVICE_STATE_ALLOC 1 /**< The service has been allocated */
|
||||
#define SERVICE_STATE_STARTED 2 /**< The service has been started */
|
||||
#define SERVICE_STATE_FAILED 3 /**< The service failed to start */
|
||||
#define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */
|
||||
#define SERVICE_STATE_ALLOC 1 /**< The service has been allocated */
|
||||
#define SERVICE_STATE_STARTED 2 /**< The service has been started */
|
||||
#define SERVICE_STATE_FAILED 3 /**< The service failed to start */
|
||||
#define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */
|
||||
|
||||
/**
|
||||
* Find a service
|
||||
@ -166,7 +185,7 @@ typedef enum count_spec_t
|
||||
*
|
||||
* @return Service or NULL of no service was found
|
||||
*/
|
||||
SERVICE* service_find(const char *name);
|
||||
SERVICE* service_find(const char* name);
|
||||
|
||||
/**
|
||||
* @brief Stop a service
|
||||
@ -175,7 +194,7 @@ SERVICE* service_find(const char *name);
|
||||
*
|
||||
* @return True if service was stopped
|
||||
*/
|
||||
bool serviceStop(SERVICE *service);
|
||||
bool serviceStop(SERVICE* service);
|
||||
|
||||
/**
|
||||
* @brief Restart a stopped service
|
||||
@ -184,7 +203,7 @@ bool serviceStop(SERVICE *service);
|
||||
*
|
||||
* @return True if service was restarted
|
||||
*/
|
||||
bool serviceStart(SERVICE *service);
|
||||
bool serviceStart(SERVICE* service);
|
||||
|
||||
/**
|
||||
* @brief Stop a listener for a service
|
||||
@ -194,7 +213,7 @@ bool serviceStart(SERVICE *service);
|
||||
*
|
||||
* @return True if listener was stopped
|
||||
*/
|
||||
bool serviceStopListener(SERVICE *service, const char *name);
|
||||
bool serviceStopListener(SERVICE* service, const char* name);
|
||||
|
||||
/**
|
||||
* @brief Restart a stopped listener
|
||||
@ -204,19 +223,19 @@ bool serviceStopListener(SERVICE *service, const char *name);
|
||||
*
|
||||
* @return True if listener was restarted
|
||||
*/
|
||||
bool serviceStartListener(SERVICE *service, const char *name);
|
||||
bool serviceStartListener(SERVICE* service, const char* name);
|
||||
|
||||
// TODO: Change binlogrouter to use the functions in config_runtime.h
|
||||
bool serviceAddBackend(SERVICE *service, SERVER *server);
|
||||
bool serviceAddBackend(SERVICE* service, SERVER* server);
|
||||
|
||||
// Used by authenticators
|
||||
void serviceGetUser(SERVICE *service, const char **user, const char **auth);
|
||||
void serviceGetUser(SERVICE* service, const char** user, const char** auth);
|
||||
|
||||
// Used by routers
|
||||
const char* serviceGetWeightingParameter(SERVICE *service);
|
||||
const char* serviceGetWeightingParameter(SERVICE* service);
|
||||
|
||||
// Reload users
|
||||
int service_refresh_users(SERVICE *service);
|
||||
int service_refresh_users(SERVICE* service);
|
||||
|
||||
/**
|
||||
* Diagnostics
|
||||
@ -228,13 +247,13 @@ int service_refresh_users(SERVICE *service);
|
||||
* @param dcb DCB to print to
|
||||
* @param service The service to diagnose
|
||||
*/
|
||||
void service_print_users(DCB *, const SERVICE *);
|
||||
void service_print_users(DCB*, const SERVICE*);
|
||||
|
||||
void dprintAllServices(DCB *dcb);
|
||||
void dprintService(DCB *dcb, SERVICE *service);
|
||||
void dListServices(DCB *dcb);
|
||||
void dListListeners(DCB *dcb);
|
||||
int serviceSessionCountAll(void);
|
||||
void dprintAllServices(DCB* dcb);
|
||||
void dprintService(DCB* dcb, SERVICE* service);
|
||||
void dListServices(DCB* dcb);
|
||||
void dListListeners(DCB* dcb);
|
||||
int serviceSessionCountAll(void);
|
||||
|
||||
/**
|
||||
* Get the capabilities of the servive.
|
||||
@ -244,16 +263,16 @@ int serviceSessionCountAll(void);
|
||||
*
|
||||
* @return The service capabilities.
|
||||
*/
|
||||
static inline uint64_t service_get_capabilities(const SERVICE *service)
|
||||
static inline uint64_t service_get_capabilities(const SERVICE* service)
|
||||
{
|
||||
return service->capabilities;
|
||||
}
|
||||
|
||||
typedef enum service_version_which_t
|
||||
{
|
||||
SERVICE_VERSION_ANY, /*< Any version of the servers of a service. */
|
||||
SERVICE_VERSION_MIN, /*< The minimum version. */
|
||||
SERVICE_VERSION_MAX, /*< The maximum version. */
|
||||
SERVICE_VERSION_ANY, /*< Any version of the servers of a service. */
|
||||
SERVICE_VERSION_MIN, /*< The minimum version. */
|
||||
SERVICE_VERSION_MAX, /*< The maximum version. */
|
||||
} service_version_which_t;
|
||||
|
||||
/**
|
||||
@ -271,6 +290,6 @@ typedef enum service_version_which_t
|
||||
*
|
||||
* @return The version of the service.
|
||||
*/
|
||||
uint64_t service_get_version(const SERVICE *service, service_version_which_t which);
|
||||
uint64_t service_get_version(const SERVICE* service, service_version_which_t which);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file include/maxscale/session.h - The public session interface
|
||||
@ -50,38 +50,71 @@ typedef enum
|
||||
SESSION_STATE_DUMMY /*< dummy session for consistency */
|
||||
} mxs_session_state_t;
|
||||
|
||||
#define STRSESSIONSTATE(s) ((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" : \
|
||||
((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \
|
||||
((s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY" : \
|
||||
((s) == SESSION_STATE_STOPPING ? "SESSION_STATE_STOPPING": \
|
||||
((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \
|
||||
((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \
|
||||
((s) == SESSION_STATE_TO_BE_FREED ? "SESSION_STATE_TO_BE_FREED" : \
|
||||
((s) == SESSION_STATE_FREE ? "SESSION_STATE_TO_BE_FREE" : \
|
||||
((s) == SESSION_STATE_DUMMY ? "SESSION_STATE_DUMMY" : \
|
||||
"SESSION_STATE_UNKNOWN")))))))))
|
||||
#define STRSESSIONSTATE(s) \
|
||||
((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" \
|
||||
: ((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" \
|
||||
: ((s) \
|
||||
== SESSION_STATE_ROUTER_READY ? \
|
||||
"SESSION_STATE_ROUTER_READY" \
|
||||
: ((s) \
|
||||
== \
|
||||
SESSION_STATE_STOPPING \
|
||||
? \
|
||||
"SESSION_STATE_STOPPING" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
SESSION_STATE_LISTENER \
|
||||
? \
|
||||
"SESSION_STATE_LISTENER" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
SESSION_STATE_LISTENER_STOPPED \
|
||||
? \
|
||||
"SESSION_STATE_LISTENER_STOPPED" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
SESSION_STATE_TO_BE_FREED \
|
||||
? \
|
||||
"SESSION_STATE_TO_BE_FREED" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
SESSION_STATE_FREE \
|
||||
? \
|
||||
"SESSION_STATE_TO_BE_FREE" \
|
||||
: (( \
|
||||
s) \
|
||||
== \
|
||||
SESSION_STATE_DUMMY \
|
||||
? \
|
||||
"SESSION_STATE_DUMMY" \
|
||||
: \
|
||||
"SESSION_STATE_UNKNOWN")))))))))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SESSION_TRX_INACTIVE_BIT = 0x01, /* 0b00001 */
|
||||
SESSION_TRX_ACTIVE_BIT = 0x02, /* 0b00010 */
|
||||
SESSION_TRX_READ_ONLY_BIT = 0x04, /* 0b00100 */
|
||||
SESSION_TRX_READ_WRITE_BIT = 0x08, /* 0b01000 */
|
||||
SESSION_TRX_ENDING_BIT = 0x10, /* 0b10000*/
|
||||
SESSION_TRX_INACTIVE_BIT = 0x01, /* 0b00001 */
|
||||
SESSION_TRX_ACTIVE_BIT = 0x02, /* 0b00010 */
|
||||
SESSION_TRX_READ_ONLY_BIT = 0x04, /* 0b00100 */
|
||||
SESSION_TRX_READ_WRITE_BIT = 0x08, /* 0b01000 */
|
||||
SESSION_TRX_ENDING_BIT = 0x10, /* 0b10000*/
|
||||
} session_trx_state_bit_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/*< There is no on-going transaction. */
|
||||
SESSION_TRX_INACTIVE = SESSION_TRX_INACTIVE_BIT,
|
||||
SESSION_TRX_INACTIVE = SESSION_TRX_INACTIVE_BIT,
|
||||
/*< A transaction is active. */
|
||||
SESSION_TRX_ACTIVE = SESSION_TRX_ACTIVE_BIT,
|
||||
SESSION_TRX_ACTIVE = SESSION_TRX_ACTIVE_BIT,
|
||||
/*< An explicit READ ONLY transaction is active. */
|
||||
SESSION_TRX_READ_ONLY = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_ONLY_BIT),
|
||||
SESSION_TRX_READ_ONLY = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_ONLY_BIT),
|
||||
/*< An explicit READ WRITE transaction is active. */
|
||||
SESSION_TRX_READ_WRITE = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_WRITE_BIT),
|
||||
SESSION_TRX_READ_WRITE = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_WRITE_BIT),
|
||||
/*< An explicit READ ONLY transaction is ending. */
|
||||
SESSION_TRX_READ_ONLY_ENDING = (SESSION_TRX_ENDING_BIT | SESSION_TRX_READ_ONLY),
|
||||
SESSION_TRX_READ_ONLY_ENDING = (SESSION_TRX_ENDING_BIT | SESSION_TRX_READ_ONLY),
|
||||
/*< An explicit READ WRITE transaction is ending. */
|
||||
SESSION_TRX_READ_WRITE_ENDING = (SESSION_TRX_ENDING_BIT | SESSION_TRX_READ_WRITE),
|
||||
} mxs_session_trx_state_t;
|
||||
@ -98,7 +131,7 @@ typedef enum
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
time_t connect; /**< Time when the session was started */
|
||||
time_t connect; /**< Time when the session was started */
|
||||
} MXS_SESSION_STATS;
|
||||
|
||||
/**
|
||||
@ -109,14 +142,18 @@ struct mxs_filter;
|
||||
struct mxs_filter_session;
|
||||
|
||||
// These are more convenient types
|
||||
typedef int32_t (*DOWNSTREAMFUNC)(struct mxs_filter *instance, struct mxs_filter_session *session, GWBUF *response);
|
||||
typedef int32_t (*UPSTREAMFUNC)(struct mxs_filter *instance, struct mxs_filter_session *session, GWBUF *response);
|
||||
typedef int32_t (* DOWNSTREAMFUNC)(struct mxs_filter* instance,
|
||||
struct mxs_filter_session* session,
|
||||
GWBUF* response);
|
||||
typedef int32_t (* UPSTREAMFUNC)(struct mxs_filter* instance,
|
||||
struct mxs_filter_session* session,
|
||||
GWBUF* response);
|
||||
|
||||
typedef struct mxs_downstream
|
||||
{
|
||||
struct mxs_filter *instance;
|
||||
struct mxs_filter_session *session;
|
||||
DOWNSTREAMFUNC routeQuery;
|
||||
struct mxs_filter* instance;
|
||||
struct mxs_filter_session* session;
|
||||
DOWNSTREAMFUNC routeQuery;
|
||||
} MXS_DOWNSTREAM;
|
||||
|
||||
/**
|
||||
@ -125,9 +162,9 @@ typedef struct mxs_downstream
|
||||
*/
|
||||
typedef struct mxs_upstream
|
||||
{
|
||||
struct mxs_filter *instance;
|
||||
struct mxs_filter_session *session;
|
||||
UPSTREAMFUNC clientReply;
|
||||
struct mxs_filter* instance;
|
||||
struct mxs_filter_session* session;
|
||||
UPSTREAMFUNC clientReply;
|
||||
} MXS_UPSTREAM;
|
||||
|
||||
/* Specific reasons why a session was closed */
|
||||
@ -159,10 +196,10 @@ typedef enum
|
||||
* @return NULL if successful, otherwise a dynamically allocated string
|
||||
* containing an end-user friendly error message.
|
||||
*/
|
||||
typedef char* (*session_variable_handler_t)(void* context,
|
||||
const char* name,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
typedef char* (* session_variable_handler_t)(void* context,
|
||||
const char* name,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
|
||||
/**
|
||||
* The session status block
|
||||
@ -176,27 +213,28 @@ typedef char* (*session_variable_handler_t)(void* context,
|
||||
*/
|
||||
typedef struct session
|
||||
{
|
||||
mxs_session_state_t state; /*< Current descriptor state */
|
||||
uint64_t ses_id; /*< Unique session identifier */
|
||||
struct dcb *client_dcb; /*< The client connection */
|
||||
mxs_session_state_t state; /*< Current descriptor state */
|
||||
uint64_t ses_id; /*< Unique session identifier */
|
||||
struct dcb* client_dcb; /*< The client connection */
|
||||
|
||||
struct mxs_router_session *router_session; /*< The router instance data */
|
||||
MXS_SESSION_STATS stats; /*< Session statistics */
|
||||
struct service *service; /*< The service this session is using */
|
||||
MXS_DOWNSTREAM head; /*< Head of the filter chain */
|
||||
MXS_UPSTREAM tail; /*< The tail of the filter chain */
|
||||
int refcount; /*< Reference count on the session */
|
||||
mxs_session_trx_state_t trx_state; /*< The current transaction state. */
|
||||
bool autocommit; /*< Whether autocommit is on. */
|
||||
intptr_t client_protocol_data; /*< Owned and managed by the client protocol. */
|
||||
bool qualifies_for_pooling; /**< Whether this session qualifies for the connection pool */
|
||||
struct mxs_router_session* router_session; /*< The router instance data */
|
||||
MXS_SESSION_STATS stats; /*< Session statistics */
|
||||
struct service* service; /*< The service this session is using */
|
||||
MXS_DOWNSTREAM head; /*< Head of the filter chain */
|
||||
MXS_UPSTREAM tail; /*< The tail of the filter chain */
|
||||
int refcount; /*< Reference count on the session */
|
||||
mxs_session_trx_state_t trx_state; /*< The current transaction state. */
|
||||
bool autocommit; /*< Whether autocommit is on. */
|
||||
intptr_t client_protocol_data; /*< Owned and managed by the client protocol. */
|
||||
bool qualifies_for_pooling; /**< Whether this session qualifies for the connection
|
||||
* pool */
|
||||
struct
|
||||
{
|
||||
MXS_UPSTREAM up; /*< Upward component to receive buffer. */
|
||||
GWBUF* buffer; /*< Buffer to deliver to up. */
|
||||
} response; /*< Shortcircuited response */
|
||||
session_close_t close_reason; /*< Reason why the session was closed */
|
||||
bool load_active; /*< Data streaming state (for LOAD DATA LOCAL INFILE) */
|
||||
MXS_UPSTREAM up; /*< Upward component to receive buffer. */
|
||||
GWBUF* buffer; /*< Buffer to deliver to up. */
|
||||
} response; /*< Shortcircuited response */
|
||||
session_close_t close_reason; /*< Reason why the session was closed */
|
||||
bool load_active; /*< Data streaming state (for LOAD DATA LOCAL INFILE) */
|
||||
} MXS_SESSION;
|
||||
|
||||
/**
|
||||
@ -209,7 +247,7 @@ typedef struct session
|
||||
* @param up The filter that should receive the response.
|
||||
* @param buffer The response.
|
||||
*/
|
||||
void session_set_response(MXS_SESSION *session, const MXS_UPSTREAM *up, GWBUF *buffer);
|
||||
void session_set_response(MXS_SESSION* session, const MXS_UPSTREAM* up, GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* Function to be used by protocol module for routing incoming data
|
||||
@ -220,7 +258,7 @@ void session_set_response(MXS_SESSION *session, const MXS_UPSTREAM *up, GWBUF *b
|
||||
*
|
||||
* @return True, if the routing should continue, false otherwise.
|
||||
*/
|
||||
bool session_route_query(MXS_SESSION *session, GWBUF *buffer);
|
||||
bool session_route_query(MXS_SESSION* session, GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* Function to be used by the router module to route the replies to
|
||||
@ -231,7 +269,7 @@ bool session_route_query(MXS_SESSION *session, GWBUF *buffer);
|
||||
*
|
||||
* @return True, if the routing should continue, false otherwise.
|
||||
*/
|
||||
bool session_route_reply(MXS_SESSION *session, GWBUF *buffer);
|
||||
bool session_route_reply(MXS_SESSION* session, GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* A convenience macro that can be used by the protocol modules to route
|
||||
@ -258,7 +296,7 @@ bool session_route_reply(MXS_SESSION *session, GWBUF *buffer);
|
||||
* @param client_dcb The client side DCB
|
||||
* @return The newly created session or NULL if an error occurred
|
||||
*/
|
||||
MXS_SESSION *session_alloc(struct service *, struct dcb *);
|
||||
MXS_SESSION* session_alloc(struct service*, struct dcb*);
|
||||
|
||||
/**
|
||||
* A version of session_alloc() which takes the session id number as parameter.
|
||||
@ -269,17 +307,17 @@ MXS_SESSION *session_alloc(struct service *, struct dcb *);
|
||||
* @param id Id for the new session.
|
||||
* @return The newly created session or NULL if an error occurred
|
||||
*/
|
||||
MXS_SESSION *session_alloc_with_id(struct service *, struct dcb *, uint64_t);
|
||||
MXS_SESSION* session_alloc_with_id(struct service*, struct dcb*, uint64_t);
|
||||
|
||||
MXS_SESSION *session_set_dummy(struct dcb *);
|
||||
MXS_SESSION* session_set_dummy(struct dcb*);
|
||||
|
||||
static inline bool session_is_dummy(MXS_SESSION* session)
|
||||
{
|
||||
return session->state == SESSION_STATE_DUMMY;
|
||||
}
|
||||
|
||||
const char *session_get_remote(const MXS_SESSION *);
|
||||
const char *session_get_user(const MXS_SESSION *);
|
||||
const char* session_get_remote(const MXS_SESSION*);
|
||||
const char* session_get_user(const MXS_SESSION*);
|
||||
|
||||
/**
|
||||
* Convert transaction state to string representation.
|
||||
@ -450,7 +488,7 @@ uint64_t session_get_next_id();
|
||||
*
|
||||
* @param session The session to close
|
||||
*/
|
||||
void session_close(MXS_SESSION *session);
|
||||
void session_close(MXS_SESSION* session);
|
||||
|
||||
/**
|
||||
* @brief Release a session reference
|
||||
@ -459,7 +497,7 @@ void session_close(MXS_SESSION *session);
|
||||
*
|
||||
* @param session Session reference to release
|
||||
*/
|
||||
void session_put_ref(MXS_SESSION *session);
|
||||
void session_put_ref(MXS_SESSION* session);
|
||||
|
||||
/**
|
||||
* @brief Convert a session to JSON
|
||||
@ -469,7 +507,7 @@ void session_put_ref(MXS_SESSION *session);
|
||||
*
|
||||
* @return New JSON object or NULL on error
|
||||
*/
|
||||
json_t* session_to_json(const MXS_SESSION *session, const char* host);
|
||||
json_t* session_to_json(const MXS_SESSION* session, const char* host);
|
||||
|
||||
/**
|
||||
* @brief Convert all sessions to JSON
|
||||
@ -531,10 +569,10 @@ uint64_t session_get_current_id();
|
||||
*
|
||||
* @return True, if the variable could be added, false otherwise.
|
||||
*/
|
||||
bool session_add_variable(MXS_SESSION* session,
|
||||
const char* name,
|
||||
bool session_add_variable(MXS_SESSION* session,
|
||||
const char* name,
|
||||
session_variable_handler_t handler,
|
||||
void* context);
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* @brief Remove MaxScale specific user variable from the session.
|
||||
@ -553,7 +591,7 @@ bool session_add_variable(MXS_SESSION* session,
|
||||
*/
|
||||
bool session_remove_variable(MXS_SESSION* session,
|
||||
const char* name,
|
||||
void** context);
|
||||
void** context);
|
||||
/**
|
||||
* @brief Set value of maxscale session variable.
|
||||
*
|
||||
@ -570,10 +608,10 @@ bool session_remove_variable(MXS_SESSION* session,
|
||||
* incoming statements.
|
||||
*/
|
||||
char* session_set_variable_value(MXS_SESSION* session,
|
||||
const char* name_begin,
|
||||
const char* name_end,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
const char* name_begin,
|
||||
const char* name_end,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
|
||||
/**
|
||||
* @brief Specify how many statements each session should retain for
|
||||
|
@ -22,7 +22,7 @@ namespace maxscale
|
||||
template<>
|
||||
struct RegistryTraits<MXS_SESSION>
|
||||
{
|
||||
typedef uint64_t id_type;
|
||||
typedef uint64_t id_type;
|
||||
typedef MXS_SESSION* entry_type;
|
||||
|
||||
static id_type get_id(entry_type entry)
|
||||
@ -34,5 +34,4 @@ struct RegistryTraits<MXS_SESSION>
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -25,7 +25,7 @@ namespace maxscale
|
||||
|
||||
class SessionCommand;
|
||||
typedef std::shared_ptr<SessionCommand> SSessionCommand;
|
||||
typedef std::list<SSessionCommand> SessionCommandList;
|
||||
typedef std::list<SSessionCommand> SessionCommandList;
|
||||
|
||||
class SessionCommand
|
||||
{
|
||||
@ -71,7 +71,7 @@ public:
|
||||
* of @c buffer is transferred to this object.
|
||||
* @param id A unique position identifier used to track replies
|
||||
*/
|
||||
SessionCommand(GWBUF *buffer, uint64_t id);
|
||||
SessionCommand(GWBUF* buffer, uint64_t id);
|
||||
|
||||
~SessionCommand();
|
||||
|
||||
@ -101,20 +101,19 @@ public:
|
||||
void mark_as_duplicate(const SessionCommand& rhs);
|
||||
|
||||
private:
|
||||
mxs::Buffer m_buffer; /**< The buffer containing the command */
|
||||
uint8_t m_command; /**< The command being executed */
|
||||
uint64_t m_pos; /**< Unique position identifier */
|
||||
bool m_reply_sent; /**< Whether the session command reply has been sent */
|
||||
mxs::Buffer m_buffer; /**< The buffer containing the command */
|
||||
uint8_t m_command; /**< The command being executed */
|
||||
uint64_t m_pos; /**< Unique position identifier */
|
||||
bool m_reply_sent; /**< Whether the session command reply has been sent */
|
||||
};
|
||||
|
||||
inline bool operator ==(const SessionCommand& lhs, const SessionCommand& rhs)
|
||||
inline bool operator==(const SessionCommand& lhs, const SessionCommand& rhs)
|
||||
{
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
|
||||
inline bool operator !=(const SessionCommand& lhs, const SessionCommand& rhs)
|
||||
inline bool operator!=(const SessionCommand& lhs, const SessionCommand& rhs)
|
||||
{
|
||||
return !lhs.eq(rhs);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file spinlock.h
|
||||
@ -42,22 +42,22 @@ MXS_BEGIN_DECLS
|
||||
*/
|
||||
typedef struct spinlock
|
||||
{
|
||||
int lock; /*< Is the lock held? */
|
||||
int lock; /*< Is the lock held? */
|
||||
#if SPINLOCK_PROFILE
|
||||
uint64_t spins; /*< Number of spins on this lock */
|
||||
uint64_t maxspins; /*< Max no of spins to acquire lock */
|
||||
uint64_t acquired; /*< No. of times lock was acquired */
|
||||
uint64_t waiting; /*< No. of threads acquiring this lock */
|
||||
uint64_t max_waiting; /*< Max no of threads waiting for lock */
|
||||
uint64_t contended; /*< No. of times acquire was contended */
|
||||
THREAD owner; /*< Last owner of this lock */
|
||||
uint64_t spins; /*< Number of spins on this lock */
|
||||
uint64_t maxspins; /*< Max no of spins to acquire lock */
|
||||
uint64_t acquired; /*< No. of times lock was acquired */
|
||||
uint64_t waiting; /*< No. of threads acquiring this lock */
|
||||
uint64_t max_waiting; /*< Max no of threads waiting for lock */
|
||||
uint64_t contended; /*< No. of times acquire was contended */
|
||||
THREAD owner; /*< Last owner of this lock */
|
||||
#endif
|
||||
} SPINLOCK;
|
||||
|
||||
#if SPINLOCK_PROFILE
|
||||
#define SPINLOCK_INIT { 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
#define SPINLOCK_INIT {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#else
|
||||
#define SPINLOCK_INIT { 0 }
|
||||
#define SPINLOCK_INIT {0}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -72,14 +72,14 @@ typedef struct spinlock
|
||||
*
|
||||
* @param lock The spinlock to initialise.
|
||||
*/
|
||||
extern void spinlock_init(SPINLOCK *lock);
|
||||
extern void spinlock_init(SPINLOCK* lock);
|
||||
|
||||
/**
|
||||
* Acquire a spinlock.
|
||||
*
|
||||
* @param lock The spinlock to acquire
|
||||
*/
|
||||
extern void spinlock_acquire(const SPINLOCK *lock);
|
||||
extern void spinlock_acquire(const SPINLOCK* lock);
|
||||
|
||||
/**
|
||||
* Acquire a spinlock if it is not already locked.
|
||||
@ -87,14 +87,14 @@ extern void spinlock_acquire(const SPINLOCK *lock);
|
||||
* @param lock The spinlock to acquire
|
||||
* @return True if the spinlock was acquired, otherwise false
|
||||
*/
|
||||
extern bool spinlock_acquire_nowait(const SPINLOCK *lock);
|
||||
extern bool spinlock_acquire_nowait(const SPINLOCK* lock);
|
||||
|
||||
/*
|
||||
* Release a spinlock.
|
||||
*
|
||||
* @param lock The spinlock to release
|
||||
*/
|
||||
extern void spinlock_release(const SPINLOCK *lock);
|
||||
extern void spinlock_release(const SPINLOCK* lock);
|
||||
|
||||
/**
|
||||
* Report statistics on a spinlock. This only has an effect if the
|
||||
@ -109,6 +109,6 @@ extern void spinlock_release(const SPINLOCK *lock);
|
||||
* @param reporter The callback function to pass the statistics to
|
||||
* @param hdl A handle that is passed to the reporter function
|
||||
*/
|
||||
extern void spinlock_stats(const SPINLOCK *lock, void (*reporter)(void *, char *, int), void *hdl);
|
||||
extern void spinlock_stats(const SPINLOCK* lock, void (* reporter)(void*, char*, int), void* hdl);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/spinlock.h>
|
||||
@ -60,8 +60,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
SpinLock(const SpinLock&) /* = delete */;
|
||||
SpinLock& operator = (const SpinLock&) /* = delete */;
|
||||
SpinLock(const SpinLock&) /* = delete */;
|
||||
SpinLock& operator=(const SpinLock&) /* = delete */;
|
||||
|
||||
private:
|
||||
mutable SPINLOCK m_lock;
|
||||
@ -112,10 +112,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
SpinLockGuard(const SpinLockGuard&) /* = delete */;
|
||||
SpinLockGuard& operator = (const SpinLockGuard&) /* = delete */;
|
||||
SpinLockGuard(const SpinLockGuard&) /* = delete */;
|
||||
SpinLockGuard& operator=(const SpinLockGuard&) /* = delete */;
|
||||
|
||||
const SPINLOCK& m_lock;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file sqlite3.h
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file ssl.h
|
||||
@ -47,9 +47,9 @@ typedef enum ssl_method_type
|
||||
/**
|
||||
* Return codes for SSL authentication checks
|
||||
*/
|
||||
#define SSL_AUTH_CHECKS_OK 0
|
||||
#define SSL_AUTH_CHECKS_OK 0
|
||||
#define SSL_ERROR_CLIENT_NOT_SSL 1
|
||||
#define SSL_ERROR_ACCEPT_FAILED 2
|
||||
#define SSL_ERROR_ACCEPT_FAILED 2
|
||||
|
||||
/**
|
||||
* The ssl_listener structure is used to aggregate the SSL configuration items
|
||||
@ -57,26 +57,28 @@ typedef enum ssl_method_type
|
||||
*/
|
||||
typedef struct ssl_listener
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
SSL_METHOD *method; /*< SSLv3 or TLS1.0/1.1/1.2 methods
|
||||
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
|
||||
int ssl_cert_verify_depth; /*< SSL certificate verification depth */
|
||||
ssl_method_type_t ssl_method_type; /*< Which of the SSLv3 or TLS1.0/1.1/1.2 methods to use */
|
||||
char *ssl_cert; /*< SSL certificate */
|
||||
char *ssl_key; /*< SSL private key */
|
||||
char *ssl_ca_cert; /*< SSL CA certificate */
|
||||
bool ssl_init_done; /*< If SSL has already been initialized for this service */
|
||||
bool ssl_verify_peer_certificate; /*< Enable peer certificate verification */
|
||||
SSL_CTX* ctx;
|
||||
SSL_METHOD* method; /*< SSLv3 or TLS1.0/1.1/1.2 methods
|
||||
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html
|
||||
**/
|
||||
int ssl_cert_verify_depth; /*< SSL certificate verification depth */
|
||||
ssl_method_type_t ssl_method_type; /*< Which of the SSLv3 or TLS1.0/1.1/1.2 methods to use */
|
||||
char* ssl_cert; /*< SSL certificate */
|
||||
char* ssl_key; /*< SSL private key */
|
||||
char* ssl_ca_cert; /*< SSL CA certificate */
|
||||
bool ssl_init_done; /*< If SSL has already been initialized for this service
|
||||
* */
|
||||
bool ssl_verify_peer_certificate; /*< Enable peer certificate verification */
|
||||
struct ssl_listener
|
||||
*next; /*< Next SSL configuration, currently used to store obsolete configurations */
|
||||
* next; /*< Next SSL configuration, currently used to store obsolete configurations */
|
||||
} SSL_LISTENER;
|
||||
|
||||
int ssl_authenticate_client(struct dcb *dcb, bool is_capable);
|
||||
bool ssl_is_connection_healthy(struct dcb *dcb);
|
||||
bool ssl_check_data_to_process(struct dcb *dcb);
|
||||
bool ssl_required_by_dcb(struct dcb *dcb);
|
||||
bool ssl_required_but_not_negotiated(struct dcb *dcb);
|
||||
const char* ssl_method_type_to_string(ssl_method_type_t method_type);
|
||||
int ssl_authenticate_client(struct dcb* dcb, bool is_capable);
|
||||
bool ssl_is_connection_healthy(struct dcb* dcb);
|
||||
bool ssl_check_data_to_process(struct dcb* dcb);
|
||||
bool ssl_required_by_dcb(struct dcb* dcb);
|
||||
bool ssl_required_but_not_negotiated(struct dcb* dcb);
|
||||
const char* ssl_method_type_to_string(ssl_method_type_t method_type);
|
||||
ssl_method_type_t string_to_ssl_method_type(const char* str);
|
||||
|
||||
/**
|
||||
@ -89,7 +91,7 @@ ssl_method_type_t string_to_ssl_method_type(const char* str);
|
||||
* if ssl authentication is in progress and should be retried, MXS_AUTH_SSL_COMPLETE
|
||||
* if ssl authentication is complete or not required.
|
||||
*/
|
||||
int ssl_authenticate_check_status(struct dcb *dcb);
|
||||
int ssl_authenticate_check_status(struct dcb* dcb);
|
||||
|
||||
// TODO: Move this to an internal ssl.h header
|
||||
void write_ssl_config(int fd, SSL_LISTENER* ssl);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file statistics.h - Lock-free statistics gathering
|
||||
@ -26,10 +26,10 @@ typedef void* ts_stats_t;
|
||||
/** Enum values for ts_stats_get */
|
||||
enum ts_stats_type
|
||||
{
|
||||
TS_STATS_MAX, /**< Maximum value */
|
||||
TS_STATS_MIX, /**< Minimum value */
|
||||
TS_STATS_SUM, /**< Sum of all value */
|
||||
TS_STATS_AVG /**< Average of all values */
|
||||
TS_STATS_MAX, /**< Maximum value */
|
||||
TS_STATS_MIX, /**< Minimum value */
|
||||
TS_STATS_SUM, /**< Sum of all value */
|
||||
TS_STATS_AVG /**< Average of all values */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file users.h The functions to manipulate a set of administrative users
|
||||
@ -29,8 +29,8 @@ MXS_BEGIN_DECLS
|
||||
enum user_account_type
|
||||
{
|
||||
USER_ACCOUNT_UNKNOWN,
|
||||
USER_ACCOUNT_BASIC, /**< Allows read-only access */
|
||||
USER_ACCOUNT_ADMIN /**< Allows complete access */
|
||||
USER_ACCOUNT_BASIC, /**< Allows read-only access */
|
||||
USER_ACCOUNT_ADMIN /**< Allows complete access */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -64,7 +64,7 @@ void users_free(USERS* users);
|
||||
*
|
||||
* @return True if user was added
|
||||
*/
|
||||
bool users_add(USERS *users, const char *user, const char *password, enum user_account_type type);
|
||||
bool users_add(USERS* users, const char* user, const char* password, enum user_account_type type);
|
||||
|
||||
/**
|
||||
* Delete a user from the user table.
|
||||
@ -74,7 +74,7 @@ bool users_add(USERS *users, const char *user, const char *password, enum user_a
|
||||
*
|
||||
* @return True if user was deleted
|
||||
*/
|
||||
bool users_delete(USERS *users, const char *user);
|
||||
bool users_delete(USERS* users, const char* user);
|
||||
|
||||
/**
|
||||
* Authenticate a user
|
||||
@ -125,7 +125,7 @@ int users_admin_count(USERS* users);
|
||||
*
|
||||
* @return JSON form of the users that can be used for serialization
|
||||
*/
|
||||
json_t* users_to_json(USERS *users);
|
||||
json_t* users_to_json(USERS* users);
|
||||
|
||||
/**
|
||||
* Load users from JSON
|
||||
@ -144,7 +144,7 @@ USERS* users_from_json(json_t* json);
|
||||
* @param port Listener configuration
|
||||
* @return Always AUTH_LOADUSERS_OK
|
||||
*/
|
||||
int users_default_loadusers(SERV_LISTENER *port);
|
||||
int users_default_loadusers(SERV_LISTENER* port);
|
||||
|
||||
/**
|
||||
* @brief Default authenticator diagnostic function
|
||||
@ -152,14 +152,14 @@ int users_default_loadusers(SERV_LISTENER *port);
|
||||
* @param dcb DCB where data is printed
|
||||
* @param port Port whose data is to be printed
|
||||
*/
|
||||
void users_default_diagnostic(DCB *dcb, SERV_LISTENER *port);
|
||||
void users_default_diagnostic(DCB* dcb, SERV_LISTENER* port);
|
||||
|
||||
/**
|
||||
* @brief Default authenticator diagnostic function
|
||||
*
|
||||
* @param port Port whose data is to be printed
|
||||
*/
|
||||
json_t* users_default_diagnostic_json(const SERV_LISTENER *port);
|
||||
json_t* users_default_diagnostic_json(const SERV_LISTENER* port);
|
||||
|
||||
/**
|
||||
* Print users to a DCB
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file utils.h Utility functions headers
|
||||
@ -26,9 +26,9 @@
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#define CALCLEN(i) ((size_t)(floor(log10(abs((int64_t)i))) + 1))
|
||||
#define UINTLEN(i) (i<10 ? 1 : (i<100 ? 2 : (i<1000 ? 3 : CALCLEN(i))))
|
||||
#define UINTLEN(i) (i < 10 ? 1 : (i < 100 ? 2 : (i < 1000 ? 3 : CALCLEN(i))))
|
||||
|
||||
#define MXS_ARRAY_NELEMS(array) ((size_t)(sizeof(array)/sizeof(array[0])))
|
||||
#define MXS_ARRAY_NELEMS(array) ((size_t)(sizeof(array) / sizeof(array[0])))
|
||||
|
||||
/** Macro for safe pointer arithmetic on void pointers
|
||||
* @param a The void pointer
|
||||
@ -39,11 +39,11 @@ MXS_BEGIN_DECLS
|
||||
/** The type of the socket */
|
||||
enum mxs_socket_type
|
||||
{
|
||||
MXS_SOCKET_LISTENER, /**< */
|
||||
MXS_SOCKET_LISTENER, /**< */
|
||||
MXS_SOCKET_NETWORK,
|
||||
};
|
||||
|
||||
bool utils_init(); /*< Call this first before using any other function */
|
||||
bool utils_init(); /*< Call this first before using any other function */
|
||||
void utils_end();
|
||||
|
||||
/**
|
||||
@ -67,8 +67,10 @@ void utils_end();
|
||||
*
|
||||
* @return The opened socket or -1 on failure
|
||||
*/
|
||||
int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr,
|
||||
const char *host, uint16_t port);
|
||||
int open_network_socket(enum mxs_socket_type type,
|
||||
struct sockaddr_storage* addr,
|
||||
const char* host,
|
||||
uint16_t port);
|
||||
|
||||
/**
|
||||
* @brief Create a UNIX domain socket
|
||||
@ -84,21 +86,22 @@ int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr
|
||||
*
|
||||
* @return The opened socket or -1 on failure
|
||||
*/
|
||||
int open_unix_socket(enum mxs_socket_type type, struct sockaddr_un *addr,
|
||||
const char *path);
|
||||
int open_unix_socket(enum mxs_socket_type type,
|
||||
struct sockaddr_un* addr,
|
||||
const char* path);
|
||||
|
||||
int setnonblocking(int fd);
|
||||
int setblocking(int fd);
|
||||
char *gw_strend(register const char *s);
|
||||
int setnonblocking(int fd);
|
||||
int setblocking(int fd);
|
||||
char* gw_strend(register const char* s);
|
||||
static char gw_randomchar();
|
||||
int gw_generate_random_str(char *output, int len);
|
||||
int gw_hex2bin(uint8_t *out, const char *in, unsigned int len);
|
||||
char *gw_bin2hex(char *out, const uint8_t *in, unsigned int len);
|
||||
void gw_str_xor(uint8_t *output, const uint8_t *input1, const uint8_t *input2, unsigned int len);
|
||||
void gw_sha1_str(const uint8_t *in, int in_len, uint8_t *out);
|
||||
void gw_sha1_2_str(const uint8_t *in, int in_len, const uint8_t *in2, int in2_len, uint8_t *out);
|
||||
int gw_getsockerrno(int fd);
|
||||
char *create_hex_sha1_sha1_passwd(char *passwd);
|
||||
int gw_generate_random_str(char* output, int len);
|
||||
int gw_hex2bin(uint8_t* out, const char* in, unsigned int len);
|
||||
char* gw_bin2hex(char* out, const uint8_t* in, unsigned int len);
|
||||
void gw_str_xor(uint8_t* output, const uint8_t* input1, const uint8_t* input2, unsigned int len);
|
||||
void gw_sha1_str(const uint8_t* in, int in_len, uint8_t* out);
|
||||
void gw_sha1_2_str(const uint8_t* in, int in_len, const uint8_t* in2, int in2_len, uint8_t* out);
|
||||
int gw_getsockerrno(int fd);
|
||||
char* create_hex_sha1_sha1_passwd(char* passwd);
|
||||
|
||||
/**
|
||||
* Trim leading whitespace from a string.
|
||||
@ -133,26 +136,30 @@ char* trim_trailing(char* str);
|
||||
* the returned pointer is always the same the one given as
|
||||
* argument.
|
||||
*/
|
||||
char* trim(char *str);
|
||||
char* trim(char* str);
|
||||
|
||||
void replace_whitespace(char* str);
|
||||
void replace_whitespace(char* str);
|
||||
char* squeeze_whitespace(char* str);
|
||||
bool strip_escape_chars(char*);
|
||||
bool strip_escape_chars(char*);
|
||||
|
||||
bool is_valid_posix_path(char* path);
|
||||
|
||||
char* remove_mysql_comments(const char** src, const size_t* srcsize, char** dest,
|
||||
char* remove_mysql_comments(const char** src,
|
||||
const size_t* srcsize,
|
||||
char** dest,
|
||||
size_t* destsize);
|
||||
char* replace_values(const char** src, const size_t* srcsize, char** dest,
|
||||
char* replace_values(const char** src,
|
||||
const size_t* srcsize,
|
||||
char** dest,
|
||||
size_t* destsize);
|
||||
char* replace_literal(char* haystack,
|
||||
const char* needle,
|
||||
const char* replacement);
|
||||
char* replace_quoted(const char** src, const size_t* srcsize, char** dest, size_t* destsize);
|
||||
|
||||
bool clean_up_pathname(char *path);
|
||||
bool clean_up_pathname(char* path);
|
||||
|
||||
bool mxs_mkdir_all(const char *path, int mask);
|
||||
bool mxs_mkdir_all(const char* path, int mask);
|
||||
|
||||
/**
|
||||
* Return the number of processors
|
||||
@ -195,8 +202,8 @@ static inline uint8_t* mxs_set_byte4(uint8_t* ptr, uint32_t value)
|
||||
*/
|
||||
static inline uint32_t mxs_get_byte4(const uint8_t* ptr)
|
||||
{
|
||||
return ((uint32_t) ptr[0]) | ((uint32_t) ptr[1] << 8) |
|
||||
((uint32_t) ptr[2] << 16) | ((uint32_t) ptr[3] << 24);
|
||||
return ((uint32_t) ptr[0]) | ((uint32_t) ptr[1] << 8)
|
||||
| ((uint32_t) ptr[2] << 16) | ((uint32_t) ptr[3] << 24);
|
||||
}
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
|
||||
@ -39,10 +39,12 @@ namespace maxscale
|
||||
*
|
||||
* @param s The string to be trimmed.
|
||||
*/
|
||||
inline void ltrim(std::string &s)
|
||||
inline void ltrim(std::string& s)
|
||||
{
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
s.erase(s.begin(),
|
||||
std::find_if(s.begin(),
|
||||
s.end(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,10 +52,12 @@ inline void ltrim(std::string &s)
|
||||
*
|
||||
* @param s The string to be trimmed.
|
||||
*/
|
||||
inline void rtrim(std::string &s)
|
||||
inline void rtrim(std::string& s)
|
||||
{
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
s.erase(std::find_if(s.rbegin(),
|
||||
s.rend(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))).base(),
|
||||
s.end());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +65,7 @@ inline void rtrim(std::string &s)
|
||||
*
|
||||
* @param s The string to be trimmed.
|
||||
*/
|
||||
inline void trim(std::string &s)
|
||||
inline void trim(std::string& s)
|
||||
{
|
||||
ltrim(s);
|
||||
rtrim(s);
|
||||
@ -270,12 +274,11 @@ public:
|
||||
|
||||
private:
|
||||
Closer(const Closer&);
|
||||
Closer& operator = (const Closer&);
|
||||
Closer& operator=(const Closer&);
|
||||
|
||||
private:
|
||||
T m_resource;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -309,12 +312,13 @@ struct CloserTraits<FILE*>
|
||||
template<typename EntryType>
|
||||
struct RegistryTraits
|
||||
{
|
||||
typedef int id_type;
|
||||
typedef int id_type;
|
||||
typedef EntryType* entry_type;
|
||||
|
||||
static id_type get_id(entry_type entry)
|
||||
{
|
||||
static_assert(sizeof(EntryType) != sizeof(EntryType), "get_id() and the"
|
||||
static_assert(sizeof(EntryType) != sizeof(EntryType),
|
||||
"get_id() and the"
|
||||
" surrounding struct must be specialized for every EntryType!");
|
||||
return 0;
|
||||
}
|
||||
@ -331,13 +335,13 @@ struct RegistryTraits
|
||||
* underlying container implements. When instantiating with a new EntryType, the
|
||||
* traits-class RegistryTraits should be specialized for the new type as well.
|
||||
*/
|
||||
template <typename EntryType>
|
||||
template<typename EntryType>
|
||||
class Registry
|
||||
{
|
||||
Registry(const Registry&);
|
||||
Registry& operator = (const Registry&);
|
||||
Registry& operator=(const Registry&);
|
||||
public:
|
||||
typedef typename RegistryTraits<EntryType>::id_type id_type;
|
||||
typedef typename RegistryTraits<EntryType>::id_type id_type;
|
||||
typedef typename RegistryTraits<EntryType>::entry_type entry_type;
|
||||
|
||||
Registry()
|
||||
@ -406,7 +410,9 @@ template<typename T>
|
||||
class EqualPointees : public std::unary_function<T, bool>
|
||||
{
|
||||
public:
|
||||
EqualPointees(const T& lhs) : m_ppLhs(&lhs) {}
|
||||
EqualPointees(const T& lhs) : m_ppLhs(&lhs)
|
||||
{
|
||||
}
|
||||
bool operator()(const T& pRhs)
|
||||
{
|
||||
return **m_ppLhs == *pRhs;
|
||||
@ -430,12 +436,12 @@ EqualPointees<T> equal_pointees(const T& t)
|
||||
*/
|
||||
std::string to_hex(uint8_t value);
|
||||
|
||||
template <typename T, typename V>
|
||||
template<typename T, typename V>
|
||||
struct hex_iterator
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
struct hex_iterator<T, uint8_t>
|
||||
{
|
||||
std::string operator()(T begin, T end)
|
||||
@ -457,10 +463,10 @@ struct hex_iterator<T, uint8_t>
|
||||
*
|
||||
* @return Hexadecimal string representation of the data
|
||||
*/
|
||||
template <typename Iter>
|
||||
template<typename Iter>
|
||||
std::string to_hex(Iter begin, Iter end)
|
||||
{
|
||||
return hex_iterator<Iter, typename std::iterator_traits<Iter>::value_type > ()(begin, end);
|
||||
return hex_iterator<Iter, typename std::iterator_traits<Iter>::value_type>()(begin, end);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -470,7 +476,9 @@ class Checksum
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~Checksum() {}
|
||||
virtual ~Checksum()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the checksum calculation
|
||||
@ -509,7 +517,7 @@ public:
|
||||
/**
|
||||
* A SHA1 checksum
|
||||
*/
|
||||
class SHA1Checksum: public Checksum
|
||||
class SHA1Checksum : public Checksum
|
||||
{
|
||||
public:
|
||||
|
||||
@ -518,7 +526,7 @@ public:
|
||||
SHA1Checksum()
|
||||
{
|
||||
SHA1_Init(&m_ctx);
|
||||
m_sum.fill(0); // CentOS 6 doesn't like aggregate initialization...
|
||||
m_sum.fill(0); // CentOS 6 doesn't like aggregate initialization...
|
||||
}
|
||||
|
||||
void update(GWBUF* buffer)
|
||||
@ -552,16 +560,16 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
SHA_CTX m_ctx; /**< SHA1 context */
|
||||
Sum m_sum; /**< Final checksum */
|
||||
SHA_CTX m_ctx; /**< SHA1 context */
|
||||
Sum m_sum; /**< Final checksum */
|
||||
};
|
||||
|
||||
static inline bool operator ==(const SHA1Checksum& lhs, const SHA1Checksum& rhs)
|
||||
static inline bool operator==(const SHA1Checksum& lhs, const SHA1Checksum& rhs)
|
||||
{
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
|
||||
static inline bool operator !=(const SHA1Checksum& lhs, const SHA1Checksum& rhs)
|
||||
static inline bool operator!=(const SHA1Checksum& lhs, const SHA1Checksum& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
@ -569,7 +577,7 @@ static inline bool operator !=(const SHA1Checksum& lhs, const SHA1Checksum& rhs)
|
||||
/**
|
||||
* A CRC32 checksum
|
||||
*/
|
||||
class CRC32Checksum: public Checksum
|
||||
class CRC32Checksum : public Checksum
|
||||
{
|
||||
public:
|
||||
|
||||
@ -612,16 +620,16 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
uint32_t m_ctx; /**< Ongoing checksum value */
|
||||
uint32_t m_sum; /**< Final checksum */
|
||||
uint32_t m_ctx; /**< Ongoing checksum value */
|
||||
uint32_t m_sum; /**< Final checksum */
|
||||
};
|
||||
|
||||
static inline bool operator ==(const CRC32Checksum& lhs, const CRC32Checksum& rhs)
|
||||
static inline bool operator==(const CRC32Checksum& lhs, const CRC32Checksum& rhs)
|
||||
{
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
|
||||
static inline bool operator !=(const CRC32Checksum& lhs, const CRC32Checksum& rhs)
|
||||
static inline bool operator!=(const CRC32Checksum& lhs, const CRC32Checksum& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
@ -652,10 +660,10 @@ namespace http
|
||||
|
||||
struct Result
|
||||
{
|
||||
int code; // HTTP response code
|
||||
std::string raw_body; // Raw response body
|
||||
std::unique_ptr<json_t> body; // JSON form of the body if it was valid JSON
|
||||
std::unordered_map<std::string, std::string> headers; // Headers attached to the response
|
||||
int code; // HTTP response code
|
||||
std::string raw_body; // Raw response body
|
||||
std::unique_ptr<json_t> body; // JSON form of the body if it was valid JSON
|
||||
std::unordered_map<std::string, std::string> headers; // Headers attached to the response
|
||||
};
|
||||
|
||||
/**
|
||||
@ -668,7 +676,5 @@ struct Result
|
||||
* @return A Result
|
||||
*/
|
||||
Result get(const std::string& url, const std::string& user = "", const std::string& password = "");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,9 +25,11 @@ void alter_readwritesplit(TestConnections& test)
|
||||
|
||||
// Check that writes work for both connections
|
||||
test.assert(first.query("SELECT @@last_insert_id"),
|
||||
"Write to first connection should work: %s", first.error());
|
||||
"Write to first connection should work: %s",
|
||||
first.error());
|
||||
test.assert(second.query("SELECT @@last_insert_id"),
|
||||
"Write to second connection should work: %s", second.error());
|
||||
"Write to second connection should work: %s",
|
||||
second.error());
|
||||
|
||||
// Block the master
|
||||
test.repl->block_node(0);
|
||||
@ -37,7 +39,8 @@ void alter_readwritesplit(TestConnections& test)
|
||||
test.assert(!first.query("SELECT 1"),
|
||||
"Read to first connection should fail.");
|
||||
test.assert(second.query("SELECT 1"),
|
||||
"Read to second connection should work: %s", second.error());
|
||||
"Read to second connection should work: %s",
|
||||
second.error());
|
||||
|
||||
// Unblock the master, restart Maxscale and check that changes are persisted
|
||||
test.repl->unblock_node(0);
|
||||
@ -46,13 +49,15 @@ void alter_readwritesplit(TestConnections& test)
|
||||
|
||||
third.connect();
|
||||
test.assert(third.query("SELECT @@last_insert_id"),
|
||||
"Write to third connection should work: %s", third.error());
|
||||
"Write to third connection should work: %s",
|
||||
third.error());
|
||||
|
||||
test.repl->block_node(0);
|
||||
test.maxscales->wait_for_monitor();
|
||||
|
||||
test.assert(third.query("SELECT 1"),
|
||||
"Read to third connection should work: %s", third.error());
|
||||
"Read to third connection should work: %s",
|
||||
third.error());
|
||||
|
||||
test.repl->unblock_node(0);
|
||||
test.maxscales->wait_for_monitor();
|
||||
@ -71,8 +76,10 @@ void alter_readconnroute(TestConnections& test)
|
||||
conn.connect();
|
||||
Row row = conn.row("SELECT @@server_id");
|
||||
conn.disconnect();
|
||||
test.assert(row[0] == master_id, "First connection should use master: %s != %s",
|
||||
row[0].c_str(), master_id.c_str());
|
||||
test.assert(row[0] == master_id,
|
||||
"First connection should use master: %s != %s",
|
||||
row[0].c_str(),
|
||||
master_id.c_str());
|
||||
}
|
||||
|
||||
test.check_maxctrl("alter service Read-Connection-Router-Master router_options slave");
|
||||
@ -82,8 +89,10 @@ void alter_readconnroute(TestConnections& test)
|
||||
conn.connect();
|
||||
Row row = conn.row("SELECT @@server_id");
|
||||
conn.disconnect();
|
||||
test.assert(row[0] != master_id, "Second connection should not use master: %s == %s",
|
||||
row[0].c_str(), master_id.c_str());
|
||||
test.assert(row[0] != master_id,
|
||||
"Second connection should not use master: %s == %s",
|
||||
row[0].c_str(),
|
||||
master_id.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,15 +122,15 @@ int main(int argc, char** argv)
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
std::vector<std::pair<const char*, std::function<void (TestConnections&)>>> tests =
|
||||
std::vector<std::pair<const char*, std::function<void(TestConnections&)>>> tests =
|
||||
{
|
||||
TEST(alter_readwritesplit),
|
||||
TEST(alter_readconnroute),
|
||||
TEST(alter_schemarouter),
|
||||
TEST(alter_unsupported)
|
||||
TEST(alter_readwritesplit),
|
||||
TEST(alter_readconnroute),
|
||||
TEST(alter_schemarouter),
|
||||
TEST(alter_unsupported)
|
||||
};
|
||||
|
||||
for (auto& a: tests)
|
||||
for (auto& a : tests)
|
||||
{
|
||||
std::cout << a.first << std::endl;
|
||||
a.second(test);
|
||||
|
@ -12,17 +12,17 @@
|
||||
#include "execute_cmd.h"
|
||||
#include "rds_vpc.h"
|
||||
|
||||
int set_endspoints(RDS * cluster)
|
||||
int set_endspoints(RDS* cluster)
|
||||
{
|
||||
|
||||
json_t *endpoint;
|
||||
json_t* endpoint;
|
||||
long long int port;
|
||||
const char * IP;
|
||||
const char* IP;
|
||||
char p[64];
|
||||
size_t i;
|
||||
char cmd[1024];
|
||||
|
||||
json_t * endpoints = cluster->get_endpoints();
|
||||
json_t* endpoints = cluster->get_endpoints();
|
||||
if (endpoints == NULL)
|
||||
{
|
||||
return -1;
|
||||
@ -49,9 +49,9 @@ int set_endspoints(RDS * cluster)
|
||||
}
|
||||
|
||||
|
||||
void compare_masters(TestConnections* Test, RDS * cluster)
|
||||
void compare_masters(TestConnections* Test, RDS* cluster)
|
||||
{
|
||||
const char * aurora_master;
|
||||
const char* aurora_master;
|
||||
cluster->get_writer(&aurora_master);
|
||||
Test->tprintf("Aurora writer node: %s\n", aurora_master);
|
||||
char maxadmin_status[1024];
|
||||
@ -60,7 +60,7 @@ void compare_masters(TestConnections* Test, RDS * cluster)
|
||||
for (i = 0; i < Test->repl->N; i++)
|
||||
{
|
||||
sprintf(cmd, "show server server%d", i + 1);
|
||||
Test->maxscales->get_maxadmin_param(0, cmd, (char *) "Status:", &maxadmin_status[0]);
|
||||
Test->maxscales->get_maxadmin_param(0, cmd, (char*) "Status:", &maxadmin_status[0]);
|
||||
Test->tprintf("Server%d status %s\n", i + 1, maxadmin_status);
|
||||
sprintf(cmd, "node%03d", i);
|
||||
if (strcmp(aurora_master, cmd) == 0)
|
||||
@ -71,7 +71,10 @@ void compare_masters(TestConnections* Test, RDS * cluster)
|
||||
}
|
||||
else
|
||||
{
|
||||
Test->add_result(1, "Server node%03d status is not 'Master, Running'', it is '%s'", i, maxadmin_status);
|
||||
Test->add_result(1,
|
||||
"Server node%03d status is not 'Master, Running'', it is '%s'",
|
||||
i,
|
||||
maxadmin_status);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -82,16 +85,18 @@ void compare_masters(TestConnections* Test, RDS * cluster)
|
||||
}
|
||||
else
|
||||
{
|
||||
Test->add_result(1, "Server node%03d status is not 'Slave, Running'', it is '%s'", i, maxadmin_status);
|
||||
Test->add_result(1,
|
||||
"Server node%03d status is not 'Slave, Running'', it is '%s'",
|
||||
i,
|
||||
maxadmin_status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
RDS * cluster = new RDS((char *) "auroratest");
|
||||
RDS* cluster = new RDS((char*) "auroratest");
|
||||
|
||||
if (cluster->create_rds_db(4) != 0)
|
||||
{
|
||||
@ -108,7 +113,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
TestConnections * Test = new TestConnections(argc, argv);
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(30);
|
||||
|
||||
compare_masters(Test, cluster);
|
||||
@ -131,7 +136,7 @@ int main(int argc, char *argv[])
|
||||
Test->tprintf("Failover done\n");
|
||||
|
||||
// Do the failover here and wait until it is over
|
||||
//sleep(10);
|
||||
// sleep(10);
|
||||
|
||||
Test->set_timeout(30);
|
||||
Test->tprintf("Executing a query through readwritesplit after failover");
|
||||
@ -145,7 +150,7 @@ int main(int argc, char *argv[])
|
||||
compare_masters(Test, cluster);
|
||||
|
||||
|
||||
//Test->check_maxscale_alive(0);
|
||||
// Test->check_maxscale_alive(0);
|
||||
|
||||
|
||||
Test->stop_timeout();
|
||||
|
@ -21,14 +21,14 @@
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int exit_code;
|
||||
TestConnections::skip_maxscale_start(true);
|
||||
TestConnections::check_nodes(false);
|
||||
TestConnections test(argc, argv);
|
||||
test.set_timeout(600);
|
||||
test.maxscales->ssh_node(0, (char *) "rm -rf /var/lib/maxscale/avro", true);
|
||||
test.maxscales->ssh_node(0, (char*) "rm -rf /var/lib/maxscale/avro", true);
|
||||
|
||||
/** Start master to binlogrouter replication */
|
||||
test.replicate_from_master();
|
||||
@ -47,9 +47,10 @@ int main(int argc, char *argv[])
|
||||
sleep(10);
|
||||
test.set_timeout(120);
|
||||
|
||||
char * output = test.maxscales->ssh_node_output(0,
|
||||
"maxavrocheck -d /var/lib/maxscale/avro/test.t1.000001.avro",
|
||||
true, &exit_code);
|
||||
char* output = test.maxscales->ssh_node_output(0,
|
||||
"maxavrocheck -d /var/lib/maxscale/avro/test.t1.000001.avro",
|
||||
true,
|
||||
&exit_code);
|
||||
|
||||
std::istringstream iss;
|
||||
iss.str(output);
|
||||
@ -65,8 +66,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (x1 != x1_exp || fl != fl_exp)
|
||||
{
|
||||
test.add_result(1, "Output:x1 %lld, fl %lld, Expected: x1 %d, fl %d",
|
||||
x1, fl, x1_exp, fl_exp);
|
||||
test.add_result(1,
|
||||
"Output:x1 %lld, fl %lld, Expected: x1 %d, fl %d",
|
||||
x1,
|
||||
fl,
|
||||
x1_exp,
|
||||
fl_exp);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,14 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int exit_code;
|
||||
TestConnections::skip_maxscale_start(true);
|
||||
TestConnections::check_nodes(false);
|
||||
TestConnections test(argc, argv);
|
||||
test.set_timeout(600);
|
||||
test.maxscales->ssh_node(0, (char *) "rm -rf /var/lib/maxscale/avro", true);
|
||||
test.maxscales->ssh_node(0, (char*) "rm -rf /var/lib/maxscale/avro", true);
|
||||
|
||||
/** Start master to binlogrouter replication */
|
||||
test.replicate_from_master();
|
||||
@ -68,7 +68,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
// The number of changes that are present in each version of the schema
|
||||
const int nchanges = 2;
|
||||
test.add_result(nrows != nchanges, "Expected %d line in file number %d, got %d: %s", nchanges, i, nrows, rows);
|
||||
test.add_result(nrows != nchanges,
|
||||
"Expected %d line in file number %d, got %d: %s",
|
||||
nchanges,
|
||||
i,
|
||||
nrows,
|
||||
rows);
|
||||
free(rows);
|
||||
}
|
||||
|
||||
|
@ -12,18 +12,19 @@
|
||||
|
||||
#include "test_binlog_fnc.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
TestConnections * Test = new TestConnections(argc, argv);
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(600);
|
||||
Test->maxscales->stop_maxscale(0);
|
||||
Test->maxscales->ssh_node(0, (char *) "rm -rf /var/lib/maxscale/avro", true);
|
||||
Test->maxscales->ssh_node(0, (char*) "rm -rf /var/lib/maxscale/avro", true);
|
||||
|
||||
//Test->maxscales->ssh_node(0, (char *) "mkdir /var/lib/maxscale/avro; chown -R maxscale:maxscale /var/lib/maxscale/avro", true);
|
||||
// Test->maxscales->ssh_node(0, (char *) "mkdir /var/lib/maxscale/avro; chown -R maxscale:maxscale
|
||||
// /var/lib/maxscale/avro", true);
|
||||
|
||||
Test->repl->connect();
|
||||
execute_query(Test->repl->nodes[0], (char *) "DROP TABLE IF EXISTS t1;");
|
||||
execute_query(Test->repl->nodes[0], (char*) "DROP TABLE IF EXISTS t1;");
|
||||
Test->repl->close_connections();
|
||||
sleep(5);
|
||||
|
||||
@ -34,7 +35,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Test->maxscales->stop_maxscale(0);
|
||||
|
||||
Test->maxscales->ssh_node(0, (char *) "rm -rf /var/lib/maxscale/avro", true);
|
||||
Test->maxscales->ssh_node(0, (char*) "rm -rf /var/lib/maxscale/avro", true);
|
||||
|
||||
Test->set_timeout(120);
|
||||
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
MYSQL *mysql[1000];
|
||||
TestConnections * Test = new TestConnections(argc, argv);
|
||||
MYSQL* mysql[1000];
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->stop_timeout();
|
||||
Test->repl->execute_query_all_nodes((char *) "set global max_connections = 10;");
|
||||
Test->repl->execute_query_all_nodes((char*) "set global max_connections = 10;");
|
||||
|
||||
for (int x = 0; x < 3; x++)
|
||||
{
|
||||
@ -39,5 +39,4 @@ int main(int argc, char** argv)
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
|
||||
}
|
||||
|
@ -13,15 +13,14 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
TestConnections * Test = new TestConnections(argc, argv);
|
||||
TestConnections* Test = new TestConnections(argc, argv);
|
||||
Test->set_timeout(10);
|
||||
Test->maxscales->connect_maxscale(0);
|
||||
Test->check_log_err(0, (char *) "warning -1", true);
|
||||
Test->check_log_err(0, (char*) "warning -1", true);
|
||||
Test->check_maxscale_alive(0);
|
||||
int rval = Test->global_result;
|
||||
delete Test;
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -23,25 +23,29 @@ namespace base
|
||||
class AppException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
AppException(const std::string& msg, const std::string& file,
|
||||
int line) :
|
||||
std::runtime_error(msg), m_file(file), m_line(line)
|
||||
{}
|
||||
AppException(const std::string& msg,
|
||||
const std::string& file,
|
||||
int line)
|
||||
: std::runtime_error(msg)
|
||||
, m_file(file)
|
||||
, m_line(line)
|
||||
{
|
||||
}
|
||||
private:
|
||||
std::string m_file;
|
||||
int m_line;
|
||||
int m_line;
|
||||
};
|
||||
} //base
|
||||
} // base
|
||||
|
||||
#define DEFINE_EXCEPTION(Type) \
|
||||
struct Type : public base::AppException { \
|
||||
Type(const std::string& msg, const char* file, \
|
||||
int line) : \
|
||||
AppException(msg, file, line) {}}
|
||||
Type(const std::string& msg, \
|
||||
const char* file, \
|
||||
int line) \
|
||||
: AppException(msg, file, line) {} }
|
||||
|
||||
#define THROW(Type, msg_str) do {\
|
||||
#define THROW(Type, msg_str) \
|
||||
do { \
|
||||
std::ostringstream os; \
|
||||
os << __FILE__ << ':' << __LINE__ << '\n' << msg_str; \
|
||||
throw Type(os.str(), __FILE__, __LINE__);} while(false)
|
||||
|
||||
|
||||
throw Type(os.str(), __FILE__, __LINE__);} while (false)
|
||||
|
@ -42,5 +42,4 @@ public:
|
||||
private:
|
||||
bool m_is_defined;
|
||||
};
|
||||
|
||||
} // base
|
||||
} // base
|
||||
|
@ -38,7 +38,7 @@ Duration StopWatch::restart()
|
||||
m_start = now;
|
||||
return lap;
|
||||
}
|
||||
} // base
|
||||
} // base
|
||||
|
||||
/********** OUTPUT ***********/
|
||||
namespace
|
||||
@ -46,21 +46,20 @@ namespace
|
||||
using namespace base;
|
||||
struct TimeConvert
|
||||
{
|
||||
double div; // divide the value of the previous unit by this
|
||||
std::string suffix; // milliseconds, hours etc.
|
||||
double max_visual; // threashold to switch to the next unit
|
||||
double div; // divide the value of the previous unit by this
|
||||
std::string suffix; // milliseconds, hours etc.
|
||||
double max_visual; // threashold to switch to the next unit
|
||||
};
|
||||
// Will never get to centuries because the duration is a long carrying nanoseconds
|
||||
TimeConvert convert[]
|
||||
{
|
||||
{1, "ns", 1000}, {1000, "us", 1000}, {1000, "ms", 1000},
|
||||
{1, "ns", 1000}, {1000, "us", 1000}, {1000, "ms", 1000},
|
||||
{1000, "s", 60}, {60, "min", 60}, {60, "hours", 24},
|
||||
{24, "days", 365.25}, {365.25, "years", 10000},
|
||||
{100, "centuries", std::numeric_limits<double>::max()}
|
||||
};
|
||||
|
||||
int convert_size = sizeof(convert) / sizeof(convert[0]);
|
||||
|
||||
}
|
||||
|
||||
namespace base
|
||||
@ -87,7 +86,7 @@ std::pair<double, std::string> dur_to_human_readable(Duration dur)
|
||||
}
|
||||
}
|
||||
|
||||
abort(); // should never get here
|
||||
abort(); // should never get here
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Duration dur)
|
||||
@ -101,12 +100,12 @@ std::ostream& operator<<(std::ostream& os, Duration dur)
|
||||
// TODO: this will require some thought. time_point_to_string() for a system_clock is
|
||||
// obvious, but not so for a steady_clock. Maybe TimePoint belongs to a system clock
|
||||
// and sould be called something else here, and live in a time_measuring namespace.
|
||||
std::string time_point_to_string(TimePoint tp, const std::string &fmt)
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
std::time_t timet = system_clock::to_time_t(system_clock::now()
|
||||
+ (tp - Clock::now()));
|
||||
struct tm * ptm;
|
||||
struct tm* ptm;
|
||||
ptm = gmtime(&timet);
|
||||
const int sz = 1024;
|
||||
char buf[sz];
|
||||
@ -114,30 +113,30 @@ std::string time_point_to_string(TimePoint tp, const std::string &fmt)
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, TimePoint tp)
|
||||
std::ostream& operator<<(std::ostream& os, TimePoint tp)
|
||||
{
|
||||
os << time_point_to_string(tp);
|
||||
return os;
|
||||
}
|
||||
|
||||
void test_stopwatch_output(std::ostream & os)
|
||||
void test_stopwatch_output(std::ostream& os)
|
||||
{
|
||||
long long dur[] =
|
||||
{
|
||||
400, // 400ns
|
||||
5 * 1000, // 5us
|
||||
500 * 1000, // 500us
|
||||
1 * 1000000, // 1ms
|
||||
700 * 1000000LL, // 700ms
|
||||
5 * 1000000000LL, // 5s
|
||||
200 * 1000000000LL, // 200s
|
||||
5 * 60 * 1000000000LL, // 5m
|
||||
45 * 60 * 1000000000LL, // 45m
|
||||
130 * 60 * 1000000000LL, // 130m
|
||||
24 * 60 * 60 * 1000000000LL, // 24 hours
|
||||
3 * 24 * 60 * 60 * 1000000000LL, // 72 hours
|
||||
180 * 24 * 60 * 60 * 1000000000LL, // 180 days
|
||||
1000 * 24 * 60 * 60 * 1000000000LL // 1000 days
|
||||
400, // 400ns
|
||||
5 * 1000, // 5us
|
||||
500 * 1000, // 500us
|
||||
1 * 1000000, // 1ms
|
||||
700 * 1000000LL, // 700ms
|
||||
5 * 1000000000LL, // 5s
|
||||
200 * 1000000000LL, // 200s
|
||||
5 * 60 * 1000000000LL, // 5m
|
||||
45 * 60 * 1000000000LL, // 45m
|
||||
130 * 60 * 1000000000LL, // 130m
|
||||
24 * 60 * 60 * 1000000000LL, // 24 hours
|
||||
3 * 24 * 60 * 60 * 1000000000LL, // 72 hours
|
||||
180 * 24 * 60 * 60 * 1000000000LL, // 180 days
|
||||
1000 * 24 * 60 * 60 * 1000000000LL // 1000 days
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(dur) / sizeof(dur[0]); ++i)
|
||||
@ -145,4 +144,4 @@ void test_stopwatch_output(std::ostream & os)
|
||||
os << Duration(dur[i]) << std::endl;
|
||||
}
|
||||
}
|
||||
} // base
|
||||
} // base
|
||||
|
@ -21,11 +21,13 @@ namespace base
|
||||
{
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
struct Duration : public Clock::duration // for ADL
|
||||
struct Duration : public Clock::duration // for ADL
|
||||
{
|
||||
using Clock::duration::duration;
|
||||
Duration() = default;
|
||||
Duration(Clock::duration d) : Clock::duration(d) {}
|
||||
Duration(Clock::duration d) : Clock::duration(d)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using TimePoint = std::chrono::time_point<Clock, Duration>;
|
||||
@ -50,7 +52,6 @@ std::pair<double, std::string> dur_to_human_readable(Duration dur);
|
||||
std::ostream& operator<<(std::ostream&, Duration dur);
|
||||
|
||||
// TimePoint
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt = "%F %T");
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt = "%F %T");
|
||||
std::ostream& operator<<(std::ostream&, TimePoint tp);
|
||||
|
||||
} // base
|
||||
} // base
|
||||
|
@ -1,12 +1,21 @@
|
||||
#include "big_load.h"
|
||||
#include <pthread.h>
|
||||
|
||||
void load(long int *new_inserts, long int *new_selects, long int *selects, long int *inserts, int threads_num,
|
||||
TestConnections * Test, long int *i1, long int *i2, int rwsplit_only, bool galera, bool report_errors)
|
||||
void load(long int* new_inserts,
|
||||
long int* new_selects,
|
||||
long int* selects,
|
||||
long int* inserts,
|
||||
int threads_num,
|
||||
TestConnections* Test,
|
||||
long int* i1,
|
||||
long int* i2,
|
||||
int rwsplit_only,
|
||||
bool galera,
|
||||
bool report_errors)
|
||||
{
|
||||
char sql[1000000];
|
||||
thread_data data;
|
||||
Mariadb_nodes * nodes;
|
||||
Mariadb_nodes* nodes;
|
||||
if (galera)
|
||||
{
|
||||
nodes = Test->galera;
|
||||
@ -34,13 +43,13 @@ void load(long int *new_inserts, long int *new_selects, long int *selects, long
|
||||
data.rwsplit_only = rwsplit_only;
|
||||
// connect to the MaxScale server (rwsplit)
|
||||
|
||||
if (Test->maxscales->conn_rwsplit[0] == NULL )
|
||||
if (Test->maxscales->conn_rwsplit[0] == NULL)
|
||||
{
|
||||
if (report_errors)
|
||||
{
|
||||
Test->add_result(1, "Can't connect to MaxScale\n");
|
||||
}
|
||||
//Test->copy_all_logs();
|
||||
// Test->copy_all_logs();
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
@ -95,31 +104,31 @@ void load(long int *new_inserts, long int *new_selects, long int *selects, long
|
||||
*i2 = data.i2;
|
||||
}
|
||||
|
||||
void *query_thread1( void *ptr )
|
||||
void* query_thread1(void* ptr)
|
||||
{
|
||||
MYSQL * conn1;
|
||||
MYSQL * conn2;
|
||||
MYSQL * conn3;
|
||||
MYSQL* conn1;
|
||||
MYSQL* conn2;
|
||||
MYSQL* conn3;
|
||||
int conn_err = 0;
|
||||
thread_data * data = (thread_data *) ptr;
|
||||
thread_data* data = (thread_data*) ptr;
|
||||
conn1 = open_conn_db_timeout(data->Test->maxscales->rwsplit_port[0],
|
||||
data->Test->maxscales->IP[0],
|
||||
(char *) "test",
|
||||
(char*) "test",
|
||||
data->Test->maxscales->user_name,
|
||||
data->Test->maxscales->password,
|
||||
20,
|
||||
data->Test->ssl);
|
||||
//conn1 = data->Test->maxscales->open_rwsplit_connection(0);
|
||||
// conn1 = data->Test->maxscales->open_rwsplit_connection(0);
|
||||
if (mysql_errno(conn1) != 0)
|
||||
{
|
||||
conn_err++;
|
||||
}
|
||||
if (data->rwsplit_only == 0)
|
||||
{
|
||||
//conn2 = data->Test->maxscales->open_readconn_master_connection(0);
|
||||
// conn2 = data->Test->maxscales->open_readconn_master_connection(0);
|
||||
conn2 = open_conn_db_timeout(data->Test->maxscales->readconn_master_port[0],
|
||||
data->Test->maxscales->IP[0],
|
||||
(char *) "test",
|
||||
(char*) "test",
|
||||
data->Test->maxscales->user_name,
|
||||
data->Test->maxscales->password,
|
||||
20,
|
||||
@ -128,10 +137,10 @@ void *query_thread1( void *ptr )
|
||||
{
|
||||
conn_err++;
|
||||
}
|
||||
//conn3 = data->Test->maxscales->open_readconn_slave_connection(0);
|
||||
// conn3 = data->Test->maxscales->open_readconn_slave_connection(0);
|
||||
conn3 = open_conn_db_timeout(data->Test->maxscales->readconn_slave_port[0],
|
||||
data->Test->maxscales->IP[0],
|
||||
(char *) "test",
|
||||
(char*) "test",
|
||||
data->Test->maxscales->user_name,
|
||||
data->Test->maxscales->password,
|
||||
20,
|
||||
@ -145,17 +154,16 @@ void *query_thread1( void *ptr )
|
||||
{
|
||||
while (data->exit_flag == 0)
|
||||
{
|
||||
if (execute_query_silent(conn1, (char *) "SELECT * FROM t1;") == 0)
|
||||
if (execute_query_silent(conn1, (char*) "SELECT * FROM t1;") == 0)
|
||||
{
|
||||
__sync_fetch_and_add(&data->i1, 1);
|
||||
}
|
||||
|
||||
if (data->rwsplit_only == 0)
|
||||
{
|
||||
execute_query_silent(conn2, (char *) "SELECT * FROM t1;");
|
||||
execute_query_silent(conn3, (char *) "SELECT * FROM t1;");
|
||||
execute_query_silent(conn2, (char*) "SELECT * FROM t1;");
|
||||
execute_query_silent(conn3, (char*) "SELECT * FROM t1;");
|
||||
}
|
||||
|
||||
}
|
||||
mysql_close(conn1);
|
||||
if (data->rwsplit_only == 0)
|
||||
@ -167,53 +175,53 @@ void *query_thread1( void *ptr )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *query_thread2(void *ptr )
|
||||
void* query_thread2(void* ptr)
|
||||
{
|
||||
MYSQL * conn1;
|
||||
MYSQL * conn2;
|
||||
MYSQL * conn3;
|
||||
thread_data * data = (thread_data *) ptr;
|
||||
//conn1 = data->Test->maxscales->open_rwsplit_connection(0);
|
||||
MYSQL* conn1;
|
||||
MYSQL* conn2;
|
||||
MYSQL* conn3;
|
||||
thread_data* data = (thread_data*) ptr;
|
||||
// conn1 = data->Test->maxscales->open_rwsplit_connection(0);
|
||||
conn1 = open_conn_db_timeout(data->Test->maxscales->rwsplit_port[0],
|
||||
data->Test->maxscales->IP[0],
|
||||
(char *) "test",
|
||||
(char*) "test",
|
||||
data->Test->maxscales->user_name,
|
||||
data->Test->maxscales->password,
|
||||
20,
|
||||
data->Test->ssl);
|
||||
if (data->rwsplit_only == 0)
|
||||
{
|
||||
//conn2 = data->Test->maxscales->open_readconn_master_connection(0);
|
||||
//conn3 = data->Test->maxscales->open_readconn_slave_connection(0);
|
||||
// conn2 = data->Test->maxscales->open_readconn_master_connection(0);
|
||||
// conn3 = data->Test->maxscales->open_readconn_slave_connection(0);
|
||||
|
||||
conn2 = open_conn_db_timeout(data->Test->maxscales->readconn_master_port[0],
|
||||
data->Test->maxscales->IP[0],
|
||||
(char *) "test",
|
||||
(char*) "test",
|
||||
data->Test->maxscales->user_name,
|
||||
data->Test->maxscales->password,
|
||||
20,
|
||||
data->Test->ssl);
|
||||
//if (mysql_errno(conn2) != 0) { conn_err++; }
|
||||
// if (mysql_errno(conn2) != 0) { conn_err++; }
|
||||
conn3 = open_conn_db_timeout(data->Test->maxscales->readconn_slave_port[0],
|
||||
data->Test->maxscales->IP[0],
|
||||
(char *) "test",
|
||||
(char*) "test",
|
||||
data->Test->maxscales->user_name,
|
||||
data->Test->maxscales->password,
|
||||
20,
|
||||
data->Test->ssl);
|
||||
//if (mysql_errno(conn3) != 0) { conn_err++; }
|
||||
// if (mysql_errno(conn3) != 0) { conn_err++; }
|
||||
}
|
||||
while (data->exit_flag == 0)
|
||||
{
|
||||
sleep(1);
|
||||
if (execute_query_silent(conn1, (char *) "SELECT * FROM t1;") == 0)
|
||||
if (execute_query_silent(conn1, (char*) "SELECT * FROM t1;") == 0)
|
||||
{
|
||||
__sync_fetch_and_add(&data->i2, 1);
|
||||
}
|
||||
if (data->rwsplit_only == 0)
|
||||
{
|
||||
execute_query_silent(conn2, (char *) "SELECT * FROM t1;");
|
||||
execute_query_silent(conn3, (char *) "SELECT * FROM t1;");
|
||||
execute_query_silent(conn2, (char*) "SELECT * FROM t1;");
|
||||
execute_query_silent(conn3, (char*) "SELECT * FROM t1;");
|
||||
}
|
||||
}
|
||||
mysql_close(conn1);
|
||||
|
@ -6,18 +6,18 @@
|
||||
#include "sql_t1.h"
|
||||
#include "get_com_select_insert.h"
|
||||
|
||||
//pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
|
||||
// pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
|
||||
typedef struct
|
||||
{
|
||||
int exit_flag;
|
||||
long i1;
|
||||
long i2;
|
||||
int rwsplit_only;
|
||||
TestConnections * Test;
|
||||
int exit_flag;
|
||||
long i1;
|
||||
long i2;
|
||||
int rwsplit_only;
|
||||
TestConnections* Test;
|
||||
} thread_data;
|
||||
|
||||
void *query_thread1(void *ptr );
|
||||
void *query_thread2(void *ptr );
|
||||
void* query_thread1(void* ptr);
|
||||
void* query_thread2(void* ptr);
|
||||
|
||||
/**
|
||||
* @brief load Creates load on Maxscale routers
|
||||
@ -33,7 +33,16 @@ void *query_thread2(void *ptr );
|
||||
* @param galera if true use Galera backend (Test->galera instead of Test->repl)
|
||||
* @param report_errors if true call add_result() in case of query failure
|
||||
*/
|
||||
void load(long *new_inserts, long *new_selects, long *selects, long *inserts, int threads_num,
|
||||
TestConnections *Test, long *i1, long *i2, int rwsplit_only, bool galera, bool report_errors);
|
||||
void load(long* new_inserts,
|
||||
long* new_selects,
|
||||
long* selects,
|
||||
long* inserts,
|
||||
int threads_num,
|
||||
TestConnections* Test,
|
||||
long* i1,
|
||||
long* i2,
|
||||
int rwsplit_only,
|
||||
bool galera,
|
||||
bool report_errors);
|
||||
|
||||
#endif // BIG_LOAD_H
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "big_transaction.h"
|
||||
|
||||
int big_transaction(MYSQL * conn, int N)
|
||||
int big_transaction(MYSQL* conn, int N)
|
||||
{
|
||||
int local_result = 0;
|
||||
char sql[1000000];
|
||||
local_result += create_t1(conn);
|
||||
local_result += execute_query(conn, (char *) "START TRANSACTION");
|
||||
local_result += execute_query(conn, (char *) "SET autocommit = 0");
|
||||
local_result += execute_query(conn, (char*) "START TRANSACTION");
|
||||
local_result += execute_query(conn, (char*) "SET autocommit = 0");
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
@ -18,6 +18,6 @@ int big_transaction(MYSQL * conn, int N)
|
||||
local_result += execute_query(conn, "%s", sql);
|
||||
}
|
||||
|
||||
local_result += execute_query(conn, (char *) "COMMIT");
|
||||
local_result += execute_query(conn, (char*) "COMMIT");
|
||||
return local_result;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user