pgpool2.git / summary / log / commit / refs
commit 414ffa4d4061f5eba82e36e4e455d2a0fa2b80d9
Author: Muhammad Usama <m.usama@gmail.com>
Date: Mon May 02 21:18:25 2016 +0000
Streamlining the pgpool configuration system (Work in progress).
This commit builds the framework for managing the pgpool-II configuration
parameters. It is the first step towards implementing the session level
SET command functionality in pgpool to allow the users to alter the pgpool
config parameters for a particular session only and reset it back to the
original value after the user session disconnects.
The overall design of the configuration framework is inspired by the
PostgreSQL's GUC and some of the more visible changes introduced by the
framework are.
-- There is no more a long list of if-else statements in pool_get_config function
and now a simple loop can be used to alter/initialize/print all the pgpool-II
config variables.
-- The framework keeps track of values assigned to parameters in BOOT or INIT
contexts and later value of the config parameters can be reset to that value.
In addition to the framework, the commit also revisits the internal data types
of the configuration parameters and made the following changes
-- Changes the type of all on/off type config parameters from integer to boolean type
-- All the string (char*) type parameters that can only be assigned from the
particular set of values (e.g. master_slave_sub_mode can assign with either
"stream" or "Slony") are changed to Enum type parameters.
src/Makefile.am | 1 +
src/Makefile.in | 21 +-
src/config/pool_config.c | 3666 ++-----------------------
src/config/pool_config.l | 3623 ++----------------------
src/config/pool_config_variables.c | 3233 ++++++++++++++++++++++
src/context/pool_query_context.c | 4 +-
src/include/pcp/libpcp_ext.h | 2 +-
src/include/pool.h | 6 +-
src/include/pool_config.h | 407 +--
src/include/pool_config_variables.h | 274 ++
src/include/pool_type.h | 11 +
src/include/utils/fe_ports.h | 11 +-
src/include/utils/json.h | 14 +-
src/include/utils/json_writer.h | 2 +
src/libs/pcp/Makefile.in | 16 +-
src/main/main.c | 5 +-
src/main/pgpool_main.c | 12 +-
src/pcp_con/pcp_child.c | 2 +-
src/pcp_con/pcp_worker.c | 8 +-
src/protocol/child.c | 2 +-
src/protocol/pool_process_query.c | 2 +-
src/query_cache/pool_memqcache.c | 10 +-
src/streaming_replication/pool_worker_child.c | 8 +-
src/tools/pgmd5/Makefile.am | 3 +
src/tools/pgmd5/Makefile.in | 26 +-
src/tools/pgmd5/pg_md5.c | 2 +-
src/tools/pgmd5/pool_config.c | 3499 ++---------------------
src/utils/json.c | 20 +
src/utils/json_writer.c | 11 +
src/utils/pool_process_reporting.c | 8 +-
src/utils/regex_array.c | 2 +-
src/watchdog/watchdog.c | 4 +-
src/watchdog/wd_json_data.c | 59 +-
src/watchdog/wd_lifecheck.c | 16 +-
34 files changed, 4611 insertions(+), 10379 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index a9e104662..7e1f948d8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ pgpool_SOURCES = main/main.c \
main/pool_globals.c \
main/pgpool_main.c \
config/pool_config.l \
+ config/pool_config_variables.c \
pcp_con/pcp_child.c \
pcp_con/pcp_worker.c \
pcp_con/recovery.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 6dc95a367..cbcc22590 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -85,11 +85,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/mkinstalldirs config/pool_config.c \
$(top_srcdir)/depcomp $(top_srcdir)/ylwrap
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \
- $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/c-compiler.m4 $(top_srcdir)/c-library.m4 \
+ $(top_srcdir)/general.m4 \
$(top_srcdir)/ac_func_accept_argtypes.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -104,6 +104,7 @@ PROGRAMS = $(bin_PROGRAMS)
am__dirstamp = $(am__leading_dot)dirstamp
am_pgpool_OBJECTS = main/main.$(OBJEXT) main/pool_globals.$(OBJEXT) \
main/pgpool_main.$(OBJEXT) config/pool_config.$(OBJEXT) \
+ config/pool_config_variables.$(OBJEXT) \
pcp_con/pcp_child.$(OBJEXT) pcp_con/pcp_worker.$(OBJEXT) \
pcp_con/recovery.$(OBJEXT) auth/md5.$(OBJEXT) \
auth/pool_auth.$(OBJEXT) auth/pool_passwd.$(OBJEXT) \
@@ -289,11 +290,9 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOG = @CATALOG@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-COLLATEINDEX = @COLLATEINDEX@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -302,7 +301,6 @@ DEFS = @DEFS@ \
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
-DOCBOOKSTYLE = @DOCBOOKSTYLE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -317,7 +315,6 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JADE = @JADE@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
@@ -340,7 +337,6 @@ MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
-NSGMLS = @NSGMLS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OSX = @OSX@
@@ -393,7 +389,6 @@ datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
-have_docbook = @have_docbook@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -429,6 +424,7 @@ pgpool_SOURCES = main/main.c \
main/pool_globals.c \
main/pgpool_main.c \
config/pool_config.l \
+ config/pool_config_variables.c \
pcp_con/pcp_child.c \
pcp_con/pcp_worker.c \
pcp_con/recovery.c \
@@ -656,6 +652,8 @@ config/$(DEPDIR)/$(am__dirstamp):
@: > config/$(DEPDIR)/$(am__dirstamp)
config/pool_config.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
+config/pool_config_variables.$(OBJEXT): config/$(am__dirstamp) \
+ config/$(DEPDIR)/$(am__dirstamp)
pcp_con/$(am__dirstamp):
@$(MKDIR_P) pcp_con
@: > pcp_con/$(am__dirstamp)
@@ -840,6 +838,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@auth/$(DEPDIR)/pool_hba.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@auth/$(DEPDIR)/pool_passwd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/pool_config.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/pool_config_variables.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@context/$(DEPDIR)/pool_process_context.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@context/$(DEPDIR)/pool_query_context.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@context/$(DEPDIR)/pool_session_context.Po@am__quote@
diff --git a/src/config/pool_config.c b/src/config/pool_config.c
index 1ebc25ae6..c6785da4d 100644
--- a/src/config/pool_config.c
+++ b/src/config/pool_config.c
@@ -8,7 +8,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_SUBMINOR_VERSION 37
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -46,7 +46,6 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -54,7 +53,6 @@ typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
@@ -85,6 +83,8 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! C99 */
+
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
@@ -332,7 +332,7 @@ void yyfree (void * );
/* Begin user sect3 */
-#define yywrap(n) 1
+#define yywrap() 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -358,7 +358,7 @@ static void yy_fatal_error (yyconst char msg[] );
*/
#define YY_DO_BEFORE_ACTION \
(yytext_ptr) = yy_bp; \
- yyleng = (yy_size_t) (yy_cp - yy_bp); \
+ yyleng = (size_t) (yy_cp - yy_bp); \
(yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
@@ -514,6 +514,7 @@ char *yytext;
#include <ctype.h>
#include "pool.h"
#include "pool_config.h"
+#include "pool_config_variables.h"
#include "utils/regex_array.h"
#ifndef POOL_PRIVATE
#include "utils/elog.h"
@@ -521,15 +522,13 @@ char *yytext;
#include "utils/fe_ports.h"
#endif
-#define CHECK_CONTEXT(mask, context) ((mask) & (context))
/* to shut off compiler warnings */
int yylex(void);
-POOL_CONFIG *pool_config; /* configuration values */
+POOL_CONFIG g_pool_config; /* configuration values */
+POOL_CONFIG *pool_config = &g_pool_config; /* for lagacy reason pointer to the above struct */
static unsigned Lineno;
-static char *default_reset_query_list[] = {"ABORT", "DISCARD ALL"};
-static char *default_black_function_list[] = {"nextval", "setval"};
typedef enum {
POOL_KEY = 1,
@@ -543,11 +542,11 @@ typedef enum {
} POOL_TOKEN;
static char *extract_string(char *value, POOL_TOKEN token);
-static char **extract_string_tokens(char *str, char *delim, int *n);
-static void clear_host_entry(int slot);
-static bool check_redirect_node_spec(char *node_spec);
+static void FreeConfigVariable(ConfigVariable *item);
+static bool ParseConfigFile( const char *config_file, int elevel,
+ ConfigVariable **head_p, ConfigVariable **tail_p);
-#line 551 "config/pool_config.c"
+#line 550 "config/pool_config.c"
#define INITIAL 0
@@ -634,7 +633,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -645,7 +644,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- yy_size_t n; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -727,10 +726,10 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
-#line 90 "pool_config.l"
+#line 89 "pool_config.l"
-#line 734 "config/pool_config.c"
+#line 733 "config/pool_config.c"
if ( !(yy_init) )
{
@@ -812,12 +811,12 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
-#line 92 "pool_config.l"
+#line 91 "pool_config.l"
Lineno++; return POOL_EOL;
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 93 "pool_config.l"
+#line 92 "pool_config.l"
/* eat whitespace */
YY_BREAK
case 3:
@@ -825,50 +824,50 @@ case 3:
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 94 "pool_config.l"
+#line 93 "pool_config.l"
/* eat comment */
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 96 "pool_config.l"
+#line 95 "pool_config.l"
return POOL_KEY;
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 97 "pool_config.l"
+#line 96 "pool_config.l"
return POOL_STRING;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 98 "pool_config.l"
+#line 97 "pool_config.l"
return POOL_UNQUOTED_STRING;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 99 "pool_config.l"
+#line 98 "pool_config.l"
return POOL_INTEGER;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 100 "pool_config.l"
+#line 99 "pool_config.l"
return POOL_REAL;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 101 "pool_config.l"
+#line 100 "pool_config.l"
return POOL_EQUALS;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 103 "pool_config.l"
+#line 102 "pool_config.l"
return POOL_PARSE_ERROR;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 105 "pool_config.l"
+#line 104 "pool_config.l"
ECHO;
YY_BREAK
-#line 872 "config/pool_config.c"
+#line 871 "config/pool_config.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1062,7 +1061,7 @@ static int yy_get_next_buffer (void)
{ /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
int yy_c_buf_p_offset =
(int) ((yy_c_buf_p) - b->yy_ch_buf);
@@ -1195,7 +1194,7 @@ static int yy_get_next_buffer (void)
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 37);
- return yy_is_jam ? 0 : yy_current_state;
+ return yy_is_jam ? 0 : yy_current_state;
}
#ifndef YY_NO_INPUT
@@ -1246,7 +1245,7 @@ static int yy_get_next_buffer (void)
case EOB_ACT_END_OF_FILE:
{
if ( yywrap( ) )
- return 0;
+ return EOF;
if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE;
@@ -1586,8 +1585,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
*
* @return the newly allocated buffer state object.
*/
@@ -1595,7 +1594,8 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
{
YY_BUFFER_STATE b;
char *buf;
- yy_size_t n, i;
+ yy_size_t n;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
@@ -1825,211 +1825,24 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 105 "pool_config.l"
+#line 104 "pool_config.l"
int pool_init_config(void)
{
- int res;
- static char localhostname[256];
- int i;
-
- pool_config = palloc(sizeof(POOL_CONFIG));
-
memset(pool_config, 0, sizeof(POOL_CONFIG));
#ifndef POOL_PRIVATE
- pool_config->backend_desc = pool_shared_memory_create(sizeof(BackendDesc));
+g_pool_config.backend_desc = palloc0(sizeof(BackendDesc));
+// g_pool_config.backend_desc = pool_shared_memory_create(sizeof(BackendDesc));
+// memset(g_pool_config.backend_desc, 0, sizeof(BackendDesc));
+
#else
- pool_config->backend_desc = palloc(sizeof(BackendDesc));
+ g_pool_config.backend_desc = palloc0(sizeof(BackendDesc));
#endif
+ InitializeConfigOptions();
- /*
- * add for watchdog
- */
- memset(&pool_config->wd_remote_nodes,0x00,sizeof(WdRemoteNodesConfig));
-
- /* set hardcoded default values */
- pool_config->listen_addresses = "localhost";
- pool_config->pcp_listen_addresses = "*";
- pool_config->port = 9999;
- pool_config->pcp_port = 9898;
- pool_config->socket_dir = DEFAULT_SOCKET_DIR;
- pool_config->wd_ipc_socket_dir = DEFAULT_WD_IPC_SOCKET_DIR;
- pool_config->pcp_socket_dir = DEFAULT_SOCKET_DIR;
- pool_config->num_init_children = 32;
- pool_config->listen_backlog_multiplier = 2;
- pool_config->serialize_accept = 0;
- pool_config->max_pool = 4;
- pool_config->child_life_time = 300;
- pool_config->client_idle_limit = 0;
- pool_config->connection_life_time = 0;
- pool_config->child_max_connections = 0;
- pool_config->authentication_timeout = 60;
- pool_config->logdir = DEFAULT_LOGDIR;
- pool_config->logsyslog = 0;
- pool_config->log_destination = "stderr";
- pool_config->syslog_facility = LOG_LOCAL0;
- pool_config->syslog_ident = "pgpool";
- pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
- pool_config->log_statement = 0;
- pool_config->log_per_node_statement = 0;
- pool_config->log_connections = 0;
- pool_config->log_hostname = 0;
- pool_config->enable_pool_hba = 0;
- pool_config->pool_passwd = "pool_passwd";
-
- pool_config->replication_mode = 0;
- pool_config->load_balance_mode = 0;
- pool_config->replication_stop_on_mismatch = 0;
- pool_config->failover_if_affected_tuples_mismatch = 0;
- pool_config->replicate_select = 0;
- pool_config->reset_query_list = default_reset_query_list;
- pool_config->num_reset_queries = sizeof(default_reset_query_list)/sizeof(char *);
- pool_config->white_function_list = NULL;
- pool_config->num_white_function_list = 0;
- pool_config->black_function_list = default_black_function_list;
- pool_config->num_black_function_list = sizeof(default_black_function_list)/sizeof(char *);
- pool_config->log_line_prefix = "%t: pid %p: ";
- pool_config->log_error_verbosity = 1; /* PGERROR_DEFAULT */
- pool_config->client_min_messages = 18; /* NOTICE */
- pool_config->log_min_messages = 19; /* WARNING */
- pool_config->master_slave_mode = 0;
- pool_config->master_slave_sub_mode = "slony";
- pool_config->delay_threshold = 0;
- pool_config->log_standby_delay = "none";
- pool_config->connection_cache = 1;
- pool_config->health_check_timeout = 20;
- pool_config->health_check_period = 0;
- pool_config->health_check_user = "nobody";
- pool_config->health_check_password = "";
- pool_config->health_check_database = "";
- pool_config->health_check_max_retries = 0;
- pool_config->health_check_retry_delay = 1;
- pool_config->connect_timeout = 10000;
- pool_config->sr_check_period = 0;
- pool_config->sr_check_user = "nobody";
- pool_config->sr_check_password = "";
- pool_config->sr_check_database = "postgres";
- pool_config->failover_command = "";
- pool_config->follow_master_command = "";
- pool_config->failback_command = "";
- pool_config->fail_over_on_backend_error = 1;
- pool_config->insert_lock = 1;
- pool_config->ignore_leading_white_space = 1;
- pool_config->backend_desc->num_backends = 0;
- pool_config->recovery_user = "";
- pool_config->recovery_password = "";
- pool_config->recovery_1st_stage_command = "";
- pool_config->recovery_2nd_stage_command = "";
- pool_config->recovery_timeout = 90;
- pool_config->search_primary_node_timeout = 10;
- pool_config->client_idle_limit_in_recovery = 0;
- pool_config->lobj_lock_table = "";
- pool_config->ssl = 0;
- pool_config->ssl_cert = "";
- pool_config->ssl_key = "";
- pool_config->ssl_ca_cert = "";
- pool_config->ssl_ca_cert_dir = "";
- pool_config->debug_level = 0;
- pool_config->relcache_expire = 0;
- pool_config->relcache_size = 256;
- pool_config->check_temp_table = 1;
- pool_config->check_unlogged_table = 1;
- pool_config->lists_patterns = NULL;
- pool_config->pattc = 0;
- pool_config->current_pattern_size = 0;
-
- /*
- * database_redirect_preference_list
- */
- pool_config->database_redirect_preference_list = NULL;
- pool_config->redirect_dbnames = NULL;
- pool_config->db_redirect_tokens = NULL;
-
- /*
- * app_name_redirect_preference_list
- */
- pool_config->app_name_redirect_preference_list = NULL;
- pool_config->redirect_app_names = NULL;
- pool_config->app_name_redirect_tokens = NULL;
-
- pool_config->allow_sql_comments = 0;
-
- /*
- * add for watchdog
- */
- pool_config->use_watchdog = 0;
- pool_config->wd_lifecheck_method = MODE_HEARTBEAT;
- pool_config->clear_memqcache_on_escalation = 1;
- pool_config->wd_escalation_command = "";
- pool_config->wd_de_escalation_command = "";
- pool_config->trusted_servers = "";
- pool_config->delegate_IP = "";
- res = gethostname(localhostname,sizeof(localhostname));
- if(res !=0 )
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failed to get the local hostname")));
- }
- pool_config->wd_hostname = localhostname;
- pool_config->wd_port = 9000;
- pool_config->wd_priority = 1;
- pool_config->wd_remote_nodes.num_wd = 0;
- pool_config->wd_interval = 10;
- pool_config->wd_authkey = "";
- pool_config->ping_path = "/bin";
- pool_config->if_cmd_path = "/sbin";
- pool_config->if_up_cmd = "ip addr add $_IP_$/24 dev eth0 label eth0:0";
- pool_config->if_down_cmd = "ip addr del $_IP_$/24 dev eth0";
- pool_config->arping_path = "/usr/sbin";
- pool_config->arping_cmd = "arping -U $_IP_$ -w 1";
- pool_config->wd_life_point = 3;
- pool_config->wd_lifecheck_query = "SELECT 1";
- pool_config->wd_lifecheck_dbname = "template1";
- pool_config->wd_lifecheck_user = "nobody";
- pool_config->wd_lifecheck_password = "";
- pool_config->wd_heartbeat_port = 9694;
- pool_config->wd_heartbeat_keepalive = 2;
- pool_config->wd_heartbeat_deadtime = 30;
- pool_config->num_hb_if = 0;
- pool_config->wd_monitoring_interfaces_list = NULL;
- pool_config->num_wd_monitoring_interfaces_list = 0;
-
- pool_config->memory_cache_enabled = 0;
- pool_config->memqcache_method = "shmem";
- pool_config->memqcache_memcached_host = "localhost";
- pool_config->memqcache_memcached_port = 11211;
- pool_config->memqcache_total_size = (int64)67108864;
- pool_config->memqcache_max_num_cache = 1000000;
- pool_config->memqcache_expire = 0;
- pool_config->memqcache_auto_cache_invalidation = 1;
- pool_config->memqcache_maxcache = 409600;
- pool_config->memqcache_cache_block_size = 1048576;
- pool_config->memqcache_oiddir = "/var/log/pgpool/oiddir";
- pool_config->white_memqcache_table_list = NULL;
- pool_config->num_white_memqcache_table_list = 0;
- pool_config->black_memqcache_table_list = NULL;
- pool_config->num_black_memqcache_table_list = 0;
- pool_config->lists_memqcache_table_patterns = NULL;
- pool_config->memqcache_table_pattc = 0;
- pool_config->current_memqcache_table_pattern_size = 0;
-
- res = gethostname(localhostname,sizeof(localhostname));
- if(res !=0 )
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failed to get the local hostname")));
-
- }
-
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- clear_host_entry(i);
- }
return 0;
}
@@ -2038,7 +1851,7 @@ int pool_init_config(void)
* The supported type are: black_function_list and white_function_list
* Return 0 on error, 1 on success
*/
-int add_regex_pattern(char *type, char *s)
+int add_regex_pattern(const char *type, char *s)
{
int regex_flags = REG_NOSUB;
RegPattern currItem;
@@ -2158,38 +1971,74 @@ int growMemqcacheTablePatternArray(RegPattern item)
return(pool_config->memqcache_table_pattc);
}
-int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
+/*
+ * Free a single ConfigVariable
+ */
+static void
+FreeConfigVariable(ConfigVariable *item)
+{
+ if (item->name)
+ pfree(item->name);
+ if (item->value)
+ pfree(item->value);
+ pfree(item);
+}
+
+/*
+ * Free a list of ConfigVariables, including the names and the values
+ */
+static void
+FreeConfigVariables(ConfigVariable *list)
+{
+ ConfigVariable *item;
+
+ item = list;
+ while (item)
+ {
+ ConfigVariable *next = item->next;
+ FreeConfigVariable(item);
+ item = next;
+ }
+}
+
+/*
+ * Read and parse a single configuration file.
+ *
+ * Input parameters:
+ * config_file: absolute or relative path name of the configuration file
+ * elevel: error logging level to use
+ * Input/Output parameters:
+ * head_p, tail_p: head and tail of linked list of name/value pairs
+ *
+ * *head_p and *tail_p must be initialized, either to NULL or valid pointers
+ * to a ConfigVariable list, before calling the outer recursion level. Any
+ * name-value pairs read from the input file(s) will be appended to the list.
+ *
+ * Note: if elevel >= ERROR then an error will not return control to the
+ * caller, so there is no need to check the return value in that case.
+ *
+ */
+static bool
+ParseConfigFile(const char *config_file, int elevel,
+ ConfigVariable **head_p, ConfigVariable **tail_p)
{
+
FILE *fd;
int token;
- char key[1024];
- double total_weight;
- int i;
- int error_level;
- bool log_destination_changed = false;
- sig_atomic_t local_num_backends;
-#ifdef USE_MEMCACHED
- bool use_memcached = true;
-#else
- bool use_memcached = false;
-#endif
- if(CHECK_CONTEXT(INIT_CONFIG, context))
- error_level = ERROR;
- else
- error_level = WARNING;
-
-#define PARSE_ERROR() ereport(CHECK_CONTEXT(INIT_CONFIG, context)?ERROR:WARNING, \
- (errmsg("syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME), \
- errdetail("parse error at line %d '%s'", Lineno, yytext)))
+ char *key;
+ char *val;
+ ConfigVariable *item;
+
+ *head_p = NULL;
/* open config file */
- fd = fopen(confpath, "r");
+ fd = fopen(config_file, "r");
if (!fd)
{
- ereport(WARNING,
- (errmsg("could not open configuration file: \"%s\"\n",POOL_CONF_FILE_NAME),
+ ereport(elevel,
+ (errmsg("could not open configuration file: \"%s\"\n",config_file),
errdetail("using default configuration parameter values")));
- return 0;
+ return false;
}
yyin = fd;
@@ -2198,3170 +2047,209 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
for(;;)
{
token = yylex();
+
if (token == 0)
- {
break;
- }
- if (token == POOL_PARSE_ERROR)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
+
if (token == POOL_EOL)
continue;
+ if (token == POOL_PARSE_ERROR)
+ goto parse_error;
+
if (token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
+ goto parse_error;
- strlcpy(key, yytext, sizeof(key));
+ key = pstrdup(yytext);
- ereport(DEBUG5,
- (errmsg("key: %s", key)));
token = yylex();
+ /* next we have an optional equal sign; discard if present */
if (token == POOL_EQUALS)
token = yylex();
+ val = extract_string(yytext,token);
+
ereport(DEBUG5,
- (errmsg("value: %s kind: %d", yytext, token)));
- if (!strcmp(key, "allow_inet_domain_socket") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- /* for backward compatibility */
- int v = eval_logical(yytext);
+ (errmsg("key: \"%s\" value: \"%s\" kind: %d",key, val, token)));
+
+ /* Add this to the list */
+ item = palloc(sizeof(ConfigVariable));
+ item->name = key;
+ item->value = val;
+ item->sourceline = Lineno;
+ item->next = NULL;
+ if (*head_p == NULL)
+ *head_p = item;
+ else
+ (*tail_p)->next = item;
+ *tail_p = item;
+ }
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
-
- return(-1);
- }
- if (v)
- pool_config->listen_addresses = pstrdup("*");
- else
- pool_config->listen_addresses = pstrdup("");
- }
- else if (!strcmp(key, "listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ fclose(fd);
+ return true;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->listen_addresses = str;
- }
+parse_error:
- else if (!strcmp(key, "port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
+ fclose(fd);
+ FreeConfigVariables(*head_p);
+ *head_p = NULL;
+ *tail_p = NULL;
+ ereport(elevel,
+ (errmsg("syntex error in configuration file \"%s\"",config_file),
+ errdetail("parse error at line %d '%s' token = %d", Lineno, yytext,token)));
- if (token != POOL_INTEGER || v < 1024)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1024",yytext,key, key)));
+ return false;
+}
- return(-1);
- }
- pool_config->port = v;
- }
+/*
+ * Read the configuration file and load the values of all parameters
+ */
+bool pool_get_config(const char *config_file, ConfigContext context)
+{
+ ConfigVariable *head_p = NULL;
+ ConfigVariable *tail_p = NULL;
+ bool res;
+ int elevel = (context == CFGCXT_INIT)?FATAL:WARNING;
- else if (!strcmp(key, "pcp_listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ res = ParseConfigFile(config_file, elevel, &head_p, &tail_p);
+ if (res == false || head_p == NULL)
+ return false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pcp_listen_addresses = str;
- }
+ res = set_config_options(head_p, context, PGC_S_FILE, elevel);
+ FreeConfigVariables(head_p);
+ return res;
+}
- else if (!strcmp(key, "pcp_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
- if (token != POOL_INTEGER || v < 1024)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1024",yytext,key, key)));
- return(-1);
- }
- pool_config->pcp_port = v;
- }
- else if (!strcmp(key, "socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+static char *extract_string(char *value, POOL_TOKEN token)
+{
+ char *ret = NULL;
+
+ if (token == POOL_STRING)
+ {
+ ret = pstrdup(value+1);
+ ret[strlen(ret)-1] = '\0';
+ }
+ else
+ ret = pstrdup(value);
+
+ return ret;
+}
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+/*
+ * Try to interpret value as boolean value. Valid values are: true,
+ * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
+ * If the string parses okay, return true, else false.
+ * If okay and result is not NULL, return the value in *result.
+ * This function copied from PostgreSQL source code.
+ */
+static bool parse_bool_with_len(const char *value, size_t len, bool *result)
+{
+ switch (*value)
+ {
+ case 't':
+ case 'T':
+ if (strncasecmp(value, "true", len) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ break;
+ case 'f':
+ case 'F':
+ if (strncasecmp(value, "false", len) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->socket_dir = str;
- }
- else if (!strcmp(key, "socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ break;
+ case 'y':
+ case 'Y':
+ if (strncasecmp(value, "yes", len) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ break;
+ case 'n':
+ case 'N':
+ if (strncasecmp(value, "no", len) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->socket_dir = str;
- }
- else if (!strcmp(key, "wd_ipc_socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ break;
+ case 'o':
+ case 'O':
+ /* 'o' is not unique enough */
+ if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->wd_ipc_socket_dir = str;
- }
- else if (!strcmp(key, "num_init_children") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
+ break;
+ case '1':
+ if (len == 1)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- pool_config->num_init_children = v;
- }
- else if (!strcmp(key, "listen_backlog_multiplier") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
+ break;
+ case '0':
+ if (len == 1)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->listen_backlog_multiplier = v;
- }
- else if (!strcmp(key, "serialize_accept") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
+ break;
+ default:
+ break;
+ }
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->serialize_accept = v;
- }
- else if (!strcmp(key, "child_life_time") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ if (result)
+ *result = false; /* suppress compiler warning */
+ return false;
+}
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->child_life_time = v;
- }
- else if (!strcmp(key, "client_idle_limit") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+int eval_logical(const char *str)
+{
+ bool result;
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->client_idle_limit = v;
- }
- else if (!strcmp(key, "connection_life_time") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ if (!parse_bool_with_len(str, strlen(str), &result))
+ return -1;
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->connection_life_time = v;
- }
- else if (!strcmp(key, "child_max_connections") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ return (result ? 1 : 0);
+}
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->child_max_connections = v;
- }
- else if (!strcmp(key, "authentication_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->authentication_timeout = v;
- }
- else if (!strcmp(key, "max_pool") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
+#ifdef DEBUG
+static void print_host_entry(int slot)
+{
+ ereport(DEBUG1,
+ (errmsg("initializing pool configuration"),
+ errdetail("slot: %d host: %s port: %d status: %d weight: %f",
+ slot,
+ pool_config->server_hostnames[slot],
+ pool_config->server_ports[slot],
+ pool_config->server_status[slot],
+ pool_config->server_weights[slot])));
+}
+#endif
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->max_pool = v;
- }
- else if (!strcmp(key, "logdir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->logdir = str;
- }
- else if (!strcmp(key, "log_destination") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- log_destination_changed = pool_config->log_destination != str;
- pool_config->log_destination = str;
- }
- else if (!strcmp(key, "syslog_facility") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->syslog_facility = set_syslog_facility(str);
- }
- else if (!strcmp(key, "syslog_ident") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- log_destination_changed = log_destination_changed || pool_config->syslog_ident != str;
- pool_config->syslog_ident = str;
- }
- else if (!strcmp(key, "pid_file_name") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pid_file_name = str;
- }
- else if (!strcmp(key, "log_connections") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->log_connections = v;
- }
- else if (!strcmp(key, "log_hostname") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->log_hostname = v;
- }
- else if (!strcmp(key, "enable_pool_hba") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->enable_pool_hba = v;
- }
- else if (!strcmp(key, "pool_passwd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pool_passwd = str;
- }
-
- else if (!strcmp(key, "replication_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->replication_mode = v;
-
- if (pool_config->master_slave_mode && pool_config->replication_mode)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("replication_mode and master_slave_mode cannot be enabled at the same time")));
- return(-1);
- }
-
- }
- else if (!strcmp(key, "load_balance_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->load_balance_mode = v;
- }
- else if (!strcmp(key, "replication_stop_on_mismatch") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("replication_stop_on_mismatch: %d", v)));
-
- pool_config->replication_stop_on_mismatch = v;
- }
- else if (!strcmp(key, "failover_if_affected_tuples_mismatch") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failover_if_affected_tuples_mismatch: %d", v)));
-
- pool_config->failover_if_affected_tuples_mismatch = v;
- }
- else if (!strcmp(key, "replicate_select") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("replicate_select: %d", v)));
-
- pool_config->replicate_select = v;
- }
- else if (!strcmp(key, "reset_query_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->reset_query_list = extract_string_tokens(str, ";", &pool_config->num_reset_queries);
- if (pool_config->reset_query_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- }
-
- else if (!strcmp(key, "white_function_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->white_function_list =
- extract_string_tokens(str, ",", &pool_config->num_white_function_list);
-
- if (pool_config->white_function_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_white_function_list;i++)
- {
- add_regex_pattern("white_function_list", pool_config->white_function_list[i]);
- }
- }
-
- else if (!strcmp(key, "black_function_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->black_function_list =
- extract_string_tokens(str, ",", &pool_config->num_black_function_list);
-
- if (pool_config->black_function_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_black_function_list;i++)
- {
- add_regex_pattern("black_function_list", pool_config->black_function_list[i]);
- }
- }
- else if (!strcmp(key, "log_error_verbosity") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"terse","default","verbose",NULL};
- bool found = false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->log_error_verbosity = i;
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
-
- else if (!strcmp(key, "client_min_messages") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error",NULL};
- bool found = false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
-
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->client_min_messages = i + 10;
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
- else if (!strcmp(key, "log_min_messages") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error","fatal","panic",NULL};
- bool found = false;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
-
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->log_min_messages = i + 10; /* error codes start with 10 */
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
- else if (!strcmp(key, "log_line_prefix") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->log_line_prefix = str;
- }
- else if (!strcmp(key, "print_timestamp") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- ereport(NOTICE,
- (errmsg("configuration key \"%s\" is not supported anymore",key),
- errdetail("please use \"log_line_prefix\" instead")));
- }
- else if (!strcmp(key, "print_user") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- ereport(NOTICE,
- (errmsg("configuration key \"%s\" is not supported anymore",key),
- errdetail("please use \"log_line_prefix\" instead")));
- }
-
- else if (!strcmp(key, "master_slave_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->master_slave_mode = v;
-
- if (pool_config->master_slave_mode && pool_config->replication_mode)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("replication_mode and master_slave_mode cannot be enabled at the same time")));
- return(-1);
- }
- }
-
- else if (!strcmp(key, "master_slave_sub_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, MODE_SLONY) && strcmp(str, MODE_STREAMREP))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"slony\" or \"stream\"", key)));
- return(-1);
- }
- pool_config->master_slave_sub_mode = str;
- }
-
- else if (!strcmp(key, "delay_threshold") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- long long int v = atol(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->delay_threshold = v;
- }
-
- else if (!strcmp(key, "log_standby_delay") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, "always") && strcmp(str, "if_over_threshold") && strcmp(str, "none"))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("allowed values are: \"always\", \"if_over_threshold\" and \"none\"")));
-
- return(-1);
- }
- pool_config->log_standby_delay = str;
- }
-
- else if (!strcmp(key, "connection_cache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->connection_cache = v;
- }
-
- else if (!strcmp(key, "health_check_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->health_check_timeout = v;
- }
-
- else if (!strcmp(key, "health_check_period") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->health_check_period = v;
- }
-
- else if (!strcmp(key, "health_check_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_user = str;
- }
-
- else if (!strcmp(key, "health_check_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_password = str;
- }
-
- else if (!strcmp(key, "health_check_database") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_database = str;
- }
-
-
- else if (!strcmp(key, "health_check_max_retries") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->health_check_max_retries = v;
- }
-
- else if (!strcmp(key, "health_check_retry_delay") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->health_check_retry_delay = v;
- }
-
- else if (!strcmp(key, "connect_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->connect_timeout = v;
- }
-
- else if (!strcmp(key, "sr_check_period") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->sr_check_period = v;
- }
-
- else if (!strcmp(key, "sr_check_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_user = str;
- }
-
- else if (!strcmp(key, "sr_check_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_password = str;
- }
-
- else if (!strcmp(key, "sr_check_database") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_database = str;
- }
-
- else if (!strcmp(key, "failover_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->failover_command = str;
- }
-
- else if (!strcmp(key, "follow_master_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->follow_master_command = str;
- }
-
- else if (!strcmp(key, "failback_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->failback_command = str;
- }
-
- else if (!strcmp(key, "fail_over_on_backend_error") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->fail_over_on_backend_error = v;
- }
-
- else if (!strcmp(key, "recovery_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_user = str;
- }
-
- else if (!strcmp(key, "recovery_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_password = str;
- }
-
- else if (!strcmp(key, "recovery_1st_stage_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_1st_stage_command = str;
- }
-
- else if (!strcmp(key, "recovery_2nd_stage_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_2nd_stage_command = str;
- }
-
- else if (!strcmp(key, "recovery_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->recovery_timeout = v;
- }
-
- else if (!strcmp(key, "search_primary_node_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->search_primary_node_timeout = v;
- }
-
- else if (!strcmp(key, "client_idle_limit_in_recovery") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < -1)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->client_idle_limit_in_recovery = v;
- }
-
- else if (!strcmp(key, "insert_lock") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->insert_lock = v;
- }
-
- else if (!strcmp(key, "ignore_leading_white_space") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->ignore_leading_white_space = v;
- }
-
- else if (!strncmp(key, "backend_hostname", 16) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 16);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend number must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG ||
- (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED))
- strlcpy(BACKEND_INFO(slot).backend_hostname, str, MAX_DB_HOST_NAMELEN);
-
- }
-
- else if (!strncmp(key, "backend_port", 12) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 12);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend port slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend port slot number %d port: %d ", slot,atoi(yytext))));
- if (context == INIT_CONFIG)
- {
- BACKEND_INFO(slot).backend_port = atoi(yytext);
- BACKEND_INFO(slot).backend_status = CON_CONNECT_WAIT;
- }
- else if (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED)
- {
- BACKEND_INFO(slot).backend_port = atoi(yytext);
- BACKEND_INFO(slot).backend_status = CON_DOWN;
- }
- }
-
- else if (!strncmp(key, "backend_weight", 14) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- double v;
-
- slot = atoi(key + 14);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend weight slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- v = atof(yytext);
-
- if (v < 0.0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0.0")));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("weight slot number %d weight: %f", slot, v)));
-
- if (context == INIT_CONFIG || context == RELOAD_CONFIG)
- {
- double old_v = BACKEND_INFO(slot).unnormalized_weight;
- BACKEND_INFO(slot).unnormalized_weight = v;
-
- /*
- * Log weight change event only when context is
- * reloading of pgpool.conf and weight is actually
- * changed
- */
- if (context == RELOAD_CONFIG && old_v != v)
- {
- ereport(LOG,
- (errmsg("initializing pool configuration: backend weight for backend:%d changed from %f to %f", slot, old_v, v),
- errdetail("This change will be effective from next client session")));
- }
- }
- }
- else if (!strncmp(key, "backend_data_directory", 22) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
- BACKEND_STATUS status;
-
- slot = atoi(key + 22);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend data directory slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- status = BACKEND_INFO(slot).backend_status;
- if (context == INIT_CONFIG ||
- (context == RELOAD_CONFIG && (status == CON_UNUSED || status == CON_DOWN)))
- strlcpy(BACKEND_INFO(slot).backend_data_directory, str, MAX_PATH_LENGTH);
- }
- else if (!strncmp(key, "backend_flag", 12) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- char *str;
- char **flags;
- int n;
- int i;
- int slot;
- unsigned short flag = 0;
- bool allow_to_failover_is_specified = 0;
- bool disallow_to_failover_is_specified = 0;
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("extract_string failed: %s", yytext)));
- return(-1);
- }
-
- flags = extract_string_tokens(str, "|", &n);
- if (!flags || n < 0)
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("unable to get backend flags")));
-
- fclose(fd);
- return(-1);
- }
-
- for (i=0;i<n;i++)
- {
- if (!strcmp(flags[i], "ALLOW_TO_FAILOVER"))
- {
- if (disallow_to_failover_is_specified)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
-
- return(-1);
- }
- flag &= ~POOL_FAILOVER;
- allow_to_failover_is_specified = true;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("allow_to_failover: ON")));
-
- }
-
- else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER"))
- {
- if (allow_to_failover_is_specified)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
- return(-1);
- }
- flag |= POOL_FAILOVER;
- disallow_to_failover_is_specified = true;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("disallow_to_failover: ON")));
-
- }
-
- else
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("unknown backend flag:%s", flags[i])));
- return (-1);
- }
- }
-
- slot = atoi(key + 12);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- BACKEND_INFO(slot).flag = flag;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend slot number %d flag: %04x", slot, flag)));
-
- }
-
- else if (!strcmp(key, "log_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->log_statement = v;
- }
- else if (!strcmp(key, "log_per_node_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->log_per_node_statement = v;
- }
-
- else if (!strcmp(key, "lobj_lock_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->lobj_lock_table = str;
- }
- /*
- * add for watchdog
- */
- else if (!strncmp(key, "other_pgpool_hostname", 21) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 21) ;
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_INFO(slot).hostname, str, WD_MAX_HOST_NAMELEN);
- }
-
- else if (!strncmp(key, "other_pgpool_port", 17) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 17);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- WD_INFO(slot).pgpool_port = atoi(yytext);
- }
-
- else if (!strncmp(key, "other_wd_port", 13) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 13);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- {
- WD_INFO(slot).wd_port = atoi(yytext);
- pool_config->wd_remote_nodes.num_wd = slot + 1;
- }
- }
- else if (!strcmp(key, "use_watchdog") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->use_watchdog = v;
- }
-
- else if (!strcmp(key, "clear_memqcache_on_escalation") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->clear_memqcache_on_escalation = v;
- }
-
- else if (!strcmp(key, "wd_escalation_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_escalation_command = str;
- }
-
- else if (!strcmp(key, "wd_de_escalation_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_de_escalation_command = str;
- }
-
-
- else if (!strcmp(key, "trusted_servers") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->trusted_servers = str;
- }
- else if (!strcmp(key, "delegate_IP") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->delegate_IP = str;
- }
- else if (!strcmp(key, "wd_hostname") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->wd_hostname = str;
- }
- else if (!strcmp(key, "wd_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_port = v;
- }
- else if (!strcmp(key, "wd_priority") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_priority = v;
- }
- else if (!strcmp(key, "wd_interval") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_interval = v;
- }
- else if (!strcmp(key, "ping_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->ping_path = str;
- }
- else if (!strcmp(key, "if_cmd_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_cmd_path = str;
- }
- else if (!strcmp(key, "if_up_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_up_cmd = str;
- }
- else if (!strcmp(key, "if_down_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_down_cmd = str;
- }
- else if (!strcmp(key, "arping_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->arping_path = str;
- }
- else if (!strcmp(key, "arping_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->arping_cmd = str;
- }
- else if (!strcmp(key, "wd_life_point") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_life_point = v;
- }
- else if (!strcmp(key, "wd_lifecheck_query") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->wd_lifecheck_query = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_dbname") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_dbname = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_user = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_password = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_method") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, MODE_HEARTBEAT) && strcmp(str, MODE_QUERY) && strcmp(str, MODE_EXTERNAL))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"heartbeat\" or \"query\"", key)));
- return(-1);
- }
- pool_config->wd_lifecheck_method = str;
- }
- else if (!strcmp(key, "wd_heartbeat_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_port = v;
- }
- else if (!strcmp(key, "wd_heartbeat_keepalive") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_keepalive = v;
- }
- else if (!strcmp(key, "wd_heartbeat_deadtime") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_deadtime = v;
- }
- else if (!strcmp(key, "wd_authkey") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_authkey = str;
- }
-
- else if (!strncmp(key, "heartbeat_device", 16) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 16) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_HB_IF(slot).if_name, str, WD_MAX_IF_NAME_LEN);
- }
- /* this must be prior to hertbeat_destination */
- else if (!strncmp(key, "heartbeat_destination_port", 26) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 26) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- {
- WD_HB_IF(slot).dest_port = atoi(yytext);
- pool_config->num_hb_if = slot + 1;
- }
- }
- else if (!strncmp(key, "heartbeat_destination", 21) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 21) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_HB_IF(slot).addr, str, WD_MAX_HOST_NAMELEN);
- }
-
- else if (!strcmp(key, "wd_monitoring_interfaces_list") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_monitoring_interfaces_list = extract_string_tokens(str, ",", &pool_config->num_wd_monitoring_interfaces_list);
- if (pool_config->wd_monitoring_interfaces_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- }
-
- else if (!strcmp(key, "ssl") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
-
- return(-1);
- }
- pool_config->ssl = v;
- }
- else if (!strcmp(key, "ssl_cert") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_cert = str;
- }
- else if (!strcmp(key, "ssl_key") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_key = str;
- }
- else if (!strcmp(key, "ssl_ca_cert") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_ca_cert = str;
- }
- else if (!strcmp(key, "ssl_ca_cert_dir") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_ca_cert_dir = str;
- }
-
- else if (!strcmp(key, "debug_level") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- /* Consider -d option value stored in pool_config already */
- pool_config->debug_level |= v;
- }
-
- else if (!strcmp(key, "relcache_expire") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->relcache_expire = v;
- }
-
- else if (!strcmp(key, "relcache_size") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 1")));
- return(-1);
- }
- pool_config->relcache_size = v;
- }
-
- else if (!strcmp(key, "check_temp_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->check_temp_table = v;
- }
-
- else if (!strcmp(key, "check_unlogged_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->check_unlogged_table = v;
- }
-
- else if (!strcmp(key, "memory_cache_enabled") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->memory_cache_enabled = v;
- }
- else if (!strcmp(key, "memqcache_method") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (!strcmp(str, "memcached") && !use_memcached)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration, Feature Not available"),
- errdetail("invalid value:\"%s\" for key:\"%s\", memcached not available because pgpool-II is not built with MEMCACHED support", yytext,key)));
- return -1;
- }
-
- if (strcmp(str, "memcached") && strcmp(str, "shmem"))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"shmem\" or \"memcached\"", str)));
-
- return -1;
- }
-
- pool_config->memqcache_method = str;
- }
- else if (!strcmp(key, "memqcache_memcached_host") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->memqcache_memcached_host = str;
- }
- else if (!strcmp(key, "memqcache_memcached_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->memqcache_memcached_port = v;
- }
- else if (!strcmp(key, "memqcache_total_size") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int64 v = atoll(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->memqcache_total_size = v;
- }
- else if (!strcmp(key, "memqcache_max_num_cache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_max_num_cache = v;
- }
- else if (!strcmp(key, "memqcache_expire") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_expire = v;
- }
- else if (!strcmp(key, "memqcache_auto_cache_invalidation") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->memqcache_auto_cache_invalidation = v;
- }
- else if (!strcmp(key, "memqcache_maxcache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_maxcache = v;
- }
- else if (!strcmp(key, "memqcache_cache_block_size") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 512)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 512")));
- return(-1);
- }
- pool_config->memqcache_cache_block_size = v;
- }
- else if (!strcmp(key, "memqcache_oiddir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->memqcache_oiddir = str;
- }
- else if (!strcmp(key, "white_memqcache_table_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->white_memqcache_table_list =
- extract_string_tokens(str, ",", &pool_config->num_white_memqcache_table_list);
-
- if (pool_config->white_memqcache_table_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_white_memqcache_table_list;i++)
- {
- add_regex_pattern("white_memqcache_table_list", pool_config->white_memqcache_table_list[i]);
- }
- }
-
- else if (!strcmp(key, "black_memqcache_table_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->black_memqcache_table_list =
- extract_string_tokens(str, ",", &pool_config->num_black_memqcache_table_list);
-
- if (pool_config->black_memqcache_table_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_black_memqcache_table_list;i++)
- {
- add_regex_pattern("black_memqcache_table_list", pool_config->black_memqcache_table_list[i]);
- }
- }
-
- else if (!strcmp(key, "database_redirect_preference_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
- int i;
- Left_right_tokens *lrtokens;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- pool_config->database_redirect_preference_list = str;
- lrtokens = create_lrtoken_array();
- extract_string_tokens2(str, ",", ':', lrtokens);
-
- pool_config->redirect_dbnames = create_regex_array();
- pool_config->db_redirect_tokens = lrtokens;
-
- for (i=0;i<lrtokens->pos;i++)
- {
- if (!check_redirect_node_spec(lrtokens->token[i].right_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
- return(-1);
- }
-
- if (*(lrtokens->token[i].left_token) == '\0' ||
- add_regex_array(pool_config->redirect_dbnames, lrtokens->token[i].left_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect dbname regular expression: \"%s\"", lrtokens->token[i].left_token)));
- return(-1);
- }
- }
- }
-
- else if (!strcmp(key, "app_name_redirect_preference_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
- int i;
- Left_right_tokens *lrtokens;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- pool_config->app_name_redirect_preference_list = str;
- lrtokens = create_lrtoken_array();
- extract_string_tokens2(str, ",", ':', lrtokens);
-
- pool_config->redirect_app_names = create_regex_array();
- pool_config->app_name_redirect_tokens = lrtokens;
-
- for (i=0;i<lrtokens->pos;i++)
- {
- if (!check_redirect_node_spec(lrtokens->token[i].right_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
- return(-1);
- }
-
-
- if (*(lrtokens->token[i].left_token) == '\0' ||
- add_regex_array(pool_config->redirect_app_names, lrtokens->token[i].left_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect app name regular expression: \"%s\"", lrtokens->token[i].left_token)));
- return(-1);
- }
- }
- }
-
- else if (!strcmp(key, "allow_sql_comments") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->allow_sql_comments = v;
- }
-
- }
-
- fclose(fd);
-
- if (log_destination_changed)
- {
- /* log_destination has changed, we need to open syslog or close it */
- if (!strcmp(pool_config->log_destination, "stderr"))
- {
- closelog();
- pool_config->logsyslog = 0;
- }
- else
- {
- openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility);
- pool_config->logsyslog = 1;
- }
- }
-
- local_num_backends = 0;
- total_weight = 0.0;
-
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- /* port number == 0 indicates that this server is out of use */
- if (BACKEND_INFO(i).backend_port == 0)
- {
- clear_host_entry(i);
- }
-
- else
- {
- total_weight += BACKEND_INFO(i).unnormalized_weight;
- local_num_backends = i+1;
-
- /* initialize backend_hostname with a default socket path if empty */
- if (*(BACKEND_INFO(i).backend_hostname) == '\0')
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("empty backend_hostname%d, use PostgreSQL's default unix socket path (%s)",
- i, DEFAULT_SOCKET_DIR)));
- strlcpy(BACKEND_INFO(i).backend_hostname, DEFAULT_SOCKET_DIR, MAX_DB_HOST_NAMELEN);
- }
- }
- }
- if (local_num_backends != pool_config->backend_desc->num_backends)
- pool_config->backend_desc->num_backends = local_num_backends;
-
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("num_backends: %d total_weight: %f",
- pool_config->backend_desc->num_backends, total_weight)));
- /*
- * Normalize load balancing weights. What we are doing here is,
- * assign 0 to RAND_MAX to each backend's weight according to the
- * value weightN. For example, if two backends are assigned 1.0,
- * then each backend will get RAND_MAX/2 normalized weight.
- */
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
-#ifdef DEBUG
- print_host_entry(i);
-#endif
-
- if (BACKEND_INFO(i).backend_port != 0)
- {
- BACKEND_INFO(i).backend_weight =
- (RAND_MAX) * BACKEND_INFO(i).unnormalized_weight / total_weight;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend %d weight: %f flag: %04x", i, BACKEND_INFO(i).backend_weight,BACKEND_INFO(i).flag)));
- }
- }
-
- if (strcmp(pool_config->recovery_1st_stage_command, "") ||
- strcmp(pool_config->recovery_2nd_stage_command, ""))
- {
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- if (pool_config->backend_desc->backend_info[i].backend_port != 0 &&
- !strcmp(pool_config->backend_desc->backend_info[i].backend_data_directory, ""))
- {
- ereport(ERROR,
- (errmsg("invalid configuration, recovery_1st_stage_command and recovery_2nd_stage_command requires backend_data_directory to be set")));
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static char *extract_string(char *value, POOL_TOKEN token)
-{
- char *ret;
-
- ret = pstrdup(value);
-
- if (token == POOL_STRING)
- {
- ret[strlen(ret)-1] = '\0';
- return (ret+1);
- }
- return ret;
-}
-
-/*
- * Try to interpret value as boolean value. Valid values are: true,
- * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
- * If the string parses okay, return true, else false.
- * If okay and result is not NULL, return the value in *result.
- * This function copied from PostgreSQL source code.
- */
-static bool parse_bool_with_len(const char *value, size_t len, bool *result)
-{
- switch (*value)
- {
- case 't':
- case 'T':
- if (strncasecmp(value, "true", len) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case 'f':
- case 'F':
- if (strncasecmp(value, "false", len) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case 'y':
- case 'Y':
- if (strncasecmp(value, "yes", len) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case 'n':
- case 'N':
- if (strncasecmp(value, "no", len) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case 'o':
- case 'O':
- /* 'o' is not unique enough */
- if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case '1':
- if (len == 1)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case '0':
- if (len == 1)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- default:
- break;
- }
-
- if (result)
- *result = false; /* suppress compiler warning */
- return false;
-}
-
-int eval_logical(char *str)
-{
- bool result;
-
- if (!parse_bool_with_len(str, strlen(str), &result))
- return -1;
-
- return (result ? 1 : 0);
-}
-
-/*
- * Extract tokens separated by delimi from str. Return value is an
- * array of pointers in pallocd strings. number of tokens is set to
- * n; note that str will be destroyed by strtok().
- */
-#define MAXTOKENS 256
-static char **extract_string_tokens(char *str, char *delimi, int *n)
-{
- char *token;
- char **tokens;
-
- *n = 0;
-
- tokens = palloc(MAXTOKENS*sizeof(char *));
-
- for (token = strtok(str, delimi); token != NULL ; token = strtok(NULL, delimi))
- {
- tokens[*n] = pstrdup(token);
- ereport(DEBUG3,
- (errmsg("initializing pool configuration"),
- errdetail("extracting string tokens [token: %s]", tokens[*n])));
-
- (*n)++;
-
- if ( ((*n) % MAXTOKENS ) == 0)
- {
- tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n)/MAXTOKENS) +1) ));
- }
- }
- /* how about reclaiming the unused space */
- tokens = repalloc(tokens, (sizeof(char *) * (*n) ));
- return tokens;
-}
-
-static void clear_host_entry(int slot)
-{
- *pool_config->backend_desc->backend_info[slot].backend_hostname = '\0';
- pool_config->backend_desc->backend_info[slot].backend_port = 0;
- pool_config->backend_desc->backend_info[slot].backend_status = CON_UNUSED;
- pool_config->backend_desc->backend_info[slot].backend_weight = 0.0;
-}
-
-#ifdef DEBUG
-static void print_host_entry(int slot)
-{
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("slot: %d host: %s port: %d status: %d weight: %f",
- slot,
- pool_config->server_hostnames[slot],
- pool_config->server_ports[slot],
- pool_config->server_status[slot],
- pool_config->server_weights[slot])));
-}
-#endif
-
-/* Use to set the syslog facility level if logsyslog is activated */
-int set_syslog_facility(char *value)
-{
- int facility = LOG_LOCAL0;
-
- if (value == NULL)
- return facility;
-
- if (strncmp(value, "LOCAL", 5) == 0 && strlen(value) == 6) {
- switch (value[5]) {
- case '0':
- facility = LOG_LOCAL0;
- break;
- case '1':
- facility = LOG_LOCAL1;
- break;
- case '2':
- facility = LOG_LOCAL2;
- break;
- case '3':
- facility = LOG_LOCAL3;
- break;
- case '4':
- facility = LOG_LOCAL4;
- break;
- case '5':
- facility = LOG_LOCAL5;
- break;
- case '6':
- facility = LOG_LOCAL6;
- break;
- case '7':
- facility = LOG_LOCAL7;
- break;
- }
- }
- return facility;
-}
/*
* Translate binary form of backend flag to string.
@@ -5379,40 +2267,4 @@ char *pool_flag_to_str(unsigned short flag)
return buf;
}
-/*
- * Check DB node spec. node spec should be either "primary", "standby" or
- * numeric DB node id.
-*/
-bool check_redirect_node_spec(char *node_spec)
-{
- int len = strlen(node_spec);
- int i;
- long val;
-
- if (len <= 0)
- return false;
-
- if (strcasecmp("primary", node_spec) == 0)
- {
- return true;
- }
-
- if (strcasecmp("standby", node_spec) == 0)
- {
- return true;
- }
-
- for (i=0;i<len;i++)
- {
- if (!isdigit((int)node_spec[i]))
- return false;
- }
-
- val = atol(node_spec);
-
- if (val >=0 && val < MAX_NUM_BACKENDS)
- return true;
-
- return false;
-}
diff --git a/src/config/pool_config.l b/src/config/pool_config.l
index 2152530dd..20b6be258 100644
--- a/src/config/pool_config.l
+++ b/src/config/pool_config.l
@@ -30,6 +30,7 @@
#include <ctype.h>
#include "pool.h"
#include "pool_config.h"
+#include "pool_config_variables.h"
#include "utils/regex_array.h"
#ifndef POOL_PRIVATE
#include "utils/elog.h"
@@ -37,15 +38,13 @@
#include "utils/fe_ports.h"
#endif
-#define CHECK_CONTEXT(mask, context) ((mask) & (context))
/* to shut off compiler warnings */
int yylex(void);
-POOL_CONFIG *pool_config; /* configuration values */
+POOL_CONFIG g_pool_config; /* configuration values */
+POOL_CONFIG *pool_config = &g_pool_config; /* for lagacy reason pointer to the above struct */
static unsigned Lineno;
-static char *default_reset_query_list[] = {"ABORT", "DISCARD ALL"};
-static char *default_black_function_list[] = {"nextval", "setval"};
typedef enum {
POOL_KEY = 1,
@@ -59,9 +58,9 @@ typedef enum {
} POOL_TOKEN;
static char *extract_string(char *value, POOL_TOKEN token);
-static char **extract_string_tokens(char *str, char *delim, int *n);
-static void clear_host_entry(int slot);
-static bool check_redirect_node_spec(char *node_spec);
+static void FreeConfigVariable(ConfigVariable *item);
+static bool ParseConfigFile( const char *config_file, int elevel,
+ ConfigVariable **head_p, ConfigVariable **tail_p);
%}
@@ -106,205 +105,18 @@ STRING \'([^'\n]|\\.)*\'
int pool_init_config(void)
{
- int res;
- static char localhostname[256];
- int i;
-
- pool_config = palloc(sizeof(POOL_CONFIG));
-
memset(pool_config, 0, sizeof(POOL_CONFIG));
#ifndef POOL_PRIVATE
- pool_config->backend_desc = pool_shared_memory_create(sizeof(BackendDesc));
+g_pool_config.backend_desc = palloc0(sizeof(BackendDesc));
+// g_pool_config.backend_desc = pool_shared_memory_create(sizeof(BackendDesc));
+// memset(g_pool_config.backend_desc, 0, sizeof(BackendDesc));
+
#else
- pool_config->backend_desc = palloc(sizeof(BackendDesc));
+ g_pool_config.backend_desc = palloc0(sizeof(BackendDesc));
#endif
+ InitializeConfigOptions();
- /*
- * add for watchdog
- */
- memset(&pool_config->wd_remote_nodes,0x00,sizeof(WdRemoteNodesConfig));
-
- /* set hardcoded default values */
- pool_config->listen_addresses = "localhost";
- pool_config->pcp_listen_addresses = "*";
- pool_config->port = 9999;
- pool_config->pcp_port = 9898;
- pool_config->socket_dir = DEFAULT_SOCKET_DIR;
- pool_config->wd_ipc_socket_dir = DEFAULT_WD_IPC_SOCKET_DIR;
- pool_config->pcp_socket_dir = DEFAULT_SOCKET_DIR;
- pool_config->num_init_children = 32;
- pool_config->listen_backlog_multiplier = 2;
- pool_config->serialize_accept = 0;
- pool_config->max_pool = 4;
- pool_config->child_life_time = 300;
- pool_config->client_idle_limit = 0;
- pool_config->connection_life_time = 0;
- pool_config->child_max_connections = 0;
- pool_config->authentication_timeout = 60;
- pool_config->logdir = DEFAULT_LOGDIR;
- pool_config->logsyslog = 0;
- pool_config->log_destination = "stderr";
- pool_config->syslog_facility = LOG_LOCAL0;
- pool_config->syslog_ident = "pgpool";
- pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
- pool_config->log_statement = 0;
- pool_config->log_per_node_statement = 0;
- pool_config->log_connections = 0;
- pool_config->log_hostname = 0;
- pool_config->enable_pool_hba = 0;
- pool_config->pool_passwd = "pool_passwd";
-
- pool_config->replication_mode = 0;
- pool_config->load_balance_mode = 0;
- pool_config->replication_stop_on_mismatch = 0;
- pool_config->failover_if_affected_tuples_mismatch = 0;
- pool_config->replicate_select = 0;
- pool_config->reset_query_list = default_reset_query_list;
- pool_config->num_reset_queries = sizeof(default_reset_query_list)/sizeof(char *);
- pool_config->white_function_list = NULL;
- pool_config->num_white_function_list = 0;
- pool_config->black_function_list = default_black_function_list;
- pool_config->num_black_function_list = sizeof(default_black_function_list)/sizeof(char *);
- pool_config->log_line_prefix = "%t: pid %p: ";
- pool_config->log_error_verbosity = 1; /* PGERROR_DEFAULT */
- pool_config->client_min_messages = 18; /* NOTICE */
- pool_config->log_min_messages = 19; /* WARNING */
- pool_config->master_slave_mode = 0;
- pool_config->master_slave_sub_mode = "slony";
- pool_config->delay_threshold = 0;
- pool_config->log_standby_delay = "none";
- pool_config->connection_cache = 1;
- pool_config->health_check_timeout = 20;
- pool_config->health_check_period = 0;
- pool_config->health_check_user = "nobody";
- pool_config->health_check_password = "";
- pool_config->health_check_database = "";
- pool_config->health_check_max_retries = 0;
- pool_config->health_check_retry_delay = 1;
- pool_config->connect_timeout = 10000;
- pool_config->sr_check_period = 0;
- pool_config->sr_check_user = "nobody";
- pool_config->sr_check_password = "";
- pool_config->sr_check_database = "postgres";
- pool_config->failover_command = "";
- pool_config->follow_master_command = "";
- pool_config->failback_command = "";
- pool_config->fail_over_on_backend_error = 1;
- pool_config->insert_lock = 1;
- pool_config->ignore_leading_white_space = 1;
- pool_config->backend_desc->num_backends = 0;
- pool_config->recovery_user = "";
- pool_config->recovery_password = "";
- pool_config->recovery_1st_stage_command = "";
- pool_config->recovery_2nd_stage_command = "";
- pool_config->recovery_timeout = 90;
- pool_config->search_primary_node_timeout = 10;
- pool_config->client_idle_limit_in_recovery = 0;
- pool_config->lobj_lock_table = "";
- pool_config->ssl = 0;
- pool_config->ssl_cert = "";
- pool_config->ssl_key = "";
- pool_config->ssl_ca_cert = "";
- pool_config->ssl_ca_cert_dir = "";
- pool_config->debug_level = 0;
- pool_config->relcache_expire = 0;
- pool_config->relcache_size = 256;
- pool_config->check_temp_table = 1;
- pool_config->check_unlogged_table = 1;
- pool_config->lists_patterns = NULL;
- pool_config->pattc = 0;
- pool_config->current_pattern_size = 0;
-
- /*
- * database_redirect_preference_list
- */
- pool_config->database_redirect_preference_list = NULL;
- pool_config->redirect_dbnames = NULL;
- pool_config->db_redirect_tokens = NULL;
-
- /*
- * app_name_redirect_preference_list
- */
- pool_config->app_name_redirect_preference_list = NULL;
- pool_config->redirect_app_names = NULL;
- pool_config->app_name_redirect_tokens = NULL;
-
- pool_config->allow_sql_comments = 0;
-
- /*
- * add for watchdog
- */
- pool_config->use_watchdog = 0;
- pool_config->wd_lifecheck_method = MODE_HEARTBEAT;
- pool_config->clear_memqcache_on_escalation = 1;
- pool_config->wd_escalation_command = "";
- pool_config->wd_de_escalation_command = "";
- pool_config->trusted_servers = "";
- pool_config->delegate_IP = "";
- res = gethostname(localhostname,sizeof(localhostname));
- if(res !=0 )
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failed to get the local hostname")));
- }
- pool_config->wd_hostname = localhostname;
- pool_config->wd_port = 9000;
- pool_config->wd_priority = 1;
- pool_config->wd_remote_nodes.num_wd = 0;
- pool_config->wd_interval = 10;
- pool_config->wd_authkey = "";
- pool_config->ping_path = "/bin";
- pool_config->if_cmd_path = "/sbin";
- pool_config->if_up_cmd = "ip addr add $_IP_$/24 dev eth0 label eth0:0";
- pool_config->if_down_cmd = "ip addr del $_IP_$/24 dev eth0";
- pool_config->arping_path = "/usr/sbin";
- pool_config->arping_cmd = "arping -U $_IP_$ -w 1";
- pool_config->wd_life_point = 3;
- pool_config->wd_lifecheck_query = "SELECT 1";
- pool_config->wd_lifecheck_dbname = "template1";
- pool_config->wd_lifecheck_user = "nobody";
- pool_config->wd_lifecheck_password = "";
- pool_config->wd_heartbeat_port = 9694;
- pool_config->wd_heartbeat_keepalive = 2;
- pool_config->wd_heartbeat_deadtime = 30;
- pool_config->num_hb_if = 0;
- pool_config->wd_monitoring_interfaces_list = NULL;
- pool_config->num_wd_monitoring_interfaces_list = 0;
-
- pool_config->memory_cache_enabled = 0;
- pool_config->memqcache_method = "shmem";
- pool_config->memqcache_memcached_host = "localhost";
- pool_config->memqcache_memcached_port = 11211;
- pool_config->memqcache_total_size = (int64)67108864;
- pool_config->memqcache_max_num_cache = 1000000;
- pool_config->memqcache_expire = 0;
- pool_config->memqcache_auto_cache_invalidation = 1;
- pool_config->memqcache_maxcache = 409600;
- pool_config->memqcache_cache_block_size = 1048576;
- pool_config->memqcache_oiddir = "/var/log/pgpool/oiddir";
- pool_config->white_memqcache_table_list = NULL;
- pool_config->num_white_memqcache_table_list = 0;
- pool_config->black_memqcache_table_list = NULL;
- pool_config->num_black_memqcache_table_list = 0;
- pool_config->lists_memqcache_table_patterns = NULL;
- pool_config->memqcache_table_pattc = 0;
- pool_config->current_memqcache_table_pattern_size = 0;
-
- res = gethostname(localhostname,sizeof(localhostname));
- if(res !=0 )
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failed to get the local hostname")));
-
- }
-
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- clear_host_entry(i);
- }
return 0;
}
@@ -313,7 +125,7 @@ int pool_init_config(void)
* The supported type are: black_function_list and white_function_list
* Return 0 on error, 1 on success
*/
-int add_regex_pattern(char *type, char *s)
+int add_regex_pattern(const char *type, char *s)
{
int regex_flags = REG_NOSUB;
RegPattern currItem;
@@ -433,38 +245,74 @@ int growMemqcacheTablePatternArray(RegPattern item)
return(pool_config->memqcache_table_pattc);
}
-int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
+/*
+ * Free a single ConfigVariable
+ */
+static void
+FreeConfigVariable(ConfigVariable *item)
+{
+ if (item->name)
+ pfree(item->name);
+ if (item->value)
+ pfree(item->value);
+ pfree(item);
+}
+
+/*
+ * Free a list of ConfigVariables, including the names and the values
+ */
+static void
+FreeConfigVariables(ConfigVariable *list)
+{
+ ConfigVariable *item;
+
+ item = list;
+ while (item)
+ {
+ ConfigVariable *next = item->next;
+ FreeConfigVariable(item);
+ item = next;
+ }
+}
+
+/*
+ * Read and parse a single configuration file.
+ *
+ * Input parameters:
+ * config_file: absolute or relative path name of the configuration file
+ * elevel: error logging level to use
+ * Input/Output parameters:
+ * head_p, tail_p: head and tail of linked list of name/value pairs
+ *
+ * *head_p and *tail_p must be initialized, either to NULL or valid pointers
+ * to a ConfigVariable list, before calling the outer recursion level. Any
+ * name-value pairs read from the input file(s) will be appended to the list.
+ *
+ * Note: if elevel >= ERROR then an error will not return control to the
+ * caller, so there is no need to check the return value in that case.
+ *
+ */
+static bool
+ParseConfigFile(const char *config_file, int elevel,
+ ConfigVariable **head_p, ConfigVariable **tail_p)
{
+
FILE *fd;
int token;
- char key[1024];
- double total_weight;
- int i;
- int error_level;
- bool log_destination_changed = false;
- sig_atomic_t local_num_backends;
-#ifdef USE_MEMCACHED
- bool use_memcached = true;
-#else
- bool use_memcached = false;
-#endif
- if(CHECK_CONTEXT(INIT_CONFIG, context))
- error_level = ERROR;
- else
- error_level = WARNING;
-
-#define PARSE_ERROR() ereport(CHECK_CONTEXT(INIT_CONFIG, context)?ERROR:WARNING, \
- (errmsg("syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME), \
- errdetail("parse error at line %d '%s'", Lineno, yytext)))
+ char *key;
+ char *val;
+ ConfigVariable *item;
+
+ *head_p = NULL;
/* open config file */
- fd = fopen(confpath, "r");
+ fd = fopen(config_file, "r");
if (!fd)
{
- ereport(WARNING,
- (errmsg("could not open configuration file: \"%s\"\n",POOL_CONF_FILE_NAME),
+ ereport(elevel,
+ (errmsg("could not open configuration file: \"%s\"\n",config_file),
errdetail("using default configuration parameter values")));
- return 0;
+ return false;
}
yyin = fd;
@@ -473,3179 +321,218 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
for(;;)
{
token = yylex();
+
if (token == 0)
- {
break;
- }
- if (token == POOL_PARSE_ERROR)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
+
if (token == POOL_EOL)
continue;
+ if (token == POOL_PARSE_ERROR)
+ goto parse_error;
+
if (token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
+ goto parse_error;
- strlcpy(key, yytext, sizeof(key));
+ key = pstrdup(yytext);
- ereport(DEBUG5,
- (errmsg("key: %s", key)));
token = yylex();
+ /* next we have an optional equal sign; discard if present */
if (token == POOL_EQUALS)
token = yylex();
+ val = extract_string(yytext,token);
+
ereport(DEBUG5,
- (errmsg("value: %s kind: %d", yytext, token)));
- if (!strcmp(key, "allow_inet_domain_socket") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- /* for backward compatibility */
- int v = eval_logical(yytext);
+ (errmsg("key: \"%s\" value: \"%s\" kind: %d",key, val, token)));
+
+ /* Add this to the list */
+ item = palloc(sizeof(ConfigVariable));
+ item->name = key;
+ item->value = val;
+ item->sourceline = Lineno;
+ item->next = NULL;
+ if (*head_p == NULL)
+ *head_p = item;
+ else
+ (*tail_p)->next = item;
+ *tail_p = item;
+ }
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
-
- return(-1);
- }
- if (v)
- pool_config->listen_addresses = pstrdup("*");
- else
- pool_config->listen_addresses = pstrdup("");
- }
- else if (!strcmp(key, "listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ fclose(fd);
+ return true;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->listen_addresses = str;
- }
+parse_error:
- else if (!strcmp(key, "port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
+ fclose(fd);
+ FreeConfigVariables(*head_p);
+ *head_p = NULL;
+ *tail_p = NULL;
+ ereport(elevel,
+ (errmsg("syntex error in configuration file \"%s\"",config_file),
+ errdetail("parse error at line %d '%s' token = %d", Lineno, yytext,token)));
- if (token != POOL_INTEGER || v < 1024)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1024",yytext,key, key)));
+ return false;
+}
- return(-1);
- }
- pool_config->port = v;
- }
+/*
+ * Read the configuration file and load the values of all parameters
+ */
+bool pool_get_config(const char *config_file, ConfigContext context)
+{
+ ConfigVariable *head_p = NULL;
+ ConfigVariable *tail_p = NULL;
+ bool res;
+ int elevel = (context == CFGCXT_INIT)?FATAL:WARNING;
- else if (!strcmp(key, "pcp_listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ res = ParseConfigFile(config_file, elevel, &head_p, &tail_p);
+ if (res == false || head_p == NULL)
+ return false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pcp_listen_addresses = str;
- }
+ res = set_config_options(head_p, context, PGC_S_FILE, elevel);
+ FreeConfigVariables(head_p);
+ return res;
+}
- else if (!strcmp(key, "pcp_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
- if (token != POOL_INTEGER || v < 1024)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1024",yytext,key, key)));
- return(-1);
- }
- pool_config->pcp_port = v;
- }
- else if (!strcmp(key, "socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+static char *extract_string(char *value, POOL_TOKEN token)
+{
+ char *ret = NULL;
+
+ if (token == POOL_STRING)
+ {
+ ret = pstrdup(value+1);
+ ret[strlen(ret)-1] = '\0';
+ }
+ else
+ ret = pstrdup(value);
+
+ return ret;
+}
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+/*
+ * Try to interpret value as boolean value. Valid values are: true,
+ * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
+ * If the string parses okay, return true, else false.
+ * If okay and result is not NULL, return the value in *result.
+ * This function copied from PostgreSQL source code.
+ */
+static bool parse_bool_with_len(const char *value, size_t len, bool *result)
+{
+ switch (*value)
+ {
+ case 't':
+ case 'T':
+ if (strncasecmp(value, "true", len) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ break;
+ case 'f':
+ case 'F':
+ if (strncasecmp(value, "false", len) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->socket_dir = str;
- }
- else if (!strcmp(key, "socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ break;
+ case 'y':
+ case 'Y':
+ if (strncasecmp(value, "yes", len) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ break;
+ case 'n':
+ case 'N':
+ if (strncasecmp(value, "no", len) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->socket_dir = str;
- }
- else if (!strcmp(key, "wd_ipc_socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ break;
+ case 'o':
+ case 'O':
+ /* 'o' is not unique enough */
+ if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->wd_ipc_socket_dir = str;
- }
- else if (!strcmp(key, "num_init_children") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
+ break;
+ case '1':
+ if (len == 1)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- pool_config->num_init_children = v;
- }
- else if (!strcmp(key, "listen_backlog_multiplier") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
+ break;
+ case '0':
+ if (len == 1)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->listen_backlog_multiplier = v;
- }
- else if (!strcmp(key, "serialize_accept") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
+ break;
+ default:
+ break;
+ }
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->serialize_accept = v;
- }
- else if (!strcmp(key, "child_life_time") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ if (result)
+ *result = false; /* suppress compiler warning */
+ return false;
+}
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->child_life_time = v;
- }
- else if (!strcmp(key, "client_idle_limit") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+int eval_logical(const char *str)
+{
+ bool result;
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->client_idle_limit = v;
- }
- else if (!strcmp(key, "connection_life_time") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ if (!parse_bool_with_len(str, strlen(str), &result))
+ return -1;
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->connection_life_time = v;
- }
- else if (!strcmp(key, "child_max_connections") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ return (result ? 1 : 0);
+}
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->child_max_connections = v;
- }
- else if (!strcmp(key, "authentication_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->authentication_timeout = v;
- }
- else if (!strcmp(key, "max_pool") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
+#ifdef DEBUG
+static void print_host_entry(int slot)
+{
+ ereport(DEBUG1,
+ (errmsg("initializing pool configuration"),
+ errdetail("slot: %d host: %s port: %d status: %d weight: %f",
+ slot,
+ pool_config->server_hostnames[slot],
+ pool_config->server_ports[slot],
+ pool_config->server_status[slot],
+ pool_config->server_weights[slot])));
+}
+#endif
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->max_pool = v;
- }
- else if (!strcmp(key, "logdir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->logdir = str;
- }
- else if (!strcmp(key, "log_destination") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- log_destination_changed = pool_config->log_destination != str;
- pool_config->log_destination = str;
- }
- else if (!strcmp(key, "syslog_facility") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->syslog_facility = set_syslog_facility(str);
- }
- else if (!strcmp(key, "syslog_ident") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- log_destination_changed = log_destination_changed || pool_config->syslog_ident != str;
- pool_config->syslog_ident = str;
- }
- else if (!strcmp(key, "pid_file_name") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pid_file_name = str;
- }
- else if (!strcmp(key, "log_connections") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->log_connections = v;
- }
- else if (!strcmp(key, "log_hostname") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->log_hostname = v;
- }
- else if (!strcmp(key, "enable_pool_hba") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->enable_pool_hba = v;
- }
- else if (!strcmp(key, "pool_passwd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pool_passwd = str;
- }
-
- else if (!strcmp(key, "replication_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->replication_mode = v;
-
- if (pool_config->master_slave_mode && pool_config->replication_mode)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("replication_mode and master_slave_mode cannot be enabled at the same time")));
- return(-1);
- }
-
- }
- else if (!strcmp(key, "load_balance_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->load_balance_mode = v;
- }
- else if (!strcmp(key, "replication_stop_on_mismatch") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("replication_stop_on_mismatch: %d", v)));
-
- pool_config->replication_stop_on_mismatch = v;
- }
- else if (!strcmp(key, "failover_if_affected_tuples_mismatch") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failover_if_affected_tuples_mismatch: %d", v)));
-
- pool_config->failover_if_affected_tuples_mismatch = v;
- }
- else if (!strcmp(key, "replicate_select") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("replicate_select: %d", v)));
-
- pool_config->replicate_select = v;
- }
- else if (!strcmp(key, "reset_query_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->reset_query_list = extract_string_tokens(str, ";", &pool_config->num_reset_queries);
- if (pool_config->reset_query_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- }
-
- else if (!strcmp(key, "white_function_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->white_function_list =
- extract_string_tokens(str, ",", &pool_config->num_white_function_list);
-
- if (pool_config->white_function_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_white_function_list;i++)
- {
- add_regex_pattern("white_function_list", pool_config->white_function_list[i]);
- }
- }
-
- else if (!strcmp(key, "black_function_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->black_function_list =
- extract_string_tokens(str, ",", &pool_config->num_black_function_list);
-
- if (pool_config->black_function_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_black_function_list;i++)
- {
- add_regex_pattern("black_function_list", pool_config->black_function_list[i]);
- }
- }
- else if (!strcmp(key, "log_error_verbosity") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"terse","default","verbose",NULL};
- bool found = false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->log_error_verbosity = i;
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
-
- else if (!strcmp(key, "client_min_messages") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error",NULL};
- bool found = false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
-
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->client_min_messages = i + 10;
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
- else if (!strcmp(key, "log_min_messages") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error","fatal","panic",NULL};
- bool found = false;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
-
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->log_min_messages = i + 10; /* error codes start with 10 */
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
- else if (!strcmp(key, "log_line_prefix") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->log_line_prefix = str;
- }
- else if (!strcmp(key, "print_timestamp") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- ereport(NOTICE,
- (errmsg("configuration key \"%s\" is not supported anymore",key),
- errdetail("please use \"log_line_prefix\" instead")));
- }
- else if (!strcmp(key, "print_user") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- ereport(NOTICE,
- (errmsg("configuration key \"%s\" is not supported anymore",key),
- errdetail("please use \"log_line_prefix\" instead")));
- }
-
- else if (!strcmp(key, "master_slave_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->master_slave_mode = v;
-
- if (pool_config->master_slave_mode && pool_config->replication_mode)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("replication_mode and master_slave_mode cannot be enabled at the same time")));
- return(-1);
- }
- }
-
- else if (!strcmp(key, "master_slave_sub_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, MODE_SLONY) && strcmp(str, MODE_STREAMREP))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"slony\" or \"stream\"", key)));
- return(-1);
- }
- pool_config->master_slave_sub_mode = str;
- }
-
- else if (!strcmp(key, "delay_threshold") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- long long int v = atol(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->delay_threshold = v;
- }
-
- else if (!strcmp(key, "log_standby_delay") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, "always") && strcmp(str, "if_over_threshold") && strcmp(str, "none"))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("allowed values are: \"always\", \"if_over_threshold\" and \"none\"")));
-
- return(-1);
- }
- pool_config->log_standby_delay = str;
- }
-
- else if (!strcmp(key, "connection_cache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->connection_cache = v;
- }
-
- else if (!strcmp(key, "health_check_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->health_check_timeout = v;
- }
-
- else if (!strcmp(key, "health_check_period") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->health_check_period = v;
- }
-
- else if (!strcmp(key, "health_check_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_user = str;
- }
-
- else if (!strcmp(key, "health_check_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_password = str;
- }
-
- else if (!strcmp(key, "health_check_database") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_database = str;
- }
-
-
- else if (!strcmp(key, "health_check_max_retries") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->health_check_max_retries = v;
- }
-
- else if (!strcmp(key, "health_check_retry_delay") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->health_check_retry_delay = v;
- }
-
- else if (!strcmp(key, "connect_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->connect_timeout = v;
- }
-
- else if (!strcmp(key, "sr_check_period") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->sr_check_period = v;
- }
-
- else if (!strcmp(key, "sr_check_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_user = str;
- }
-
- else if (!strcmp(key, "sr_check_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_password = str;
- }
-
- else if (!strcmp(key, "sr_check_database") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_database = str;
- }
-
- else if (!strcmp(key, "failover_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->failover_command = str;
- }
-
- else if (!strcmp(key, "follow_master_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->follow_master_command = str;
- }
-
- else if (!strcmp(key, "failback_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->failback_command = str;
- }
-
- else if (!strcmp(key, "fail_over_on_backend_error") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->fail_over_on_backend_error = v;
- }
-
- else if (!strcmp(key, "recovery_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_user = str;
- }
-
- else if (!strcmp(key, "recovery_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_password = str;
- }
-
- else if (!strcmp(key, "recovery_1st_stage_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_1st_stage_command = str;
- }
-
- else if (!strcmp(key, "recovery_2nd_stage_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_2nd_stage_command = str;
- }
-
- else if (!strcmp(key, "recovery_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->recovery_timeout = v;
- }
-
- else if (!strcmp(key, "search_primary_node_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->search_primary_node_timeout = v;
- }
-
- else if (!strcmp(key, "client_idle_limit_in_recovery") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < -1)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->client_idle_limit_in_recovery = v;
- }
-
- else if (!strcmp(key, "insert_lock") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->insert_lock = v;
- }
-
- else if (!strcmp(key, "ignore_leading_white_space") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->ignore_leading_white_space = v;
- }
-
- else if (!strncmp(key, "backend_hostname", 16) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 16);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend number must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG ||
- (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED))
- strlcpy(BACKEND_INFO(slot).backend_hostname, str, MAX_DB_HOST_NAMELEN);
-
- }
-
- else if (!strncmp(key, "backend_port", 12) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 12);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend port slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend port slot number %d port: %d ", slot,atoi(yytext))));
- if (context == INIT_CONFIG)
- {
- BACKEND_INFO(slot).backend_port = atoi(yytext);
- BACKEND_INFO(slot).backend_status = CON_CONNECT_WAIT;
- }
- else if (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED)
- {
- BACKEND_INFO(slot).backend_port = atoi(yytext);
- BACKEND_INFO(slot).backend_status = CON_DOWN;
- }
- }
-
- else if (!strncmp(key, "backend_weight", 14) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- double v;
-
- slot = atoi(key + 14);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend weight slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- v = atof(yytext);
-
- if (v < 0.0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0.0")));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("weight slot number %d weight: %f", slot, v)));
-
- if (context == INIT_CONFIG || context == RELOAD_CONFIG)
- {
- double old_v = BACKEND_INFO(slot).unnormalized_weight;
- BACKEND_INFO(slot).unnormalized_weight = v;
-
- /*
- * Log weight change event only when context is
- * reloading of pgpool.conf and weight is actually
- * changed
- */
- if (context == RELOAD_CONFIG && old_v != v)
- {
- ereport(LOG,
- (errmsg("initializing pool configuration: backend weight for backend:%d changed from %f to %f", slot, old_v, v),
- errdetail("This change will be effective from next client session")));
- }
- }
- }
- else if (!strncmp(key, "backend_data_directory", 22) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
- BACKEND_STATUS status;
-
- slot = atoi(key + 22);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend data directory slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- status = BACKEND_INFO(slot).backend_status;
- if (context == INIT_CONFIG ||
- (context == RELOAD_CONFIG && (status == CON_UNUSED || status == CON_DOWN)))
- strlcpy(BACKEND_INFO(slot).backend_data_directory, str, MAX_PATH_LENGTH);
- }
- else if (!strncmp(key, "backend_flag", 12) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- char *str;
- char **flags;
- int n;
- int i;
- int slot;
- unsigned short flag = 0;
- bool allow_to_failover_is_specified = 0;
- bool disallow_to_failover_is_specified = 0;
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("extract_string failed: %s", yytext)));
- return(-1);
- }
-
- flags = extract_string_tokens(str, "|", &n);
- if (!flags || n < 0)
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("unable to get backend flags")));
-
- fclose(fd);
- return(-1);
- }
-
- for (i=0;i<n;i++)
- {
- if (!strcmp(flags[i], "ALLOW_TO_FAILOVER"))
- {
- if (disallow_to_failover_is_specified)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
-
- return(-1);
- }
- flag &= ~POOL_FAILOVER;
- allow_to_failover_is_specified = true;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("allow_to_failover: ON")));
-
- }
-
- else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER"))
- {
- if (allow_to_failover_is_specified)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
- return(-1);
- }
- flag |= POOL_FAILOVER;
- disallow_to_failover_is_specified = true;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("disallow_to_failover: ON")));
-
- }
-
- else
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("unknown backend flag:%s", flags[i])));
- return (-1);
- }
- }
-
- slot = atoi(key + 12);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- BACKEND_INFO(slot).flag = flag;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend slot number %d flag: %04x", slot, flag)));
-
- }
-
- else if (!strcmp(key, "log_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->log_statement = v;
- }
- else if (!strcmp(key, "log_per_node_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->log_per_node_statement = v;
- }
-
- else if (!strcmp(key, "lobj_lock_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->lobj_lock_table = str;
- }
- /*
- * add for watchdog
- */
- else if (!strncmp(key, "other_pgpool_hostname", 21) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 21) ;
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_INFO(slot).hostname, str, WD_MAX_HOST_NAMELEN);
- }
-
- else if (!strncmp(key, "other_pgpool_port", 17) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 17);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- WD_INFO(slot).pgpool_port = atoi(yytext);
- }
-
- else if (!strncmp(key, "other_wd_port", 13) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 13);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- {
- WD_INFO(slot).wd_port = atoi(yytext);
- pool_config->wd_remote_nodes.num_wd = slot + 1;
- }
- }
- else if (!strcmp(key, "use_watchdog") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->use_watchdog = v;
- }
-
- else if (!strcmp(key, "clear_memqcache_on_escalation") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->clear_memqcache_on_escalation = v;
- }
-
- else if (!strcmp(key, "wd_escalation_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_escalation_command = str;
- }
-
- else if (!strcmp(key, "wd_de_escalation_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_de_escalation_command = str;
- }
-
-
- else if (!strcmp(key, "trusted_servers") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->trusted_servers = str;
- }
- else if (!strcmp(key, "delegate_IP") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->delegate_IP = str;
- }
- else if (!strcmp(key, "wd_hostname") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->wd_hostname = str;
- }
- else if (!strcmp(key, "wd_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_port = v;
- }
- else if (!strcmp(key, "wd_priority") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_priority = v;
- }
- else if (!strcmp(key, "wd_interval") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_interval = v;
- }
- else if (!strcmp(key, "ping_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->ping_path = str;
- }
- else if (!strcmp(key, "if_cmd_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_cmd_path = str;
- }
- else if (!strcmp(key, "if_up_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_up_cmd = str;
- }
- else if (!strcmp(key, "if_down_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_down_cmd = str;
- }
- else if (!strcmp(key, "arping_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->arping_path = str;
- }
- else if (!strcmp(key, "arping_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->arping_cmd = str;
- }
- else if (!strcmp(key, "wd_life_point") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_life_point = v;
- }
- else if (!strcmp(key, "wd_lifecheck_query") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->wd_lifecheck_query = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_dbname") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_dbname = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_user = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_password = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_method") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, MODE_HEARTBEAT) && strcmp(str, MODE_QUERY) && strcmp(str, MODE_EXTERNAL))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"heartbeat\" or \"query\"", key)));
- return(-1);
- }
- pool_config->wd_lifecheck_method = str;
- }
- else if (!strcmp(key, "wd_heartbeat_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_port = v;
- }
- else if (!strcmp(key, "wd_heartbeat_keepalive") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_keepalive = v;
- }
- else if (!strcmp(key, "wd_heartbeat_deadtime") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_deadtime = v;
- }
- else if (!strcmp(key, "wd_authkey") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_authkey = str;
- }
-
- else if (!strncmp(key, "heartbeat_device", 16) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 16) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_HB_IF(slot).if_name, str, WD_MAX_IF_NAME_LEN);
- }
- /* this must be prior to hertbeat_destination */
- else if (!strncmp(key, "heartbeat_destination_port", 26) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 26) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- {
- WD_HB_IF(slot).dest_port = atoi(yytext);
- pool_config->num_hb_if = slot + 1;
- }
- }
- else if (!strncmp(key, "heartbeat_destination", 21) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 21) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_HB_IF(slot).addr, str, WD_MAX_HOST_NAMELEN);
- }
-
- else if (!strcmp(key, "wd_monitoring_interfaces_list") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_monitoring_interfaces_list = extract_string_tokens(str, ",", &pool_config->num_wd_monitoring_interfaces_list);
- if (pool_config->wd_monitoring_interfaces_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- }
-
- else if (!strcmp(key, "ssl") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
-
- return(-1);
- }
- pool_config->ssl = v;
- }
- else if (!strcmp(key, "ssl_cert") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_cert = str;
- }
- else if (!strcmp(key, "ssl_key") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_key = str;
- }
- else if (!strcmp(key, "ssl_ca_cert") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_ca_cert = str;
- }
- else if (!strcmp(key, "ssl_ca_cert_dir") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_ca_cert_dir = str;
- }
-
- else if (!strcmp(key, "debug_level") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- /* Consider -d option value stored in pool_config already */
- pool_config->debug_level |= v;
- }
-
- else if (!strcmp(key, "relcache_expire") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->relcache_expire = v;
- }
-
- else if (!strcmp(key, "relcache_size") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 1")));
- return(-1);
- }
- pool_config->relcache_size = v;
- }
-
- else if (!strcmp(key, "check_temp_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->check_temp_table = v;
- }
-
- else if (!strcmp(key, "check_unlogged_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->check_unlogged_table = v;
- }
-
- else if (!strcmp(key, "memory_cache_enabled") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->memory_cache_enabled = v;
- }
- else if (!strcmp(key, "memqcache_method") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (!strcmp(str, "memcached") && !use_memcached)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration, Feature Not available"),
- errdetail("invalid value:\"%s\" for key:\"%s\", memcached not available because pgpool-II is not built with MEMCACHED support", yytext,key)));
- return -1;
- }
-
- if (strcmp(str, "memcached") && strcmp(str, "shmem"))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"shmem\" or \"memcached\"", str)));
-
- return -1;
- }
-
- pool_config->memqcache_method = str;
- }
- else if (!strcmp(key, "memqcache_memcached_host") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->memqcache_memcached_host = str;
- }
- else if (!strcmp(key, "memqcache_memcached_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->memqcache_memcached_port = v;
- }
- else if (!strcmp(key, "memqcache_total_size") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int64 v = atoll(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->memqcache_total_size = v;
- }
- else if (!strcmp(key, "memqcache_max_num_cache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_max_num_cache = v;
- }
- else if (!strcmp(key, "memqcache_expire") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_expire = v;
- }
- else if (!strcmp(key, "memqcache_auto_cache_invalidation") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->memqcache_auto_cache_invalidation = v;
- }
- else if (!strcmp(key, "memqcache_maxcache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_maxcache = v;
- }
- else if (!strcmp(key, "memqcache_cache_block_size") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 512)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 512")));
- return(-1);
- }
- pool_config->memqcache_cache_block_size = v;
- }
- else if (!strcmp(key, "memqcache_oiddir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->memqcache_oiddir = str;
- }
- else if (!strcmp(key, "white_memqcache_table_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->white_memqcache_table_list =
- extract_string_tokens(str, ",", &pool_config->num_white_memqcache_table_list);
-
- if (pool_config->white_memqcache_table_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_white_memqcache_table_list;i++)
- {
- add_regex_pattern("white_memqcache_table_list", pool_config->white_memqcache_table_list[i]);
- }
- }
-
- else if (!strcmp(key, "black_memqcache_table_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->black_memqcache_table_list =
- extract_string_tokens(str, ",", &pool_config->num_black_memqcache_table_list);
-
- if (pool_config->black_memqcache_table_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_black_memqcache_table_list;i++)
- {
- add_regex_pattern("black_memqcache_table_list", pool_config->black_memqcache_table_list[i]);
- }
- }
-
- else if (!strcmp(key, "database_redirect_preference_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
- int i;
- Left_right_tokens *lrtokens;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- pool_config->database_redirect_preference_list = str;
- lrtokens = create_lrtoken_array();
- extract_string_tokens2(str, ",", ':', lrtokens);
-
- pool_config->redirect_dbnames = create_regex_array();
- pool_config->db_redirect_tokens = lrtokens;
-
- for (i=0;i<lrtokens->pos;i++)
- {
- if (!check_redirect_node_spec(lrtokens->token[i].right_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
- return(-1);
- }
-
- if (*(lrtokens->token[i].left_token) == '\0' ||
- add_regex_array(pool_config->redirect_dbnames, lrtokens->token[i].left_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect dbname regular expression: \"%s\"", lrtokens->token[i].left_token)));
- return(-1);
- }
- }
- }
-
- else if (!strcmp(key, "app_name_redirect_preference_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
- int i;
- Left_right_tokens *lrtokens;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- pool_config->app_name_redirect_preference_list = str;
- lrtokens = create_lrtoken_array();
- extract_string_tokens2(str, ",", ':', lrtokens);
-
- pool_config->redirect_app_names = create_regex_array();
- pool_config->app_name_redirect_tokens = lrtokens;
-
- for (i=0;i<lrtokens->pos;i++)
- {
- if (!check_redirect_node_spec(lrtokens->token[i].right_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
- return(-1);
- }
-
-
- if (*(lrtokens->token[i].left_token) == '\0' ||
- add_regex_array(pool_config->redirect_app_names, lrtokens->token[i].left_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect app name regular expression: \"%s\"", lrtokens->token[i].left_token)));
- return(-1);
- }
- }
- }
-
- else if (!strcmp(key, "allow_sql_comments") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->allow_sql_comments = v;
- }
-
- }
-
- fclose(fd);
-
- if (log_destination_changed)
- {
- /* log_destination has changed, we need to open syslog or close it */
- if (!strcmp(pool_config->log_destination, "stderr"))
- {
- closelog();
- pool_config->logsyslog = 0;
- }
- else
- {
- openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility);
- pool_config->logsyslog = 1;
- }
- }
-
- local_num_backends = 0;
- total_weight = 0.0;
-
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- /* port number == 0 indicates that this server is out of use */
- if (BACKEND_INFO(i).backend_port == 0)
- {
- clear_host_entry(i);
- }
-
- else
- {
- total_weight += BACKEND_INFO(i).unnormalized_weight;
- local_num_backends = i+1;
-
- /* initialize backend_hostname with a default socket path if empty */
- if (*(BACKEND_INFO(i).backend_hostname) == '\0')
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("empty backend_hostname%d, use PostgreSQL's default unix socket path (%s)",
- i, DEFAULT_SOCKET_DIR)));
- strlcpy(BACKEND_INFO(i).backend_hostname, DEFAULT_SOCKET_DIR, MAX_DB_HOST_NAMELEN);
- }
- }
- }
- if (local_num_backends != pool_config->backend_desc->num_backends)
- pool_config->backend_desc->num_backends = local_num_backends;
-
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("num_backends: %d total_weight: %f",
- pool_config->backend_desc->num_backends, total_weight)));
- /*
- * Normalize load balancing weights. What we are doing here is,
- * assign 0 to RAND_MAX to each backend's weight according to the
- * value weightN. For example, if two backends are assigned 1.0,
- * then each backend will get RAND_MAX/2 normalized weight.
- */
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
-#ifdef DEBUG
- print_host_entry(i);
-#endif
-
- if (BACKEND_INFO(i).backend_port != 0)
- {
- BACKEND_INFO(i).backend_weight =
- (RAND_MAX) * BACKEND_INFO(i).unnormalized_weight / total_weight;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend %d weight: %f flag: %04x", i, BACKEND_INFO(i).backend_weight,BACKEND_INFO(i).flag)));
- }
- }
-
- if (strcmp(pool_config->recovery_1st_stage_command, "") ||
- strcmp(pool_config->recovery_2nd_stage_command, ""))
- {
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- if (pool_config->backend_desc->backend_info[i].backend_port != 0 &&
- !strcmp(pool_config->backend_desc->backend_info[i].backend_data_directory, ""))
- {
- ereport(ERROR,
- (errmsg("invalid configuration, recovery_1st_stage_command and recovery_2nd_stage_command requires backend_data_directory to be set")));
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static char *extract_string(char *value, POOL_TOKEN token)
-{
- char *ret;
-
- ret = pstrdup(value);
-
- if (token == POOL_STRING)
- {
- ret[strlen(ret)-1] = '\0';
- return (ret+1);
- }
- return ret;
-}
-
-/*
- * Try to interpret value as boolean value. Valid values are: true,
- * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
- * If the string parses okay, return true, else false.
- * If okay and result is not NULL, return the value in *result.
- * This function copied from PostgreSQL source code.
- */
-static bool parse_bool_with_len(const char *value, size_t len, bool *result)
-{
- switch (*value)
- {
- case 't':
- case 'T':
- if (strncasecmp(value, "true", len) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case 'f':
- case 'F':
- if (strncasecmp(value, "false", len) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case 'y':
- case 'Y':
- if (strncasecmp(value, "yes", len) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case 'n':
- case 'N':
- if (strncasecmp(value, "no", len) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case 'o':
- case 'O':
- /* 'o' is not unique enough */
- if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case '1':
- if (len == 1)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case '0':
- if (len == 1)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- default:
- break;
- }
-
- if (result)
- *result = false; /* suppress compiler warning */
- return false;
-}
-
-int eval_logical(char *str)
-{
- bool result;
-
- if (!parse_bool_with_len(str, strlen(str), &result))
- return -1;
-
- return (result ? 1 : 0);
-}
-
-/*
- * Extract tokens separated by delimi from str. Return value is an
- * array of pointers in pallocd strings. number of tokens is set to
- * n; note that str will be destroyed by strtok().
- */
-#define MAXTOKENS 256
-static char **extract_string_tokens(char *str, char *delimi, int *n)
-{
- char *token;
- char **tokens;
-
- *n = 0;
-
- tokens = palloc(MAXTOKENS*sizeof(char *));
-
- for (token = strtok(str, delimi); token != NULL ; token = strtok(NULL, delimi))
- {
- tokens[*n] = pstrdup(token);
- ereport(DEBUG3,
- (errmsg("initializing pool configuration"),
- errdetail("extracting string tokens [token: %s]", tokens[*n])));
-
- (*n)++;
-
- if ( ((*n) % MAXTOKENS ) == 0)
- {
- tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n)/MAXTOKENS) +1) ));
- }
- }
- /* how about reclaiming the unused space */
- tokens = repalloc(tokens, (sizeof(char *) * (*n) ));
- return tokens;
-}
-
-static void clear_host_entry(int slot)
-{
- *pool_config->backend_desc->backend_info[slot].backend_hostname = '\0';
- pool_config->backend_desc->backend_info[slot].backend_port = 0;
- pool_config->backend_desc->backend_info[slot].backend_status = CON_UNUSED;
- pool_config->backend_desc->backend_info[slot].backend_weight = 0.0;
-}
-
-#ifdef DEBUG
-static void print_host_entry(int slot)
-{
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("slot: %d host: %s port: %d status: %d weight: %f",
- slot,
- pool_config->server_hostnames[slot],
- pool_config->server_ports[slot],
- pool_config->server_status[slot],
- pool_config->server_weights[slot])));
-}
-#endif
-
-/* Use to set the syslog facility level if logsyslog is activated */
-int set_syslog_facility(char *value)
-{
- int facility = LOG_LOCAL0;
-
- if (value == NULL)
- return facility;
-
- if (strncmp(value, "LOCAL", 5) == 0 && strlen(value) == 6) {
- switch (value[5]) {
- case '0':
- facility = LOG_LOCAL0;
- break;
- case '1':
- facility = LOG_LOCAL1;
- break;
- case '2':
- facility = LOG_LOCAL2;
- break;
- case '3':
- facility = LOG_LOCAL3;
- break;
- case '4':
- facility = LOG_LOCAL4;
- break;
- case '5':
- facility = LOG_LOCAL5;
- break;
- case '6':
- facility = LOG_LOCAL6;
- break;
- case '7':
- facility = LOG_LOCAL7;
- break;
- }
- }
- return facility;
-}
-
-/*
- * Translate binary form of backend flag to string.
- * The returned data is in static buffer, and it will be destroyed
- * at the next call to this function.
- */
-char *pool_flag_to_str(unsigned short flag)
-{
- static char buf[1024]; /* should be large enough */
+/*
+ * Translate binary form of backend flag to string.
+ * The returned data is in static buffer, and it will be destroyed
+ * at the next call to this function.
+ */
+char *pool_flag_to_str(unsigned short flag)
+{
+ static char buf[1024]; /* should be large enough */
if (POOL_ALLOW_TO_FAILOVER(flag))
snprintf(buf, sizeof(buf), "ALLOW_TO_FAILOVER");
@@ -3654,39 +541,3 @@ char *pool_flag_to_str(unsigned short flag)
return buf;
}
-/*
- * Check DB node spec. node spec should be either "primary", "standby" or
- * numeric DB node id.
-*/
-bool check_redirect_node_spec(char *node_spec)
-{
- int len = strlen(node_spec);
- int i;
- long val;
-
- if (len <= 0)
- return false;
-
- if (strcasecmp("primary", node_spec) == 0)
- {
- return true;
- }
-
- if (strcasecmp("standby", node_spec) == 0)
- {
- return true;
- }
-
- for (i=0;i<len;i++)
- {
- if (!isdigit((int)node_spec[i]))
- return false;
- }
-
- val = atol(node_spec);
-
- if (val >=0 && val < MAX_NUM_BACKENDS)
- return true;
-
- return false;
-}
diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c
new file mode 100644
index 000000000..058dbe3ea
--- /dev/null
+++ b/src/config/pool_config_variables.c
@@ -0,0 +1,3233 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "pool.h"
+#include "pool_config.h"
+#include "pool_config_variables.h"
+#include "utils/regex_array.h"
+
+#ifndef POOL_PRIVATE
+#include "utils/elog.h"
+#include "parser/stringinfo.h"
+#else
+#include "utils/fe_ports.h"
+#endif
+
+static const char *default_reset_query_list[] = {"ABORT", "DISCARD ALL"};
+static const char *default_black_function_list[] = {"nextval", "setval"};
+
+extern POOL_CONFIG g_pool_config;
+struct config_generic **all_parameters = NULL;
+static int num_all_parameters = 0;
+
+static bool BackendPortAssignFunc (ConfigContext context, int newval, int index, int elevel);
+static bool BackendHostAssignFunc (ConfigContext context, char* newval, int index, int elevel);
+static bool BackendDataDirAssignFunc (ConfigContext context, char* newval, int index, int elevel);
+static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int index, int elevel);
+static bool BackendWeightAssignFunc (ConfigContext context, double newval, int index, int elevel);
+
+static void initialize_variables_with_default(struct config_generic * gconf);
+static bool config_enum_lookup_by_name(struct config_enum * record, const char *value, int *retval);
+static char **get_list_from_string(const char *str, char *delimi, int *n);
+
+static bool MakeDBRedirectListRegex (char* newval, int error_level);
+static bool MakeAppRedirectListRegex (char* newval, int error_level);
+static bool check_redirect_node_spec(char *node_spec);
+static void build_config_variables(void);
+
+static bool HBDestinationAssignFunc (ConfigContext context, char* newval, int index, int elevel);
+static bool HBDestinationPortAssignFunc (ConfigContext context, int newval, int index, int elevel);
+static bool HBDeviceAssignFunc (ConfigContext context, char* newval, int index, int elevel);
+static bool OtherWDPortAssignFunc (ConfigContext context, int newval, int index, int elevel);
+static bool OtherPPPortAssignFunc (ConfigContext context, int newval, int index, int elevel);
+static bool OtherPPHostAssignFunc (ConfigContext context, char* newval, int index, int elevel);
+static bool config_post_processor(ConfigContext context, int elevel);
+static void sort_config_vars(void);
+static bool setConfigOption(const char *name, const char *value,
+ ConfigContext context, GucSource source, int elevel);
+
+#ifndef POOL_PRIVATE
+/* This function is used to provide Hints for enum type config parameters.
+ * an it is not available for tools since this uses the stringInfo that is
+ * not present for tools.
+ */
+static char *config_enum_get_options(struct config_enum * record, const char *prefix,
+ const char *suffix, const char *separator);
+#endif
+
+
+static const struct config_enum_entry log_error_verbosity_options[] = {
+ {"terse", PGERROR_TERSE, false},
+ {"default", PGERROR_DEFAULT, false},
+ {"verbose", PGERROR_VERBOSE, false},
+ {NULL, 0, false}
+};
+static const struct config_enum_entry server_message_level_options[] = {
+ {"debug", DEBUG2, true},
+ {"debug5", DEBUG5, false},
+ {"debug4", DEBUG4, false},
+ {"debug3", DEBUG3, false},
+ {"debug2", DEBUG2, false},
+ {"debug1", DEBUG1, false},
+ {"info", INFO, false},
+ {"notice", NOTICE, false},
+ {"warning", WARNING, false},
+ {"error", ERROR, false},
+ {"log", LOG, false},
+ {"fatal", FATAL, false},
+ {"panic", PANIC, false},
+ {NULL, 0, false}
+};
+
+
+static const struct config_enum_entry master_slave_sub_mode_options[] = {
+ {"slony", SLONY_MODE, true},
+ {"stream", STREAM_MODE, false},
+ {NULL, 0, false}
+};
+
+
+static const struct config_enum_entry log_standby_delay_options[] = {
+ {"always", LSD_ALWAYS, true},
+ {"if_over_threshold", LSD_OVER_THRESHOLD, false},
+ {"none", LSD_NONE, false},
+ {NULL, 0, false}
+};
+
+static const struct config_enum_entry memqcache_method_options[] = {
+ {"shmem", SHMEM_CACHE, true},
+ {"memcached", MEMCACHED_CACHE, false},
+ {NULL, 0, false}
+};
+
+static const struct config_enum_entry wd_lifecheck_method_options[] = {
+ {"query", LIFECHECK_BY_QUERY, true},
+ {"heartbeat", LIFECHECK_BY_HB, false},
+ {"external", LIFECHECK_BY_EXTERNAL, false},
+ {NULL, 0, false}
+};
+
+static const struct config_enum_entry syslog_facility_options[] = {
+ {"LOCAL0", LOG_LOCAL0, true},
+ {"LOCAL1", LOG_LOCAL1, true},
+ {"LOCAL2", LOG_LOCAL2, true},
+ {"LOCAL3", LOG_LOCAL3, true},
+ {"LOCAL4", LOG_LOCAL4, true},
+ {"LOCAL5", LOG_LOCAL5, true},
+ {"LOCAL6", LOG_LOCAL6, true},
+ {"LOCAL7", LOG_LOCAL7, true},
+ {NULL, 0, false}
+};
+
+
+static struct config_bool ConfigureNamesBool[] =
+{
+ {
+ {"serialize_accept", CFGCXT_INIT, CONNECTION_CONFIG,
+ "whether to serialize accept() call to avoid thundering herd problem",
+ CONFIG_VAR_TYPE_BOOL,false
+ },
+ &g_pool_config.serialize_accept, /* variable */
+ false, /* boot value */
+ NULL, /* assign func */
+ NULL, /* check func */
+ NULL /* show hook */
+ },
+
+ {
+ {"log_connections", CFGCXT_RELOAD, LOGING_CONFIG,
+ "Logs each successful connection.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.log_connections,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"log_hostname", CFGCXT_RELOAD, LOGING_CONFIG,
+ "Logs the host name in the connection logs.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.log_hostname,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"enable_pool_hba", CFGCXT_RELOAD, CONNECTION_CONFIG,
+ "Use pool_hba.conf for client authentication.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.enable_pool_hba,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"replication_mode", CFGCXT_INIT, LOGING_CONFIG,
+ "Enables replication mode.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.replication_mode,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"load_balance_mode", CFGCXT_INIT, LOAD_BALANCE_CONFIG,
+ "Enables load balancing of queries.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.load_balance_mode,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"replication_stop_on_mismatch", CFGCXT_RELOAD, REPLICATION_CONFIG,
+ "Starts degeneration and stops replication, If there's a data mismatch between master and secondary.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.replication_stop_on_mismatch,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"failover_if_affected_tuples_mismatch", CFGCXT_RELOAD, REPLICATION_CONFIG,
+ "Starts degeneration, If there's a data mismatch between master and secondary.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.failover_if_affected_tuples_mismatch,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"replicate_select", CFGCXT_RELOAD, REPLICATION_CONFIG,
+ "Replicate SELECT statements when load balancing is disabled.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.replicate_select,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"master_slave_mode", CFGCXT_INIT, MASTER_SLAVE_CONFIG,
+ "Enables Master/Slave mode.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.master_slave_mode,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"connection_cache", CFGCXT_INIT, CONNECTION_POOL_CONFIG,
+ "Caches connections to backends.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.connection_cache,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"fail_over_on_backend_error", CFGCXT_RELOAD, FAILOVER_CONFIG,
+ "Triggers fail over when reading/writing to backend socket fails.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.fail_over_on_backend_error,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"insert_lock", CFGCXT_RELOAD, REPLICATION_CONFIG,
+ "Automatically locks table with INSERT to keep SERIAL data consistency",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.insert_lock,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"ignore_leading_white_space", CFGCXT_RELOAD, LOAD_BALANCE_CONFIG,
+ "Ignores leading white spaces of each query string.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.ignore_leading_white_space,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"log_statement", CFGCXT_RELOAD, LOGING_CONFIG,
+ "Logs all statements in the pgpool logs.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.log_statement,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"log_per_node_statement", CFGCXT_RELOAD, LOGING_CONFIG,
+ "Logs per node detailed SQL statements.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.log_per_node_statement,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"use_watchdog", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Enables the pgpool-II watchdog.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.use_watchdog,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"clear_memqcache_on_escalation", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "Clears the query cache in the shared memory when pgpool-II escaltes to master watchdog node.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.clear_memqcache_on_escalation,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"ssl", CFGCXT_INIT, SSL_CONFIG,
+ "Enables SSL support for frontend and backend connections",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.ssl,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"check_temp_table", CFGCXT_RELOAD, GENERAL_CONFIG,
+ "Enables temporary table check.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.check_temp_table,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"check_unlogged_table", CFGCXT_RELOAD, GENERAL_CONFIG,
+ "Enables unlogged table check.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.check_unlogged_table,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"memory_cache_enabled", CFGCXT_RELOAD, CACHE_CONFIG,
+ "Enables the memory cache functionality.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.memory_cache_enabled,
+ false,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"memqcache_auto_cache_invalidation", CFGCXT_RELOAD, CACHE_CONFIG,
+ "Automatically deletes the cache related to the updated tables.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.memqcache_auto_cache_invalidation,
+ true,
+ NULL, NULL,NULL
+ },
+
+ {
+ {"allow_sql_comments", CFGCXT_RELOAD, LOAD_BALANCE_CONFIG,
+ "Ignore SQL comments, while judging if load balance or query cache is possible.",
+ CONFIG_VAR_TYPE_BOOL
+ },
+ &g_pool_config.allow_sql_comments,
+ false,
+ NULL, NULL,NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, false, NULL, NULL,NULL
+ }
+
+};
+
+static struct config_string ConfigureNamesString[] =
+{
+ {
+ {"database_redirect_preference_list", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "redirect by database name.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.database_redirect_preference_list, /* variable */
+ NULL,/* boot value */
+ NULL,/* assign_func */
+ NULL,/* check_func */
+ MakeDBRedirectListRegex, /* process func */
+ NULL /* show hook */
+ },
+
+ {
+ {"app_name_redirect_preference_list", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "redirect by application name.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.app_name_redirect_preference_list,
+ NULL,
+ NULL,NULL,
+ MakeAppRedirectListRegex, NULL
+ },
+
+ {
+ {"listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG,
+ "hostname or IP address on which pgpool will listen on.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.listen_addresses,
+ "localhost",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"pcp_listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG,
+ "hostname(s) or IP address(es) on which pcp will listen on.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.pcp_listen_addresses,
+ "*",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"socket_dir", CFGCXT_INIT, CONNECTION_CONFIG,
+ "The directory to create the UNIX domain socket for accepting pgpool-II client connections.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.socket_dir,
+ DEFAULT_SOCKET_DIR,
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"pcp_socket_dir", CFGCXT_INIT, CONNECTION_CONFIG,
+ "The directory to create the UNIX domain socket for accepting pgpool-II PCP connections.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.pcp_socket_dir,
+ DEFAULT_SOCKET_DIR,
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_ipc_socket_dir", CFGCXT_INIT, CONNECTION_CONFIG,
+ "The directory to create the UNIX domain socket for accepting pgpool-II watchdog IPC connections.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_ipc_socket_dir,
+ DEFAULT_SOCKET_DIR,
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"log_destination", CFGCXT_RELOAD, LOGING_CONFIG,
+ "logging destinatio.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.log_destination,
+ "stderr",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"syslog_ident", CFGCXT_RELOAD, LOGING_CONFIG,
+ "syslog program ident string.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.syslog_ident,
+ "pgpool",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"pid_file_name", CFGCXT_INIT, FILE_LOCATION_CONFIG,
+ "Path to store pgpool-II pid file.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.pid_file_name,
+ DEFAULT_PID_FILE_NAME,
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"pool_passwd", CFGCXT_INIT, FILE_LOCATION_CONFIG,
+ "File name of pool_passwd for md5 authentication.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.pool_passwd,
+ "pool_passwd",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"log_line_prefix", CFGCXT_RELOAD, LOGING_CONFIG,
+ "printf-style string to output at beginning of each log line.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.log_line_prefix,
+ "%t: pid %p: ",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_user", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "User name for PostgreSQL backend health check.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.health_check_user,
+ "nobody",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_password", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "Password for PostgreSQL backend health check database user.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.health_check_password,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_database", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "The database name to be used to perform PostgreSQL backend health check.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.health_check_database,
+ "postgres",
+ NULL, NULL, NULL, NULL
+ },
+
+
+ {
+ {"sr_check_user", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "The User name to perform streaming replication delay check.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.sr_check_user,
+ "nobody",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"sr_check_password", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "The password for user to perform streaming replication delay check.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.sr_check_password,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"sr_check_database", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "The database name to perform streaming replication delay check.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.sr_check_database,
+ "postgres",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"failback_command", CFGCXT_RELOAD, FAILOVER_CONFIG,
+ "Command to execute when backend node is attached.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.failback_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"follow_master_command", CFGCXT_RELOAD, FAILOVER_CONFIG,
+ "Command to execute in master/slave streaming replication mode after a master node failover.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.follow_master_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"failover_command", CFGCXT_RELOAD, FAILOVER_CONFIG,
+ "Command to execute when backend node is detached.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.failover_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"recovery_user", CFGCXT_RELOAD, RECOVERY_CONFIG,
+ "User name for online recovery.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.recovery_user,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"recovery_password", CFGCXT_RELOAD, RECOVERY_CONFIG,
+ "Password for online recovery.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.recovery_password,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"recovery_1st_stage_command", CFGCXT_RELOAD, RECOVERY_CONFIG,
+ "Command to execute in first stage recovery.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.recovery_1st_stage_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"recovery_2nd_stage_command", CFGCXT_RELOAD, RECOVERY_CONFIG,
+ "Command to execute in second stage recovery.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.recovery_2nd_stage_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"lobj_lock_table", CFGCXT_RELOAD, REPLICATION_CONFIG,
+ "Table name used for large object replication control.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.lobj_lock_table,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_escalation_command", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "Command to execute when watchdog node becomes cluster master/leader node.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_escalation_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_de_escalation_command", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "Command to execute when watchdog node resigns from the cluster master/leader node.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_de_escalation_command,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"trusted_servers", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "List of servers to verify connectivity.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.trusted_servers,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"delegate_IP", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Delegate IP address to be used when pgpool node become a watchdog cluster master/leader.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.delegate_IP,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_hostname", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Host name or IP address of this watchdog.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_hostname,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"ping_path", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "path to ping command.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.ping_path,
+ "/bin",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"if_cmd_path", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Path to interface command.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.if_cmd_path,
+ "/sbin",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"if_up_cmd", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Complete command to bring UP virtual interface.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.if_up_cmd,
+ "ip addr add $_IP_$/24 dev eth0 label eth0:0",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"if_down_cmd", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Complete command to bring down virtual interface.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.if_down_cmd,
+ "ip addr del $_IP_$/24 dev eth0",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"arping_path", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "path to arping command.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.arping_path,
+ "/usr/sbin",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"arping_cmd", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "arping command.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.arping_cmd,
+ "arping -U $_IP_$ -w 1",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_lifecheck_query", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "SQL query to be used by watchdog lifecheck.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_lifecheck_query,
+ "SELECT 1",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_lifecheck_dbname", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "Database name to be used for by watchdog lifecheck.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_lifecheck_dbname,
+ "postgres",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_lifecheck_user", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "User name to be used for by watchdog lifecheck.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_lifecheck_user,
+ "nobody",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_lifecheck_password", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "Password for watchdog user in lifecheck.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_lifecheck_password,
+ "postgres",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"wd_authkey", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "Authentication key to be used in watchdog communication.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_authkey,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_cert", CFGCXT_INIT, SSL_CONFIG,
+ "Path to the SSL public certificate file.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.ssl_cert,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_key", CFGCXT_INIT, SSL_CONFIG,
+ "Path to the SSL private key file.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.ssl_key,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_ca_cert", CFGCXT_INIT, SSL_CONFIG,
+ "Path to a single PEM format file.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.ssl_ca_cert,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_ca_cert_dir", CFGCXT_INIT, SSL_CONFIG,
+ "Directory containing CA root certificate(s).",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.ssl_ca_cert_dir,
+ "",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_oiddir", CFGCXT_INIT, CACHE_CONFIG,
+ "Tempory directory to record table oids.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.memqcache_oiddir,
+ "/var/log/pgpool/oiddir",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_memcached_host", CFGCXT_INIT, CACHE_CONFIG,
+ "Hostname or IP address of memcached.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.memqcache_memcached_host,
+ "localhost",
+ NULL, NULL, NULL, NULL
+ },
+
+ {
+ {"logdir", CFGCXT_INIT, LOGING_CONFIG,
+ "PgPool status file logging directory.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.logdir,
+ DEFAULT_LOGDIR,
+ NULL, NULL, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, NULL, NULL, NULL, NULL, NULL
+ }
+};
+
+static struct config_string_list ConfigureNamesStringList[] =
+{
+ {
+ {"reset_query_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG,
+ "list of commands sent to reset the backend connection when user session exits.",
+ CONFIG_VAR_TYPE_STRING_LIST,false
+ },
+ &g_pool_config.reset_query_list, /* variable */
+ &g_pool_config.num_reset_queries, /* item count var */
+ (const char*)default_reset_query_list, /* boot value */
+ false, /* compute_regex ?*/
+ NULL, NULL, NULL /* assign, check, show funcs */
+ },
+
+ {
+ {"white_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG,
+ "list of functions that does not writes to database.",
+ CONFIG_VAR_TYPE_STRING_LIST,false
+ },
+ &g_pool_config.white_function_list,
+ &g_pool_config.num_white_function_list,
+ NULL,
+ true,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"black_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG,
+ "list of functions that writes to database.",
+ CONFIG_VAR_TYPE_STRING_LIST,false
+ },
+ &g_pool_config.black_function_list,
+ &g_pool_config.num_black_function_list,
+ (const char*)default_black_function_list,
+ true,
+ NULL, NULL, NULL
+ },
+ {
+ {"white_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG,
+ "list of tables to be cached.",
+ CONFIG_VAR_TYPE_STRING_LIST,false
+ },
+ &g_pool_config.white_memqcache_table_list,
+ &g_pool_config.num_white_memqcache_table_list,
+ "",
+ true,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"black_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG,
+ "list of tables should not be cached.",
+ CONFIG_VAR_TYPE_STRING_LIST,false
+ },
+ &g_pool_config.black_memqcache_table_list,
+ &g_pool_config.num_black_memqcache_table_list,
+ "",
+ true,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_monitoring_interfaces_list", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "List of network device names, to be monitored by the watchdog process for the network link state.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.wd_monitoring_interfaces_list,
+ &g_pool_config.num_wd_monitoring_interfaces_list,
+ "",
+ false,
+ NULL, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, NULL, NULL,false, NULL, NULL, NULL
+ }
+};
+
+/* long configs*/
+static struct config_long ConfigureNamesLong[] =
+{
+ {
+ {"delay_threshold", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "standby delay threshold.",
+ CONFIG_VAR_TYPE_LONG,false
+ },
+ &g_pool_config.delay_threshold,
+ 0,
+ 0,LONG_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"relcache_expire", CFGCXT_INIT, CACHE_CONFIG,
+ "Relation cache expiration time in seconds.",
+ CONFIG_VAR_TYPE_LONG,false
+ },
+ &g_pool_config.relcache_expire,
+ 0,
+ 0,LONG_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_total_size", CFGCXT_INIT, CACHE_CONFIG,
+ "Total memory size in bytes for storing memory cache.",
+ CONFIG_VAR_TYPE_LONG,false
+ },
+ &g_pool_config.memqcache_total_size,
+ (int64)67108864,
+ 0,LONG_MAX,
+ NULL, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
+ }
+};
+
+static struct config_int_array ConfigureNamesIntArray[] =
+{
+ {
+ {"backend_port", CFGCXT_RELOAD, CONNECTION_CONFIG,
+ "port number of PostgreSQL backend.",
+ CONFIG_VAR_TYPE_INT_ARRAY,true
+ },
+ NULL,
+ 0,
+ 1024,65535,
+ MAX_NUM_BACKENDS,
+ BackendPortAssignFunc, NULL, NULL
+ },
+
+ {
+ {"heartbeat_destination_port", CFGCXT_RELOAD, WATCHDOG_LIFECHECK,
+ "Destination port for sending heartbeat.",
+ CONFIG_VAR_TYPE_INT_ARRAY,true
+ },
+ NULL,
+ 0,
+ 1024,65535,
+ WD_MAX_IF_NUM,
+ HBDestinationPortAssignFunc, NULL, NULL
+ },
+
+ {
+ {"other_wd_port", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "tcp/ip watchdog port number of other pgpool node for watchdog connection..",
+ CONFIG_VAR_TYPE_INT_ARRAY,true
+ },
+ NULL,
+ 0,
+ 1024,65535,
+ MAX_WATCHDOG_NUM,
+ OtherWDPortAssignFunc, NULL, NULL
+ },
+
+ {
+ {"other_pgpool_port", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+ "tcp/ip pgpool port number of other pgpool node for watchdog connection.",
+ CONFIG_VAR_TYPE_INT_ARRAY,true
+ },
+ NULL,
+ 0,
+ 1024,65535,
+ MAX_WATCHDOG_NUM,
+ OtherPPPortAssignFunc, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, 0, 0, 0,-1, NULL, NULL, NULL
+ }
+};
+
+
+static struct config_double ConfigureNamesDouble[] =
+{
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, 0, 0, 0, NULL, NULL
+ }
+};
+
+static struct config_double_array ConfigureNamesDoubleArray[] =
+{
+ {
+ {"backend_weight", CFGCXT_RELOAD, CONNECTION_CONFIG,
+ "load balance weight of backend.",
+ CONFIG_VAR_TYPE_DOUBLE_ARRAY,true
+ },
+ NULL,
+ 0,
+ 0.0,100000000.0,
+ MAX_NUM_BACKENDS,
+ BackendWeightAssignFunc, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, 0, 0, 0,-1, NULL, NULL, NULL
+ }
+};
+
+
+static struct config_string_array ConfigureNamesStringArray[] =
+{
+ {
+ {"backend_hostname", CFGCXT_RELOAD, CONNECTION_CONFIG,
+ "hostname or IP address of PostgreSQL backend.",
+ CONFIG_VAR_TYPE_STRING_ARRAY,true
+ },
+ NULL,
+ "",
+ MAX_NUM_BACKENDS,
+ BackendHostAssignFunc, NULL, NULL
+ },
+
+ {
+ {"backend_data_directory", CFGCXT_RELOAD, CONNECTION_CONFIG,
+ "data directory of the backend.",
+ CONFIG_VAR_TYPE_STRING_ARRAY,true
+ },
+ NULL,
+ "",
+ MAX_NUM_BACKENDS,
+ BackendDataDirAssignFunc, NULL, NULL
+ },
+
+ {
+ {"backend_flag", CFGCXT_RELOAD, CONNECTION_CONFIG,
+ "Controls various backend behavior.",
+ CONFIG_VAR_TYPE_STRING_ARRAY,true
+ },
+ NULL,
+ "ALLOW_TO_FAILOVER",
+ MAX_NUM_BACKENDS,
+ BackendFlagsAssignFunc, NULL, NULL
+ },
+
+ {
+ {"heartbeat_destination", CFGCXT_RELOAD, WATCHDOG_LIFECHECK,
+ "destination host for sending heartbeat signal.",
+ CONFIG_VAR_TYPE_STRING_ARRAY,true
+ },
+ NULL,
+ "",
+ WD_MAX_IF_NUM,
+ HBDestinationAssignFunc, NULL, NULL
+ },
+
+ {
+ {"heartbeat_device", CFGCXT_RELOAD, WATCHDOG_LIFECHECK,
+ "Name of NIC device for sending hearbeat.",
+ CONFIG_VAR_TYPE_STRING_ARRAY,true
+ },
+ NULL,
+ "",
+ WD_MAX_IF_NUM,
+ HBDeviceAssignFunc, NULL, NULL
+ },
+
+ {
+ {"other_pgpool_hostname", CFGCXT_RELOAD, WATCHDOG_LIFECHECK,
+ "Hostname of other pgpool node for watchdog connection.",
+ CONFIG_VAR_TYPE_STRING_ARRAY,true
+ },
+ NULL,
+ "localhost",
+ MAX_WATCHDOG_NUM,
+ OtherPPHostAssignFunc, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, NULL, 0, NULL, NULL, NULL
+ }
+};
+
+
+/* int configs*/
+static struct config_int ConfigureNamesInt[] =
+{
+
+ {
+ {"port", CFGCXT_INIT, CONNECTION_CONFIG,
+ "tcp/IP port number on which pgpool will listen on.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.port,
+ 9999,
+ 1024,65535,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"pcp_port", CFGCXT_INIT, CONNECTION_CONFIG,
+ "tcp/IP port number on which pgpool PCP process will listen on.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.pcp_port,
+ 9898,
+ 1024,65535,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"num_init_children", CFGCXT_INIT, CONNECTION_POOL_CONFIG,
+ "Number of children pre-forked for client connections.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.num_init_children,
+ 32,
+ 1,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"listen_backlog_multiplier", CFGCXT_INIT, CONNECTION_CONFIG,
+ "length of connection queue from frontend to pgpool-II",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.listen_backlog_multiplier,
+ 32,
+ 1,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"child_life_time", CFGCXT_SESSION, CONNECTION_POOL_CONFIG,
+ "pgpool-II child process life time in seconds.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.child_life_time,
+ 300,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"client_idle_limit", CFGCXT_SESSION, CONNECTION_POOL_CONFIG,
+ "idle time in seconds to disconnects a client.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.client_idle_limit,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"connection_life_time", CFGCXT_SESSION, CONNECTION_POOL_CONFIG,
+ "Cached connections expiration time in seconds.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.connection_life_time,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"child_max_connections", CFGCXT_SESSION, CONNECTION_POOL_CONFIG,
+ "A pgpool-II child process will be terminated after this many connections from clients.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.child_max_connections,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"authentication_timeout", CFGCXT_SESSION, CONNECTION_CONFIG,
+ "Time out value in seconds for client authentication.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.authentication_timeout,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"max_pool", CFGCXT_INIT, CONNECTION_POOL_CONFIG,
+ "Maximum number of connection pools per child process.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.max_pool,
+ 4,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "Time out value in seconds for one health check.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.health_check_timeout,
+ 20,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_period", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "Time interval in seconds between the health checks.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.health_check_period,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_max_retries", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "The maximum number of times to retry a failed health check before giving up and initiating failover.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.health_check_max_retries,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"health_check_retry_delay", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "The amount of time in seconds to wait between failed health check retries.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.health_check_retry_delay,
+ 1,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"connect_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "Timeout in milliseconds before giving up connecting to backend.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.connect_timeout,
+ 10000,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"sr_check_period", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG,
+ "Time interval in seconds between the streaming replication delay checks.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.sr_check_period,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"recovery_timeout", CFGCXT_RELOAD, RECOVERY_CONFIG,
+ "Maximum time in seconds to wait for the recovering PostgreSQL node.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.recovery_timeout,
+ 90,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"client_idle_limit_in_recovery", CFGCXT_RELOAD, RECOVERY_CONFIG,
+ "Time limit is seconds for the child connection, before it is terminated during the 2nd stage recovery.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.client_idle_limit_in_recovery,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"search_primary_node_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG,
+ "Max time in seconds to search for primary node after failover.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.search_primary_node_timeout,
+ 10,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_port", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "tcp/IP port number on which watchdog of process of pgpool will listen on.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_port,
+ 9000,
+ 1024,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_priority", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Watchdog node priority for leader election.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_priority,
+ 1,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_interval", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Time interval in seconds between life check.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_interval,
+ 10,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_life_point", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Maximum number of retries before failing the life check.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_life_point,
+ 3,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_heartbeat_port", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Port number for receiving heartbeat signal.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_heartbeat_port,
+ 9694,
+ 1024,65535,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_heartbeat_keepalive", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Time interval in seconds between sending the heartbeat siganl.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_heartbeat_keepalive,
+ 2,
+ 1,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_heartbeat_deadtime", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "Deadtime interval in seconds for heartbeat siganl.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.wd_heartbeat_deadtime,
+ 30,
+ 1,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"relcache_size", CFGCXT_INIT, CACHE_CONFIG,
+ "Number of relation cache entry.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.relcache_size,
+ 256,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_memcached_port", CFGCXT_INIT, CACHE_CONFIG,
+ "Port number of Memcached server.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.memqcache_memcached_port,
+ 11211,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_max_num_cache", CFGCXT_INIT, CACHE_CONFIG,
+ "Total number of cache entries.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.memqcache_max_num_cache,
+ 1000000,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_expire", CFGCXT_INIT, CACHE_CONFIG,
+ "Memory cache entry life time specified in seconds.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.memqcache_expire,
+ 0,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_maxcache", CFGCXT_INIT, CACHE_CONFIG,
+ "Maximum SELECT result size in bytes.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.memqcache_maxcache,
+ 409600,
+ 0,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_cache_block_size", CFGCXT_INIT, CACHE_CONFIG,
+ "Cache block size in bytes.",
+ CONFIG_VAR_TYPE_INT,false
+ },
+ &g_pool_config.memqcache_cache_block_size,
+ 1048576,
+ 512,INT_MAX,
+ NULL, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
+ }
+};
+
+static struct config_enum ConfigureNamesEnum[] =
+{
+ {
+ {"syslog_facility", CFGCXT_RELOAD, LOGING_CONFIG,
+ "syslog local faclity.",
+ CONFIG_VAR_TYPE_STRING,false
+ },
+ &g_pool_config.syslog_facility,
+ LOG_LOCAL0,
+ syslog_facility_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"log_error_verbosity", CFGCXT_RELOAD, LOGING_CONFIG,
+ "How much details about error should be emitted.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ &g_pool_config.log_error_verbosity,
+ PGERROR_DEFAULT,
+ log_error_verbosity_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"client_min_messages", CFGCXT_RELOAD, LOGING_CONFIG,
+ "Which messages should be sent to client.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ &g_pool_config.client_min_messages,
+ NOTICE,
+ server_message_level_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"log_min_messages", CFGCXT_RELOAD, LOGING_CONFIG,
+ "Which messages should be emitted to server log.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ &g_pool_config.log_min_messages,
+ WARNING,
+ server_message_level_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"master_slave_sub_mode", CFGCXT_INIT, MASTER_SLAVE_CONFIG,
+ "master/slave sub mode.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ (int*)&g_pool_config.master_slave_sub_mode,
+ SLONY_MODE,
+ master_slave_sub_mode_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"log_standby_delay", CFGCXT_RELOAD, MASTER_SLAVE_CONFIG,
+ "When to log standby delay.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ (int*)&g_pool_config.log_standby_delay,
+ LSD_NONE,
+ log_standby_delay_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"wd_lifecheck_method", CFGCXT_INIT, WATCHDOG_CONFIG,
+ "method for watchdog lifecheck.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ (int*)&g_pool_config.wd_lifecheck_method,
+ LIFECHECK_BY_HB,
+ wd_lifecheck_method_options,
+ NULL, NULL, NULL
+ },
+
+ {
+ {"memqcache_method", CFGCXT_INIT, CACHE_CONFIG,
+ "Cache store method. either shmem(shared memory) or Memcached. shmem by default.",
+ CONFIG_VAR_TYPE_ENUM,false
+ },
+ (int*)&g_pool_config.memqcache_method,
+ SHMEM_CACHE,
+ memqcache_method_options,
+ NULL, NULL, NULL
+ },
+
+ /* End-of-list marker */
+ {
+ {NULL, 0, 0, NULL}, NULL, 0, NULL, NULL, NULL, NULL
+ }
+};
+
+bool assign_variable_to_int_array_config_var(const char* name, int** variable)
+{
+ int i;
+ for (i = 0; ConfigureNamesIntArray[i].gen.name; i++)
+ {
+ if (strcasecmp(ConfigureNamesIntArray[i].gen.name, name) == 0)
+ {
+ ConfigureNamesIntArray[i].variable = variable;
+ return true;
+ }
+ }
+ return false;
+}
+
+static void
+build_config_variables(void)
+{
+ struct config_generic **all_vars;
+ int i;
+ int num_vars = 0;
+
+ for (i = 0; ConfigureNamesBool[i].gen.name; i++)
+ {
+ struct config_bool *conf = &ConfigureNamesBool[i];
+
+ /* Rather than requiring vartype to be filled in by hand, do this: */
+ conf->gen.vartype = CONFIG_VAR_TYPE_BOOL;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesInt[i].gen.name; i++)
+ {
+ struct config_int *conf = &ConfigureNamesInt[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_INT;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesIntArray[i].gen.name; i++)
+ {
+ struct config_int_array *conf = &ConfigureNamesIntArray[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_INT_ARRAY;
+ /* Assign the memory for reset vals */
+ conf->reset_vals = palloc(sizeof(int) * conf->max_elements);
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesLong[i].gen.name; i++)
+ {
+ struct config_long *conf = &ConfigureNamesLong[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_LONG;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesDouble[i].gen.name; i++)
+ {
+ struct config_double *conf = &ConfigureNamesDouble[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_DOUBLE;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesString[i].gen.name; i++)
+ {
+ struct config_string *conf = &ConfigureNamesString[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_STRING;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
+ {
+ struct config_enum *conf = &ConfigureNamesEnum[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_ENUM;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesStringList[i].gen.name; i++)
+ {
+ struct config_string_list *conf = &ConfigureNamesStringList[i];
+
+ conf->gen.vartype = CONFIG_VAR_TYPE_STRING_LIST;
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesStringArray[i].gen.name; i++)
+ {
+ struct config_string_array *conf = &ConfigureNamesStringArray[i];
+ conf->gen.dynamic_array_var = true;
+ conf->gen.vartype = CONFIG_VAR_TYPE_STRING_ARRAY;
+ /* Assign the memory for reset vals */
+ conf->reset_vals = palloc(sizeof(char*) * conf->max_elements);
+ num_vars++;
+ }
+
+ for (i = 0; ConfigureNamesDoubleArray[i].gen.name; i++)
+ {
+ struct config_double_array *conf = &ConfigureNamesDoubleArray[i];
+ conf->gen.dynamic_array_var = true;
+ conf->gen.vartype = CONFIG_VAR_TYPE_DOUBLE_ARRAY;
+ /* Assign the memory for reset vals */
+ conf->reset_vals = palloc(sizeof(double) * conf->max_elements);
+ num_vars++;
+ }
+
+ /* For end marker */
+ num_vars++;
+
+ all_vars = (struct config_generic **)
+ palloc(num_vars * sizeof(struct config_generic *));
+
+ num_vars = 0;
+
+ for (i = 0; ConfigureNamesBool[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesBool[i].gen;
+
+ for (i = 0; ConfigureNamesInt[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesInt[i].gen;
+
+ for (i = 0; ConfigureNamesLong[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesLong[i].gen;
+
+ for (i = 0; ConfigureNamesDouble[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesDouble[i].gen;
+
+ for (i = 0; ConfigureNamesString[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesString[i].gen;
+
+ for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesEnum[i].gen;
+
+ for (i = 0; ConfigureNamesStringList[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesStringList[i].gen;
+
+ for (i = 0; ConfigureNamesStringArray[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesStringArray[i].gen;
+
+ for (i = 0; ConfigureNamesIntArray[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesIntArray[i].gen;
+
+ for (i = 0; ConfigureNamesDoubleArray[i].gen.name; i++)
+ all_vars[num_vars++] = &ConfigureNamesDoubleArray[i].gen;
+
+ if (all_parameters)
+ pfree(all_parameters);
+ all_parameters = all_vars;
+ num_all_parameters = num_vars;
+ sort_config_vars();
+
+}
+
+/* Sort the config variables on based of string length of
+ * variable names. Since we want to compare long variable names to be compared
+ * before the smaller ones. This ensure heartbeat_destination should not match
+ * with heartbeat_destination_port, when we use strncmp to cater for the index at
+ * the end of the variable names.*/
+static void sort_config_vars(void)
+{
+ int i,j;
+ for (i = 0; i < num_all_parameters; ++i)
+ {
+ struct config_generic* gconfi = all_parameters[i];
+ int leni = strlen(gconfi->name);
+ for (j = i + 1; j < num_all_parameters; ++j)
+ {
+ struct config_generic* gconfj = all_parameters[j];
+ int lenj = strlen(gconfj->name);
+
+ if (leni < lenj)
+ {
+ all_parameters[i] = gconfj;
+ all_parameters[j] = gconfi;
+ gconfi = all_parameters[i];
+ leni = lenj;
+ }
+ }
+ }
+}
+
+/*
+ * Initialize all variables to its compiled-in default.
+ */
+static void
+initialize_variables_with_default(struct config_generic * gconf)
+{
+ gconf->status = 0;
+ gconf->source = PGC_S_DEFAULT;
+ gconf->scontext = CFGCXT_BOOT;
+ gconf->sourceline = 0;
+
+ switch (gconf->vartype)
+ {
+ case CONFIG_VAR_TYPE_BOOL:
+ {
+ struct config_bool *conf = (struct config_bool *) gconf;
+ bool newval = conf->boot_val;
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ *conf->variable = conf->reset_val = newval;
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_INT:
+ {
+ struct config_int *conf = (struct config_int *) gconf;
+ int newval = conf->boot_val;
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+ conf->reset_val = newval;
+
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_DOUBLE:
+ {
+ struct config_double *conf = (struct config_double *) gconf;
+ double newval = conf->boot_val;
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+ conf->reset_val = newval;
+
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_INT_ARRAY:
+ {
+ struct config_int_array *conf = (struct config_int_array *) gconf;
+ int newval = conf->boot_val;
+ int i;
+
+ for (i = 0; i < conf->max_elements; i ++)
+ {
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, i,ERROR);
+ }
+ else
+ {
+ *conf->variable[i] = newval;
+ }
+ conf->reset_vals[i] = newval;
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_DOUBLE_ARRAY:
+ {
+ struct config_double_array *conf = (struct config_double_array *) gconf;
+ double newval = conf->boot_val;
+ int i;
+
+ for (i = 0; i < conf->max_elements; i ++)
+ {
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, i,ERROR);
+ }
+ else
+ {
+ *conf->variable[i] = newval;
+ }
+ conf->reset_vals[i] = newval;
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_LONG:
+ {
+ struct config_long *conf = (struct config_long *) gconf;
+ long newval = conf->boot_val;
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ *conf->variable = conf->reset_val = newval;
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_STRING:
+ {
+ struct config_string *conf = (struct config_string *) gconf;
+ char *newval = NULL;
+
+ /* non-NULL boot_val must always get strdup'd */
+ if (conf->boot_val != NULL)
+ newval = pstrdup(conf->boot_val);
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+ conf->reset_val = newval;
+
+ if (conf->process_func)
+ {
+ (*conf->process_func)(newval, ERROR);
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_STRING_ARRAY:
+ {
+ struct config_string_array *conf = (struct config_string_array *) gconf;
+ int i;
+ char *newval = NULL;
+
+ /* non-NULL boot_val must always get strdup'd */
+ if (conf->boot_val != NULL)
+ newval = pstrdup(conf->boot_val);
+
+ for (i = 0; i < conf->max_elements; i ++)
+ {
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, i, ERROR);
+ }
+ else
+ {
+ *conf->variable[i] = newval;
+ }
+ conf->reset_vals[i] = newval;
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_ENUM:
+ {
+ struct config_enum *conf = (struct config_enum *) gconf;
+ int newval = conf->boot_val;
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ *conf->variable = conf->reset_val = newval;
+ }
+ break;
+ }
+
+ case CONFIG_VAR_TYPE_STRING_LIST:
+ {
+ struct config_string_list *conf = (struct config_string_list *) gconf;
+ char *newval = NULL;
+
+ /* non-NULL boot_val must always get strdup'd */
+ if (conf->boot_val != NULL)
+ newval = pstrdup(conf->boot_val);
+ else
+ newval = NULL;
+
+ if (conf->assign_func)
+ {
+ (*conf->assign_func)(gconf->scontext, newval, ERROR);
+ }
+ else
+ {
+ conf->reset_val = newval;
+ *conf->variable = get_list_from_string(conf->boot_val,",", conf->list_elements_count);
+ if (conf->compute_regex)
+ {
+ int i;
+ for (i=0;i < *conf->list_elements_count; i++)
+ {
+ add_regex_pattern((const char*)conf->gen.name, *conf->variable[i]);
+ }
+ }
+ }
+ break;
+ }
+
+ }
+}
+
+/*
+ * Extract tokens separated by delimi from str. Return value is an
+ * array of pointers in pallocd strings. number of elements are set to
+ * n.
+ */
+static char **get_list_from_string(const char *str, char *delimi, int *n)
+{
+ char *token;
+ char **tokens;
+ char *temp_string;
+ const int MAXTOKENS = 256;
+
+ if (str == NULL)
+ return NULL;
+
+ *n = 0;
+
+ temp_string = pstrdup(str);
+ tokens = palloc(MAXTOKENS * sizeof(char *));
+
+ for (token = strtok(temp_string, delimi); token != NULL ; token = strtok(NULL, delimi))
+ {
+ tokens[*n] = pstrdup(token);
+ ereport(DEBUG3,
+ (errmsg("initializing pool configuration"),
+ errdetail("extracting string tokens [token: %s]", tokens[*n])));
+
+ (*n)++;
+
+ if ( ((*n) % MAXTOKENS ) == 0)
+ {
+ tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n)/MAXTOKENS) +1) ));
+ }
+ }
+ /* how about reclaiming the unused space */
+ tokens = repalloc(tokens, (sizeof(char *) * (*n) ));
+ pfree(temp_string);
+
+ return tokens;
+}
+
+/*
+ * Memory of the array type variables must be initialized befor calling this function
+ */
+void
+InitializeConfigOptions(void)
+{
+ int i;
+
+ build_config_variables();
+
+ /*
+ * Load all variables with their compiled-in defaults, and initialize
+ * status fields as needed.
+ */
+ for (i = 0; i < num_all_parameters; i++)
+ {
+ initialize_variables_with_default(all_parameters[i]);
+ }
+ /* do the post processing */
+ config_post_processor(CFGCXT_BOOT, FATAL);
+}
+
+/*
+ * Look up option NAME. If it exists, return a pointer to its record,
+ * else return NULL.
+ */
+static struct config_generic *
+find_option(const char *name, int elevel)
+{
+ int i;
+
+ for (i = 0; i < num_all_parameters; i++)
+ {
+ struct config_generic* gconf = all_parameters[i];
+ if (gconf->dynamic_array_var)
+ {
+ int index_start_index = strlen(gconf->name);
+ /*
+ * For dynamic array type vars the key also have the index at the end
+ * e.g. backend_hostname0 so we only comapare the key name part
+ */
+ if (!strncmp(gconf->name, name, index_start_index))
+ {
+ /* make sure if index is provided and its a numeric value */
+ if (strlen(name) <= index_start_index || !isdigit(*(name + index_start_index)))
+ continue;
+ return gconf;
+ }
+ }
+ else
+ {
+ if (!strcmp(gconf->name, name))
+ return gconf;
+ }
+ }
+ /* Unknown name */
+ return NULL;
+}
+
+/*
+ * Lookup the value for an enum option with the selected name
+ * (case-insensitive).
+ * If the enum option is found, sets the retval value and returns
+ * true. If it's not found, return FALSE and retval is set to 0.
+ */
+static bool
+config_enum_lookup_by_name(struct config_enum * record, const char *value,
+ int *retval)
+{
+ const struct config_enum_entry *entry;
+
+ for (entry = record->options; entry && entry->name; entry++)
+ {
+ if (strcasecmp(value, entry->name) == 0)
+ {
+ *retval = entry->val;
+ return TRUE;
+ }
+ }
+
+ *retval = 0;
+ return FALSE;
+}
+
+bool
+set_config_options(ConfigVariable *head_p,
+ ConfigContext context, GucSource source, int elevel)
+{
+ ConfigVariable *item = head_p;
+ while (item)
+ {
+ ConfigVariable *next = item->next;
+ setConfigOption(item->name, item->value, context, source, elevel);
+ item = next;
+ }
+ return config_post_processor(context,elevel);
+}
+
+bool set_one_config_option(const char *name, const char *value,
+ ConfigContext context, GucSource source, int elevel)
+{
+ if (setConfigOption(name, value, context, source, elevel) == true)
+ return config_post_processor(context,elevel);
+ return false;
+}
+
+static bool
+setConfigOption(const char *name, const char *value,
+ ConfigContext context, GucSource source, int elevel)
+{
+ struct config_generic *record;
+ int index_val = -1;
+
+ ereport(DEBUG2,
+ (errmsg("set_config_option \"%s\" = \"%s\"", name,value)));
+ record = find_option(name, elevel);
+ if (record == NULL)
+ {
+ ereport(WARNING,
+ (errmsg("unrecognized configuration parameter \"%s\"", name)));
+ return false;
+ }
+
+ /*
+ * Check if the option can be set at this time. See guc.h for the precise
+ * rules.
+ */
+ switch (record->context)
+ {
+ case CFGCXT_BOOT:
+ if (context != CFGCXT_BOOT)
+ {
+ ereport(elevel,
+ (errmsg("parameter \"%s\" cannot be changed",
+ name)));
+ return false;
+ }
+ break;
+ case CFGCXT_INIT:
+ if (context != CFGCXT_INIT && context != CFGCXT_BOOT)
+ {
+ ereport(elevel,
+ (errmsg("parameter \"%s\" cannot be changed",
+ name)));
+ return false;
+ }
+ break;
+ case CFGCXT_RELOAD:
+ /* Reject if we're connecting but user is not superuser */
+ if (context > CFGCXT_RELOAD)
+ {
+ ereport(elevel,
+ (errmsg("parameter \"%s\" cannot be changed",
+ name)));
+ return false;
+ }
+ break;
+ case CFGCXT_PCP:
+ if (context > CFGCXT_PCP)
+ {
+ ereport(elevel,
+ (errmsg("parameter \"%s\" cannot be changed",
+ name)));
+ return false;
+ }
+ break;
+
+ case CFGCXT_SESSION:
+ break;
+
+ default:
+ {
+ ereport(elevel,
+ (errmsg("invalid configuration context")));
+ return false;
+ }
+ break;
+ }
+
+ /*
+ * Evaluate value and set variable.
+ */
+ if (record->dynamic_array_var)
+ {
+ /* get the index */
+ int index_start_index = strlen(record->name);
+ if (strlen(name) <= index_start_index)
+ {
+ /* index is not provided */
+ ereport(elevel,
+ (errmsg("parameter \"%s\" expects the index value",
+ name)));
+ return false;
+ }
+ index_val = atoi(name + index_start_index);
+ }
+
+ switch (record->vartype)
+ {
+ case CONFIG_VAR_TYPE_BOOL:
+ {
+ struct config_bool *conf = (struct config_bool *) record;
+ bool newval = conf->boot_val;
+
+ if (value != NULL)
+ {
+ newval = eval_logical(value);
+
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_val;
+ }
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ *conf->variable = newval;
+
+ if (context == CFGCXT_INIT)
+ conf->reset_val = newval;
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_INT:
+ {
+ struct config_int *conf = (struct config_int *) record;
+ int newval;
+
+ if (value != NULL)
+ {
+ newval = atoi(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_val;
+ }
+
+ if (newval < conf->min || newval > conf->max)
+ {
+ ereport(elevel,
+ (errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
+ newval, name,
+ conf->min, conf->max)));
+ return false;
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+
+ if (context == CFGCXT_INIT)
+ conf->reset_val = newval;
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_DOUBLE:
+ {
+ struct config_double *conf = (struct config_double *) record;
+ double newval;
+
+ if (value != NULL)
+ {
+ newval = atof(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_val;
+ }
+
+ if (newval < conf->min || newval > conf->max)
+ {
+ ereport(elevel,
+ (errmsg("%f is outside the valid range for parameter \"%s\" (%f .. %f)",
+ newval, name,
+ conf->min, conf->max)));
+ return false;
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+
+ if (context == CFGCXT_INIT)
+ conf->reset_val = newval;
+
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_INT_ARRAY:
+ {
+ struct config_int_array *conf = (struct config_int_array *) record;
+ int newval;
+
+ if (index_val < 0 || index_val > conf->max_elements)
+ {
+ ereport(elevel,
+ (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)",
+ index_val, name,
+ 0, conf->max_elements)));
+ return false;
+ }
+
+ if (value != NULL)
+ {
+ newval = atoi(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_vals[index_val];
+ }
+
+ if (newval < conf->min || newval > conf->max)
+ {
+ ereport(elevel,
+ (errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
+ newval, name,
+ conf->min, conf->max)));
+ return false;
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, index_val, elevel) == false)
+ return false;
+ }
+ else
+ {
+ *conf->variable[index_val] = newval;
+ }
+
+ if (context == CFGCXT_INIT)
+ conf->reset_vals[index_val] = newval;
+
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_DOUBLE_ARRAY:
+ {
+ struct config_double_array *conf = (struct config_double_array *) record;
+ double newval;
+
+ if (index_val < 0 || index_val > conf->max_elements)
+ {
+ ereport(elevel,
+ (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)",
+ index_val, name,
+ 0, conf->max_elements)));
+ return false;
+ }
+
+ if (value != NULL)
+ {
+ newval = atof(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_vals[index_val];
+ }
+
+ if (newval < conf->min || newval > conf->max)
+ {
+ ereport(elevel,
+ (errmsg("%f is outside the valid range for parameter \"%s\" (%f .. %f)",
+ newval, name,
+ conf->min, conf->max)));
+ return false;
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, index_val, elevel) ==false)
+ return false;
+ }
+ else
+ {
+ *conf->variable[index_val] = newval;
+ }
+
+ if (context == CFGCXT_INIT)
+ conf->reset_vals[index_val] = newval;
+
+ }
+ break;
+
+
+ case CONFIG_VAR_TYPE_LONG:
+ {
+ struct config_long *conf = (struct config_long *) record;
+ long newval;
+
+ if (value != NULL)
+ {
+ newval = pool_atoi64(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_val;
+ }
+
+ if (newval < conf->min || newval > conf->max)
+ {
+ ereport(elevel,
+ (errmsg("%ld is outside the valid range for parameter \"%s\" (%ld .. %ld)",
+ newval, name,
+ conf->min, conf->max)));
+ return false;
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+
+ if (context == CFGCXT_INIT)
+ conf->reset_val = newval;
+
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_STRING:
+ {
+ struct config_string *conf = (struct config_string *) record;
+ char *newval = NULL;
+
+ if (value != NULL)
+ {
+ newval = pstrdup(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ if (conf->boot_val)
+ newval = pstrdup(conf->boot_val);
+ }
+ else
+ {
+ /* Reset */
+ if (conf->reset_val)
+ newval = pstrdup(conf->reset_val);
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ {
+ if (*conf->variable)
+ pfree(*conf->variable);
+ *conf->variable = newval;
+ }
+ if (context == CFGCXT_INIT)
+ {
+ conf->reset_val = newval;
+ }
+ if (conf->process_func)
+ {
+ (*conf->process_func)(newval, elevel);
+ }
+
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_STRING_ARRAY:
+ {
+ struct config_string_array *conf = (struct config_string_array *) record;
+ char *newval = NULL;
+
+ if (index_val < 0 || index_val > conf->max_elements)
+ {
+ ereport(elevel,
+ (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)",
+ index_val, name,
+ 0, conf->max_elements)));
+ return false;
+ }
+
+ if (value != NULL)
+ {
+ newval = pstrdup(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ if (conf->boot_val)
+ newval = pstrdup(conf->boot_val);
+ }
+ else
+ {
+ /* Reset */
+ if (conf->reset_vals[index_val])
+ newval = pstrdup(conf->reset_vals[index_val]);
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, index_val,elevel) == false)
+ return false;
+ }
+ else
+ {
+ if (*conf->variable[index_val])
+ pfree(*conf->variable[index_val]);
+ *conf->variable[index_val] = newval;
+ }
+ if (context == CFGCXT_INIT)
+ {
+ conf->reset_vals[index_val] = newval;
+ }
+
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_STRING_LIST:
+ {
+ struct config_string_list *conf = (struct config_string_list *) record;
+ char *newval = NULL;
+ if (value != NULL)
+ {
+ newval = (char*)value;
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ if (conf->boot_val)
+ newval = (char*)conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ if (conf->reset_val)
+ newval = pstrdup(conf->reset_val);
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ {
+ if (*conf->variable)
+ {
+ int i;
+ for (i=0;i < *conf->list_elements_count; i++)
+ {
+ if (*conf->variable[i])
+ pfree(*conf->variable[i]);
+ *conf->variable[i] = NULL;
+ }
+ pfree(*conf->variable);
+ }
+
+ *conf->variable = get_list_from_string(newval,",", conf->list_elements_count);
+ if (conf->compute_regex)
+ {
+ /* TODO clear the old array please */
+ int i;
+ for (i=0;i < *conf->list_elements_count; i++)
+ {
+ add_regex_pattern(conf->gen.name, (*conf->variable)[i]);
+ }
+ }
+ }
+
+ if (context == CFGCXT_INIT)
+ {
+ if (conf->reset_val)
+ pfree(conf->reset_val);
+ if (newval)
+ conf->reset_val = pstrdup(newval);
+ else
+ conf->reset_val = NULL;
+ }
+
+ }
+ break;
+
+ case CONFIG_VAR_TYPE_ENUM:
+ {
+ struct config_enum *conf = (struct config_enum *) record;
+ int newval;
+
+ if (value != NULL)
+ {
+ newval = atoi(value);
+ }
+ else if (source == PGC_S_DEFAULT)
+ {
+ newval = conf->boot_val;
+ }
+ else
+ {
+ /* Reset */
+ newval = conf->reset_val;
+ }
+
+ if (!config_enum_lookup_by_name(conf, value, &newval))
+ {
+
+ char *hintmsg = NULL;
+
+#ifndef POOL_PRIVATE
+ hintmsg = config_enum_get_options(conf,
+ "Available values: ",
+ ".", ", ");
+#endif
+
+ ereport(elevel,
+ (errmsg("invalid value for parameter \"%s\": \"%s\"",
+ name, value),
+ hintmsg ? errhint("%s",hintmsg) : 0));
+
+ if (hintmsg)
+ pfree(hintmsg);
+ return false;
+ }
+
+ if (conf->assign_func)
+ {
+ if ((*conf->assign_func)(context, newval, elevel) == false)
+ return false;
+ }
+ else
+ {
+ *conf->variable = newval;
+ }
+
+ if (context == CFGCXT_INIT)
+ conf->reset_val = newval;
+
+ break;
+ }
+ }
+
+ record->scontext = context;
+ return true;
+}
+
+#ifndef POOL_PRIVATE
+
+/*
+ * Return a list of all available options for an enum, excluding
+ * hidden ones, separated by the given separator.
+ * If prefix is non-NULL, it is added before the first enum value.
+ * If suffix is non-NULL, it is added to the end of the string.
+ */
+static char *
+config_enum_get_options(struct config_enum * record, const char *prefix,
+ const char *suffix, const char *separator)
+{
+ const struct config_enum_entry *entry;
+ StringInfoData retstr;
+ int seplen;
+
+ initStringInfo(&retstr);
+ appendStringInfoString(&retstr, prefix);
+
+ seplen = strlen(separator);
+ for (entry = record->options; entry && entry->name; entry++)
+ {
+ if (!entry->hidden)
+ {
+ appendStringInfoString(&retstr, entry->name);
+ appendBinaryStringInfo(&retstr, separator, seplen);
+ }
+ }
+
+ /*
+ * All the entries may have been hidden, leaving the string empty if no
+ * prefix was given. This indicates a broken GUC setup, since there is no
+ * use for an enum without any values, so we just check to make sure we
+ * don't write to invalid memory instead of actually trying to do
+ * something smart with it.
+ */
+ if (retstr.len >= seplen)
+ {
+ /* Replace final separator */
+ retstr.data[retstr.len - seplen] = '\0';
+ retstr.len -= seplen;
+ }
+
+ appendStringInfoString(&retstr, suffix);
+
+ return retstr.data;
+}
+#endif
+
+static bool BackendWeightAssignFunc (ConfigContext context, double newval, int index, int elevel)
+{
+ double old_v = g_pool_config.backend_desc->backend_info[index].unnormalized_weight;
+ g_pool_config.backend_desc->backend_info[index].unnormalized_weight = newval;
+ /*
+ * Log weight change event only when context is
+ * reloading of pgpool.conf and weight is actually
+ * changed
+ */
+ if (context == CFGCXT_RELOAD && old_v != newval)
+ {
+ ereport(LOG,
+ (errmsg("initializing pool configuration: backend weight for backend:%d changed from %f to %f", index, old_v, newval),
+ errdetail("This change will be effective from next client session")));
+ }
+ return true;
+}
+
+
+static bool BackendPortAssignFunc (ConfigContext context, int newval, int index, int elevel)
+{
+ BACKEND_STATUS backend_status = g_pool_config.backend_desc->backend_info[index].backend_status;
+
+ if (context <= CFGCXT_INIT)
+ {
+ g_pool_config.backend_desc->backend_info[index].backend_port = newval;
+ g_pool_config.backend_desc->backend_info[index].backend_status = CON_CONNECT_WAIT;
+ }
+ else if (backend_status == CON_UNUSED)
+ {
+ g_pool_config.backend_desc->backend_info[index].backend_port = newval;
+ g_pool_config.backend_desc->backend_info[index].backend_status = CON_DOWN;
+ }
+ else
+ {
+ ereport(elevel,
+ (errmsg("backend_port%d cannot be changed",index)));
+ return false;
+ }
+ return true;
+}
+
+static bool BackendHostAssignFunc (ConfigContext context, char* newval, int index, int elevel)
+{
+ BACKEND_STATUS backend_status = g_pool_config.backend_desc->backend_info[index].backend_status;
+ if (context <= CFGCXT_INIT || backend_status == CON_UNUSED)
+ {
+ if (newval == NULL || strlen(newval) == 0)
+ g_pool_config.backend_desc->backend_info[index].backend_hostname[0] = '\0';
+ else
+ strlcpy(g_pool_config.backend_desc->backend_info[index].backend_hostname, newval, MAX_DB_HOST_NAMELEN-1);
+ return true;
+ }
+ ereport(elevel,
+ (errmsg("backend_hostname%d cannot be changed",index)));
+ return false;
+}
+
+static bool BackendDataDirAssignFunc (ConfigContext context, char* newval, int index, int elevel)
+{
+ BACKEND_STATUS backend_status = g_pool_config.backend_desc->backend_info[index].backend_status;
+ if (context <= CFGCXT_INIT || backend_status == CON_UNUSED || backend_status == CON_DOWN)
+ {
+ if (newval == NULL || strlen(newval) == 0)
+ g_pool_config.backend_desc->backend_info[index].backend_data_directory[0] = '\0';
+ else
+ strlcpy(g_pool_config.backend_desc->backend_info[index].backend_data_directory, newval, MAX_PATH_LENGTH-1);
+ return true;
+ }
+ ereport(elevel,
+ (errmsg("backend_data_directory%d cannot be changed",index)));
+ return false;
+}
+
+static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int index, int elevel)
+{
+
+ unsigned short flag = 0;
+ int i,n;
+ bool allow_to_failover_is_specified = false;
+ bool disallow_to_failover_is_specified = false;
+ char **flags;
+
+ flags = get_list_from_string(newval, "|", &n);
+ if (!flags || n < 0)
+ {
+ ereport(elevel,
+ (errmsg("invalid configuration for key \"backend_flag%d\"",index),
+ errdetail("unable to get backend flags")));
+ return false;
+ }
+
+ for (i=0;i<n;i++)
+ {
+ if (!strcmp(flags[i], "ALLOW_TO_FAILOVER"))
+ {
+ if (disallow_to_failover_is_specified)
+ {
+ ereport(elevel,
+ (errmsg("invalid configuration for key \"backend_flag%d\"",index),
+ errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
+ return false;
+ }
+ flag &= ~POOL_FAILOVER;
+ allow_to_failover_is_specified = true;
+
+ }
+
+ else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER"))
+ {
+ if (allow_to_failover_is_specified)
+ {
+ ereport(elevel,
+ (errmsg("invalid configuration for key \"backend_flag%d\"",index),
+ errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
+ return false;
+ }
+ flag |= POOL_FAILOVER;
+ disallow_to_failover_is_specified = true;
+ }
+
+ else
+ {
+ ereport(elevel,
+ (errmsg("invalid configuration for key \"backend_flag%d\"",index),
+ errdetail("unknown backend flag:%s", flags[i])));
+ return false;
+ }
+ }
+
+ g_pool_config.backend_desc->backend_info[index].flag = flag;
+ ereport(DEBUG1,
+ (errmsg("invalid configuration for key \"backend_flag%d\"",index),
+ errdetail("backend slot number %d flag: %04x", index, flag)));
+ return true;
+}
+
+/* Watchdog Assign functions */
+/*other_pgpool_hostname*/
+static bool OtherPPHostAssignFunc (ConfigContext context, char* newval, int index, int elevel)
+{
+ if (newval == NULL || strlen(newval) == 0)
+ g_pool_config.wd_remote_nodes.wd_remote_node_info[index].hostname[0] = '\0';
+ else
+ strlcpy(g_pool_config.wd_remote_nodes.wd_remote_node_info[index].hostname, newval, MAX_DB_HOST_NAMELEN-1);
+ return true;
+}
+
+/*other_pgpool_port*/
+static bool OtherPPPortAssignFunc (ConfigContext context, int newval, int index, int elevel)
+{
+ g_pool_config.wd_remote_nodes.wd_remote_node_info[index].pgpool_port = newval;
+ return true;
+}
+
+/*other_wd_port*/
+static bool OtherWDPortAssignFunc (ConfigContext context, int newval, int index, int elevel)
+{
+ g_pool_config.wd_remote_nodes.wd_remote_node_info[index].wd_port = newval;
+ return true;
+}
+
+/*heartbeat_device*/
+static bool HBDeviceAssignFunc (ConfigContext context, char* newval, int index, int elevel)
+{
+ if (newval == NULL || strlen(newval) == 0)
+ g_pool_config.hb_if[index].if_name[0] = '\0';
+ else
+ strlcpy(g_pool_config.hb_if[index].if_name, newval, WD_MAX_IF_NAME_LEN);
+ return true;
+}
+
+/*heartbeat_destination*/
+static bool HBDestinationAssignFunc (ConfigContext context, char* newval, int index, int elevel)
+{
+ if (newval == NULL || strlen(newval) == 0)
+ g_pool_config.hb_if[index].addr[0] = '\0';
+ else
+ strlcpy(g_pool_config.hb_if[index].addr, newval, WD_MAX_HOST_NAMELEN -1);
+ return true;
+}
+
+/*heartbeat_destination_port*/
+static bool HBDestinationPortAssignFunc (ConfigContext context, int newval, int index, int elevel)
+{
+ g_pool_config.hb_if[index].dest_port = newval;
+ return true;
+}
+
+/*
+ * Check DB node spec. node spec should be either "primary", "standby" or
+ * numeric DB node id.
+ */
+static bool check_redirect_node_spec(char *node_spec)
+{
+ int len = strlen(node_spec);
+ int i;
+ int64 val;
+
+ if (len <= 0)
+ return false;
+
+ if (strcasecmp("primary", node_spec) == 0)
+ {
+ return true;
+ }
+
+ if (strcasecmp("standby", node_spec) == 0)
+ {
+ return true;
+ }
+
+ for (i=0;i<len;i++)
+ {
+ if (!isdigit((int)node_spec[i]))
+ return false;
+ }
+
+ val = pool_atoi64(node_spec);
+
+ if (val >=0 && val < MAX_NUM_BACKENDS)
+ return true;
+
+ return false;
+}
+
+static bool config_post_processor(ConfigContext context, int elevel)
+{
+ double total_weight = 0.0;
+ sig_atomic_t local_num_backends = 0;
+ int i;
+
+ if (context == CFGCXT_BOOT)
+ {
+ char localhostname[256];
+ int res = gethostname(localhostname,sizeof(localhostname));
+ if(res !=0 )
+ {
+ ereport(WARNING,
+ (errmsg("initializing pool configuration"),
+ errdetail("failed to get the local hostname")));
+ return false;
+ }
+ g_pool_config.wd_hostname = pstrdup(localhostname);
+ return true;
+ }
+ for (i=0;i<MAX_CONNECTION_SLOTS;i++)
+ {
+ BackendInfo *backend_info = &g_pool_config.backend_desc->backend_info[i];
+
+ /* port number == 0 indicates that this server is out of use */
+ if (backend_info->backend_port == 0)
+ {
+ *backend_info->backend_hostname = '\0';
+ backend_info->backend_status = CON_UNUSED;
+ backend_info->backend_weight = 0.0;
+ }
+ else
+ {
+ total_weight += backend_info->unnormalized_weight;
+ local_num_backends = i+1;
+
+ /* initialize backend_hostname with a default socket path if empty */
+ if (*(backend_info->backend_hostname) == '\0')
+ {
+ ereport(LOG,
+ (errmsg("initializing pool configuration"),
+ errdetail("empty backend_hostname%d, use PostgreSQL's default unix socket path (%s)",
+ i, DEFAULT_SOCKET_DIR)));
+ strlcpy(backend_info->backend_hostname, DEFAULT_SOCKET_DIR, MAX_DB_HOST_NAMELEN);
+ }
+ }
+ }
+
+ if (local_num_backends != pool_config->backend_desc->num_backends)
+ pool_config->backend_desc->num_backends = local_num_backends;
+
+ ereport(DEBUG1,
+ (errmsg("initializing pool configuration"),
+ errdetail("num_backends: %d total_weight: %f",
+ pool_config->backend_desc->num_backends, total_weight)));
+ /*
+ * Normalize load balancing weights. What we are doing here is,
+ * assign 0 to RAND_MAX to each backend's weight according to the
+ * value weightN. For example, if two backends are assigned 1.0,
+ * then each backend will get RAND_MAX/2 normalized weight.
+ */
+ for (i=0;i<MAX_CONNECTION_SLOTS;i++)
+ {
+ BackendInfo *backend_info = &g_pool_config.backend_desc->backend_info[i];
+
+ if (backend_info->backend_port != 0)
+ {
+ backend_info->backend_weight =
+ (RAND_MAX) * backend_info->unnormalized_weight / total_weight;
+
+ ereport(DEBUG1,
+ (errmsg("initializing pool configuration"),
+ errdetail("backend %d weight: %f flag: %04x", i, backend_info->backend_weight,backend_info->flag)));
+ }
+ }
+
+ /* Set the number of configured Watchdog nodes */
+ g_pool_config.wd_remote_nodes.num_wd = 0;
+ for (i=0; i< MAX_WATCHDOG_NUM; i++ )
+ {
+ WdRemoteNodeInfo* wdNode = &g_pool_config.wd_remote_nodes.wd_remote_node_info[i];
+ if (wdNode->wd_port > 0)
+ g_pool_config.wd_remote_nodes.num_wd = i + 1;
+ }
+
+ /* Set the number of configured heartbeat interfaces */
+ g_pool_config.num_hb_if = 0;
+ for (i=0; i< WD_MAX_IF_NUM; i++ )
+ {
+ if (g_pool_config.hb_if[i].dest_port > 0)
+ g_pool_config.num_hb_if = i + 1;
+ }
+
+
+ if (strcmp(pool_config->recovery_1st_stage_command, "") ||
+ strcmp(pool_config->recovery_2nd_stage_command, ""))
+ {
+ for (i=0;i<MAX_CONNECTION_SLOTS;i++)
+ {
+ BackendInfo *backend_info = &g_pool_config.backend_desc->backend_info[i];
+
+ if (backend_info->backend_port != 0 &&
+ !strcmp(backend_info->backend_data_directory, ""))
+ {
+ ereport(elevel,
+ (errmsg("invalid configuration, recovery_1st_stage_command and recovery_2nd_stage_command requires backend_data_directory to be set")));
+ return false;
+ }
+ }
+ }
+
+#ifndef POOL_PRIVATE
+ /* finally set syslog parameters */
+ if ( strcmp(g_pool_config.log_destination,"syslog") == 0)
+ set_syslog_parameters(g_pool_config.syslog_ident ? g_pool_config.syslog_ident : "pgpool",
+ g_pool_config.syslog_facility);
+
+#endif
+ return true;
+}
+
+static bool MakeAppRedirectListRegex (char* newval, int error_level)
+{
+ /* TODO Deal with the memory */
+ int i;
+ Left_right_tokens *lrtokens;
+
+ if (newval == NULL)
+ {
+ pool_config->redirect_app_names = NULL;
+ pool_config->app_name_redirect_tokens = NULL;
+ return true;
+ }
+
+ lrtokens = create_lrtoken_array();
+ extract_string_tokens2(newval, ",", ':', lrtokens);
+
+ pool_config->redirect_app_names = create_regex_array();
+ pool_config->app_name_redirect_tokens = lrtokens;
+
+ for (i=0;i<lrtokens->pos;i++)
+ {
+ if (!check_redirect_node_spec(lrtokens->token[i].right_token))
+ {
+ ereport(error_level,
+ (errmsg("invalid configuration for key \"app_name_redirect_preference_list\""),
+ errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
+ return false;
+ }
+
+
+ if (*(lrtokens->token[i].left_token) == '\0' ||
+ add_regex_array(pool_config->redirect_app_names, lrtokens->token[i].left_token))
+ {
+ ereport(error_level,
+ (errmsg("invalid configuration for key \"app_name_redirect_preference_list\""),
+ errdetail("wrong redirect app name regular expression: \"%s\"", lrtokens->token[i].left_token)));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool MakeDBRedirectListRegex (char* newval, int error_level)
+{
+ /* TODO Deal with the memory */
+ int i;
+ Left_right_tokens *lrtokens;
+ if (newval == NULL)
+ {
+ pool_config->redirect_dbnames = NULL;
+ pool_config->db_redirect_tokens = NULL;
+ return true;
+ }
+
+ lrtokens = create_lrtoken_array();
+ extract_string_tokens2(newval, ",", ':', lrtokens);
+
+ pool_config->redirect_dbnames = create_regex_array();
+ pool_config->db_redirect_tokens = lrtokens;
+
+ for (i=0;i<lrtokens->pos;i++)
+ {
+ if (!check_redirect_node_spec(lrtokens->token[i].right_token))
+ {
+ ereport(error_level,
+ (errmsg("invalid configuration for key \"database_redirect_preference_list\""),
+ errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
+ return false;
+ }
+
+ if (*(lrtokens->token[i].left_token) == '\0' ||
+ add_regex_array(pool_config->redirect_dbnames, lrtokens->token[i].left_token))
+ {
+ ereport(error_level,
+ (errmsg("invalid configuration for key \"database_redirect_preference_list\""),
+ errdetail("wrong redirect dbname regular expression: \"%s\"", lrtokens->token[i].left_token)));
+ return false;
+ }
+ }
+ return true;
+}
+
diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c
index c24016224..b8d23e823 100644
--- a/src/context/pool_query_context.c
+++ b/src/context/pool_query_context.c
@@ -190,7 +190,7 @@ void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context)
* send query.
*/
if (pool_config->master_slave_mode &&
- !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
+ pool_config->master_slave_sub_mode == STREAM_MODE &&
i != PRIMARY_NODE_ID && i != sc->load_balance_node_id)
{
continue;
@@ -409,7 +409,7 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no
/*
* If replication delay is too much, we prefer to send to the primary.
*/
- if (!strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
+ if (pool_config->master_slave_sub_mode == STREAM_MODE &&
pool_config->delay_threshold &&
bkinfo->standby_delay > pool_config->delay_threshold)
{
diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h
index ed86e7bee..f65d3a966 100644
--- a/src/include/pcp/libpcp_ext.h
+++ b/src/include/pcp/libpcp_ext.h
@@ -18,7 +18,7 @@
* is" without express or implied warranty.
*
*
- * libpcpcp_ext.h -
+ * libpcp_ext.h -
* This file contains definitions for structures and
* externs for functions used by frontend libpcp applications.
*/
diff --git a/src/include/pool.h b/src/include/pool.h
index 30759e0f4..4c6e82f75 100644
--- a/src/include/pool.h
+++ b/src/include/pool.h
@@ -342,8 +342,8 @@ extern int my_master_node_id;
#define REPLICATION (pool_config->replication_mode)
#define MASTER_SLAVE (pool_config->master_slave_mode)
-#define STREAM (MASTER_SLAVE && !strcmp("stream", pool_config->master_slave_sub_mode))
-#define SLONY (MASTER_SLAVE && !strcmp("slony", pool_config->master_slave_sub_mode))
+#define STREAM (MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE)
+#define SLONY (MASTER_SLAVE && pool_config->master_slave_sub_mode == SLONY_MODE)
#define DUAL_MODE (REPLICATION || MASTER_SLAVE)
#define RAW_MODE (!REPLICATION && !MASTER_SLAVE)
#define MAJOR(p) MASTER_CONNECTION(p)->sp->major
@@ -371,7 +371,7 @@ extern int my_master_node_id;
#define MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION 6 /*number of sec to wait for watchdog command if cluster is stabalizing */
-#define SERIALIZE_ACCEPT (pool_config->serialize_accept != 0 && \
+#define SERIALIZE_ACCEPT (pool_config->serialize_accept == true && \
pool_config->child_life_time == 0)
/*
diff --git a/src/include/pool_config.h b/src/include/pool_config.h
index 5dbbc2693..e170a00e5 100644
--- a/src/include/pool_config.h
+++ b/src/include/pool_config.h
@@ -6,7 +6,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2015 PgPool Global Development Group
+ * Copyright (c) 2003-2016 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -36,19 +36,6 @@
#define WD_MAX_IF_NUM (256)
#define WD_MAX_IF_NAME_LEN (16)
-/*
- * Master/slave sub mode
- */
-#define MODE_STREAMREP "stream" /* Streaming Replication */
-#define MODE_SLONY "slony" /* Slony-I */
-
-/*
- * watchdog lifecheck method
- */
-#define MODE_HEARTBEAT "heartbeat"
-#define MODE_QUERY "query"
-#define MODE_EXTERNAL "external"
-
#include "utils/regex_array.h"
/*
* Regex support in white and black list function
@@ -64,6 +51,33 @@ typedef struct {
regex_t regexv;
} RegPattern;
+typedef enum MasterSlaveSubModes
+{
+ SLONY_MODE = 1,
+ STREAM_MODE
+}MasterSlaveSubModes;
+
+typedef enum LogStandbyDelayModes
+{
+ LSD_ALWAYS = 1,
+ LSD_OVER_THRESHOLD,
+ LSD_NONE
+}LogStandbyDelayModes;
+
+
+typedef enum MemCacheMethod
+{
+ SHMEM_CACHE = 1,
+ MEMCACHED_CACHE
+}MemCacheMethod;
+
+typedef enum WdLifeCheckMethod
+{
+ LIFECHECK_BY_QUERY = 1,
+ LIFECHECK_BY_HB,
+ LIFECHECK_BY_EXTERNAL
+}WdLifeCheckMethod;
+
/*
* Flags for backendN_flag
*/
@@ -99,233 +113,236 @@ typedef struct {
* configuration parameters
*/
typedef struct {
- char *listen_addresses; /* hostnames/IP addresses to listen on */
- int port; /* port # to bind */
+ char *listen_addresses; /* hostnames/IP addresses to listen on */
+ int port; /* port # to bind */
char *pcp_listen_addresses; /* PCP listen address to listen on */
- int pcp_port; /* PCP port # to bind */
- char *socket_dir; /* pgpool socket directory */
- char *wd_ipc_socket_dir; /* watchdog command IPC socket directory */
- char *pcp_socket_dir; /* PCP socket directory */
- int num_init_children; /* # of children initially pre-forked */
- int listen_backlog_multiplier; /* determines the size of the connection queue */
- int serialize_accept; /* if non 0, serialize call to accept() to avoid thundering herd problem */
- int child_life_time; /* if idle for this seconds, child exits */
- int connection_life_time; /* if idle for this seconds, connection closes */
- int child_max_connections; /* if max_connections received, child exits */
- int client_idle_limit; /* If client_idle_limit is n (n > 0), the client is forced to be
- disconnected after n seconds idle */
- int authentication_timeout; /* maximum time in seconds to complete client authentication */
- int max_pool; /* max # of connection pool per child */
- char *logdir; /* logging directory */
- char *log_destination; /* log destination: stderr or syslog */
- int syslog_facility; /* syslog facility: LOCAL0, LOCAL1, ... */
- char *syslog_ident; /* syslog ident string: pgpool */
- char *pid_file_name; /* pid file name */
- int replication_mode; /* replication mode */
-
- int log_connections; /* 0:false, 1:true - logs incoming connections */
- int log_hostname; /* 0:false, 1:true - resolve hostname */
- int enable_pool_hba; /* 0:false, 1:true - enables pool_hba.conf file authentication */
- char *pool_passwd; /* pool_passwd file name. "" disables pool_passwd */
-
- int load_balance_mode; /* load balance mode */
-
- int replication_stop_on_mismatch; /* if there's a data mismatch between master and secondary
- * start degeneration to stop replication mode
- */
-
- /* If there's a disagreement with the number of affected tuples in
- * UPDATE/DELETE, then degenerate the node which is most likely
- * "minority". # If false, just abort the transaction to keep the
- * consistency.*/
- int failover_if_affected_tuples_mismatch;
-
- int replicate_select; /* if non 0, replicate SELECT statement when load balancing is disabled. */
+ int pcp_port; /* PCP port # to bind */
+ char *socket_dir; /* pgpool socket directory */
+ char *wd_ipc_socket_dir; /* watchdog command IPC socket directory */
+ char *pcp_socket_dir; /* PCP socket directory */
+ int num_init_children; /* # of children initially pre-forked */
+ int listen_backlog_multiplier; /* determines the size of the connection queue */
+ bool serialize_accept; /* if non 0, serialize call to accept() to avoid thundering herd problem */
+ int child_life_time; /* if idle for this seconds, child exits */
+ int connection_life_time; /* if idle for this seconds, connection closes */
+ int child_max_connections; /* if max_connections received, child exits */
+ int client_idle_limit; /* If client_idle_limit is n (n > 0), the client is forced to be
+ *disconnected after n seconds idle */
+ int authentication_timeout; /* maximum time in seconds to complete client authentication */
+ int max_pool; /* max # of connection pool per child */
+ char *logdir; /* logging directory */
+ char *log_destination; /* log destination: stderr or syslog */
+ int syslog_facility; /* syslog facility: LOCAL0, LOCAL1, ... */
+ char *syslog_ident; /* syslog ident string: pgpool */
+ char *pid_file_name; /* pid file name */
+ bool replication_mode; /* replication mode */
+ bool log_connections; /* logs incoming connections */
+ bool log_hostname; /* resolve hostname */
+ bool enable_pool_hba; /* enables pool_hba.conf file authentication */
+ char *pool_passwd; /* pool_passwd file name. "" disables pool_passwd */
+ bool load_balance_mode; /* load balance mode */
+
+ bool replication_stop_on_mismatch; /* if there's a data mismatch between master and secondary
+ * start degeneration to stop replication mode
+ */
+ bool failover_if_affected_tuples_mismatch; /* If there's a disagreement with the number of affected tuples in
+ * UPDATE/DELETE, then degenerate the node which is most likely
+ * "minority". # If false, just abort the transaction to keep the
+ * consistency.
+ */
+ bool replicate_select; /* replicate SELECT statement when load balancing is disabled. */
char **reset_query_list; /* comma separated list of queries to be issued at the end of session */
char **white_function_list; /* list of functions with no side effects */
char **black_function_list; /* list of functions with side effects */
- char *log_line_prefix; /* printf-style string to output at beginning of each log line */
- int log_error_verbosity; /* controls how much detail about error should be emitted */
- int client_min_messages; /*controls which message should be sent to client */
- int log_min_messages; /*controls which message should be emitted to server log */
- int master_slave_mode; /* if non 0, operate in master/slave mode */
- char *master_slave_sub_mode; /* either "slony" or "stream" */
- unsigned long long int delay_threshold; /* If the standby server delays more than delay_threshold,
- * any query goes to the primary only. The unit is in bytes.
- * 0 disables the check. Default is 0.
- * Note that health_check_period required to be greater than 0
- * to enable the functionality. */
- char *log_standby_delay; /* how to log standby lag */
- int connection_cache; /* if non 0, cache connection pool */
- int health_check_timeout; /* health check timeout */
- int health_check_period; /* health check period */
- char *health_check_user; /* PostgreSQL user name for health check */
- char *health_check_password; /* password for health check username */
- char *health_check_database; /* database name for health check username */
- int health_check_max_retries; /* health check max retries */
- int health_check_retry_delay; /* amount of time to wait between retries */
- int connect_timeout; /* timeout value before giving up connecting to backend */
- int sr_check_period; /* streaming replication check period */
- char *sr_check_user; /* PostgreSQL user name for streaming replication check */
- char *sr_check_password; /* password for sr_check_user */
- char *sr_check_database; /* PostgreSQL database name for streaming replication check */
- char *failover_command; /* execute command when failover happens */
- char *follow_master_command; /* execute command when failover is ended */
- char *failback_command; /* execute command when failback happens */
+ char *log_line_prefix; /* printf-style string to output at beginning of each log line */
+ int log_error_verbosity; /* controls how much detail about error should be emitted */
+ int client_min_messages; /* controls which message should be sent to client */
+ int log_min_messages; /* controls which message should be emitted to server log */
+ bool master_slave_mode; /* operate in master/slave mode */
+ MasterSlaveSubModes master_slave_sub_mode; /* either "slony" or "stream" */
+ int64 delay_threshold; /* If the standby server delays more than delay_threshold,
+ * any query goes to the primary only. The unit is in bytes.
+ * 0 disables the check. Default is 0.
+ * Note that health_check_period required to be greater than 0
+ * to enable the functionality.
+ */
+ LogStandbyDelayModes log_standby_delay; /* how to log standby lag */
+ bool connection_cache; /* cache connection pool? */
+ int health_check_timeout; /* health check timeout */
+ int health_check_period; /* health check period */
+ char *health_check_user; /* PostgreSQL user name for health check */
+ char *health_check_password; /* password for health check username */
+ char *health_check_database; /* database name for health check username */
+ int health_check_max_retries; /* health check max retries */
+ int health_check_retry_delay; /* amount of time to wait between retries */
+ int connect_timeout; /* timeout value before giving up connecting to backend */
+ int sr_check_period; /* streaming replication check period */
+ char *sr_check_user; /* PostgreSQL user name for streaming replication check */
+ char *sr_check_password; /* password for sr_check_user */
+ char *sr_check_database; /* PostgreSQL database name for streaming replication check */
+ char *failover_command; /* execute command when failover happens */
+ char *follow_master_command; /* execute command when failover is ended */
+ char *failback_command; /* execute command when failback happens */
+
+ bool fail_over_on_backend_error; /* If true, trigger fail over when writing to the backend
+ * communication socket fails. This is the same behavior of
+ * pgpool-II 2.2.x or earlier. If set to false, pgpool will report
+ * an error and disconnect the session.
+ */
- /*
- * If true, trigger fail over when writing to the backend
- * communication socket fails. This is the same behavior of
- * pgpool-II 2.2.x or earlier. If set to false, pgpool will report
- * an error and disconnect the session.
- */
- int fail_over_on_backend_error;
-
- char *recovery_user; /* PostgreSQL user name for online recovery */
- char *recovery_password; /* PostgreSQL user password for online recovery */
- char *recovery_1st_stage_command; /* Online recovery command in 1st stage */
- char *recovery_2nd_stage_command; /* Online recovery command in 2nd stage */
- int recovery_timeout; /* maximum time in seconds to wait for remote start-up */
- int search_primary_node_timeout; /* maximum time in seconds to search for new primary
- * node after failover */
+ char *recovery_user; /* PostgreSQL user name for online recovery */
+ char *recovery_password; /* PostgreSQL user password for online recovery */
+ char *recovery_1st_stage_command; /* Online recovery command in 1st stage */
+ char *recovery_2nd_stage_command; /* Online recovery command in 2nd stage */
+ int recovery_timeout; /* maximum time in seconds to wait for remote start-up */
+ int search_primary_node_timeout; /* maximum time in seconds to search for new primary
+ * node after failover
+ */
int client_idle_limit_in_recovery; /* If > 0, the client is forced to be
* disconnected after n seconds idle
- * This parameter is only valid while in recovery 2nd stage */
- int insert_lock; /* if non 0, automatically lock table with INSERT to keep SERIAL
- data consistency */
- int ignore_leading_white_space; /* ignore leading white spaces of each query */
- int log_statement; /* 0:false, 1: true - logs all SQL statements */
- int log_per_node_statement; /* 0:false, 1: true - logs per node detailed SQL statements */
-
- char *lobj_lock_table; /* table name to lock for rewriting lo_creat */
+ * This parameter is only valid while in recovery 2nd stage
+ */
+ bool insert_lock; /* automatically locking of table with INSERT to keep SERIAL data consistency?
+ */
+ bool ignore_leading_white_space; /* ignore leading white spaces of each query */
+ bool log_statement; /* logs all SQL statements */
+ bool log_per_node_statement; /* logs per node detailed SQL statements */
+ char *lobj_lock_table; /* table name to lock for rewriting lo_creat */
- int debug_level; /* debug message verbosity level.
- * 0: no message, 1 <= : more verbose
- */
+ int debug_level; /* debug message verbosity level.
+ * 0: no message, 1 <= : more verbose
+ */
- BackendDesc *backend_desc; /* PostgreSQL Server description. Placed on shared memory */
+ BackendDesc *backend_desc; /* PostgreSQL Server description. Placed on shared memory */
LOAD_BALANCE_STATUS load_balance_status[MAX_NUM_BACKENDS]; /* to remember which DB node is selected for load balancing */
- /* followings do not exist in the configuration file */
- int num_reset_queries; /* number of queries in reset_query_list */
- int num_white_function_list; /* number of functions in white_function_list */
- int num_black_function_list; /* number of functions in black_function_list */
+ /* followings till syslog, does not exist in the configuration file */
+ int num_reset_queries; /* number of queries in reset_query_list */
+ int num_white_function_list; /* number of functions in white_function_list */
+ int num_black_function_list; /* number of functions in black_function_list */
int num_white_memqcache_table_list; /* number of functions in white_memqcache_table_list */
int num_black_memqcache_table_list; /* number of functions in black_memqcache_table_list */
int num_wd_monitoring_interfaces_list; /* number of items in wd_monitoring_interfaces_list */
- int logsyslog; /* flag used to start logging to syslog */
+ int logsyslog; /* flag used to start logging to syslog */
/* ssl configuration */
- int ssl; /* if non 0, activate ssl support (frontend+backend) */
- char *ssl_cert; /* path to ssl certificate (frontend only) */
- char *ssl_key; /* path to ssl key (frontend only) */
- char *ssl_ca_cert; /* path to root (CA) certificate */
- char *ssl_ca_cert_dir; /* path to directory containing CA certificates */
+ bool ssl; /* if non 0, activate ssl support (frontend+backend) */
+ char *ssl_cert; /* path to ssl certificate (frontend only) */
+ char *ssl_key; /* path to ssl key (frontend only) */
+ char *ssl_ca_cert; /* path to root (CA) certificate */
+ char *ssl_ca_cert_dir; /* path to directory containing CA certificates */
- time_t relcache_expire; /* relation cache life time in seconds */
- int relcache_size; /* number of relation cache life entry */
- int check_temp_table; /* enable temporary table check */
- int check_unlogged_table; /* enable unlogged table check */
+ int64 relcache_expire; /* relation cache life time in seconds */
+ int relcache_size; /* number of relation cache life entry */
+ bool check_temp_table; /* enable temporary table check */
+ bool check_unlogged_table; /* enable unlogged table check */
/* followings are for regex support and do not exist in the configuration file */
- RegPattern *lists_patterns; /* Precompiled regex patterns for black/white lists */
- int pattc; /* number of regexp pattern */
- int current_pattern_size; /* size of the regex pattern array */
-
- int memory_cache_enabled; /* if true, use the memory cache functionality, false by default */
- char *memqcache_method; /* Cache store method. Either 'shmem'(shared memory) or 'memcached'. 'shmem' by default */
- char *memqcache_memcached_host; /* Memcached host name. Mandatory if memqcache_method=memcached. */
- int memqcache_memcached_port; /* Memcached port number. Mandatory if memqcache_method=memcached. */
- int64 memqcache_total_size; /* Total memory size in bytes for storing memory cache. Mandatory if memqcache_method=shmem. */
- int memqcache_max_num_cache; /* Total number of cache entries. Mandatory if memqcache_method=shmem. */
- int memqcache_expire; /* Memory cache entry life time specified in seconds. 60 by default. */
- int memqcache_auto_cache_invalidation; /* If true, invalidation of query cache is triggered by corresponding */
- /* DDL/DML/DCL(and memqcache_expire). If false, it is only triggered */
- /* by memqcache_expire. True by default. */
- int memqcache_maxcache; /* Maximum SELECT result size in bytes. */
- int memqcache_cache_block_size; /* Cache block size in bytes. 8192 by default */
- char *memqcache_oiddir; /* Temporary work directory to record table oids */
+ RegPattern *lists_patterns; /* Precompiled regex patterns for black/white lists */
+ int pattc; /* number of regexp pattern */
+ int current_pattern_size; /* size of the regex pattern array */
+
+ bool memory_cache_enabled; /* if true, use the memory cache functionality, false by default */
+ MemCacheMethod memqcache_method; /* Cache store method. Either 'shmem'(shared memory) or 'memcached'. 'shmem' by default */
+ char *memqcache_memcached_host; /* Memcached host name. Mandatory if memqcache_method=memcached. */
+ int memqcache_memcached_port; /* Memcached port number. Mandatory if memqcache_method=memcached. */
+ int64 memqcache_total_size; /* Total memory size in bytes for storing memory cache. Mandatory if memqcache_method=shmem. */
+ int memqcache_max_num_cache; /* Total number of cache entries. Mandatory if memqcache_method=shmem. */
+ int memqcache_expire; /* Memory cache entry life time specified in seconds. 60 by default. */
+ bool memqcache_auto_cache_invalidation; /* If true, invalidation of query cache is triggered by corresponding */
+ /* DDL/DML/DCL(and memqcache_expire). If false, it is only triggered */
+ /* by memqcache_expire. True by default. */
+ int memqcache_maxcache; /* Maximum SELECT result size in bytes. */
+ int memqcache_cache_block_size; /* Cache block size in bytes. 8192 by default */
+ char *memqcache_oiddir; /* Temporary work directory to record table oids */
char **white_memqcache_table_list; /* list of tables to memqcache */
char **black_memqcache_table_list; /* list of tables not to memqcache */
RegPattern *lists_memqcache_table_patterns; /* Precompiled regex patterns for black/white lists */
- int memqcache_table_pattc; /* number of regexp pattern */
- int current_memqcache_table_pattern_size; /* size of the regex pattern array */
+ int memqcache_table_pattc; /* number of regexp pattern */
+ int current_memqcache_table_pattern_size; /* size of the regex pattern array */
/*
* database_redirect_preference_list = 'postgres:primary,mydb[0-4]:1,mydb[5-9]:2'
*/
char *database_redirect_preference_list; /* raw string in pgpool.conf */
- RegArray *redirect_dbnames; /* Precompiled regex patterns for db prefrence list */
- Left_right_tokens *db_redirect_tokens; /* db redirect for dbname and node string */
+ RegArray *redirect_dbnames; /* Precompiled regex patterns for db prefrence list */
+ Left_right_tokens *db_redirect_tokens; /* db redirect for dbname and node string */
/*
* app_name_redirect_preference_list = 'psql:primary,myapp[0-4]:1,myapp[5-9]:standby'
*/
char *app_name_redirect_preference_list; /* raw string in pgpool.conf */
- RegArray *redirect_app_names; /* Precompiled regex patterns for app name prefrence list */
- Left_right_tokens *app_name_redirect_tokens; /* app name redirect for app_name and node string */
-
- /*
- * if on, ignore SQL comments when judging if load balance or query cache
- * is possible. If off, SQL comments effectively prevent the judgment
- * (pre 3.4 behavior). For backward compatibilty sake, default is off.
- */
- int allow_sql_comments;
+ RegArray *redirect_app_names; /* Precompiled regex patterns for app name prefrence list */
+ Left_right_tokens *app_name_redirect_tokens;/* app name redirect for app_name and node string */
+ bool allow_sql_comments; /* if on, ignore SQL comments when judging if load balance or query cache
+ * is possible. If off, SQL comments effectively prevent the judgment
+ * (pre 3.4 behavior). For backward compatibilty sake, default is off.
+ */
/*
* add for watchdog
*/
- int use_watchdog; /* if non 0, use watchdog */
- char *wd_lifecheck_method; /* method of lifecheck. 'heartbeat' or 'query' */
- int clear_memqcache_on_escalation; /* if no 0, clear query cache on shmem when escalating */
- char *wd_escalation_command; /* Executes this command at escalation on new active pgpool.*/
- char *wd_de_escalation_command; /* Executes this command when master pgpool goes down.*/
- char *wd_hostname; /* watchdog hostname */
- int wd_port; /* watchdog port */
- int wd_priority; /* watchdog node priority, during leader election*/
- WdRemoteNodesConfig wd_remote_nodes;/* watchdog lists */
- char * trusted_servers; /* icmp reachable server list (A,B,C) */
- char * delegate_IP; /* delegate IP address */
- int wd_interval; /* lifecheck interval (sec) */
- char *wd_authkey; /* Authentication key for watchdog communication */
- char * ping_path; /* path to ping command */
- char * if_cmd_path; /* path to interface up/down command */
- char * if_up_cmd; /* ifup command */
- char * if_down_cmd; /* ifdown command */
- char * arping_path; /* path to arping command */
- char * arping_cmd; /* arping command */
- int wd_life_point; /* life point (retry times at lifecheck) */
- char *wd_lifecheck_query; /* lifecheck query */
- char *wd_lifecheck_dbname; /* Database name connected for lifecheck */
- char *wd_lifecheck_user; /* PostgreSQL user name for watchdog */
- char *wd_lifecheck_password; /* password for watchdog user */
- int wd_heartbeat_port; /* Port number for heartbeat lifecheck */
- int wd_heartbeat_keepalive; /* Interval time of sending heartbeat signal (sec) */
- int wd_heartbeat_deadtime; /* Deadtime interval for heartbeat signal (sec) */
- WdHbIf hb_if[WD_MAX_IF_NUM]; /* interface devices */
- int num_hb_if; /* number of interface devices */
- char **wd_monitoring_interfaces_list;/* network interface name list to be monitored by watchdog */
+ bool use_watchdog; /* Enables watchdog */
+ WdLifeCheckMethod wd_lifecheck_method; /* method of lifecheck. 'heartbeat' or 'query' */
+ bool clear_memqcache_on_escalation; /* Clear query cache on shmem when escalating ?*/
+ char *wd_escalation_command; /* Executes this command at escalation on new active pgpool.*/
+ char *wd_de_escalation_command; /* Executes this command when master pgpool goes down.*/
+ char *wd_hostname; /* watchdog hostname */
+ int wd_port; /* watchdog port */
+ int wd_priority; /* watchdog node priority, during leader election*/
+ WdRemoteNodesConfig wd_remote_nodes; /* watchdog lists */
+ char * trusted_servers; /* icmp reachable server list (A,B,C) */
+ char * delegate_IP; /* delegate IP address */
+ int wd_interval; /* lifecheck interval (sec) */
+ char *wd_authkey; /* Authentication key for watchdog communication */
+ char * ping_path; /* path to ping command */
+ char * if_cmd_path; /* path to interface up/down command */
+ char * if_up_cmd; /* ifup command */
+ char * if_down_cmd; /* ifdown command */
+ char * arping_path; /* path to arping command */
+ char * arping_cmd; /* arping command */
+ int wd_life_point; /* life point (retry times at lifecheck) */
+ char *wd_lifecheck_query; /* lifecheck query */
+ char *wd_lifecheck_dbname; /* Database name connected for lifecheck */
+ char *wd_lifecheck_user; /* PostgreSQL user name for watchdog */
+ char *wd_lifecheck_password; /* password for watchdog user */
+ int wd_heartbeat_port; /* Port number for heartbeat lifecheck */
+ int wd_heartbeat_keepalive; /* Interval time of sending heartbeat signal (sec) */
+ int wd_heartbeat_deadtime; /* Deadtime interval for heartbeat signal (sec) */
+ WdHbIf hb_if[WD_MAX_IF_NUM]; /* interface devices */
+ int num_hb_if; /* number of interface devices */
+ char **wd_monitoring_interfaces_list; /* network interface name list to be monitored by watchdog */
} POOL_CONFIG;
-typedef enum {
- INIT_CONFIG = 1, /* 0x01 */
- RELOAD_CONFIG = 2 /* 0x02 */
-} POOL_CONFIG_CONTEXT;
+extern POOL_CONFIG* pool_config;
+
+typedef enum
+{
+ CFGCXT_BOOT,
+ CFGCXT_INIT,
+ CFGCXT_RELOAD,
+ CFGCXT_PCP,
+ CFGCXT_SESSION
+} ConfigContext;
+
+typedef struct ConfigVariable
+{
+ char *name;
+ char *value;
+ int sourceline;
+ struct ConfigVariable *next;
+} ConfigVariable;
-extern POOL_CONFIG *pool_config; /* configuration values */
extern int pool_init_config(void);
-extern int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context);
-extern int eval_logical(char *str);
+extern bool pool_get_config(const char *config_file, ConfigContext context);
+extern int eval_logical(const char *str);
extern char *pool_flag_to_str(unsigned short flag);
-/* method use for syslog support */
-extern int set_syslog_facility (char *);
-
/* methods used for regexp support */
-extern int add_regex_pattern(char *type, char *s);
+extern int add_regex_pattern(const char *type, char *s);
extern int growFunctionPatternArray(RegPattern item);
extern int growMemqcacheTablePatternArray(RegPattern item);
diff --git a/src/include/pool_config_variables.h b/src/include/pool_config_variables.h
new file mode 100644
index 000000000..336185782
--- /dev/null
+++ b/src/include/pool_config_variables.h
@@ -0,0 +1,274 @@
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Copyright (c) 2003-2016 PgPool Global Development Group
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * pool_config_variables.h.
+ *
+ */
+
+#ifndef POOL_CONFIG_VARIABLES_H
+#define POOL_CONFIG_VARIABLES_H
+
+
+typedef enum
+{
+ CONNECTION_CONFIG,
+ CONNECTION_POOL_CONFIG,
+ LOGING_CONFIG,
+ HEALTH_CHECK_CONFIG,
+ FILE_LOCATION_CONFIG,
+ LOAD_BALANCE_CONFIG,
+ REPLICATION_CONFIG,
+ STREAMING_REPLICATION_CONFIG,
+ MASTER_SLAVE_CONFIG,
+ WATCHDOG_CONFIG,
+ SSL_CONFIG,
+ FAILOVER_CONFIG,
+ RECOVERY_CONFIG,
+ WATCHDOG_LIFECHECK,
+ GENERAL_CONFIG,
+ CACHE_CONFIG
+} config_group;
+
+typedef enum
+{
+ CONFIG_VAR_TYPE_BOOL,
+ CONFIG_VAR_TYPE_INT,
+ CONFIG_VAR_TYPE_LONG,
+ CONFIG_VAR_TYPE_DOUBLE,
+ CONFIG_VAR_TYPE_STRING,
+ CONFIG_VAR_TYPE_STRING_LIST,
+ CONFIG_VAR_TYPE_ENUM,
+ CONFIG_VAR_TYPE_INT_ARRAY,
+ CONFIG_VAR_TYPE_DOUBLE_ARRAY,
+ CONFIG_VAR_TYPE_STRING_ARRAY
+}config_type;
+
+/*
+ * The possible values of an enum variable are specified by an array of
+ * name-value pairs. The "hidden" flag means the value is accepted but
+ * won't be displayed when guc.c is asked for a list of acceptable values.
+ */
+struct config_enum_entry
+{
+ const char *name;
+ int val;
+ bool hidden;
+};
+
+typedef enum
+{
+ PGC_S_DEFAULT, /* hard-wired default ("boot_val") */
+ PGC_S_FILE, /* pgpool.conf */
+ PGC_S_ARGV, /* command line */
+ PGC_S_CLIENT, /* from client connection request */
+ PGC_S_SESSION /* SET command */
+} GucSource;
+
+/*
+ * Signatures for per-variable check/assign/show functions
+ */
+
+typedef const char *(*GucShowHook) (void);
+
+typedef bool (*ConfigBoolAssignFunc) (ConfigContext scontext, bool newval, int elevel);
+typedef bool (*ConfigEnumAssignFunc) (ConfigContext scontext, int newval, int elevel);
+
+typedef bool (*ConfigStringListAssignFunc) (ConfigContext scontext, char* newval, int index);
+
+typedef bool (*ConfigInt64AssignFunc) (ConfigContext scontext, int64 newval, int elevel);
+
+typedef bool (*ConfigStringAssignFunc) (ConfigContext scontext, char* newval, int elevel);
+typedef bool (*ConfigStringArrayAssignFunc) (ConfigContext scontext, char* newval, int index, int elevel);
+
+typedef bool (*ConfigIntAssignFunc) (ConfigContext scontext, int newval, int elevel);
+typedef bool (*ConfigIntArrayAssignFunc) (ConfigContext scontext, int newval, int index, int elevel);
+
+typedef bool (*ConfigDoubleAssignFunc) (ConfigContext scontext, double newval, int elevel);
+typedef bool (*ConfigDoubleArrayAssignFunc) (ConfigContext scontext, double newval, int index, int elevel);
+
+typedef bool (*ConfigStringProcessingFunc) (char* newval,int error_level);
+
+
+struct config_generic
+{
+ /* constant fields, must be set correctly in initial value: */
+ const char *name; /* name of variable - MUST BE FIRST */
+ ConfigContext context; /* context required to set the variable */
+ config_group group; /* to help organize variables by function */
+ const char *description; /* short desc. of this variable's purpose */
+ config_type vartype; /* type of variable (set only at startup) */
+ bool dynamic_array_var; /* true if the variable name contains index postfix */
+ int status; /* status bits, see below */
+ GucSource source; /* source of the current actual value */
+ ConfigContext scontext; /* context that set the current value */
+ int sourceline; /* line in source file */
+};
+
+/* GUC records for specific variable types */
+
+struct config_bool
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ bool *variable;
+ bool boot_val;
+ ConfigBoolAssignFunc assign_func;
+ ConfigBoolAssignFunc check_func;
+ GucShowHook show_hook;
+ bool reset_val;
+};
+
+struct config_int
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ int *variable;
+ int boot_val;
+ int min;
+ int max;
+ ConfigIntAssignFunc assign_func;
+ ConfigIntAssignFunc check_func;
+ GucShowHook show_hook;
+ int reset_val;
+};
+
+struct config_int_array
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ int **variable;
+ int boot_val;
+ int min;
+ int max;
+ int max_elements;
+ ConfigIntArrayAssignFunc assign_func;
+ ConfigIntArrayAssignFunc check_func;
+ GucShowHook show_hook;
+ int *reset_vals; /* Array of reset values */
+};
+
+
+struct config_double
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ double *variable;
+ double boot_val;
+ double min;
+ double max;
+ ConfigDoubleAssignFunc assign_func;
+ ConfigDoubleAssignFunc check_func;
+ GucShowHook show_hook;
+ double reset_val;
+};
+
+struct config_double_array
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ double **variable;
+ double boot_val;
+ double min;
+ double max;
+ int max_elements;
+ ConfigDoubleArrayAssignFunc assign_func;
+ ConfigDoubleArrayAssignFunc check_func;
+ GucShowHook show_hook;
+ double *reset_vals;
+};
+
+struct config_long
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ int64 *variable;
+ int64 boot_val;
+ int64 min;
+ int64 max;
+ ConfigInt64AssignFunc assign_func;
+ ConfigInt64AssignFunc check_func;
+ GucShowHook show_hook;
+ int64 reset_val;
+};
+
+struct config_string
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ char **variable;
+ const char *boot_val;
+ ConfigStringAssignFunc assign_func;
+ ConfigStringAssignFunc check_func;
+ ConfigStringProcessingFunc process_func;
+ GucShowHook show_hook;
+ char* reset_val;
+};
+
+struct config_string_array
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ char ***variable;
+ const char *boot_val;
+ int max_elements;
+ ConfigStringArrayAssignFunc assign_func;
+ ConfigStringArrayAssignFunc check_func;
+ GucShowHook show_hook;
+ char **reset_vals;
+};
+
+struct config_string_list
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ char ***variable;
+ int *list_elements_count;
+ const char *boot_val;
+ bool compute_regex;
+ ConfigStringListAssignFunc assign_func;
+ ConfigStringListAssignFunc check_func;
+ GucShowHook show_hook;
+ char *reset_val;
+};
+
+
+struct config_enum
+{
+ struct config_generic gen;
+ /* constant fields, must be set correctly in initial value: */
+ int *variable;
+ int boot_val;
+ const struct config_enum_entry *options;
+ ConfigEnumAssignFunc assign_func;
+ ConfigEnumAssignFunc check_func;
+ GucShowHook show_hook;
+ int reset_val;
+};
+
+extern void InitializeConfigOptions(void);
+extern bool set_one_config_option(const char *name, const char *value,
+ ConfigContext context, GucSource source, int elevel);
+
+extern bool set_config_options(ConfigVariable *head_p,
+ ConfigContext context, GucSource source, int elevel);
+extern bool assign_variable_to_int_array_config_var(const char* name, int** variable);
+
+#endif /* POOL_CONFIG_VARIABLES_H */
\ No newline at end of file
diff --git a/src/include/pool_type.h b/src/include/pool_type.h
index c2db66d81..5e70ed72e 100644
--- a/src/include/pool_type.h
+++ b/src/include/pool_type.h
@@ -73,7 +73,18 @@ typedef unsigned char uint8; /* == 8 bits */
typedef unsigned short uint16; /* == 16 bits */
typedef unsigned int uint32; /* == 32 bits */
+#ifdef HAVE_LONG_INT_64
+/* Plain "long int" fits, use it */
typedef long int int64;
+#define pool_atoi64 atol
+#elif defined(HAVE_LONG_LONG_INT_64)
+/* We have working support for "long long int", use that */
+typedef long long int int64;
+#define pool_atoi64 atoll
+#else
+/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
+#error must have a working 64-bit integer datatype
+#endif
typedef enum {
LOAD_UNSELECTED = 0,
diff --git a/src/include/utils/fe_ports.h b/src/include/utils/fe_ports.h
index 5eb18fa9f..b50ca2032 100644
--- a/src/include/utils/fe_ports.h
+++ b/src/include/utils/fe_ports.h
@@ -115,4 +115,13 @@ do { \
if(elevel >= ERROR) \
exit(-1); \
} while(0)
-#endif /* HAVE__BUILTIN_CONSTANT_P */
+
+
+typedef enum
+{
+ PGERROR_TERSE, /* single-line error messages */
+ PGERROR_DEFAULT, /* recommended style */
+ PGERROR_VERBOSE /* all the facts, ma'am */
+} PGErrorVerbosity;
+
+#endif /* FE_PORTS */
diff --git a/src/include/utils/json.h b/src/include/utils/json.h
index 3334a40a7..fe7bb96e1 100644
--- a/src/include/utils/json.h
+++ b/src/include/utils/json.h
@@ -67,6 +67,7 @@
#endif
#include <stdlib.h>
+#include <pool_type.h>
#ifdef __cplusplus
@@ -296,16 +297,17 @@ void json_value_free_ex (json_settings * settings,
json_value *);
- /* pgpool-II extensions */
- json_value* json_get_value_for_key(json_value* source, const char* key);
- int json_get_int_value_for_key(json_value* source, const char* key, int* value);
- int json_get_long_value_for_key(json_value* source, const char* key, long* value);
- char* json_get_string_value_for_key(json_value* source, const char* key);
-
#ifdef __cplusplus
} /* extern "C" */
#endif
+/* pgpool-II extensions */
+json_value* json_get_value_for_key(json_value* source, const char* key);
+int json_get_int_value_for_key(json_value* source, const char* key, int* value);
+int json_get_long_value_for_key(json_value* source, const char* key, long* value);
+char* json_get_string_value_for_key(json_value* source, const char* key);
+int json_get_bool_value_for_key(json_value* source, const char* key, bool* value);
+
#endif
diff --git a/src/include/utils/json_writer.h b/src/include/utils/json_writer.h
index f23ab4372..47e3947cf 100644
--- a/src/include/utils/json_writer.h
+++ b/src/include/utils/json_writer.h
@@ -48,10 +48,12 @@ extern JsonNode* jw_create_with_array(bool pretty_output);
extern JsonNode* jw_create_with_object(bool pretty_output);
extern bool jw_put_string(JsonNode* jNode, char* key, char* value);
extern bool jw_put_int(JsonNode* jNode, char* key, int value);
+extern bool jw_put_bool(JsonNode* jNode, char* key, bool value);
extern bool jw_put_long(JsonNode* jNode, char* key, long value);
extern bool jw_put_null(JsonNode* jNode, char* key);
extern bool jw_put_string_value(JsonNode* jNode, char* value);
extern bool jw_put_int_value(JsonNode* jNode, int value);
+extern bool jw_put_bool_value(JsonNode* jNode, bool value);
extern bool jw_put_long_value(JsonNode* jNode, long value);
extern bool jw_put_null_value(JsonNode* jNode);
extern bool jw_start_element(JsonNode* jNode, JWElementType element, char* key);
diff --git a/src/libs/pcp/Makefile.in b/src/libs/pcp/Makefile.in
index 0fc7d4e0f..eaebe484c 100644
--- a/src/libs/pcp/Makefile.in
+++ b/src/libs/pcp/Makefile.in
@@ -84,11 +84,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
$(include_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \
- $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/c-compiler.m4 $(top_srcdir)/c-library.m4 \
+ $(top_srcdir)/general.m4 \
$(top_srcdir)/ac_func_accept_argtypes.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -209,18 +209,15 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOG = @CATALOG@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-COLLATEINDEX = @COLLATEINDEX@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
-DOCBOOKSTYLE = @DOCBOOKSTYLE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -235,7 +232,6 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JADE = @JADE@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
@@ -258,7 +254,6 @@ MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
-NSGMLS = @NSGMLS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OSX = @OSX@
@@ -311,7 +306,6 @@ datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
-have_docbook = @have_docbook@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
diff --git a/src/main/main.c b/src/main/main.c
index 651205285..6452df302 100644
--- a/src/main/main.c
+++ b/src/main/main.c
@@ -5,7 +5,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2015 PgPool Global Development Group
+ * Copyright (c) 2003-2016 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -61,6 +61,7 @@ int stop_sig = SIGTERM; /* stopping signal default value */
int myargc;
char **myargv;
int assert_enabled = 0;
+
int main(int argc, char **argv)
{
int opt;
@@ -193,7 +194,7 @@ int main(int argc, char **argv)
*/
pool_config->debug_level = debug_level;
- pool_get_config(conf_file, INIT_CONFIG);
+ pool_get_config(conf_file, CFGCXT_INIT);
/*
* Override debug level
*/
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
index b9a3624e7..017dc7a8b 100644
--- a/src/main/pgpool_main.c
+++ b/src/main/pgpool_main.c
@@ -1193,7 +1193,7 @@ void promote_backend(int node_id)
{
WdCommandResult res = COMMAND_OK;
- if (!MASTER_SLAVE || strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+ if (!MASTER_SLAVE || pool_config->master_slave_sub_mode != STREAM_MODE)
{
return;
}
@@ -1789,7 +1789,7 @@ static void failover(void)
* recognize the former primary as the new primary node, which
* will reduce the time to process standby down.
*/
- else if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
+ else if (MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE &&
reqkind == NODE_DOWN_REQUEST)
{
if (Req_info->primary_node_id != node_id)
@@ -1806,7 +1806,7 @@ static void failover(void)
* as they are not replicated anymore.
*/
int follow_cnt = 0;
- if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+ if (MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE)
{
if (*pool_config->follow_master_command != '\0' ||
reqkind == PROMOTE_NODE_REQUEST)
@@ -2796,8 +2796,8 @@ static int find_primary_node_repeatedly(void)
int node_id = -1;
/* Streaming replication mode? */
- if (pool_config->master_slave_mode == 0 ||
- strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+ if (pool_config->master_slave_mode == false ||
+ pool_config->master_slave_sub_mode != STREAM_MODE)
{
/* No point to look for primary node if not in streaming
* replication mode.
@@ -3215,7 +3215,7 @@ static void reload_config(void)
ereport(LOG,
(errmsg("reload config files.")));
MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
- pool_get_config(conf_file, RELOAD_CONFIG);
+ pool_get_config(conf_file, CFGCXT_RELOAD);
/* Realoading config file could change backend status */
(void)write_status_file();
diff --git a/src/pcp_con/pcp_child.c b/src/pcp_con/pcp_child.c
index ded032fb1..fbabdc5bf 100644
--- a/src/pcp_con/pcp_child.c
+++ b/src/pcp_con/pcp_child.c
@@ -211,7 +211,7 @@ pcp_do_accept(int unix_fd, int inet_fd)
if (pcp_got_sighup)
{
MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
- pool_get_config(get_config_file_name(), RELOAD_CONFIG);
+ pool_get_config(get_config_file_name(), CFGCXT_RELOAD);
MemoryContextSwitchTo(oldContext);
pcp_got_sighup = 0;
}
diff --git a/src/pcp_con/pcp_worker.c b/src/pcp_con/pcp_worker.c
index 7e93550ce..7e2ebd477 100644
--- a/src/pcp_con/pcp_worker.c
+++ b/src/pcp_con/pcp_worker.c
@@ -934,12 +934,12 @@ process_recovery_request(PCP_CONNECTION *frontend,char *buf)
if ((!REPLICATION &&
!(MASTER_SLAVE &&
- !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))) ||
+ pool_config->master_slave_sub_mode == STREAM_MODE)) ||
(MASTER_SLAVE &&
- !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
+ pool_config->master_slave_sub_mode == STREAM_MODE &&
node_id == PRIMARY_NODE_ID))
{
- if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+ if (MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE)
ereport(ERROR,
(errmsg("process recovery request failed"),
errdetail("primary server cannot be recovered by online recovery.")));
@@ -1051,7 +1051,7 @@ process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos)
(errmsg("could not process recovery request"),
errdetail("node id %d is not valid", node_id)));
/* promoting node is reserved to Streaming Replication */
- if (!MASTER_SLAVE || (strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) != 0))
+ if (!MASTER_SLAVE || pool_config->master_slave_sub_mode != STREAM_MODE)
{
ereport(FATAL,
(errmsg("invalid pgpool mode for process recovery request"),
diff --git a/src/protocol/child.c b/src/protocol/child.c
index ab3bf39cf..a33c263c2 100644
--- a/src/protocol/child.c
+++ b/src/protocol/child.c
@@ -1991,7 +1991,7 @@ static void check_config_reload(void)
if (got_sighup)
{
MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
- pool_get_config(get_config_file_name(), RELOAD_CONFIG);
+ pool_get_config(get_config_file_name(), CFGCXT_RELOAD);
MemoryContextSwitchTo(oldContext);
if (pool_config->enable_pool_hba)
{
diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c
index bfee3c24f..45f6bd06e 100644
--- a/src/protocol/pool_process_query.c
+++ b/src/protocol/pool_process_query.c
@@ -408,7 +408,7 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
if (got_sighup)
{
MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
- pool_get_config(get_config_file_name(), RELOAD_CONFIG);
+ pool_get_config(get_config_file_name(), CFGCXT_RELOAD);
MemoryContextSwitchTo(oldContext);
if (pool_config->enable_pool_hba)
load_hba(get_hba_file_name());
diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c
index a809ef997..a446456e6 100644
--- a/src/query_cache/pool_memqcache.c
+++ b/src/query_cache/pool_memqcache.c
@@ -1695,13 +1695,7 @@ static void pool_reset_memqcache_buffer(void)
*/
bool pool_is_shmem_cache(void)
{
- static int result = -1;
-
- if (result == -1)
- {
- result = strcmp(pool_config->memqcache_method, "shmem");
- }
- return (result==0)?true:false;
+ return (pool_config->memqcache_method == SHMEM_CACHE)?true:false;
}
/*
@@ -3879,7 +3873,7 @@ POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void)
mystats.cache_stats.num_selects = stats->num_selects;
mystats.cache_stats.num_cache_hits = stats->num_cache_hits;
- if (strcmp(pool_config-> memqcache_method, "shmem"))
+ if (pool_config->memqcache_method == SHMEM_CACHE)
return &mystats;
/* number of total hash entries */
diff --git a/src/streaming_replication/pool_worker_child.c b/src/streaming_replication/pool_worker_child.c
index 559f395d2..6db43c48b 100644
--- a/src/streaming_replication/pool_worker_child.c
+++ b/src/streaming_replication/pool_worker_child.c
@@ -157,7 +157,7 @@ void do_worker_child(void)
* If streaming replication mode, do time lag checking
*/
- if (pool_config->sr_check_period > 0 && MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
+ if (pool_config->sr_check_period > 0 && MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE)
{
establish_persistent_connection();
PG_TRY();
@@ -351,9 +351,9 @@ static void check_replication_time_lag(void)
bkinfo->standby_delay = lag;
/* Log delay if necessary */
- if ((!strcmp(pool_config->log_standby_delay, "always") && lag > 0) ||
+ if ((pool_config->log_standby_delay == LSD_ALWAYS && lag > 0) ||
(pool_config->delay_threshold &&
- !strcmp(pool_config->log_standby_delay, "if_over_threshold") &&
+ pool_config->log_standby_delay == LSD_OVER_THRESHOLD &&
lag > pool_config->delay_threshold))
{
ereport(LOG,
@@ -437,7 +437,7 @@ static void reload_config(void)
ereport(LOG,
(errmsg("reloading config file")));
MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
- pool_get_config(get_config_file_name(), RELOAD_CONFIG);
+ pool_get_config(get_config_file_name(), CFGCXT_RELOAD);
MemoryContextSwitchTo(oldContext);
if (pool_config->enable_pool_hba)
load_hba(get_hba_file_name());
diff --git a/src/tools/pgmd5/Makefile.am b/src/tools/pgmd5/Makefile.am
index 23f16cae0..381654120 100644
--- a/src/tools/pgmd5/Makefile.am
+++ b/src/tools/pgmd5/Makefile.am
@@ -7,6 +7,7 @@ pg_md5_SOURCES = pg_md5.c \
pool_signal.c \
strlcpy.c \
regex_array.c \
+ pool_config_variables.c \
pool_config.l \
../fe_port.c \
fe_memutils.c \
@@ -27,6 +28,8 @@ strlcpy.c: ../../../src/utils/strlcpy.c
rm -f $@ && ln -s $< .
regex_array.c: ../../../src/utils/regex_array.c
rm -f $@ && ln -s $< .
+pool_config_variables.c: ../../../src/config/pool_config_variables.c
+ rm -f $@ && ln -s $< .
pool_config.l: ../../../src/config/pool_config.l
rm -f $@ && ln -s $< .
fe_memutils.c: ../../../src/tools/fe_memutils.c
diff --git a/src/tools/pgmd5/Makefile.in b/src/tools/pgmd5/Makefile.in
index 472cb38fd..3ada30ce5 100644
--- a/src/tools/pgmd5/Makefile.in
+++ b/src/tools/pgmd5/Makefile.in
@@ -84,11 +84,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/mkinstalldirs pool_config.c \
$(top_srcdir)/depcomp $(top_srcdir)/ylwrap
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \
- $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/c-compiler.m4 $(top_srcdir)/c-library.m4 \
+ $(top_srcdir)/general.m4 \
$(top_srcdir)/ac_func_accept_argtypes.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -102,9 +102,9 @@ PROGRAMS = $(bin_PROGRAMS)
am__dirstamp = $(am__leading_dot)dirstamp
am_pg_md5_OBJECTS = pg_md5.$(OBJEXT) md5.$(OBJEXT) \
pool_passwd.$(OBJEXT) pool_signal.$(OBJEXT) strlcpy.$(OBJEXT) \
- regex_array.$(OBJEXT) pool_config.$(OBJEXT) \
- ../fe_port.$(OBJEXT) fe_memutils.$(OBJEXT) \
- pool_globals.$(OBJEXT)
+ regex_array.$(OBJEXT) pool_config_variables.$(OBJEXT) \
+ pool_config.$(OBJEXT) ../fe_port.$(OBJEXT) \
+ fe_memutils.$(OBJEXT) pool_globals.$(OBJEXT)
pg_md5_OBJECTS = $(am_pg_md5_OBJECTS)
pg_md5_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -189,11 +189,9 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOG = @CATALOG@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-COLLATEINDEX = @COLLATEINDEX@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -202,7 +200,6 @@ DEFS = @DEFS@ \
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
-DOCBOOKSTYLE = @DOCBOOKSTYLE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -217,7 +214,6 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JADE = @JADE@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
@@ -240,7 +236,6 @@ MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
-NSGMLS = @NSGMLS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OSX = @OSX@
@@ -293,7 +288,6 @@ datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
-have_docbook = @have_docbook@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -329,6 +323,7 @@ pg_md5_SOURCES = pg_md5.c \
pool_signal.c \
strlcpy.c \
regex_array.c \
+ pool_config_variables.c \
pool_config.l \
../fe_port.c \
fe_memutils.c \
@@ -441,6 +436,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pg_md5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_config.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_config_variables.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_globals.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_passwd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_signal.Po@am__quote@
@@ -701,6 +697,8 @@ strlcpy.c: ../../../src/utils/strlcpy.c
rm -f $@ && ln -s $< .
regex_array.c: ../../../src/utils/regex_array.c
rm -f $@ && ln -s $< .
+pool_config_variables.c: ../../../src/config/pool_config_variables.c
+ rm -f $@ && ln -s $< .
pool_config.l: ../../../src/config/pool_config.l
rm -f $@ && ln -s $< .
fe_memutils.c: ../../../src/tools/fe_memutils.c
diff --git a/src/tools/pgmd5/pg_md5.c b/src/tools/pgmd5/pg_md5.c
index 907566443..82c43351f 100644
--- a/src/tools/pgmd5/pg_md5.c
+++ b/src/tools/pgmd5/pg_md5.c
@@ -201,7 +201,7 @@ static void update_pool_passwd(char *conf_file, char *username, char *password)
fprintf(stderr, "pool_init_config() failed\n\n");
exit(EXIT_FAILURE);
}
- if (pool_get_config(conf_file, INIT_CONFIG))
+ if (pool_get_config(conf_file, CFGCXT_RELOAD))
{
fprintf(stderr, "Unable to get configuration. Exiting...");
exit(EXIT_FAILURE);
diff --git a/src/tools/pgmd5/pool_config.c b/src/tools/pgmd5/pool_config.c
index 57c9bb52d..2f6cfefd2 100644
--- a/src/tools/pgmd5/pool_config.c
+++ b/src/tools/pgmd5/pool_config.c
@@ -491,7 +491,7 @@ char *yytext;
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2015 PgPool Global Development Group
+ * Copyright (c) 2003-2016 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -514,6 +514,7 @@ char *yytext;
#include <ctype.h>
#include "pool.h"
#include "pool_config.h"
+#include "pool_config_variables.h"
#include "utils/regex_array.h"
#ifndef POOL_PRIVATE
#include "utils/elog.h"
@@ -521,15 +522,13 @@ char *yytext;
#include "utils/fe_ports.h"
#endif
-#define CHECK_CONTEXT(mask, context) ((mask) & (context))
/* to shut off compiler warnings */
int yylex(void);
-POOL_CONFIG *pool_config; /* configuration values */
+POOL_CONFIG g_pool_config; /* configuration values */
+POOL_CONFIG *pool_config = &g_pool_config; /* for lagacy reason pointer to the above struct */
static unsigned Lineno;
-static char *default_reset_query_list[] = {"ABORT", "DISCARD ALL"};
-static char *default_black_function_list[] = {"nextval", "setval"};
typedef enum {
POOL_KEY = 1,
@@ -543,11 +542,11 @@ typedef enum {
} POOL_TOKEN;
static char *extract_string(char *value, POOL_TOKEN token);
-static char **extract_string_tokens(char *str, char *delim, int *n);
-static void clear_host_entry(int slot);
-static bool check_redirect_node_spec(char *node_spec);
+static void FreeConfigVariable(ConfigVariable *item);
+static bool ParseConfigFile( const char *config_file, int elevel,
+ ConfigVariable **head_p, ConfigVariable **tail_p);
-#line 552 "pool_config.c"
+#line 550 "pool_config.c"
#define INITIAL 0
@@ -727,10 +726,10 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
-#line 91 "pool_config.l"
+#line 89 "pool_config.l"
-#line 735 "pool_config.c"
+#line 733 "pool_config.c"
if ( !(yy_init) )
{
@@ -812,12 +811,12 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
-#line 93 "pool_config.l"
+#line 91 "pool_config.l"
Lineno++; return POOL_EOL;
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 94 "pool_config.l"
+#line 92 "pool_config.l"
/* eat whitespace */
YY_BREAK
case 3:
@@ -825,50 +824,50 @@ case 3:
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 95 "pool_config.l"
+#line 93 "pool_config.l"
/* eat comment */
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 97 "pool_config.l"
+#line 95 "pool_config.l"
return POOL_KEY;
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 98 "pool_config.l"
+#line 96 "pool_config.l"
return POOL_STRING;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 99 "pool_config.l"
+#line 97 "pool_config.l"
return POOL_UNQUOTED_STRING;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 100 "pool_config.l"
+#line 98 "pool_config.l"
return POOL_INTEGER;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 101 "pool_config.l"
+#line 99 "pool_config.l"
return POOL_REAL;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 102 "pool_config.l"
+#line 100 "pool_config.l"
return POOL_EQUALS;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 104 "pool_config.l"
+#line 102 "pool_config.l"
return POOL_PARSE_ERROR;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 106 "pool_config.l"
+#line 104 "pool_config.l"
ECHO;
YY_BREAK
-#line 873 "pool_config.c"
+#line 871 "pool_config.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1825,205 +1824,24 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 106 "pool_config.l"
+#line 104 "pool_config.l"
int pool_init_config(void)
{
- int res;
- static char localhostname[256];
- int i;
-
- pool_config = palloc(sizeof(POOL_CONFIG));
-
memset(pool_config, 0, sizeof(POOL_CONFIG));
#ifndef POOL_PRIVATE
- pool_config->backend_desc = pool_shared_memory_create(sizeof(BackendDesc));
+g_pool_config.backend_desc = palloc0(sizeof(BackendDesc));
+// g_pool_config.backend_desc = pool_shared_memory_create(sizeof(BackendDesc));
+// memset(g_pool_config.backend_desc, 0, sizeof(BackendDesc));
+
#else
- pool_config->backend_desc = palloc(sizeof(BackendDesc));
+ g_pool_config.backend_desc = palloc0(sizeof(BackendDesc));
#endif
+ InitializeConfigOptions();
- /*
- * add for watchdog
- */
- memset(&pool_config->wd_remote_nodes,0x00,sizeof(WdRemoteNodesConfig));
-
- /* set hardcoded default values */
- pool_config->listen_addresses = "localhost";
- pool_config->pcp_listen_addresses = "*";
- pool_config->port = 9999;
- pool_config->pcp_port = 9898;
- pool_config->socket_dir = DEFAULT_SOCKET_DIR;
- pool_config->pcp_socket_dir = DEFAULT_SOCKET_DIR;
- pool_config->num_init_children = 32;
- pool_config->listen_backlog_multiplier = 2;
- pool_config->max_pool = 4;
- pool_config->child_life_time = 300;
- pool_config->client_idle_limit = 0;
- pool_config->connection_life_time = 0;
- pool_config->child_max_connections = 0;
- pool_config->authentication_timeout = 60;
- pool_config->logdir = DEFAULT_LOGDIR;
- pool_config->logsyslog = 0;
- pool_config->log_destination = "stderr";
- pool_config->syslog_facility = LOG_LOCAL0;
- pool_config->syslog_ident = "pgpool";
- pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
- pool_config->log_statement = 0;
- pool_config->log_per_node_statement = 0;
- pool_config->log_connections = 0;
- pool_config->log_hostname = 0;
- pool_config->enable_pool_hba = 0;
- pool_config->pool_passwd = "pool_passwd";
-
- pool_config->replication_mode = 0;
- pool_config->load_balance_mode = 0;
- pool_config->replication_stop_on_mismatch = 0;
- pool_config->failover_if_affected_tuples_mismatch = 0;
- pool_config->replicate_select = 0;
- pool_config->reset_query_list = default_reset_query_list;
- pool_config->num_reset_queries = sizeof(default_reset_query_list)/sizeof(char *);
- pool_config->white_function_list = NULL;
- pool_config->num_white_function_list = 0;
- pool_config->black_function_list = default_black_function_list;
- pool_config->num_black_function_list = sizeof(default_black_function_list)/sizeof(char *);
- pool_config->log_line_prefix = "%t: pid %p: ";
- pool_config->log_error_verbosity = 1; /* PGERROR_DEFAULT */
- pool_config->client_min_messages = 18; /* NOTICE */
- pool_config->log_min_messages = 19; /* WARNING */
- pool_config->master_slave_mode = 0;
- pool_config->master_slave_sub_mode = "slony";
- pool_config->delay_threshold = 0;
- pool_config->log_standby_delay = "none";
- pool_config->connection_cache = 1;
- pool_config->health_check_timeout = 20;
- pool_config->health_check_period = 0;
- pool_config->health_check_user = "nobody";
- pool_config->health_check_password = "";
- pool_config->health_check_max_retries = 0;
- pool_config->health_check_retry_delay = 1;
- pool_config->connect_timeout = 10000;
- pool_config->sr_check_period = 0;
- pool_config->sr_check_user = "nobody";
- pool_config->sr_check_password = "";
- pool_config->failover_command = "";
- pool_config->follow_master_command = "";
- pool_config->failback_command = "";
- pool_config->fail_over_on_backend_error = 1;
- pool_config->insert_lock = 1;
- pool_config->ignore_leading_white_space = 1;
- pool_config->backend_desc->num_backends = 0;
- pool_config->recovery_user = "";
- pool_config->recovery_password = "";
- pool_config->recovery_1st_stage_command = "";
- pool_config->recovery_2nd_stage_command = "";
- pool_config->recovery_timeout = 90;
- pool_config->search_primary_node_timeout = 10;
- pool_config->client_idle_limit_in_recovery = 0;
- pool_config->lobj_lock_table = "";
- pool_config->ssl = 0;
- pool_config->ssl_cert = "";
- pool_config->ssl_key = "";
- pool_config->ssl_ca_cert = "";
- pool_config->ssl_ca_cert_dir = "";
- pool_config->debug_level = 0;
- pool_config->relcache_expire = 0;
- pool_config->relcache_size = 256;
- pool_config->check_temp_table = 1;
- pool_config->check_unlogged_table = 1;
- pool_config->lists_patterns = NULL;
- pool_config->pattc = 0;
- pool_config->current_pattern_size = 0;
-
- /*
- * database_redirect_preference_list
- */
- pool_config->database_redirect_preference_list = NULL;
- pool_config->redirect_dbnames = NULL;
- pool_config->db_redirect_tokens = NULL;
-
- /*
- * app_name_redirect_preference_list
- */
- pool_config->app_name_redirect_preference_list = NULL;
- pool_config->redirect_app_names = NULL;
- pool_config->app_name_redirect_tokens = NULL;
-
- pool_config->allow_sql_comments = 0;
-
- /*
- * add for watchdog
- */
- pool_config->use_watchdog = 0;
- pool_config->wd_lifecheck_method = MODE_HEARTBEAT;
- pool_config->clear_memqcache_on_escalation = 1;
- pool_config->wd_escalation_command = "";
- pool_config->wd_de_escalation_command = "";
- pool_config->trusted_servers = "";
- pool_config->delegate_IP = "";
- res = gethostname(localhostname,sizeof(localhostname));
- if(res !=0 )
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failed to get the local hostname")));
- }
- pool_config->wd_hostname = localhostname;
- pool_config->wd_port = 9000;
- pool_config->wd_priority = 1;
- pool_config->wd_remote_nodes.num_wd = 0;
- pool_config->wd_interval = 10;
- pool_config->wd_authkey = "";
- pool_config->ping_path = "/bin";
- pool_config->if_cmd_path = "/sbin";
- pool_config->if_up_cmd = "ip addr add $_IP_$/24 dev eth0 label eth0:0";
- pool_config->if_down_cmd = "ip addr del $_IP_$/24 dev eth0";
- pool_config->arping_path = "/usr/sbin";
- pool_config->arping_cmd = "arping -U $_IP_$ -w 1";
- pool_config->wd_life_point = 3;
- pool_config->wd_lifecheck_query = "SELECT 1";
- pool_config->wd_lifecheck_dbname = "template1";
- pool_config->wd_lifecheck_user = "nobody";
- pool_config->wd_lifecheck_password = "";
- pool_config->wd_heartbeat_port = 9694;
- pool_config->wd_heartbeat_keepalive = 2;
- pool_config->wd_heartbeat_deadtime = 30;
- pool_config->num_hb_if = 0;
-
- pool_config->memory_cache_enabled = 0;
- pool_config->memqcache_method = "shmem";
- pool_config->memqcache_memcached_host = "localhost";
- pool_config->memqcache_memcached_port = 11211;
- pool_config->memqcache_total_size = (int64)67108864;
- pool_config->memqcache_max_num_cache = 1000000;
- pool_config->memqcache_expire = 0;
- pool_config->memqcache_auto_cache_invalidation = 1;
- pool_config->memqcache_maxcache = 409600;
- pool_config->memqcache_cache_block_size = 1048576;
- pool_config->memqcache_oiddir = "/var/log/pgpool/oiddir";
- pool_config->white_memqcache_table_list = NULL;
- pool_config->num_white_memqcache_table_list = 0;
- pool_config->black_memqcache_table_list = NULL;
- pool_config->num_black_memqcache_table_list = 0;
- pool_config->lists_memqcache_table_patterns = NULL;
- pool_config->memqcache_table_pattc = 0;
- pool_config->current_memqcache_table_pattern_size = 0;
-
- res = gethostname(localhostname,sizeof(localhostname));
- if(res !=0 )
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failed to get the local hostname")));
-
- }
-
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- clear_host_entry(i);
- }
return 0;
}
@@ -2032,7 +1850,7 @@ int pool_init_config(void)
* The supported type are: black_function_list and white_function_list
* Return 0 on error, 1 on success
*/
-int add_regex_pattern(char *type, char *s)
+int add_regex_pattern(const char *type, char *s)
{
int regex_flags = REG_NOSUB;
RegPattern currItem;
@@ -2152,37 +1970,74 @@ int growMemqcacheTablePatternArray(RegPattern item)
return(pool_config->memqcache_table_pattc);
}
-int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
+/*
+ * Free a single ConfigVariable
+ */
+static void
+FreeConfigVariable(ConfigVariable *item)
+{
+ if (item->name)
+ pfree(item->name);
+ if (item->value)
+ pfree(item->value);
+ pfree(item);
+}
+
+/*
+ * Free a list of ConfigVariables, including the names and the values
+ */
+static void
+FreeConfigVariables(ConfigVariable *list)
+{
+ ConfigVariable *item;
+
+ item = list;
+ while (item)
+ {
+ ConfigVariable *next = item->next;
+ FreeConfigVariable(item);
+ item = next;
+ }
+}
+
+/*
+ * Read and parse a single configuration file.
+ *
+ * Input parameters:
+ * config_file: absolute or relative path name of the configuration file
+ * elevel: error logging level to use
+ * Input/Output parameters:
+ * head_p, tail_p: head and tail of linked list of name/value pairs
+ *
+ * *head_p and *tail_p must be initialized, either to NULL or valid pointers
+ * to a ConfigVariable list, before calling the outer recursion level. Any
+ * name-value pairs read from the input file(s) will be appended to the list.
+ *
+ * Note: if elevel >= ERROR then an error will not return control to the
+ * caller, so there is no need to check the return value in that case.
+ *
+ */
+static bool
+ParseConfigFile(const char *config_file, int elevel,
+ ConfigVariable **head_p, ConfigVariable **tail_p)
{
+
FILE *fd;
int token;
- char key[1024];
- double total_weight;
- int i;
- int error_level;
- bool log_destination_changed = false;
-#ifdef USE_MEMCACHED
- bool use_memcached = true;
-#else
- bool use_memcached = false;
-#endif
- if(CHECK_CONTEXT(INIT_CONFIG, context))
- error_level = ERROR;
- else
- error_level = WARNING;
-
-#define PARSE_ERROR() ereport(CHECK_CONTEXT(INIT_CONFIG, context)?ERROR:WARNING, \
- (errmsg("syntex error in configuration file \"%s\"",POOL_CONF_FILE_NAME), \
- errdetail("parse error at line %d '%s'", Lineno, yytext)))
+ char *key;
+ char *val;
+ ConfigVariable *item;
+
+ *head_p = NULL;
/* open config file */
- fd = fopen(confpath, "r");
+ fd = fopen(config_file, "r");
if (!fd)
{
- ereport(WARNING,
- (errmsg("could not open configuration file: \"%s\"\n",POOL_CONF_FILE_NAME),
+ ereport(elevel,
+ (errmsg("could not open configuration file: \"%s\"\n",config_file),
errdetail("using default configuration parameter values")));
- return 0;
+ return false;
}
yyin = fd;
@@ -2191,3010 +2046,194 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
for(;;)
{
token = yylex();
+
if (token == 0)
- {
break;
- }
- if (token == POOL_PARSE_ERROR)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
+
if (token == POOL_EOL)
continue;
+ if (token == POOL_PARSE_ERROR)
+ goto parse_error;
+
if (token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
+ goto parse_error;
- strlcpy(key, yytext, sizeof(key));
+ key = pstrdup(yytext);
- ereport(DEBUG5,
- (errmsg("key: %s", key)));
token = yylex();
+ /* next we have an optional equal sign; discard if present */
if (token == POOL_EQUALS)
token = yylex();
+ val = extract_string(yytext,token);
+
ereport(DEBUG5,
- (errmsg("value: %s kind: %d", yytext, token)));
- if (!strcmp(key, "allow_inet_domain_socket") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- /* for backward compatibility */
- int v = eval_logical(yytext);
+ (errmsg("key: \"%s\" value: \"%s\" kind: %d",key, val, token)));
+
+ /* Add this to the list */
+ item = palloc(sizeof(ConfigVariable));
+ item->name = key;
+ item->value = val;
+ item->sourceline = Lineno;
+ item->next = NULL;
+ if (*head_p == NULL)
+ *head_p = item;
+ else
+ (*tail_p)->next = item;
+ *tail_p = item;
+ }
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
-
- return(-1);
- }
- if (v)
- pool_config->listen_addresses = pstrdup("*");
- else
- pool_config->listen_addresses = pstrdup("");
- }
- else if (!strcmp(key, "listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ fclose(fd);
+ return true;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->listen_addresses = str;
- }
+parse_error:
- else if (!strcmp(key, "port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
+ fclose(fd);
+ FreeConfigVariables(*head_p);
+ *head_p = NULL;
+ *tail_p = NULL;
+ ereport(elevel,
+ (errmsg("syntex error in configuration file \"%s\"",config_file),
+ errdetail("parse error at line %d '%s' token = %d", Lineno, yytext,token)));
- if (token != POOL_INTEGER || v < 1024)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1024",yytext,key, key)));
+ return false;
+}
- return(-1);
- }
- pool_config->port = v;
- }
+/*
+ * Read the configuration file and load the values of all parameters
+ */
+bool pool_get_config(const char *config_file, ConfigContext context)
+{
+ ConfigVariable *head_p = NULL;
+ ConfigVariable *tail_p = NULL;
+ bool res;
+ int elevel = (context == CFGCXT_INIT)?FATAL:WARNING;
- else if (!strcmp(key, "pcp_listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ res = ParseConfigFile(config_file, elevel, &head_p, &tail_p);
+ if (res == false || head_p == NULL)
+ return false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pcp_listen_addresses = str;
- }
+ res = set_config_options(head_p, context, PGC_S_FILE, elevel);
+ FreeConfigVariables(head_p);
+ return res;
+}
- else if (!strcmp(key, "pcp_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
- if (token != POOL_INTEGER || v < 1024)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1024",yytext,key, key)));
- return(-1);
- }
- pool_config->pcp_port = v;
- }
- else if (!strcmp(key, "socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+static char *extract_string(char *value, POOL_TOKEN token)
+{
+ char *ret = NULL;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->socket_dir = str;
- }
- else if (!strcmp(key, "pcp_socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+ if (token == POOL_STRING)
+ {
+ ret = pstrdup(value+1);
+ ret[strlen(ret)-1] = '\0';
+ }
+ else
+ ret = pstrdup(value);
+
+ return ret;
+}
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+/*
+ * Try to interpret value as boolean value. Valid values are: true,
+ * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
+ * If the string parses okay, return true, else false.
+ * If okay and result is not NULL, return the value in *result.
+ * This function copied from PostgreSQL source code.
+ */
+static bool parse_bool_with_len(const char *value, size_t len, bool *result)
+{
+ switch (*value)
+ {
+ case 't':
+ case 'T':
+ if (strncasecmp(value, "true", len) == 0)
{
- PARSE_ERROR();
- fclose(fd);
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- str = extract_string(yytext, token);
- if (str == NULL)
+ break;
+ case 'f':
+ case 'F':
+ if (strncasecmp(value, "false", len) == 0)
{
- fclose(fd);
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->pcp_socket_dir = str;
- }
- else if (!strcmp(key, "num_init_children") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
+ break;
+ case 'y':
+ case 'Y':
+ if (strncasecmp(value, "yes", len) == 0)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- pool_config->num_init_children = v;
- }
- else if (!strcmp(key, "listen_backlog_multiplier") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
+ break;
+ case 'n':
+ case 'N':
+ if (strncasecmp(value, "no", len) == 0)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 1",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->listen_backlog_multiplier = v;
- }
- else if (!strcmp(key, "child_life_time") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
+ break;
+ case 'o':
+ case 'O':
+ /* 'o' is not unique enough */
+ if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- pool_config->child_life_time = v;
- }
- else if (!strcmp(key, "client_idle_limit") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
+ else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->client_idle_limit = v;
- }
- else if (!strcmp(key, "connection_life_time") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
+ break;
+ case '1':
+ if (len == 1)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = true;
+ return true;
}
- pool_config->connection_life_time = v;
- }
- else if (!strcmp(key, "child_max_connections") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
+ break;
+ case '0':
+ if (len == 1)
{
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
+ if (result)
+ *result = false;
+ return true;
}
- pool_config->child_max_connections = v;
- }
- else if (!strcmp(key, "authentication_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
+ break;
+ default:
+ break;
+ }
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->authentication_timeout = v;
- }
- else if (!strcmp(key, "max_pool") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
+ if (result)
+ *result = false; /* suppress compiler warning */
+ return false;
+}
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->max_pool = v;
- }
- else if (!strcmp(key, "logdir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
+int eval_logical(const char *str)
+{
+ bool result;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->logdir = str;
- }
- else if (!strcmp(key, "log_destination") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
+ if (!parse_bool_with_len(str, strlen(str), &result))
+ return -1;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- log_destination_changed = pool_config->log_destination != str;
- pool_config->log_destination = str;
- }
- else if (!strcmp(key, "syslog_facility") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
+ return (result ? 1 : 0);
+}
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->syslog_facility = set_syslog_facility(str);
- }
- else if (!strcmp(key, "syslog_ident") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- log_destination_changed = log_destination_changed || pool_config->syslog_ident != str;
- pool_config->syslog_ident = str;
- }
- else if (!strcmp(key, "pid_file_name") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pid_file_name = str;
- }
- else if (!strcmp(key, "log_connections") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->log_connections = v;
- }
- else if (!strcmp(key, "log_hostname") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->log_hostname = v;
- }
- else if (!strcmp(key, "enable_pool_hba") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->enable_pool_hba = v;
- }
- else if (!strcmp(key, "pool_passwd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->pool_passwd = str;
- }
-
- else if (!strcmp(key, "replication_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->replication_mode = v;
-
- if (pool_config->master_slave_mode && pool_config->replication_mode)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("replication_mode and master_slave_mode cannot be enabled at the same time")));
- return(-1);
- }
-
- }
- else if (!strcmp(key, "load_balance_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->load_balance_mode = v;
- }
- else if (!strcmp(key, "replication_stop_on_mismatch") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("replication_stop_on_mismatch: %d", v)));
-
- pool_config->replication_stop_on_mismatch = v;
- }
- else if (!strcmp(key, "failover_if_affected_tuples_mismatch") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("failover_if_affected_tuples_mismatch: %d", v)));
-
- pool_config->failover_if_affected_tuples_mismatch = v;
- }
- else if (!strcmp(key, "replicate_select") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("replicate_select: %d", v)));
-
- pool_config->replicate_select = v;
- }
- else if (!strcmp(key, "reset_query_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->reset_query_list = extract_string_tokens(str, ";", &pool_config->num_reset_queries);
- if (pool_config->reset_query_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- }
-
- else if (!strcmp(key, "white_function_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->white_function_list =
- extract_string_tokens(str, ",", &pool_config->num_white_function_list);
-
- if (pool_config->white_function_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_white_function_list;i++)
- {
- add_regex_pattern("white_function_list", pool_config->white_function_list[i]);
- }
- }
-
- else if (!strcmp(key, "black_function_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->black_function_list =
- extract_string_tokens(str, ",", &pool_config->num_black_function_list);
-
- if (pool_config->black_function_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_black_function_list;i++)
- {
- add_regex_pattern("black_function_list", pool_config->black_function_list[i]);
- }
- }
- else if (!strcmp(key, "log_error_verbosity") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"terse","default","verbose",NULL};
- bool found = false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->log_error_verbosity = i;
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
-
- else if (!strcmp(key, "client_min_messages") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error",NULL};
- bool found = false;
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
-
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->client_min_messages = i + 10;
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
- else if (!strcmp(key, "log_min_messages") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str, *valid_val;
- int i;
- const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error","fatal","panic",NULL};
- bool found = false;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for(i=0; ; i++)
- {
- valid_val = (char*)ordered_valid_values[i];
- if(!valid_val)
- break;
-
- if (!strcasecmp(str, valid_val))
- {
- found = true;
- pool_config->log_min_messages = i + 10; /* error codes start with 10 */
- break;
- }
- }
- if (!found)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- }
- else if (!strcmp(key, "log_line_prefix") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->log_line_prefix = str;
- }
- else if (!strcmp(key, "print_timestamp") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- ereport(NOTICE,
- (errmsg("configuration key \"%s\" is not supported anymore",key),
- errdetail("please use \"log_line_prefix\" instead")));
- }
- else if (!strcmp(key, "print_user") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- ereport(NOTICE,
- (errmsg("configuration key \"%s\" is not supported anymore",key),
- errdetail("please use \"log_line_prefix\" instead")));
- }
-
- else if (!strcmp(key, "master_slave_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"",yytext,key)));
- return(-1);
- }
- pool_config->master_slave_mode = v;
-
- if (pool_config->master_slave_mode && pool_config->replication_mode)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("replication_mode and master_slave_mode cannot be enabled at the same time")));
- return(-1);
- }
- }
-
- else if (!strcmp(key, "master_slave_sub_mode") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, MODE_SLONY) && strcmp(str, MODE_STREAMREP))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"slony\" or \"stream\"", key)));
- return(-1);
- }
- pool_config->master_slave_sub_mode = str;
- }
-
- else if (!strcmp(key, "delay_threshold") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- long long int v = atol(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\". %s must be >= 0",yytext,key, key)));
- return(-1);
- }
- pool_config->delay_threshold = v;
- }
-
- else if (!strcmp(key, "log_standby_delay") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, "always") && strcmp(str, "if_over_threshold") && strcmp(str, "none"))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("allowed values are: \"always\", \"if_over_threshold\" and \"none\"")));
-
- return(-1);
- }
- pool_config->log_standby_delay = str;
- }
-
- else if (!strcmp(key, "connection_cache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->connection_cache = v;
- }
-
- else if (!strcmp(key, "health_check_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->health_check_timeout = v;
- }
-
- else if (!strcmp(key, "health_check_period") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->health_check_period = v;
- }
-
- else if (!strcmp(key, "health_check_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_user = str;
- }
-
- else if (!strcmp(key, "health_check_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->health_check_password = str;
- }
-
- else if (!strcmp(key, "health_check_max_retries") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->health_check_max_retries = v;
- }
-
- else if (!strcmp(key, "health_check_retry_delay") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->health_check_retry_delay = v;
- }
- else if (!strcmp(key, "connect_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->connect_timeout = v;
- }
-
- else if (!strcmp(key, "sr_check_period") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->sr_check_period = v;
- }
-
- else if (!strcmp(key, "sr_check_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_user = str;
- }
-
- else if (!strcmp(key, "sr_check_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->sr_check_password = str;
- }
-
- else if (!strcmp(key, "failover_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->failover_command = str;
- }
-
- else if (!strcmp(key, "follow_master_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->follow_master_command = str;
- }
-
- else if (!strcmp(key, "failback_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->failback_command = str;
- }
-
- else if (!strcmp(key, "fail_over_on_backend_error") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->fail_over_on_backend_error = v;
- }
-
- else if (!strcmp(key, "recovery_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_user = str;
- }
-
- else if (!strcmp(key, "recovery_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_password = str;
- }
-
- else if (!strcmp(key, "recovery_1st_stage_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_1st_stage_command = str;
- }
-
- else if (!strcmp(key, "recovery_2nd_stage_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->recovery_2nd_stage_command = str;
- }
-
- else if (!strcmp(key, "recovery_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->recovery_timeout = v;
- }
-
- else if (!strcmp(key, "search_primary_node_timeout") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->search_primary_node_timeout = v;
- }
-
- else if (!strcmp(key, "client_idle_limit_in_recovery") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < -1)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->client_idle_limit_in_recovery = v;
- }
-
- else if (!strcmp(key, "insert_lock") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->insert_lock = v;
- }
-
- else if (!strcmp(key, "ignore_leading_white_space") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->ignore_leading_white_space = v;
- }
-
-
- else if (!strncmp(key, "backend_hostname", 16) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 16);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend number must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG ||
- (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED))
- strlcpy(BACKEND_INFO(slot).backend_hostname, str, MAX_DB_HOST_NAMELEN);
- }
-
- else if (!strncmp(key, "backend_port", 12) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 12);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend port slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend port slot number %d port: %d ", slot,atoi(yytext))));
- if (context == INIT_CONFIG)
- {
- BACKEND_INFO(slot).backend_port = atoi(yytext);
- BACKEND_INFO(slot).backend_status = CON_CONNECT_WAIT;
- }
- else if (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED)
- {
- BACKEND_INFO(slot).backend_port = atoi(yytext);
- BACKEND_INFO(slot).backend_status = CON_DOWN;
- }
- }
-
- else if (!strncmp(key, "backend_weight", 14) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- double v;
-
- slot = atoi(key + 14);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend weight slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- v = atof(yytext);
-
- if (v < 0.0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0.0")));
- return(-1);
- }
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("weight slot number %d weight: %f", slot, v)));
-
- if (context == INIT_CONFIG || context == RELOAD_CONFIG)
- {
- double old_v = BACKEND_INFO(slot).unnormalized_weight;
- BACKEND_INFO(slot).unnormalized_weight = v;
-
- /*
- * Log weight change event only when context is
- * reloading of pgpool.conf and weight is actually
- * changed
- */
- if (context == RELOAD_CONFIG && old_v != v)
- {
- ereport(LOG,
- (errmsg("initializing pool configuration: backend weight for backend:%d changed from %f to %f", slot, old_v, v),
- errdetail("This change will be effective from next client session")));
- }
- }
- }
- else if (!strncmp(key, "backend_data_directory", 22) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
- BACKEND_STATUS status;
-
- slot = atoi(key + 22);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("backend data directory slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- status = BACKEND_INFO(slot).backend_status;
- if (context == INIT_CONFIG ||
- (context == RELOAD_CONFIG && (status == CON_UNUSED || status == CON_DOWN)))
- strlcpy(BACKEND_INFO(slot).backend_data_directory, str, MAX_PATH_LENGTH);
- }
- else if (!strncmp(key, "backend_flag", 12) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- char *str;
- char **flags;
- int n;
- int i;
- int slot;
- unsigned short flag = 0;
- bool allow_to_failover_is_specified = 0;
- bool disallow_to_failover_is_specified = 0;
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("extract_string failed: %s", yytext)));
- return(-1);
- }
-
- flags = extract_string_tokens(str, "|", &n);
- if (!flags || n < 0)
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("unable to get backend flags")));
-
- fclose(fd);
- return(-1);
- }
-
- for (i=0;i<n;i++)
- {
- if (!strcmp(flags[i], "ALLOW_TO_FAILOVER"))
- {
- if (disallow_to_failover_is_specified)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
-
- return(-1);
- }
- flag &= ~POOL_FAILOVER;
- allow_to_failover_is_specified = true;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("allow_to_failover: ON")));
-
- }
-
- else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER"))
- {
- if (allow_to_failover_is_specified)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time")));
- return(-1);
- }
- flag |= POOL_FAILOVER;
- disallow_to_failover_is_specified = true;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("disallow_to_failover: ON")));
-
- }
-
- else
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("unknown backend flag:%s", flags[i])));
- return (-1);
- }
- }
-
- slot = atoi(key + 12);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- BACKEND_INFO(slot).flag = flag;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend slot number %d flag: %04x", slot, flag)));
-
- }
-
- else if (!strcmp(key, "log_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->log_statement = v;
- }
- else if (!strcmp(key, "log_per_node_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->log_per_node_statement = v;
- }
-
- else if (!strcmp(key, "lobj_lock_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->lobj_lock_table = str;
- }
- /*
- * add for watchdog
- */
- else if (!strncmp(key, "other_pgpool_hostname", 21) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 21) ;
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_INFO(slot).hostname, str, WD_MAX_HOST_NAMELEN);
- }
-
- else if (!strncmp(key, "other_pgpool_port", 17) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 17);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- WD_INFO(slot).pgpool_port = atoi(yytext);
- }
-
- else if (!strncmp(key, "other_wd_port", 13) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 13);
- if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- {
- WD_INFO(slot).wd_port = atoi(yytext);
- pool_config->wd_remote_nodes.num_wd = slot + 1;
- }
- }
- else if (!strcmp(key, "use_watchdog") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->use_watchdog = v;
- }
-
- else if (!strcmp(key, "clear_memqcache_on_escalation") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->clear_memqcache_on_escalation = v;
- }
-
- else if (!strcmp(key, "wd_escalation_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_escalation_command = str;
- }
-
- else if (!strcmp(key, "wd_de_escalation_command") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_de_escalation_command = str;
- }
-
-
- else if (!strcmp(key, "trusted_servers") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->trusted_servers = str;
- }
- else if (!strcmp(key, "delegate_IP") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->delegate_IP = str;
- }
- else if (!strcmp(key, "wd_hostname") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->wd_hostname = str;
- }
- else if (!strcmp(key, "wd_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_port = v;
- }
- else if (!strcmp(key, "wd_priority") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_priority = v;
- }
- else if (!strcmp(key, "wd_interval") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_interval = v;
- }
- else if (!strcmp(key, "ping_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->ping_path = str;
- }
- else if (!strcmp(key, "if_cmd_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_cmd_path = str;
- }
- else if (!strcmp(key, "if_up_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_up_cmd = str;
- }
- else if (!strcmp(key, "if_down_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->if_down_cmd = str;
- }
- else if (!strcmp(key, "arping_path") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->arping_path = str;
- }
- else if (!strcmp(key, "arping_cmd") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->arping_cmd = str;
- }
- else if (!strcmp(key, "wd_life_point") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_life_point = v;
- }
- else if (!strcmp(key, "wd_lifecheck_query") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if(strlen(str))
- pool_config->wd_lifecheck_query = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_dbname") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_dbname = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_user") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_user = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_password") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_lifecheck_password = str;
- }
-
- else if (!strcmp(key, "wd_lifecheck_method") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (strcmp(str, MODE_HEARTBEAT) && strcmp(str, MODE_QUERY) && strcmp(str, MODE_EXTERNAL))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"heartbeat\" or \"query\"", key)));
- return(-1);
- }
- pool_config->wd_lifecheck_method = str;
- }
- else if (!strcmp(key, "wd_heartbeat_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_port = v;
- }
- else if (!strcmp(key, "wd_heartbeat_keepalive") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_keepalive = v;
- }
- else if (!strcmp(key, "wd_heartbeat_deadtime") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v <= 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than 0")));
- return(-1);
- }
- pool_config->wd_heartbeat_deadtime = v;
- }
- else if (!strcmp(key, "wd_authkey") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->wd_authkey = str;
- }
-
- else if (!strncmp(key, "heartbeat_device", 16) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 16) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_HB_IF(slot).if_name, str, WD_MAX_IF_NAME_LEN);
-
- }
- /* this must be prior to hertbeat_destination */
- else if (!strncmp(key, "heartbeat_destination_port", 26) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
-
- slot = atoi(key + 26) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- {
- WD_HB_IF(slot).dest_port = atoi(yytext);
- pool_config->num_hb_if = slot + 1;
- }
- }
- else if (!strncmp(key, "heartbeat_destination", 21) &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
- mypid == getpid()) /* this parameter must be modified by parent pid */
- {
- int slot;
- char *str;
-
- slot = atoi(key + 21) ;
- if (slot < 0 || slot >= WD_MAX_IF_NUM)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid slot no :\"%d\" for key:\"%s\"", slot,key),
- errhint("slot must be between 0 and %d inclusive",MAX_CONNECTION_SLOTS)));
- return(-1);
- }
-
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- if (context == INIT_CONFIG || (context == RELOAD_CONFIG ))
- strlcpy(WD_HB_IF(slot).addr, str, WD_MAX_HOST_NAMELEN);
- }
-
- else if (!strcmp(key, "ssl") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
-
- return(-1);
- }
- pool_config->ssl = v;
- }
- else if (!strcmp(key, "ssl_cert") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_cert = str;
- }
- else if (!strcmp(key, "ssl_key") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_key = str;
- }
- else if (!strcmp(key, "ssl_ca_cert") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_ca_cert = str;
- }
- else if (!strcmp(key, "ssl_ca_cert_dir") &&
- CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->ssl_ca_cert_dir = str;
- }
-
- else if (!strcmp(key, "debug_level") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- /* Consider -d option value stored in pool_config already */
- pool_config->debug_level |= v;
- }
-
- else if (!strcmp(key, "relcache_expire") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->relcache_expire = v;
- }
-
- else if (!strcmp(key, "relcache_size") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 1)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 1")));
- return(-1);
- }
- pool_config->relcache_size = v;
- }
-
- else if (!strcmp(key, "check_temp_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->check_temp_table = v;
- }
-
- else if (!strcmp(key, "check_unlogged_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->check_unlogged_table = v;
- }
-
- else if (!strcmp(key, "memory_cache_enabled") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->memory_cache_enabled = v;
- }
- else if (!strcmp(key, "memqcache_method") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- if (!strcmp(str, "memcached") && !use_memcached)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration, Feature Not available"),
- errdetail("invalid value:\"%s\" for key:\"%s\", memcached not available because pgpool-II is not built with MEMCACHED support", yytext,key)));
- return -1;
- }
-
- if (strcmp(str, "memcached") && strcmp(str, "shmem"))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("allowed values for configuration parameter %s can be either \"shmem\" or \"memcached\"", str)));
-
- return -1;
- }
-
- pool_config->memqcache_method = str;
- }
- else if (!strcmp(key, "memqcache_memcached_host") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->memqcache_memcached_host = str;
- }
- else if (!strcmp(key, "memqcache_memcached_port") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->memqcache_memcached_port = v;
- }
- else if (!strcmp(key, "memqcache_total_size") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int64 v = atoll(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
- return(-1);
- }
- pool_config->memqcache_total_size = v;
- }
- else if (!strcmp(key, "memqcache_max_num_cache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_max_num_cache = v;
- }
- else if (!strcmp(key, "memqcache_expire") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_expire = v;
- }
- else if (!strcmp(key, "memqcache_auto_cache_invalidation") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key)));
- return(-1);
- }
- pool_config->memqcache_auto_cache_invalidation = v;
- }
- else if (!strcmp(key, "memqcache_maxcache") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal 0")));
- return(-1);
- }
- pool_config->memqcache_maxcache = v;
- }
- else if (!strcmp(key, "memqcache_cache_block_size") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- int v = atoi(yytext);
-
- if (token != POOL_INTEGER || v < 512)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 512")));
- return(-1);
- }
- pool_config->memqcache_cache_block_size = v;
- }
- else if (!strcmp(key, "memqcache_oiddir") && CHECK_CONTEXT(INIT_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->memqcache_oiddir = str;
- }
- else if (!strcmp(key, "white_memqcache_table_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->white_memqcache_table_list =
- extract_string_tokens(str, ",", &pool_config->num_white_memqcache_table_list);
-
- if (pool_config->white_memqcache_table_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_white_memqcache_table_list;i++)
- {
- add_regex_pattern("white_memqcache_table_list", pool_config->white_memqcache_table_list[i]);
- }
- }
-
- else if (!strcmp(key, "black_memqcache_table_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
- pool_config->black_memqcache_table_list =
- extract_string_tokens(str, ",", &pool_config->num_black_memqcache_table_list);
-
- if (pool_config->black_memqcache_table_list == NULL)
- {
- fclose(fd);
- return(-1);
- }
- for (i=0;i<pool_config->num_black_memqcache_table_list;i++)
- {
- add_regex_pattern("black_memqcache_table_list", pool_config->black_memqcache_table_list[i]);
- }
- }
-
- else if (!strcmp(key, "database_redirect_preference_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
- int i;
- Left_right_tokens *lrtokens;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- pool_config->database_redirect_preference_list = str;
- lrtokens = create_lrtoken_array();
- extract_string_tokens2(str, ",", ':', lrtokens);
-
- pool_config->redirect_dbnames = create_regex_array();
- pool_config->db_redirect_tokens = lrtokens;
-
- for (i=0;i<lrtokens->pos;i++)
- {
- if (!check_redirect_node_spec(lrtokens->token[i].right_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
- return(-1);
- }
-
- if (*(lrtokens->token[i].left_token) == '\0' ||
- add_regex_array(pool_config->redirect_dbnames, lrtokens->token[i].left_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect dbname regular expression: \"%s\"", lrtokens->token[i].left_token)));
- return(-1);
- }
- }
- }
-
- else if (!strcmp(key, "app_name_redirect_preference_list") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- char *str;
- int i;
- Left_right_tokens *lrtokens;
-
- if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
- {
- PARSE_ERROR();
- fclose(fd);
- return(-1);
- }
- str = extract_string(yytext, token);
- if (str == NULL)
- {
- fclose(fd);
- return(-1);
- }
-
- pool_config->app_name_redirect_preference_list = str;
- lrtokens = create_lrtoken_array();
- extract_string_tokens2(str, ",", ':', lrtokens);
-
- pool_config->redirect_app_names = create_regex_array();
- pool_config->app_name_redirect_tokens = lrtokens;
-
- for (i=0;i<lrtokens->pos;i++)
- {
- if (!check_redirect_node_spec(lrtokens->token[i].right_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token)));
- return(-1);
- }
-
-
- if (*(lrtokens->token[i].left_token) == '\0' ||
- add_regex_array(pool_config->redirect_app_names, lrtokens->token[i].left_token))
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("wrong redirect app name regular expression: \"%s\"", lrtokens->token[i].left_token)));
- return(-1);
- }
- }
- }
-
- else if (!strcmp(key, "allow_sql_comments") &&
- CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
- {
- int v = eval_logical(yytext);
-
- if (v < 0)
- {
- fclose(fd);
- ereport(error_level,
- (errmsg("invalid configuration for key \"%s\"",key),
- errdetail("invalid value:\"%s\" for key:\"%s\"", yytext,key),
- errhint("value must be greater than or equal to 0")));
-
- return(-1);
- }
- pool_config->allow_sql_comments = v;
- }
-
- }
-
- fclose(fd);
-
- if (log_destination_changed)
- {
- /* log_destination has changed, we need to open syslog or close it */
- if (!strcmp(pool_config->log_destination, "stderr"))
- {
- closelog();
- pool_config->logsyslog = 0;
- }
- else
- {
- openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility);
- pool_config->logsyslog = 1;
- }
- }
-
- pool_config->backend_desc->num_backends = 0;
- total_weight = 0.0;
-
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- /* port number == 0 indicates that this server is out of use */
- if (BACKEND_INFO(i).backend_port == 0)
- {
- clear_host_entry(i);
- }
-
- else
- {
- total_weight += BACKEND_INFO(i).unnormalized_weight;
- pool_config->backend_desc->num_backends = i+1;
-
- /* initialize backend_hostname with a default socket path if empty */
- if (*(BACKEND_INFO(i).backend_hostname) == '\0')
- {
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("empty backend_hostname%d, use PostgreSQL's default unix socket path (%s)",
- i, DEFAULT_SOCKET_DIR)));
- strlcpy(BACKEND_INFO(i).backend_hostname, DEFAULT_SOCKET_DIR, MAX_DB_HOST_NAMELEN);
- }
- }
- }
-
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("num_backends: %d total_weight: %f",
- pool_config->backend_desc->num_backends, total_weight)));
- /*
- * Normalize load balancing weights. What we are doing here is,
- * assign 0 to RAND_MAX to each backend's weight according to the
- * value weightN. For example, if two backends are assigned 1.0,
- * then each backend will get RAND_MAX/2 normalized weight.
- */
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
-#ifdef DEBUG
- print_host_entry(i);
-#endif
-
- if (BACKEND_INFO(i).backend_port != 0)
- {
- BACKEND_INFO(i).backend_weight =
- (RAND_MAX) * BACKEND_INFO(i).unnormalized_weight / total_weight;
- ereport(DEBUG1,
- (errmsg("initializing pool configuration"),
- errdetail("backend %d weight: %f flag: %04x", i, BACKEND_INFO(i).backend_weight,BACKEND_INFO(i).flag)));
- }
- }
-
- if (strcmp(pool_config->recovery_1st_stage_command, "") ||
- strcmp(pool_config->recovery_2nd_stage_command, ""))
- {
- for (i=0;i<MAX_CONNECTION_SLOTS;i++)
- {
- if (pool_config->backend_desc->backend_info[i].backend_port != 0 &&
- !strcmp(pool_config->backend_desc->backend_info[i].backend_data_directory, ""))
- {
- ereport(ERROR,
- (errmsg("invalid configuration, recovery_1st_stage_command and recovery_2nd_stage_command requires backend_data_directory to be set")));
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static char *extract_string(char *value, POOL_TOKEN token)
-{
- char *ret;
-
- ret = pstrdup(value);
-
- if (token == POOL_STRING)
- {
- ret[strlen(ret)-1] = '\0';
- return (ret+1);
- }
- return ret;
-}
-
-/*
- * Try to interpret value as boolean value. Valid values are: true,
- * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
- * If the string parses okay, return true, else false.
- * If okay and result is not NULL, return the value in *result.
- * This function copied from PostgreSQL source code.
- */
-static bool parse_bool_with_len(const char *value, size_t len, bool *result)
-{
- switch (*value)
- {
- case 't':
- case 'T':
- if (strncasecmp(value, "true", len) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case 'f':
- case 'F':
- if (strncasecmp(value, "false", len) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case 'y':
- case 'Y':
- if (strncasecmp(value, "yes", len) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case 'n':
- case 'N':
- if (strncasecmp(value, "no", len) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case 'o':
- case 'O':
- /* 'o' is not unique enough */
- if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
- {
- if (result)
- *result = true;
- return true;
- }
- else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- case '1':
- if (len == 1)
- {
- if (result)
- *result = true;
- return true;
- }
- break;
- case '0':
- if (len == 1)
- {
- if (result)
- *result = false;
- return true;
- }
- break;
- default:
- break;
- }
-
- if (result)
- *result = false; /* suppress compiler warning */
- return false;
-}
-
-int eval_logical(char *str)
-{
- bool result;
-
- if (!parse_bool_with_len(str, strlen(str), &result))
- return -1;
-
- return (result ? 1 : 0);
-}
-
-/*
- * Extract tokens separated by delimi from str. Return value is an
- * array of pointers in pallocd strings. number of tokens is set to
- * n; note that str will be destroyed by strtok().
- */
-#define MAXTOKENS 1024
-static char **extract_string_tokens(char *str, char *delimi, int *n)
-{
- char *token;
- static char **tokens;
-
- *n = 0;
-
- tokens = palloc(MAXTOKENS*sizeof(char *));
-
- for (token = strtok(str, delimi); token != NULL && *n < MAXTOKENS; token = strtok(NULL, delimi))
- {
- tokens[*n] = pstrdup(token);
- ereport(DEBUG3,
- (errmsg("initializing pool configuration"),
- errdetail("extracting string tokens [token: %s]", tokens[*n])));
-
- (*n)++;
- }
- return tokens;
-}
-
-static void clear_host_entry(int slot)
-{
- *pool_config->backend_desc->backend_info[slot].backend_hostname = '\0';
- pool_config->backend_desc->backend_info[slot].backend_port = 0;
- pool_config->backend_desc->backend_info[slot].backend_status = CON_UNUSED;
- pool_config->backend_desc->backend_info[slot].backend_weight = 0.0;
-}
#ifdef DEBUG
static void print_host_entry(int slot)
@@ -5210,44 +2249,6 @@ static void print_host_entry(int slot)
}
#endif
-/* Use to set the syslog facility level if logsyslog is activated */
-int set_syslog_facility(char *value)
-{
- int facility = LOG_LOCAL0;
-
- if (value == NULL)
- return facility;
-
- if (strncmp(value, "LOCAL", 5) == 0 && strlen(value) == 6) {
- switch (value[5]) {
- case '0':
- facility = LOG_LOCAL0;
- break;
- case '1':
- facility = LOG_LOCAL1;
- break;
- case '2':
- facility = LOG_LOCAL2;
- break;
- case '3':
- facility = LOG_LOCAL3;
- break;
- case '4':
- facility = LOG_LOCAL4;
- break;
- case '5':
- facility = LOG_LOCAL5;
- break;
- case '6':
- facility = LOG_LOCAL6;
- break;
- case '7':
- facility = LOG_LOCAL7;
- break;
- }
- }
- return facility;
-}
/*
* Translate binary form of backend flag to string.
@@ -5265,40 +2266,4 @@ char *pool_flag_to_str(unsigned short flag)
return buf;
}
-/*
- * Check DB node spec. node spec should be either "primary", "standby" or
- * numeric DB node id.
-*/
-bool check_redirect_node_spec(char *node_spec)
-{
- int len = strlen(node_spec);
- int i;
- long val;
-
- if (len <= 0)
- return false;
-
- if (strcasecmp("primary", node_spec) == 0)
- {
- return true;
- }
-
- if (strcasecmp("standby", node_spec) == 0)
- {
- return true;
- }
-
- for (i=0;i<len;i++)
- {
- if (!isdigit((int)node_spec[i]))
- return false;
- }
-
- val = atol(node_spec);
-
- if (val >=0 && val < MAX_NUM_BACKENDS)
- return true;
-
- return false;
-}
diff --git a/src/utils/json.c b/src/utils/json.c
index 79587e80e..eee00c120 100644
--- a/src/utils/json.c
+++ b/src/utils/json.c
@@ -1102,6 +1102,26 @@ json_value* json_get_value_for_key(json_value* source, const char* key)
* for all other cases when key or integer value is not found
* function returns -1
*/
+
+int json_get_bool_value_for_key(json_value* source, const char* key, bool* value)
+{
+ json_value* jNode;
+
+ jNode = json_get_value_for_key(source,key);
+ if (jNode == NULL)
+ return -1;
+ /* for older version compatibility, We use int for encoding bool values */
+ if (jNode->type == json_integer || jNode->type == json_boolean)
+ {
+ *value = jNode->u.integer?true:false;
+ }
+ else
+ return -1;
+
+ return 0;
+}
+
+
int json_get_int_value_for_key(json_value* source, const char* key, int* value)
{
json_value* jNode;
diff --git a/src/utils/json_writer.c b/src/utils/json_writer.c
index fb8f4ebcc..833f9d113 100644
--- a/src/utils/json_writer.c
+++ b/src/utils/json_writer.c
@@ -67,6 +67,12 @@ bool jw_put_string(JsonNode* jNode, char* key, char* value)
return true;
}
+/* for compatibility reasons we pack bool in int*/
+bool jw_put_bool(JsonNode* jNode, char* key, bool value)
+{
+ return jw_put_int(jNode,key,value?1:0);
+}
+
bool jw_put_int(JsonNode* jNode, char* key, int value)
{
if (key == NULL)
@@ -131,6 +137,11 @@ bool jw_put_string_value(JsonNode* jNode, char* value)
return true;
}
+bool jw_put_bool_value(JsonNode* jNode, bool value)
+{
+ return jw_put_int_value(jNode, value?1:0);
+}
+
bool jw_put_int_value(JsonNode* jNode, int value)
{
if (jw_get_current_element_count(jNode) < 0)
diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c
index 9687bb494..9b190c79e 100644
--- a/src/utils/pool_process_reporting.c
+++ b/src/utils/pool_process_reporting.c
@@ -323,7 +323,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
i++;
StrNCpy(status[i].name, "log_standby_delay", POOLCONFIG_MAXNAMELEN);
- snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->log_standby_delay);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_standby_delay);
StrNCpy(status[i].desc, "how to log standby delay", POOLCONFIG_MAXDESCLEN);
i++;
@@ -455,7 +455,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
i++;
StrNCpy(status[i].name, "master_slave_sub_mode", POOLCONFIG_MAXNAMELEN);
- snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->master_slave_sub_mode);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->master_slave_sub_mode);
StrNCpy(status[i].desc, "master/slave sub mode", POOLCONFIG_MAXDESCLEN);
i++;
@@ -633,7 +633,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
i++;
StrNCpy(status[i].name, "wd_lifecheck_method", POOLCONFIG_MAXNAMELEN);
- snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->wd_lifecheck_method);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->wd_lifecheck_method);
StrNCpy(status[i].desc, "method of watchdog lifecheck", POOLCONFIG_MAXDESCLEN);
i++;
@@ -775,7 +775,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
i++;
StrNCpy(status[i].name, "memqcache_method", POOLCONFIG_MAXNAMELEN);
- snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->memqcache_method);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->memqcache_method);
StrNCpy(status[i].desc, "Cache store method. either shmem(shared memory) or Memcached. shmem by default", POOLCONFIG_MAXDESCLEN);
i++;
diff --git a/src/utils/regex_array.c b/src/utils/regex_array.c
index a262bdcf1..5541d27fc 100644
--- a/src/utils/regex_array.c
+++ b/src/utils/regex_array.c
@@ -5,7 +5,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2015 PgPool Global Development Group
+ * Copyright (c) 2003-2016 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
diff --git a/src/watchdog/watchdog.c b/src/watchdog/watchdog.c
index 69cc956e0..ffa851d9f 100644
--- a/src/watchdog/watchdog.c
+++ b/src/watchdog/watchdog.c
@@ -462,7 +462,7 @@ wd_check_config(void)
ereport(ERROR,
(errmsg("invalid watchdog configuration. wd_authkey length can't be larger than %d",
MAX_PASSWORD_SIZE)));
- if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT))
+ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB)
{
if (pool_config->num_hb_if <= 0)
ereport(ERROR,
@@ -867,7 +867,7 @@ static void check_signals(void)
if (reload_config_signal)
{
MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
- pool_get_config(get_config_file_name(), RELOAD_CONFIG);
+ pool_get_config(get_config_file_name(), CFGCXT_RELOAD);
MemoryContextSwitchTo(oldContext);
reload_config_signal = 0;
}
diff --git a/src/watchdog/wd_json_data.c b/src/watchdog/wd_json_data.c
index df97d70d0..a0710f832 100644
--- a/src/watchdog/wd_json_data.c
+++ b/src/watchdog/wd_json_data.c
@@ -31,6 +31,7 @@
#include "watchdog/wd_json_data.h"
#include "watchdog/wd_ipc_defines.h"
+
POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len)
{
int i;
@@ -58,21 +59,21 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len)
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "max_pool", &config->max_pool))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "replication_mode", &config->replication_mode))
+ if (json_get_bool_value_for_key(root, "replication_mode", &config->replication_mode))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "enable_pool_hba", &config->enable_pool_hba))
+ if (json_get_bool_value_for_key(root, "enable_pool_hba", &config->enable_pool_hba))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "load_balance_mode", &config->load_balance_mode))
+ if (json_get_int_value_for_key(root, "load_balance_mode", (int*)&config->load_balance_mode))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "replication_stop_on_mismatch", &config->replication_stop_on_mismatch))
+ if (json_get_bool_value_for_key(root, "replication_stop_on_mismatch", &config->replication_stop_on_mismatch))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "failover_if_affected_tuples_mismatch", &config->failover_if_affected_tuples_mismatch))
+ if (json_get_bool_value_for_key(root, "failover_if_affected_tuples_mismatch", &config->failover_if_affected_tuples_mismatch))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "replicate_select", &config->replicate_select))
+ if (json_get_bool_value_for_key(root, "replicate_select", &config->replicate_select))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "master_slave_mode", &config->master_slave_mode))
+ if (json_get_int_value_for_key(root, "master_slave_mode", (int*)&config->master_slave_mode))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "connection_cache", &config->connection_cache))
+ if (json_get_bool_value_for_key(root, "connection_cache", &config->connection_cache))
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "health_check_timeout", &config->health_check_timeout))
goto ERROR_EXIT;
@@ -82,7 +83,7 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len)
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "health_check_retry_delay", &config->health_check_retry_delay))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "fail_over_on_backend_error", &config->fail_over_on_backend_error))
+ if (json_get_bool_value_for_key(root, "fail_over_on_backend_error", &config->fail_over_on_backend_error))
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "recovery_timeout", &config->recovery_timeout))
goto ERROR_EXIT;
@@ -90,23 +91,20 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len)
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "client_idle_limit_in_recovery", &config->client_idle_limit_in_recovery))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "insert_lock", &config->insert_lock))
+ if (json_get_bool_value_for_key(root, "insert_lock", &config->insert_lock))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "memory_cache_enabled", &config->memory_cache_enabled))
+ if (json_get_bool_value_for_key(root, "memory_cache_enabled", &config->memory_cache_enabled))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "use_watchdog", &config->use_watchdog))
+ if (json_get_bool_value_for_key(root, "use_watchdog", &config->use_watchdog))
goto ERROR_EXIT;
- if (json_get_int_value_for_key(root, "clear_memqcache_on_escalation", &config->clear_memqcache_on_escalation))
+ if (json_get_bool_value_for_key(root, "clear_memqcache_on_escalation", &config->clear_memqcache_on_escalation))
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "wd_port", &config->wd_port))
goto ERROR_EXIT;
if (json_get_int_value_for_key(root, "wd_priority", &config->wd_priority))
goto ERROR_EXIT;
-
- config->master_slave_sub_mode = json_get_string_value_for_key(root, "master_slave_sub_mode");
- if (config->master_slave_sub_mode == NULL)
+ if (json_get_int_value_for_key(root, "master_slave_sub_mode", (int*)&config->master_slave_sub_mode))
goto ERROR_EXIT;
- config->master_slave_sub_mode = pstrdup(config->master_slave_sub_mode);
/* backend_desc array */
@@ -155,8 +153,6 @@ ERROR_EXIT:
json_value_free(root);
if (config->backend_desc)
pfree(config->backend_desc);
- if (config->master_slave_sub_mode)
- pfree(config->master_slave_sub_mode);
pfree(config);
return NULL;
}
@@ -175,30 +171,29 @@ char* get_pool_config_json(void)
jw_put_int(jNode, "child_max_connections", pool_config->child_max_connections);
jw_put_int(jNode, "client_idle_limit", pool_config->client_idle_limit);
jw_put_int(jNode, "max_pool", pool_config->max_pool);
- jw_put_int(jNode, "replication_mode", pool_config->replication_mode);
- jw_put_int(jNode, "enable_pool_hba", pool_config->enable_pool_hba);
+ jw_put_bool(jNode, "replication_mode", pool_config->replication_mode);
+ jw_put_bool(jNode, "enable_pool_hba", pool_config->enable_pool_hba);
jw_put_int(jNode, "load_balance_mode", pool_config->load_balance_mode);
- jw_put_int(jNode, "replication_stop_on_mismatch", pool_config->replication_stop_on_mismatch);
- jw_put_int(jNode, "failover_if_affected_tuples_mismatch", pool_config->failover_if_affected_tuples_mismatch);
- jw_put_int(jNode, "replicate_select", pool_config->replicate_select);
+ jw_put_bool(jNode, "replication_stop_on_mismatch", pool_config->replication_stop_on_mismatch);
+ jw_put_bool(jNode, "failover_if_affected_tuples_mismatch", pool_config->failover_if_affected_tuples_mismatch);
+ jw_put_bool(jNode, "replicate_select", pool_config->replicate_select);
jw_put_int(jNode, "master_slave_mode", pool_config->master_slave_mode);
- jw_put_int(jNode, "connection_cache", pool_config->connection_cache);
+ jw_put_bool(jNode, "connection_cache", pool_config->connection_cache);
jw_put_int(jNode, "health_check_timeout", pool_config->health_check_timeout);
jw_put_int(jNode, "health_check_period", pool_config->health_check_period);
jw_put_int(jNode, "health_check_max_retries", pool_config->health_check_max_retries);
jw_put_int(jNode, "health_check_retry_delay", pool_config->health_check_retry_delay);
- jw_put_int(jNode, "fail_over_on_backend_error", pool_config->fail_over_on_backend_error);
+ jw_put_bool(jNode, "fail_over_on_backend_error", pool_config->fail_over_on_backend_error);
jw_put_int(jNode, "recovery_timeout", pool_config->recovery_timeout);
jw_put_int(jNode, "search_primary_node_timeout", pool_config->search_primary_node_timeout);
jw_put_int(jNode, "client_idle_limit_in_recovery", pool_config->client_idle_limit_in_recovery);
- jw_put_int(jNode, "insert_lock", pool_config->insert_lock);
- jw_put_int(jNode, "memory_cache_enabled", pool_config->memory_cache_enabled);
- jw_put_int(jNode, "use_watchdog", pool_config->use_watchdog);
- jw_put_int(jNode, "clear_memqcache_on_escalation", pool_config->clear_memqcache_on_escalation);
+ jw_put_bool(jNode, "insert_lock", pool_config->insert_lock);
+ jw_put_bool(jNode, "memory_cache_enabled", pool_config->memory_cache_enabled);
+ jw_put_bool(jNode, "use_watchdog", pool_config->use_watchdog);
+ jw_put_bool(jNode, "clear_memqcache_on_escalation", pool_config->clear_memqcache_on_escalation);
jw_put_int(jNode, "wd_port", pool_config->wd_port);
jw_put_int(jNode, "wd_priority", pool_config->wd_priority);
-
- jw_put_string(jNode, "master_slave_sub_mode", pool_config->master_slave_sub_mode);
+ jw_put_int(jNode, "master_slave_sub_mode", pool_config->master_slave_sub_mode);
/* Array of backends */
jw_start_array(jNode, "backend_desc");
diff --git a/src/watchdog/wd_lifecheck.c b/src/watchdog/wd_lifecheck.c
index 229de38c4..4cf4d7ef1 100644
--- a/src/watchdog/wd_lifecheck.c
+++ b/src/watchdog/wd_lifecheck.c
@@ -238,7 +238,7 @@ wd_reaper_lifecheck(pid_t pid, int status)
static bool lifecheck_kill_all_children(int sig)
{
bool ret = false;
- if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)
+ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB
&& g_hb_receiver_pid && g_hb_sender_pid)
{
int i;
@@ -322,7 +322,7 @@ pid_t initialize_watchdog_lifecheck(void)
if (!pool_config->use_watchdog)
return 0;
- if (!strcmp(pool_config->wd_lifecheck_method, MODE_EXTERNAL))
+ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_EXTERNAL)
return 0;
return fork_lifecheck_child();
@@ -449,7 +449,7 @@ lifecheck_main(void)
static void spawn_lifecheck_children(void)
{
- if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT))
+ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB)
{
int i;
g_hb_receiver_pid = palloc0(sizeof(pid_t) * pool_config->num_hb_if);
@@ -621,7 +621,7 @@ static int is_wd_lifecheck_ready(void)
{
LifeCheckNode* node = &gslifeCheckCluster->lifeCheckNodes[i];
/* query mode */
- if (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY))
+ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_QUERY)
{
if (wd_ping_pgpool(node) == WD_NG)
{
@@ -633,7 +633,7 @@ static int is_wd_lifecheck_ready(void)
}
}
/* heartbeat mode */
- else if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT))
+ else if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB)
{
if (node->ID == 0) /* local node */
continue;
@@ -652,7 +652,7 @@ static int is_wd_lifecheck_ready(void)
else
{
ereport(ERROR,
- (errmsg("checking if watchdog is ready, unkown watchdog mode \"%s\"",
+ (errmsg("checking if watchdog is ready, unkown watchdog mode \"%d\"",
pool_config->wd_lifecheck_method)));
}
}
@@ -703,12 +703,12 @@ static void
check_pgpool_status()
{
/* query mode */
- if (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY))
+ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_QUERY)
{
check_pgpool_status_by_query();
}
/* heartbeat mode */
- else if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT))
+ else if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB)
{
check_pgpool_status_by_hb();
}
[parent: 441be4314c95]