Merge branch 'develop' into mon_script_test
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -34,3 +34,4 @@ depend.mk
|
|||||||
|
|
||||||
# Vi swap files
|
# Vi swap files
|
||||||
.*.swp
|
.*.swp
|
||||||
|
/build/
|
||||||
@ -446,6 +446,7 @@ backend_write_timeout=2
|
|||||||
# galeramon specific options
|
# galeramon specific options
|
||||||
disable_master_failback=0
|
disable_master_failback=0
|
||||||
available_when_donor=0
|
available_when_donor=0
|
||||||
|
disable_master_role_setting=0
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `module`
|
#### `module`
|
||||||
@ -518,6 +519,13 @@ This option if set to 1 will allow Galera monitor to keep a node in `Donor` stat
|
|||||||
|
|
||||||
As xtrabackup is a non-locking SST method, a node in `Donor` status can still be considered in sync. This option is not enabled by default and should be used as the administrator's discretion.
|
As xtrabackup is a non-locking SST method, a node in `Donor` status can still be considered in sync. This option is not enabled by default and should be used as the administrator's discretion.
|
||||||
|
|
||||||
|
#### `disable_master_role_setting`
|
||||||
|
|
||||||
|
This option if set to 1 will stop the Galera monitor from setting the status of
|
||||||
|
backend servers to master or slave. It is applicable when the Galera router is
|
||||||
|
being used to spread writes across multiple nodes, so that no server is to be
|
||||||
|
nominated as the master.
|
||||||
|
|
||||||
#### `backend_connect_timeout`
|
#### `backend_connect_timeout`
|
||||||
|
|
||||||
This option, with default value of `3` sets the monitor connect timeout to backends.
|
This option, with default value of `3` sets the monitor connect timeout to backends.
|
||||||
@ -1377,11 +1385,11 @@ Example:
|
|||||||
```
|
```
|
||||||
[Galera Listener]
|
[Galera Listener]
|
||||||
type=listener
|
type=listener
|
||||||
address=192.1681.3.33
|
address=192.168.3.33
|
||||||
port=4408
|
port=4408
|
||||||
socket=/servers/maxscale/galera.sock
|
socket=/servers/maxscale/galera.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
TCP/IP Traffic must be permitted to 192.1681.3.33 port 4408
|
TCP/IP Traffic must be permitted to 192.168.3.33 port 4408
|
||||||
|
|
||||||
For Unix socket, the socket file path (example: `/servers/maxscale/galera.sock`) must be writable by the Unix user MaxScale runs as.
|
For Unix socket, the socket file path (example: `/servers/maxscale/galera.sock`) must be writable by the Unix user MaxScale runs as.
|
||||||
|
|||||||
@ -54,7 +54,7 @@ static simple_mutex_t msg_mutex;
|
|||||||
static int highprec = 0;
|
static int highprec = 0;
|
||||||
static int do_syslog = 1;
|
static int do_syslog = 1;
|
||||||
static int do_maxscalelog = 1;
|
static int do_maxscalelog = 1;
|
||||||
|
static int use_stdout = 0;
|
||||||
/**
|
/**
|
||||||
* Variable holding the enabled logfiles information.
|
* Variable holding the enabled logfiles information.
|
||||||
* Used from log users to check enabled logs prior calling
|
* Used from log users to check enabled logs prior calling
|
||||||
@ -1331,12 +1331,14 @@ static bool logfile_set_enabled(
|
|||||||
}
|
}
|
||||||
lf = &lm->lm_logfile[id];
|
lf = &lm->lm_logfile[id];
|
||||||
CHK_LOGFILE(lf);
|
CHK_LOGFILE(lf);
|
||||||
|
if(use_stdout == 0)
|
||||||
|
{
|
||||||
if (val) {
|
if (val) {
|
||||||
logstr = strdup("---\tLogging to file is enabled\t--");
|
logstr = strdup("---\tLogging to file is enabled\t--");
|
||||||
} else {
|
} else {
|
||||||
logstr = strdup("---\tLogging to file is disabled\t--");
|
logstr = strdup("---\tLogging to file is disabled\t--");
|
||||||
}
|
}
|
||||||
|
|
||||||
oldval = lf->lf_enabled;
|
oldval = lf->lf_enabled;
|
||||||
lf->lf_enabled = val;
|
lf->lf_enabled = val;
|
||||||
err = logmanager_write_log(id,
|
err = logmanager_write_log(id,
|
||||||
@ -1348,7 +1350,7 @@ static bool logfile_set_enabled(
|
|||||||
logstr,
|
logstr,
|
||||||
notused);
|
notused);
|
||||||
free(logstr);
|
free(logstr);
|
||||||
|
}
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
lf->lf_enabled = oldval;
|
lf->lf_enabled = oldval;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -1695,9 +1697,12 @@ static bool fnames_conf_init(
|
|||||||
fn->fn_chk_tail = CHK_NUM_FNAMES;
|
fn->fn_chk_tail = CHK_NUM_FNAMES;
|
||||||
#endif
|
#endif
|
||||||
optind = 1; /**<! reset getopt index */
|
optind = 1; /**<! reset getopt index */
|
||||||
while ((opt = getopt(argc, argv, "+a:b:c:d:e:f:g:h:i:j:l:m:s:")) != -1)
|
while ((opt = getopt(argc, argv, "+a:b:c:d:e:f:g:h:i:j:l:m:s:o")) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'o':
|
||||||
|
use_stdout = 1;
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
fn->fn_debug_prefix = strndup(optarg, MAX_PREFIXLEN);
|
fn->fn_debug_prefix = strndup(optarg, MAX_PREFIXLEN);
|
||||||
break;
|
break;
|
||||||
@ -2154,7 +2159,13 @@ static bool logfile_open_file(
|
|||||||
char* start_msg_str;
|
char* start_msg_str;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (lf->lf_store_shmem)
|
if(use_stdout)
|
||||||
|
{
|
||||||
|
fw->fwr_file[lf->lf_id] = skygw_file_alloc (
|
||||||
|
lf->lf_full_file_name);
|
||||||
|
fw->fwr_file[lf->lf_id]->sf_file = stdout;
|
||||||
|
}
|
||||||
|
else if (lf->lf_store_shmem)
|
||||||
{
|
{
|
||||||
/** Create symlink pointing to log file */
|
/** Create symlink pointing to log file */
|
||||||
fw->fwr_file[lf->lf_id] = skygw_file_init(
|
fw->fwr_file[lf->lf_id] = skygw_file_init(
|
||||||
@ -2178,6 +2189,8 @@ static bool logfile_open_file(
|
|||||||
goto return_succp;
|
goto return_succp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(use_stdout == 0)
|
||||||
|
{
|
||||||
if (lf->lf_enabled)
|
if (lf->lf_enabled)
|
||||||
{
|
{
|
||||||
start_msg_str = strdup("---\tLogging is enabled.\n");
|
start_msg_str = strdup("---\tLogging is enabled.\n");
|
||||||
@ -2203,6 +2216,7 @@ static bool logfile_open_file(
|
|||||||
goto return_succp;
|
goto return_succp;
|
||||||
}
|
}
|
||||||
free(start_msg_str);
|
free(start_msg_str);
|
||||||
|
}
|
||||||
succp = true;
|
succp = true;
|
||||||
|
|
||||||
return_succp:
|
return_succp:
|
||||||
@ -2727,6 +2741,9 @@ static void filewriter_done(
|
|||||||
for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i++)
|
for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i++)
|
||||||
{
|
{
|
||||||
id = (logfile_id_t)i;
|
id = (logfile_id_t)i;
|
||||||
|
if(use_stdout)
|
||||||
|
skygw_file_free(fw->fwr_file[id]);
|
||||||
|
else
|
||||||
skygw_file_close(fw->fwr_file[id], true);
|
skygw_file_close(fw->fwr_file[id], true);
|
||||||
}
|
}
|
||||||
fw->fwr_state = DONE;
|
fw->fwr_state = DONE;
|
||||||
@ -2859,6 +2876,9 @@ static void* thr_filewriter_fun(
|
|||||||
}
|
}
|
||||||
else if ((succp = logfile_open_file(fwr, lf)))
|
else if ((succp = logfile_open_file(fwr, lf)))
|
||||||
{
|
{
|
||||||
|
if(use_stdout)
|
||||||
|
skygw_file_free (file);
|
||||||
|
else
|
||||||
skygw_file_close(file, false); /*< close old file */
|
skygw_file_close(file, false); /*< close old file */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,7 @@
|
|||||||
* 20/02/15 Markus Mäkelä Added connection_timeout parameter for services
|
* 20/02/15 Markus Mäkelä Added connection_timeout parameter for services
|
||||||
* 05/03/15 Massimiliano Pinto Added notification_feedback support
|
* 05/03/15 Massimiliano Pinto Added notification_feedback support
|
||||||
* 20/04/15 Guillaume Lefranc Added available_when_donor parameter
|
* 20/04/15 Guillaume Lefranc Added available_when_donor parameter
|
||||||
|
* 22/04/15 Martin Brampton Added disable_master_role_setting parameter
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -301,7 +302,15 @@ process_config_context(CONFIG_CONTEXT *context)
|
|||||||
{
|
{
|
||||||
CONFIG_CONTEXT *obj;
|
CONFIG_CONTEXT *obj;
|
||||||
int error_count = 0;
|
int error_count = 0;
|
||||||
|
HASHTABLE* monitorhash;
|
||||||
|
|
||||||
|
if((monitorhash = hashtable_alloc(5,simple_str_hash,strcmp)) == NULL)
|
||||||
|
{
|
||||||
|
skygw_log_write(LOGFILE_ERROR,"Error: Failed to allocate ,onitor configuration check hashtable.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
|
||||||
/**
|
/**
|
||||||
* Process the data and create the services and servers defined
|
* Process the data and create the services and servers defined
|
||||||
* in the data.
|
* in the data.
|
||||||
@ -953,6 +962,13 @@ int error_count = 0;
|
|||||||
obj->element && obj1->element)
|
obj->element && obj1->element)
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
|
if(hashtable_add(monitorhash,obj1->object,"") == 0)
|
||||||
|
{
|
||||||
|
skygw_log_write(LOGFILE_ERROR,
|
||||||
|
"Warning: Multiple monitors are monitoring server [%s]. "
|
||||||
|
"This will cause undefined behavior.",
|
||||||
|
obj1->object);
|
||||||
|
}
|
||||||
monitorAddServer(
|
monitorAddServer(
|
||||||
obj->element,
|
obj->element,
|
||||||
obj1->element);
|
obj1->element);
|
||||||
@ -1014,6 +1030,7 @@ int error_count = 0;
|
|||||||
} /*< while */
|
} /*< while */
|
||||||
/** TODO: consistency check function */
|
/** TODO: consistency check function */
|
||||||
|
|
||||||
|
hashtable_free(monitorhash);
|
||||||
/**
|
/**
|
||||||
* error_count += consistency_checks();
|
* error_count += consistency_checks();
|
||||||
*/
|
*/
|
||||||
@ -1920,6 +1937,7 @@ static char *monitor_params[] =
|
|||||||
"backend_read_timeout",
|
"backend_read_timeout",
|
||||||
"backend_write_timeout",
|
"backend_write_timeout",
|
||||||
"available_when_donor",
|
"available_when_donor",
|
||||||
|
"disable_master_role_setting",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@ -2033,15 +2051,18 @@ bool config_set_qualified_param(
|
|||||||
int
|
int
|
||||||
config_truth_value(char *str)
|
config_truth_value(char *str)
|
||||||
{
|
{
|
||||||
if (strcasecmp(str, "true") == 0 || strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0)
|
if (strcasecmp(str, "true") == 0 || strcasecmp(str, "on") == 0 ||
|
||||||
|
strcasecmp(str, "yes") == 0 || strcasecmp(str, "1") == 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (strcasecmp(str, "false") == 0 || strcasecmp(str, "off") == 0 || strcasecmp(str, "no") == 0)
|
if (strcasecmp(str, "false") == 0 || strcasecmp(str, "off") == 0 ||
|
||||||
|
strcasecmp(str, "no") == 0|| strcasecmp(str, "0") == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return atoi(str);
|
skygw_log_write(LOGFILE_ERROR,"Error: Not a boolean value: %s",str);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
#include <log_manager.h>
|
#include <log_manager.h>
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int arg_count = 3;
|
int arg_count = 4;
|
||||||
char *home;
|
char *home;
|
||||||
char** arg_vector;
|
char** arg_vector;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector = malloc(sizeof(char*)*4);
|
arg_vector = malloc(sizeof(char*)*5);
|
||||||
|
|
||||||
if(arg_vector == NULL)
|
if(arg_vector == NULL)
|
||||||
{
|
{
|
||||||
@ -64,8 +64,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log");
|
arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log");
|
||||||
}
|
}
|
||||||
|
arg_vector[3] = "-o";
|
||||||
arg_vector[3] = NULL;
|
arg_vector[4] = NULL;
|
||||||
skygw_logmanager_init(arg_count,arg_vector);
|
skygw_logmanager_init(arg_count,arg_vector);
|
||||||
skygw_log_enable(LOGFILE_TRACE);
|
skygw_log_enable(LOGFILE_TRACE);
|
||||||
skygw_log_enable(LOGFILE_DEBUG);
|
skygw_log_enable(LOGFILE_DEBUG);
|
||||||
|
|||||||
@ -41,7 +41,7 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *enc, *pw;
|
char *enc, *pw;
|
||||||
int arg_count = 3;
|
int arg_count = 4;
|
||||||
char *home;
|
char *home;
|
||||||
char** arg_vector;
|
char** arg_vector;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector = malloc(sizeof(char*)*4);
|
arg_vector = malloc(sizeof(char*)*5);
|
||||||
|
|
||||||
if(arg_vector == NULL)
|
if(arg_vector == NULL)
|
||||||
{
|
{
|
||||||
@ -73,7 +73,8 @@ main(int argc, char **argv)
|
|||||||
arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log");
|
arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log");
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector[3] = NULL;
|
arg_vector[3] = "-o";
|
||||||
|
arg_vector[4] = NULL;
|
||||||
skygw_logmanager_init(arg_count,arg_vector);
|
skygw_logmanager_init(arg_count,arg_vector);
|
||||||
skygw_log_enable(LOGFILE_TRACE);
|
skygw_log_enable(LOGFILE_TRACE);
|
||||||
skygw_log_enable(LOGFILE_DEBUG);
|
skygw_log_enable(LOGFILE_DEBUG);
|
||||||
|
|||||||
@ -96,7 +96,11 @@ HASHTABLE *hashtable_alloc_flat(HASHTABLE* target,
|
|||||||
int (*hashfn)(),
|
int (*hashfn)(),
|
||||||
int (*cmpfn)());
|
int (*cmpfn)());
|
||||||
/**< Allocate a hashtable */
|
/**< Allocate a hashtable */
|
||||||
extern void hashtable_memory_fns(HASHTABLE *, HASHMEMORYFN, HASHMEMORYFN, HASHMEMORYFN, HASHMEMORYFN);
|
extern void hashtable_memory_fns(HASHTABLE *table,
|
||||||
|
HASHMEMORYFN kcopyfn,
|
||||||
|
HASHMEMORYFN vcopyfn,
|
||||||
|
HASHMEMORYFN kfreefn,
|
||||||
|
HASHMEMORYFN vfreefn);
|
||||||
/**< Provide an interface to control key/value memory
|
/**< Provide an interface to control key/value memory
|
||||||
* manipulation
|
* manipulation
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2225,15 +2225,11 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
printf("Log files written to: %s\n",home?home:"/tpm");
|
printf("Log files written to: %s\n",home?home:"/tpm");
|
||||||
|
|
||||||
int argc_ = 11;
|
int argc_ = 2;
|
||||||
char* argv_[] =
|
char* argv_[] =
|
||||||
{
|
{
|
||||||
"log_manager",
|
"log_manager",
|
||||||
"-j",home?home:"/tmp",
|
"-o",
|
||||||
"-a","ruleparser_debug",
|
|
||||||
"-c","ruleparser_trace",
|
|
||||||
"-e","ruleparser_message",
|
|
||||||
"-g","ruleparser_error",
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,8 @@
|
|||||||
* 24/06/14 Massimiliano Pinto Added depth level 0 for each node
|
* 24/06/14 Massimiliano Pinto Added depth level 0 for each node
|
||||||
* 30/10/14 Massimiliano Pinto Added disableMasterFailback feature
|
* 30/10/14 Massimiliano Pinto Added disableMasterFailback feature
|
||||||
* 10/11/14 Massimiliano Pinto Added setNetworkTimeout for connect,read,write
|
* 10/11/14 Massimiliano Pinto Added setNetworkTimeout for connect,read,write
|
||||||
* 20/05/15 Guillaume Lefranc Added availableWhenDonor feature
|
* 20/04/15 Guillaume Lefranc Added availableWhenDonor feature
|
||||||
|
* 22/04/15 Martin Brampton Addition of disableMasterRoleSetting
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -160,6 +161,7 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
handle->interval = MONITOR_INTERVAL;
|
handle->interval = MONITOR_INTERVAL;
|
||||||
handle->disableMasterFailback = 0;
|
handle->disableMasterFailback = 0;
|
||||||
handle->availableWhenDonor = 0;
|
handle->availableWhenDonor = 0;
|
||||||
|
handle->disableMasterRoleSetting = 0;
|
||||||
handle->master = NULL;
|
handle->master = NULL;
|
||||||
handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT;
|
handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT;
|
||||||
handle->read_timeout=DEFAULT_READ_TIMEOUT;
|
handle->read_timeout=DEFAULT_READ_TIMEOUT;
|
||||||
@ -172,8 +174,10 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
{
|
{
|
||||||
if(!strcmp(params->name,"disable_master_failback"))
|
if(!strcmp(params->name,"disable_master_failback"))
|
||||||
handle->disableMasterFailback = config_truth_value(params->value);
|
handle->disableMasterFailback = config_truth_value(params->value);
|
||||||
if(!strcmp(params->name,"available_when_donor"))
|
else if(!strcmp(params->name,"available_when_donor"))
|
||||||
handle->availableWhenDonor = config_truth_value(params->value);
|
handle->availableWhenDonor = config_truth_value(params->value);
|
||||||
|
else if(!strcmp(params->name,"disable_master_role_setting"))
|
||||||
|
handle->disableMasterRoleSetting = config_truth_value(params->value);
|
||||||
params = params->next;
|
params = params->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,6 +298,7 @@ char *sep;
|
|||||||
dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval);
|
dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval);
|
||||||
dcb_printf(dcb,"\tMaster Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on");
|
dcb_printf(dcb,"\tMaster Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on");
|
||||||
dcb_printf(dcb,"\tAvailable when Donor:\t%s\n", (handle->availableWhenDonor == 1) ? "on" : "off");
|
dcb_printf(dcb,"\tAvailable when Donor:\t%s\n", (handle->availableWhenDonor == 1) ? "on" : "off");
|
||||||
|
dcb_printf(dcb,"\tMaster Role Setting Disabled:\t%s\n", (handle->disableMasterRoleSetting == 1) ? "on" : "off");
|
||||||
dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout);
|
dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout);
|
||||||
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout);
|
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout);
|
||||||
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout);
|
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout);
|
||||||
@ -596,26 +601,32 @@ int log_no_members = 1;
|
|||||||
* Decision depends on master_stickiness value set in configuration
|
* Decision depends on master_stickiness value set in configuration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* get the candidate master, followinf MIN(node_id) rule */
|
/* get the candidate master, following MIN(node_id) rule */
|
||||||
candidate_master = get_candidate_master(handle->databases);
|
candidate_master = get_candidate_master(handle->databases);
|
||||||
|
|
||||||
/* Select the master, based on master_stickiness */
|
/* Select the master, based on master_stickiness */
|
||||||
|
if (1 == handle->disableMasterRoleSetting) {
|
||||||
|
handle->master = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness);
|
handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness);
|
||||||
|
}
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = handle->databases;
|
||||||
|
|
||||||
while (ptr && handle->master) {
|
while (ptr) {
|
||||||
if (!SERVER_IS_JOINED(ptr->server) || SERVER_IN_MAINT(ptr->server)) {
|
if (!SERVER_IS_JOINED(ptr->server) || SERVER_IN_MAINT(ptr->server)) {
|
||||||
ptr = ptr->next;
|
ptr = ptr->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (handle->master) {
|
||||||
if (ptr != handle->master) {
|
if (ptr != handle->master) {
|
||||||
/* set the Slave role */
|
/* set the Slave role */
|
||||||
server_set_status(ptr->server, SERVER_SLAVE);
|
server_set_status(ptr->server, SERVER_SLAVE);
|
||||||
server_clear_status(ptr->server, SERVER_MASTER);
|
server_clear_status(ptr->server, SERVER_MASTER);
|
||||||
|
|
||||||
/* clear master stickyness */
|
/* clear master stickiness */
|
||||||
server_clear_status(ptr->server, SERVER_MASTER_STICKINESS);
|
server_clear_status(ptr->server, SERVER_MASTER_STICKINESS);
|
||||||
} else {
|
} else {
|
||||||
/* set the Master role */
|
/* set the Master role */
|
||||||
@ -623,13 +634,14 @@ int log_no_members = 1;
|
|||||||
server_clear_status(handle->master->server, SERVER_SLAVE);
|
server_clear_status(handle->master->server, SERVER_SLAVE);
|
||||||
|
|
||||||
if (candidate_master && handle->master->server->node_id != candidate_master->server->node_id) {
|
if (candidate_master && handle->master->server->node_id != candidate_master->server->node_id) {
|
||||||
/* set master stickyness */
|
/* set master stickiness */
|
||||||
server_set_status(handle->master->server, SERVER_MASTER_STICKINESS);
|
server_set_status(handle->master->server, SERVER_MASTER_STICKINESS);
|
||||||
} else {
|
} else {
|
||||||
/* clear master stickyness */
|
/* clear master stickiness */
|
||||||
server_clear_status(ptr->server, SERVER_MASTER_STICKINESS);
|
server_clear_status(ptr->server, SERVER_MASTER_STICKINESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
is_cluster++;
|
is_cluster++;
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,8 @@
|
|||||||
* 28/08/14 Massimiliano Pinto Addition of detectStaleMaster
|
* 28/08/14 Massimiliano Pinto Addition of detectStaleMaster
|
||||||
* 30/10/14 Massimiliano Pinto Addition of disableMasterFailback
|
* 30/10/14 Massimiliano Pinto Addition of disableMasterFailback
|
||||||
* 07/11/14 Massimiliano Pinto Addition of NetworkTimeout: connect, read, write
|
* 07/11/14 Massimiliano Pinto Addition of NetworkTimeout: connect, read, write
|
||||||
* 20/05/15 Guillaume Lefranc Addition of availableWhenDonor
|
* 20/04/15 Guillaume Lefranc Addition of availableWhenDonor
|
||||||
|
* 22/04/15 Martin Brampton Addition of disableMasterRoleSetting
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -70,6 +71,7 @@ typedef struct {
|
|||||||
int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */
|
int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */
|
||||||
int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */
|
int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */
|
||||||
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
|
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
|
||||||
|
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
|
||||||
MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */
|
MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */
|
||||||
MONITOR_SERVERS *databases; /**< Linked list of servers to monitor */
|
MONITOR_SERVERS *databases; /**< Linked list of servers to monitor */
|
||||||
int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */
|
int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */
|
||||||
|
|||||||
@ -238,24 +238,23 @@ static int hashcmpfun(
|
|||||||
/**
|
/**
|
||||||
* Convert a length encoded string into a C string.
|
* Convert a length encoded string into a C string.
|
||||||
* @param data Pointer to the first byte of the string
|
* @param data Pointer to the first byte of the string
|
||||||
* @param len Pointer to an integer where the length of the string will be stored. On errors this will be set to -1.
|
|
||||||
* @return Pointer to the newly allocated string or NULL if the value is NULL or an error occurred
|
* @return Pointer to the newly allocated string or NULL if the value is NULL or an error occurred
|
||||||
*/
|
*/
|
||||||
char* get_lenenc_str(void* data, int* len)
|
char* get_lenenc_str(void* data)
|
||||||
{
|
{
|
||||||
unsigned char* ptr = (unsigned char*)data;
|
unsigned char* ptr = (unsigned char*)data;
|
||||||
char* rval;
|
char* rval;
|
||||||
unsigned long size, offset;
|
uintptr_t size;
|
||||||
|
long offset;
|
||||||
|
|
||||||
if(data == NULL || len == NULL)
|
if(data == NULL)
|
||||||
{
|
{
|
||||||
*len = -1;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*ptr < 251)
|
if(*ptr < 251)
|
||||||
{
|
{
|
||||||
size = *ptr;
|
size = (uintptr_t)*ptr;
|
||||||
offset = 1;
|
offset = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -263,7 +262,6 @@ char* get_lenenc_str(void* data, int* len)
|
|||||||
switch(*(ptr))
|
switch(*(ptr))
|
||||||
{
|
{
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
*len = 1;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
size = *(ptr + 1) + (*(ptr + 2) << 8);
|
size = *(ptr + 1) + (*(ptr + 2) << 8);
|
||||||
@ -274,14 +272,9 @@ char* get_lenenc_str(void* data, int* len)
|
|||||||
offset = 3;
|
offset = 3;
|
||||||
break;
|
break;
|
||||||
case 0xfe:
|
case 0xfe:
|
||||||
size = *ptr +
|
size = *ptr + ((*(ptr + 2) << 8)) + (*(ptr + 3) << 16) +
|
||||||
((*(ptr + 2) << 8)) +
|
(*(ptr + 4) << 24) + ((uintptr_t)*(ptr + 5) << 32) + ((uintptr_t)*(ptr + 6) << 40) +
|
||||||
(*(ptr + 3) << 16) +
|
((uintptr_t)*(ptr + 7) << 48) + ((uintptr_t)*(ptr + 8) << 56);
|
||||||
(*(ptr + 4) << 24) +
|
|
||||||
((unsigned long)*(ptr + 5) << 32) +
|
|
||||||
((unsigned long)*(ptr + 6) << 40) +
|
|
||||||
((unsigned long)*(ptr + 7) << 48) +
|
|
||||||
((unsigned long)*(ptr + 8) << 56);
|
|
||||||
offset = 8;
|
offset = 8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -297,7 +290,6 @@ char* get_lenenc_str(void* data, int* len)
|
|||||||
memset(rval + size,0,1);
|
memset(rval + size,0,1);
|
||||||
|
|
||||||
}
|
}
|
||||||
*len = size + offset;
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,8 +352,7 @@ bool parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* bref, GWBUF**
|
|||||||
{
|
{
|
||||||
int payloadlen = gw_mysql_get_byte3(ptr);
|
int payloadlen = gw_mysql_get_byte3(ptr);
|
||||||
int packetlen = payloadlen + 4;
|
int packetlen = payloadlen + 4;
|
||||||
int len = 0;
|
char* data = get_lenenc_str(ptr+4);
|
||||||
char* data = get_lenenc_str(ptr+4,&len);
|
|
||||||
|
|
||||||
if(data)
|
if(data)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -246,25 +246,23 @@ hashcmpfun(
|
|||||||
/**
|
/**
|
||||||
* Convert a length encoded string into a C string.
|
* Convert a length encoded string into a C string.
|
||||||
* @param data Pointer to the first byte of the string
|
* @param data Pointer to the first byte of the string
|
||||||
* @param len Pointer to an integer where the length of the string will be stored. On errors this will be set to -1.
|
|
||||||
* @return Pointer to the newly allocated string or NULL if the value is NULL or an error occurred
|
* @return Pointer to the newly allocated string or NULL if the value is NULL or an error occurred
|
||||||
*/
|
*/
|
||||||
char* get_lenenc_str(void* data, int* len)
|
char* get_lenenc_str(void* data)
|
||||||
{
|
{
|
||||||
unsigned char* ptr = (unsigned char*)data;
|
unsigned char* ptr = (unsigned char*)data;
|
||||||
char* rval;
|
char* rval;
|
||||||
long size, offset;
|
uintptr_t size;
|
||||||
|
long offset;
|
||||||
|
|
||||||
if(data == NULL || len == NULL)
|
if(data == NULL)
|
||||||
{
|
{
|
||||||
if(len)
|
|
||||||
*len = -1;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*ptr < 251)
|
if(*ptr < 251)
|
||||||
{
|
{
|
||||||
size = *ptr;
|
size = (uintptr_t)*ptr;
|
||||||
offset = 1;
|
offset = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -272,7 +270,6 @@ char* get_lenenc_str(void* data, int* len)
|
|||||||
switch(*(ptr))
|
switch(*(ptr))
|
||||||
{
|
{
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
*len = 1;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
size = *(ptr + 1) + (*(ptr + 2) << 8);
|
size = *(ptr + 1) + (*(ptr + 2) << 8);
|
||||||
@ -284,8 +281,8 @@ char* get_lenenc_str(void* data, int* len)
|
|||||||
break;
|
break;
|
||||||
case 0xfe:
|
case 0xfe:
|
||||||
size = *ptr + ((*(ptr + 2) << 8)) + (*(ptr + 3) << 16) +
|
size = *ptr + ((*(ptr + 2) << 8)) + (*(ptr + 3) << 16) +
|
||||||
(*(ptr + 4) << 24) + ((long)*(ptr + 5) << 32) + ((long)*(ptr + 6) << 40) +
|
(*(ptr + 4) << 24) + ((uintptr_t)*(ptr + 5) << 32) + ((uintptr_t)*(ptr + 6) << 40) +
|
||||||
((long)*(ptr + 7) << 48) + ((long)*(ptr + 8) << 56);
|
((uintptr_t)*(ptr + 7) << 48) + ((uintptr_t)*(ptr + 8) << 56);
|
||||||
offset = 8;
|
offset = 8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -301,7 +298,6 @@ char* get_lenenc_str(void* data, int* len)
|
|||||||
memset(rval + size,0,1);
|
memset(rval + size,0,1);
|
||||||
|
|
||||||
}
|
}
|
||||||
*len = size + offset;
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,8 +340,7 @@ parse_mapping_response(ROUTER_CLIENT_SES* rses, char* target, GWBUF* buf)
|
|||||||
{
|
{
|
||||||
int payloadlen = gw_mysql_get_byte3(ptr);
|
int payloadlen = gw_mysql_get_byte3(ptr);
|
||||||
int packetlen = payloadlen + 4;
|
int packetlen = payloadlen + 4;
|
||||||
int len = 0;
|
char* data = get_lenenc_str(ptr+4);
|
||||||
char* data = get_lenenc_str(ptr+4,&len);
|
|
||||||
|
|
||||||
if(data)
|
if(data)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -30,76 +30,6 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "skygw_utils.h"
|
#include "skygw_utils.h"
|
||||||
|
|
||||||
const char* timestamp_formatstr = "%04d-%02d-%02d %02d:%02d:%02d ";
|
|
||||||
/** One for terminating '\0' */
|
|
||||||
const size_t timestamp_len = (4+1 +2+1 +2+1 +2+1 +2+1 +2+3 +1) * sizeof(char);
|
|
||||||
|
|
||||||
|
|
||||||
const char* timestamp_formatstr_hp = "%04d-%02d-%02d %02d:%02d:%02d.%03d ";
|
|
||||||
/** One for terminating '\0' */
|
|
||||||
const size_t timestamp_len_hp = (4+1 +2+1 +2+1 +2+1 +2+1 +2+1+3+3 +1) * sizeof(char);
|
|
||||||
|
|
||||||
/** Single-linked list for storing test cases */
|
|
||||||
|
|
||||||
struct slist_node_st {
|
|
||||||
skygw_chk_t slnode_chk_top;
|
|
||||||
slist_t* slnode_list;
|
|
||||||
slist_node_t* slnode_next;
|
|
||||||
void* slnode_data;
|
|
||||||
size_t slnode_cursor_refcount;
|
|
||||||
skygw_chk_t slnode_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct slist_st {
|
|
||||||
skygw_chk_t slist_chk_top;
|
|
||||||
slist_node_t* slist_head;
|
|
||||||
slist_node_t* slist_tail;
|
|
||||||
int slist_nelems;
|
|
||||||
slist_t* slist_cursors_list;
|
|
||||||
skygw_chk_t slist_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct slist_cursor_st {
|
|
||||||
skygw_chk_t slcursor_chk_top;
|
|
||||||
slist_t* slcursor_list;
|
|
||||||
slist_node_t* slcursor_pos;
|
|
||||||
skygw_chk_t slcursor_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skygw_thread_st {
|
|
||||||
skygw_chk_t sth_chk_top;
|
|
||||||
bool sth_must_exit;
|
|
||||||
simple_mutex_t* sth_mutex;
|
|
||||||
pthread_t sth_parent;
|
|
||||||
pthread_t sth_thr;
|
|
||||||
int sth_errno;
|
|
||||||
#if defined(SS_DEBUG)
|
|
||||||
skygw_thr_state_t sth_state;
|
|
||||||
#endif
|
|
||||||
char* sth_name;
|
|
||||||
void* (*sth_thrfun)(void* data);
|
|
||||||
void* sth_data;
|
|
||||||
skygw_chk_t sth_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skygw_message_st {
|
|
||||||
skygw_chk_t mes_chk_top;
|
|
||||||
bool mes_sent;
|
|
||||||
pthread_mutex_t mes_mutex;
|
|
||||||
pthread_cond_t mes_cond;
|
|
||||||
skygw_chk_t mes_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skygw_file_st {
|
|
||||||
skygw_chk_t sf_chk_top;
|
|
||||||
char* sf_fname;
|
|
||||||
FILE* sf_file;
|
|
||||||
int sf_fd;
|
|
||||||
skygw_chk_t sf_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** End of structs and types */
|
|
||||||
|
|
||||||
#if defined(MLIST)
|
#if defined(MLIST)
|
||||||
|
|
||||||
|
|
||||||
@ -1952,9 +1882,8 @@ return_rc:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
skygw_file_t* skygw_file_init(
|
skygw_file_t* skygw_file_alloc(
|
||||||
char* fname,
|
char* fname)
|
||||||
char* symlinkname)
|
|
||||||
{
|
{
|
||||||
skygw_file_t* file;
|
skygw_file_t* file;
|
||||||
|
|
||||||
@ -1964,12 +1893,26 @@ skygw_file_t* skygw_file_init(
|
|||||||
"* Error : Memory allocation for file %s failed.\n",
|
"* Error : Memory allocation for file %s failed.\n",
|
||||||
fname);
|
fname);
|
||||||
perror("SkyGW file allocation\n");
|
perror("SkyGW file allocation\n");
|
||||||
goto return_file;
|
return NULL;
|
||||||
}
|
}
|
||||||
ss_dassert(file != NULL);
|
ss_dassert(file != NULL);
|
||||||
file->sf_chk_top = CHK_NUM_FILE;
|
file->sf_chk_top = CHK_NUM_FILE;
|
||||||
file->sf_chk_tail = CHK_NUM_FILE;
|
file->sf_chk_tail = CHK_NUM_FILE;
|
||||||
file->sf_fname = strdup(fname);
|
file->sf_fname = strdup(fname);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
skygw_file_t* skygw_file_init(
|
||||||
|
char* fname,
|
||||||
|
char* symlinkname)
|
||||||
|
{
|
||||||
|
skygw_file_t* file;
|
||||||
|
|
||||||
|
if ((file = skygw_file_alloc (fname)) == NULL)
|
||||||
|
{
|
||||||
|
/** Error was reported in skygw_file_alloc */
|
||||||
|
goto return_file;
|
||||||
|
}
|
||||||
|
|
||||||
if ((file->sf_file = fopen(file->sf_fname, "a")) == NULL)
|
if ((file->sf_file = fopen(file->sf_fname, "a")) == NULL)
|
||||||
{
|
{
|
||||||
@ -2033,6 +1976,12 @@ return_file:
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skygw_file_free(skygw_file_t* file)
|
||||||
|
{
|
||||||
|
free(file->sf_fname);
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
|
||||||
void skygw_file_close(
|
void skygw_file_close(
|
||||||
skygw_file_t* file,
|
skygw_file_t* file,
|
||||||
bool shutdown)
|
bool shutdown)
|
||||||
@ -2065,8 +2014,7 @@ void skygw_file_close(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ss_dfprintf(stderr, "Closed %s\n", file->sf_fname);
|
ss_dfprintf(stderr, "Closed %s\n", file->sf_fname);
|
||||||
free(file->sf_fname);
|
skygw_file_free (file);
|
||||||
free(file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,6 +80,75 @@ struct mlist_node_st {
|
|||||||
typedef enum { THR_INIT, THR_RUNNING, THR_STOPPED, THR_DONE } skygw_thr_state_t;
|
typedef enum { THR_INIT, THR_RUNNING, THR_STOPPED, THR_DONE } skygw_thr_state_t;
|
||||||
typedef enum { MES_RC_FAIL, MES_RC_SUCCESS, MES_RC_TIMEOUT } skygw_mes_rc_t;
|
typedef enum { MES_RC_FAIL, MES_RC_SUCCESS, MES_RC_TIMEOUT } skygw_mes_rc_t;
|
||||||
|
|
||||||
|
|
||||||
|
static const char* timestamp_formatstr = "%04d-%02d-%02d %02d:%02d:%02d ";
|
||||||
|
/** One for terminating '\0' */
|
||||||
|
static const size_t timestamp_len = (4+1 +2+1 +2+1 +2+1 +2+1 +2+3 +1) * sizeof(char);
|
||||||
|
|
||||||
|
|
||||||
|
static const char* timestamp_formatstr_hp = "%04d-%02d-%02d %02d:%02d:%02d.%03d ";
|
||||||
|
/** One for terminating '\0' */
|
||||||
|
static const size_t timestamp_len_hp = (4+1 +2+1 +2+1 +2+1 +2+1 +2+1+3+3 +1) * sizeof(char);
|
||||||
|
|
||||||
|
/** Single-linked list for storing test cases */
|
||||||
|
|
||||||
|
struct slist_node_st {
|
||||||
|
skygw_chk_t slnode_chk_top;
|
||||||
|
slist_t* slnode_list;
|
||||||
|
slist_node_t* slnode_next;
|
||||||
|
void* slnode_data;
|
||||||
|
size_t slnode_cursor_refcount;
|
||||||
|
skygw_chk_t slnode_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist_st {
|
||||||
|
skygw_chk_t slist_chk_top;
|
||||||
|
slist_node_t* slist_head;
|
||||||
|
slist_node_t* slist_tail;
|
||||||
|
int slist_nelems;
|
||||||
|
slist_t* slist_cursors_list;
|
||||||
|
skygw_chk_t slist_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist_cursor_st {
|
||||||
|
skygw_chk_t slcursor_chk_top;
|
||||||
|
slist_t* slcursor_list;
|
||||||
|
slist_node_t* slcursor_pos;
|
||||||
|
skygw_chk_t slcursor_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct skygw_thread_st {
|
||||||
|
skygw_chk_t sth_chk_top;
|
||||||
|
bool sth_must_exit;
|
||||||
|
simple_mutex_t* sth_mutex;
|
||||||
|
pthread_t sth_parent;
|
||||||
|
pthread_t sth_thr;
|
||||||
|
int sth_errno;
|
||||||
|
#if defined(SS_DEBUG)
|
||||||
|
skygw_thr_state_t sth_state;
|
||||||
|
#endif
|
||||||
|
char* sth_name;
|
||||||
|
void* (*sth_thrfun)(void* data);
|
||||||
|
void* sth_data;
|
||||||
|
skygw_chk_t sth_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct skygw_message_st {
|
||||||
|
skygw_chk_t mes_chk_top;
|
||||||
|
bool mes_sent;
|
||||||
|
pthread_mutex_t mes_mutex;
|
||||||
|
pthread_cond_t mes_cond;
|
||||||
|
skygw_chk_t mes_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct skygw_file_st {
|
||||||
|
skygw_chk_t sf_chk_top;
|
||||||
|
char* sf_fname;
|
||||||
|
FILE* sf_file;
|
||||||
|
int sf_fd;
|
||||||
|
skygw_chk_t sf_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
EXTERN_C_BLOCK_BEGIN
|
EXTERN_C_BLOCK_BEGIN
|
||||||
|
|
||||||
slist_cursor_t* slist_init(void);
|
slist_cursor_t* slist_init(void);
|
||||||
@ -147,6 +216,8 @@ EXTERN_C_BLOCK_END
|
|||||||
/** Skygw thread routines */
|
/** Skygw thread routines */
|
||||||
|
|
||||||
/** Skygw file routines */
|
/** Skygw file routines */
|
||||||
|
skygw_file_t* skygw_file_alloc(char* fname);
|
||||||
|
void skygw_file_free(skygw_file_t* file);
|
||||||
skygw_file_t* skygw_file_init(char* fname, char* symlinkname);
|
skygw_file_t* skygw_file_init(char* fname, char* symlinkname);
|
||||||
void skygw_file_close(skygw_file_t* file, bool shutdown);
|
void skygw_file_close(skygw_file_t* file, bool shutdown);
|
||||||
int skygw_file_write(
|
int skygw_file_write(
|
||||||
|
|||||||
Reference in New Issue
Block a user